综述
这篇笔记主要是为了记录下自己写 k8s 综合项目的过程。
由于自己之前已经写过简单的开发和运维项目,所以这里就结合一下,在搭建 k8s 集群后安装运维常用服务,比如 ansible 和 prometheus,用 NFS 实现数据存储同步,再部署一些制作成镜像的应用,进行压力测试,尝试发布,可以的话安装一些 CICD 相关软件,比如 gitlab、harbor、jenkins,主要是为了让自己更熟悉这些流程。
具体要达成的效果,就是实现容器化应用部署(通过 Kubernetes 部署和管理多个微服务应用)、监控和告警(使用 Prometheus 和 Grafana 进行集群和应用监控,及时发现和处理问题)、持久化存储(通过 NFS 提供持久化存储,支持应用的数据持久化)、负载均衡(通过 Ingress Controller 实现请求的负载均衡和路由)、弹性伸缩(通过 HPA 实现基于资源使用情况的自动扩缩容)、CI/CD流水线(使用 GitLab、Harbor 和 Jenkins 实现持续集成和持续部署,自动化构建和发布流程)、故障恢复(通过探针和监控实现故障检测和自动恢复)等。
这个项目不仅可以帮助团队更高效地开发和部署应用,还能提升运维的自动化程度。
项目过程
安装虚拟机
因为安装虚拟机的部分在前面的笔记里有一步步介绍个过,所以这里就不再展开介绍了。
最后开启虚拟机前记得选择对应的镜像文件。
在xshell登录后为了后续方便分辨机器,可以先自行修改主机名,这里用节点二为例。
这里在进行一切后续操作之前必须换一个国内源,原理和操作在之前的 docker 笔记都提过了,这里也就不再展开介绍。
这里安装 net-tools 是为了后面查看网络连接、路由表、接口统计等信息。。
对应的 netstat 命令可以帮助用户了解系统的网络状态,包括当前打开的TCP和UDP端口、网络连接的状态等。
修改为静态IP
这里进入根目录下的 network-scripts 是为了修改静态IP,避免之后IP变化影响k8s集群配置。
这一步就是为了方便修改,也可以免去这步,直接用 nano 编辑文件也可以。
这里是顺便先安装了扩展源,避免之后安装遇到阻碍。
这里编辑网关相关文件。
下面是具体修改内容。
只需修改红框内的内容,其他的不用管。网关地址的配置只需确保其唯一即可。
还可以加入上图的DNS信息,这是网络配置文件中的一行,用于指定 DNS(域名系统)服务器的地址。这里的 8.8.8.8 是 Google 提供的公共 DNS 服务器地址。
这里的 114.114.114.114 是由中国电信提供的一家公共 DNS 服务器,由于该 DNS 服务器位于中国,通常对于国内用户的访问速度较快,且相对稳定。
修改后重启一下。
查询后出现上面的结果表明修改静态IP成功。
配置到这里后,如果为了方便,其实另外几台 master 或者 node 可以直接克隆配置好的这台,我因为电脑也带不动太多,所以这几台都是一个个配置的。
配置主机清单
配置 hosts 文件,通过主机名互相访问。
关闭SELINUX
这是为了避免权限问题,因为Kubernetes 和容器化应用程序可能会与 SELinux 的默认策略发生冲突,从而影响 Pod 的运行。
# 临时关闭
setenforce 0
# 永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 修改selinux配置文件之后,重启机器,selinux配置才能永久生效
reboot# 检查
getenforce
# 显示Disabled说明selinux已经关闭
关闭firewalld和iptables
firewalld 是一种动态防火墙管理工具,使用 zones 和 services 来管理网络流量。
关闭 firewalld 是为了避免网络干扰,在 Kubernetes 集群中,Pod 之间的通信依赖于网络流量的开放,关闭 firewalld 可以避免防火墙规则阻止 Pod 之间的流量;关闭 firewalld 可以减少网络配置的复杂性,特别是在调试和测试环境中。
iptables 是 Linux 内核的一个组件,用于配置网络流量过滤规则。
关闭 iptables 是为了避免流量阻塞,在 Kubernetes 中,Pod 之间的流量可能会受到 iptables 规则的影响,闭 iptables 可以确保所有流量不受限制地通过; 关闭 iptables 可以简化网络管理,尤其是在调试和开发环境中。
systemctl stop firewalld
systemctl disable firewalld
iptables -F
这条命令可以清除当前防火墙的所有规则。
下面是关闭交换分区的命令。
# 临时关闭
swapoff -a
# 永久关闭
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 或者 vim /etc/fstab ,进去注释 swap 那行
这一步的作用如下。
1、保证性能。Kubernetes 依赖于节点的内存进行资源调度和管理。如果系统启用了交换分区,Kubernetes 可能会将某些 Pod 调度到内存不足的节点上,而这些节点可能会因为使用交换空间而导致性能下降。
2、避免不确定性。启用交换分区可能导致 Pod 的 OOM(Out Of Memory)杀手在处理内存不足时做出不可预测的行为。Kubernetes 在内存管理方面假设节点的内存是固定的,使用交换空间可能打破这种假设。
3、提升稳定性。在 Kubernetes 中,关闭交换可以确保当节点的内存达到阈值时,Pod 能够正确地被 Kubernetes 调度和管理,避免出现性能瓶颈或服务中断。
调整内核参数
具体修改和查看的命令如下。
这里解释一下这里调整各个参数和命令的作用。
# 内核参数设置
net.bridge.bridge-nf-call-iptables = 1
# 该参数配置 Linux 内核的网络桥接(bridge)功能,允许 iptables 规则应用于通过桥接接口的流量
# 启用此参数后,所有通过 Linux 桥接转发的流量将经过 iptables 进行过滤
# 重要性
# 在 Kubernetes 中,Pod 之间的通信通常通过 Linux 桥接网络进行
# 启用此参数可以确保网络策略(Network Policies)和防火墙规则能够正确应用到 Pod 之间的流量net.bridge.bridge-nf-call-ip6tables = 1
# 和上面的参数类似,但这是针对 IPv6 流量
# 它允许 ip6tables 规则应用于通过桥接接口的 IPv6 流量
# 重要性
# 如果 Kubernetes 集群支持 IPv6,启用此参数是必要的,因为可以以确保 IPv6 流量能够被正确过滤和管理net.ipv4.ip_forward = 1
# 启用 IP 转发功能,这允许 Linux 内核在接收到数据包时,将其转发到其他网络接口
# 重要性
# 在 Kubernetes 集群中,Pod 需要能够与其他 Pod、服务以及外部网络通信
# 启用 IP 转发是实现这种通信的必要条件sysctl -p
# 该命令用于重新加载 sysctl 配置文件中的所有参数
# 通常在更改 `/etc/sysctl.conf` 或其他 sysctl 配置文件后使用
# 重要性
# 通过重新加载参数,可以确保所有设置立即生效,而无需重启系统modprobe br_netfilter
# 该命令用于加载 `br_netfilter` 内核模块。此模块提供了对桥接网络流量进行过滤的能力
# 重要性
# 在使用 Kubernetes 的网络桥接功能时,加载此模块是必要的,以确保 iptables 规则能够正确应用于桥接流量lsmod | grep br_netfilter
# 该命令用于检查 `br_netfilter` 模块是否已加载。如果模块已被加载,它将显示相关信息
# 重要性
# 确保 `br_netfilter` 模块已加载是确保 Kubernetes 网络功能正常运作的关键步骤# 总的来说,这些设置和命令主要用于配置 Kubernetes 集群的网络功能,确保流量能正确地通过 iptables 进行过滤和管理。启用这些参数和模块有助于实现更安全和高效的网络通信,确保 Pod 之间以及与外部网络的连接正常
这一步的作用如下。
1、优化性能。一些内核参数可以优化网络性能、内存管理和进程调度等。调整这些参数可以提高集群的整体性能和响应速度。
2、提高可靠性。某些参数(如 vm.swappiness)影响系统如何使用内存和交换。通过调整这些参数,可以更好地控制系统在内存不足时的行为,从而提高应用程序的可靠性。
3、适应容器化环境。Kubernetes 运行在容器之上,某些内核参数可能需要根据容器的特性进行调整,以确保容器能够高效运行。
自动加载内核模块
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOFmodprobe overlay
modprobe br_netfilter
overlay,这个模块用于支持 Overlay 网络。它允许创建虚拟网络,以便在不同主机上的容器之间进行通信。
br_netfilter,这个模块用于确保网络流量通过 Linux 桥接网络时可以被正确过滤。Kubernetes 中的网络插件通常需要这个模块来正确处理网络策略和防火墙规则。
可以用这条命令查看 br_netfilter 和 overlay 模块是否加载成功。
更新和配置软件源
上面其实也提到过,这里就简单放个代码。
cd /etc/yum.repos.d
rm -rf *
curl -O http://mirrors.aliyun.com/repo/Centos-7.repo
这里是额外的操作,最好执行,会使后续操作更加方便。
yum clean all && yum makecache fast
# 清理 YUM 缓存并快速生成新的缓存,以确保获取最新的包信息
yum install -y yum-utils
# 安装 yum-utils,以便使用额外的 YUM 工具
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 添加 Docker CE 的阿里云镜像仓库,以便后续可以方便地安装 Docker CE
配置ipvs功能
# 安装ipset和ipvsadm,主要是对ipvs进行传递参数的或者管理的
yum install ipset ipvsadm -y# 添加需要加载的模块写入脚本文件
#modprobo 作用是加载模块到内核里
cat <<EOF > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 为脚本文件添加执行权限
chmod +x /etc/sysconfig/modules/ipvs.modules
# 执行脚本文件
/bin/bash /etc/sysconfig/modules/ipvs.modules
# 重启
reboot# 查看对应的模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
reboot 重启之后再看模块是否加载成功。
配置时间同步
systemctl restart chronyd && systemctl enable chronyd
安装docker环境
如果之前安装过 docker,这里就需要先移除原有的环境,我这里因为都是全新安装的虚拟机,所以不需要,就只放个代码。
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
移除后重新下载。
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 总结
# Docker CE: 通过安装 docker-ce,用户可以获得 Docker 的核心功能
# Docker CLI: docker-ce-cli 使得用户能够通过命令行与 Docker 守护进程交互
# Containerd: containerd.io 提供了容器的运行时支持
# Buildx 插件: docker-buildx-plugin 使得用户能够使用更高级的构建功能
# Docker Compose 插件: docker-compose-plugin 允许用户使用 Docker CLI 管理多容器应用
配置docker服务自启动
# 启动docker
systemctl start docker
# 设置docker开机启动
systemctl enable docker
# 验证
systemctl status docker
启动 docker 并确保之后都会自启动后查看一下 docker 状态,是否在运行。
配置docker的国内镜像源加速
vim /etc/docker/daemon.json
# 下面是 daemon.json 里面的内容
{"registry-mirrors": ["https://hub.docker-alhk.dkdun.com/"],"exec-opts": ["native.cgroupdriver=systemd"]
}
# 重启服务生效
systemctl daemon-reload
systemctl restart docker
配置cri-docker
kubernets 1.24版本后默认使用containerd做底层容器,需要使用cri-dockerd做中间层来与docker通信
如果下载多次失败,可以去Gitee里的一个开源点下载对应版本的到本机,再用xftp上传到各个虚拟机。
cri-dockerd:dockerd as a compliant Container Runtime Interface for Kubernetes - GitCodehttps://gitcode.com/gh_mirrors/cr/cri-dockerd/tags?presetConfig=%7B%22tags%22:23,%22release%22:0%7D
我后面下载rpm成功了,所以上面的就没再继续。
# 下载
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.8/cri-dockerd-0.3.8-3.el7.x86_64.rpm
# 安装
rpm -ivh cri-dockerd-0.3.8-3.el7.x86_64.rpm
# 重载系统守护进程
systemctl daemon-reload
# 修改配置文件
vim /usr/lib/systemd/system/cri-docker.service
# 修改第10行 ExecStart
# 改为
# ExecStart=/usr/bin/cri-dockerd --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 --container-runtime-endpoint fd://
配置k8s集群环境
这里安装的是 k8s 1.28 版本。
安装kubectl
# 下载
curl -LO "https://dl.k8s.io/release/v1.28.2/bin/linux/amd64/kubectl"
# 检验 可选
curl -LO "https://dl.k8s.io/v1.28.2/bin/linux/amd64/kubectl.sha256"
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
# 安装
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 测试
kubectl version --client
配置k8s组件源
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 更新索引缓冲
yum makecache
安装
# 安装
yum install -y install kubeadm-1.28.2-0 kubelet-1.28.2-0 kubectl-1.28.2-0 --disableexcludes=kubernetes
# 如果报错未找到就试试不指定版本
yum install -y install kubeadm kubelet kubectl --disableexcludes=kubernetes
# 设置自启动
systemctl enable --now kubelet
# kubeadm - 用来安装master节点上的组件(apiserver、etcd、scheduler等),部署k8s集群的
# kubelet - 用来对容器运行时软件进行管理的(管理docker的)
# kubectl - 用来输入k8s的命令的
集群初始化
kubeadm init
这一步仅在 master 节点执行。
kubeadm init --kubernetes-version=v1.28.2 \--pod-network-cidr=10.224.0.0/16 \--apiserver-advertise-address=master的IP \ --image-repository=registry.aliyuncs.com/google_containers \--cri-socket=unix:///var/run/cri-dockerd.sock
其中,apiserver-advertise-address 记得替换为 master 节点IP。
成功后会提示以下信息。
在系统提示命令 " kubectl join xxx " 后追加 " --cri-socket unix:///var/run/cri-dockerd.sock "。
完整命令应该类似于 " kubeadm join master的IP地址:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx --cri-socket unix:///var/run/cri-dockerd.sock "。
将 node 节点加入集群
将上面的那段密钥复制粘贴到其他节点内部。
完成后应该能得到以下结果。
# 在master上执行
kubectl get nodes
分配 worker
# 在master上执行
kubectl label node k8s-node-1 node-role.kubernetes.io/worker=worker
kubectl label node k8s-node-2 node-role.kubernetes.io/worker=worker
安装Calico网络插件
# master执行
wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
# 验证
kubectl get nodes
安装完成后,可以检查下。
这里发现有几个都拉起失败,这是因为我用的国内网,很多时候无法正常拉取国外镜像仓库的文件。暂时的解决办法是在网上另外下载缺失的这两个镜像文件,将其导入本地。
导入完成后可以再次检查,这时没有完成可能是需要等会儿,也可能是没有在所有节点导入,记得在所有节点导入需要的镜像文件。
下面这里就可以看出已经安装和启动完毕。
安装Dashboard
以下命令均只在 master 节点上执行。
下载安装
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
修改 Service 部分,改为 NodePort 对外暴露端口。
kind: Service
apiVersion: v1
metadata:...
spec:type: NodePort # 改为NodePort
kubectl apply -f recommended.yaml
查看
kubectl get pods,svc -n kubernetes-dashboard
这里可以等一等。
创建账号
创建 dashboard-access-token.yaml 文件。
apiVersion: v1
kind: ServiceAccount
metadata:name: admin-usernamespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: admin-user
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-admin
subjects:
- kind: ServiceAccountname: admin-usernamespace: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:name: admin-usernamespace: kubernetes-dashboardannotations:kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token
下面这一步是为了获取后面在网站上登录的 token 密码。
# 获取token
kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d
访问dashboard
# 获取端口
kubectl get svc -n kubernetes-dashboard
这里看得出端口是30275。
然后在浏览器上访问网址为 - " 集群ip:端口(https://ip:端口号)"(注意https)。
之后再输入上一步获取到的 token 即可。
安装Kuborad
任意节点执行,推荐 master 节点。
sudo docker run -d \--restart=unless-stopped \--name=kuboard \-p 80:80 \-p 10081:10081 \-e KUBOARD_ENDPOINT="http://ip:80" \-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \-v /root/kuboard-data:/data \eipwork/kuboard:v3
在浏览器输入 http://IP:80 即可访问 Kuboard v3.x 的界面,登录时的用户名为 admin ,密码为 Kuboard123,下面是进入后的界面。
安装kubectl命令自动补全
yum install bash-completion -y
# 临时设置自动补全
source <(kubectl completion bash)
# 永久设置自动补全
echo "source <(kubectl completion bash)" >> ~/.bashrc && bash
部署metric-server
下载
在 master 节点上执行。
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.2/components.yaml
修改
修改140行左右。
原:containers:
- args:...image: k8s.gcr.io/metrics-server/metrics-server:v0.6.2
修改后:containers:
- args:...- --kubelet-insecure-tls # 添加这一行image: admin4j/metrics-server:v0.6.2 # 修改镜像仓库地址
应用
kubectl apply -f components.yaml
查看
kubectl top nodes # 显示集群中各个节点的资源使用情况
kubectl top pods # 显示集群中各个Pod的资源使用情况
提示错误或者其他,可以等等再试,我就是等了会儿才执行成功。
下面这个命令是在查看日志,看是否有错误提示。
上面这个命令是查看集群里每个节点的详细信息。
安装prometheus和grafana
安装prometheus和node_exporter
这一步是用来监控集群的日常性能情况。
二进制安装
更加具体的步骤在前面的 prometheus 笔记里,这里只记录大概。
下面这步可做可不做,这里建文件夹只是为了清晰分类。
然后解压。
这步重命名也是可做可不做,这里只是为了简化目录名。
这里是临时和永久修改PATH变量,添加 prometheus 的路径,最后查看效果。
然后可以添加一个添加 service 方式管理,以后可以直接 systemctl stop/start prometheus来停止和启动 prometheus ,方便操作。
修改后需要重启服务以生效,然后用 systemctl 启动 prometheus,并查看进程情况。
这里是查看进程运行情况。
node 节点这边也很简单,先如法炮制把 node_exporter 传过来。
再写一个安装 node_exporter 的全过程脚本。
然后运行脚本。
这样就可以了。
在另外一个节点上也如法炮制,可以把脚本通过 xftp 传到本机,再从本机通过 xftp 传到另外节点上运行,也可以用 ansible,因为这里只是做一个小项目测试,所以我暂时没用 ansible,直接用的 xftp。
下一步就是修改 prometheus.yml 里的内容,添加监控的虚拟机。
下面是具体的修改内容。
修改后重启一下 prometheus 的服务,就可以去浏览器上用 master 节点的IP加上9090端口查看详情。
Yaml文件安装
这种安装方法主要在Kubernetes或类似容器编排平台上进行,依赖Kubernetes集群和相关组件(如kubectl、etcd等)。
主要的优势在于以下几点:
1、配置通过YAML文件进行管理,易于版本控制和复制。
2、可以使用 Kubernetes 的滚动更新等功能来更新 Prometheus 配置或版本。
3、可以利用 Kubernetes 的自动扩展、健康检查等功能。
4、轻松实现 Prometheus 的水平扩展和高可用性配置(如使用 StatefulSet 和 Headless Service)。
5、可以利用 Kubernetes 的持久化存储解决方案(如 PersistentVolume)来持久化Prometheus 数据。
6、与 Kubernetes 生态系统紧密集成,可以轻松与其他 Kubernetes 组件和服务(如Grafana、Alertmanager 等)进行集成和交互。
7、可以利用 Kubernetes 的日志收集、监控和告警等功能来增强 Prometheus 的功能。
prometheus 可以在 master 或任意节点安装,也可以在 kubernets 集群外的虚拟机上安装,我这里是在 master 节点上安装的。
首先需要根据二进制文件制作相应的镜像,我这里因为自己制作的镜像在后续一直有问题解决不了,所以在网上下载了一个镜像导入本地,这个文件我也在CSDN上传了。
然后创建 prometheus-service.yaml 文件,这一步是用于暴露 Prometheus 监控服务。上面是具体实施效果图,下面是 yaml 文件中的具体内容。
apiVersion: v1
kind: Service
metadata:name: prometheusnamespace: prometheuslabels:app: prometheus
spec:type: NodePortports:- port: 9090targetPort: 9090protocol: TCPselector:app: prometheuscomponent: server
然后创建 prometheus-deploy.yaml 文件,这一步是用来定义 Prometheus 在 Kubernetes 环境中的部署配置。
具体 yaml 文件内容如下。
apiVersion: apps/v1
kind: Deployment
metadata:name: prometheus-servernamespace: prometheuslabels:app: prometheus
spec:replicas: 1selector:matchLabels:app: prometheuscomponent: servertemplate:metadata:labels:app: prometheuscomponent: serverannotations:prometheus.io/scrape: 'false'spec:serviceAccountName: prometheuscontainers:- name: prometheusimage: prom/prometheus:v2.51.1imagePullPolicy: IfNotPresentcommand:- prometheus- --config.file=/etc/prometheus/prometheus.yml- --storage.tsdb.path=/prometheus- --storage.tsdb.retention=720h- --web.enable-lifecycleports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: /etc/prometheusname: prometheus-config- mountPath: /prometheus/name: prometheus-storage-volumevolumes:- name: prometheus-configconfigMap:name: prometheus-config- name: prometheus-storage-volumehostPath:path: /datatype: Directory
还需要创建一个 prometheus-config.yaml 文件,这是Prometheus监控系统的核心配置文件。它的主要作用是定义Prometheus的运行参数、监控目标(scrape targets)、告警规则等,内容如下。
kind: ConfigMap
apiVersion: v1
metadata:labels:app: prometheusname: prometheus-confignamespace: prometheus
data:prometheus.yml: |global:scrape_interval: 15sscrape_timeout: 10sevaluation_interval: 1mscrape_configs:- job_name: 'kubernetes-node'kubernetes_sd_configs:- role: noderelabel_configs:- source_labels: [__address__]regex: '(.*):10250'replacement: '${1}:9100'target_label: __address__action: replace- action: labelmapregex: __meta_kubernetes_node_label_(.+)- job_name: 'kubernetes-node-cadvisor'kubernetes_sd_configs:- role: nodescheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- action: labelmapregex: __meta_kubernetes_node_label_(.+)- target_label: __address__replacement: kubernetes.default.svc:443- source_labels: [__meta_kubernetes_node_name]regex: (.+)target_label: __metrics_path__replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor- job_name: 'kubernetes-apiserver'kubernetes_sd_configs:- role: endpointsscheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]action: keepregex: default;kubernetes;https- job_name: 'kubernetes-service-endpoints'kubernetes_sd_configs:- role: endpointsrelabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]action: replacetarget_label: __scheme__regex: (https?)- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]action: replacetarget_label: __address__regex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2- action: labelmapregex: __meta_kubernetes_service_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_service_name]action: replacetarget_label: kubernetes_name
然后需要在其它需要被监控的节点安装 node_exporter。
首先制作 node_exporter 镜像文件,具体内容如下。
FROM alpine:latest# 设置工作目录
WORKDIR /node_exporter# 将node_exporter的二进制文件复制到镜像中
# 注意:这里假设node_exporter的二进制文件已经在本地的./node_exporter目录下
COPY ./node_exporter/node_exporter /node_exporter/node_exporter# 暴露node_exporter的默认端口(9100)
EXPOSE 9100# 设置容器启动时运行的命令
# 注意:node_exporter通常不需要额外的配置文件或参数
CMD ["/node_exporter/node_exporter"]# 将日志输出到一个特定的目录
VOLUME ["/node_exporter/logs"]
制作完成后打上标签,上传到私人镜像仓库,我这里是上传到自己在阿里云的镜像仓库。
最后在 node-exporter.yaml 文件里设置好镜像文件的名字和拉取方式。
apiVersion: apps/v1
kind: DaemonSet
metadata:name: node-exporternamespace: prometheuslabels:name: node-exporter
spec:selector:matchLabels:name: node-exportertemplate:metadata:labels:name: node-exporterspec:hostPID: truehostIPC: truehostNetwork: truecontainers:- name: node-exporterimage: registry.cn-hangzhou.aliyuncs.com/syr030111/node_exporter:1.4.0imagePullPolicy: IfNotPresentports:- containerPort: 9100securityContext:privileged: truevolumeMounts:- name: devmountPath: /host/dev- name: procmountPath: /host/proc- name: sysmountPath: /host/sys- name: rootfsmountPath: /rootfstolerations:- key: "node-role.kubernetes.io/master"operator: "Exists"effect: "NoSchedule"volumes:- name: prochostPath:path: /proc- name: devhostPath:path: /dev- name: syshostPath:path: /sys- name: rootfshostPath:path: /
如果不行或者镜像拉取失败,大概率是需要制作拉取凭证,格式类似下面。
kubectl create secret docker-registry <secret-name> \ --docker-server=registry.<region>.aliyuncs.com \ --docker-username=<阿里云用户名> \ --docker-password=<阿里云密码> \ --docker-email=<邮箱> \ --namespace=<命名空间>
下面是成功的效果图。
安装grafana
首先用 xftp 传输本地下载好的 grafana 镜像文件,再导入。(这个镜像文件我也已经上传)
然后创建 grafana.yaml 文件,具体内容如下。
apiVersion: apps/v1
kind: Deployment
metadata:name: grafananamespace: prometheus
spec:replicas: 1selector:matchLabels:app: grafanatemplate:metadata:labels:app: grafanaspec:containers:- name: grafanaimage: docker.io/grafana/grafana:10.4.2imagePullPolicy: IfNotPresentports:- containerPort: 3000protocol: TCPvolumeMounts:- mountPath: /etc/ssl/certsname: ca-certificatesreadOnly: trueenv:- name: INFLUXDB_HOSTvalue: monitoring-influxdb- name: GF_SERVER_HTTP_PORTvalue: "3000"- name: GF_AUTH_BASIC_ENABLEDvalue: "false"- name: GF_AUTH_ANONYMOUS_ENABLEDvalue: "true"- name: GF_AUTH_ANONYMOUS_ORG_ROLEvalue: Admin- name: GF_SERVER_ROOT_URLvalue: /volumes:- name: ca-certificateshostPath:path: /etc/ssl/certs
---
apiVersion: v1
kind: Service
metadata:labels:name: grafananame: grafananamespace: prometheus
spec:ports:- port: 3000targetPort: 3000selector:app: grafanatype: NodePort
上面查询到端口号32463后去浏览器登录进入。
安装NFS服务
搭建NFS服务器
准备服务器,这一步可以在 kubernets 集群之外的虚拟机上进行,也可以在集群内的任一节点进行。
yum install nfs-utils -y
创建共享目录,给文件修改权限。
make -p /data/nfs
chmod 777 /data/nfs
添加共享目录的配置。
/data/nfs *(rw,sync,no_subtree_check)
# rw表示读写权限
# sync表示同步写入
# no_subtree_check表示不检查父目录的变化(提高性能)
创建持久卷
剩下的步骤主要是构建三个 yaml 文件。
创建一个 yaml 文件,定义 NFS 持久卷。
apiVersion: v1
kind: PersistentVolume
metadata:name: nfs-pv
spec:capacity:storage: 10Gi # 指定存储容量 accessModes:- ReadWriteMany # 指定访问模式 nfs:server: 192.168.31.192path: /data/nfs
创建一个 yaml 文件,定义持久卷声明。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nfs-pvc
spec:accessModes:- ReadWriteMany # 与 PV 的访问模式匹配 resources:requests:storage: 5Gi
在 Pod 的定义文件中,添加对 NFS 持久卷的引用,这里为 nginx 添加提供静态文件服务。
apiVersion: v1
kind: Pod
metadata:name: test-nfs-volume
spec:containers:- name: test-nfsimage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80protocol: TCPvolumeMounts:- name: nfs-volumesmountPath: /usr/share/nginx/htmlvolumes:- name: nfs-volumesnfs:path: /data/nfsserver: 192.168.31.192
显示下面的状态表示前面的操作成功。
客户端挂载共享目录
客户端和服务器需要下载的内容一致。
sudo yum install nfs-utils
然后在其他节点需要挂载共享目录,挂载成功后即可实时共享、修改存储数据。
vim /etc/fstab
服务器虚拟机ip:服务器上共享目录的路径 /mnt/NFS共享在本地系统上的挂载路径 nfs defaults 0 0
访问上面显示的IP,出现原始界面内容。
修改页面内容,这一操作在共享的任一虚拟机都可执行,效果一样。再次访问时发现修改成,这里的第二个修改权限操作不用管。
部署nginx
需要的几个 yaml 文件内容如下。
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-deployment-labelsname: nginx-deployment
spec:replicas: 2 # 设置副本数量selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latest #镜像拉取地址imagePullPolicy: IfNotPresentports:- containerPort: 80 #监听端口protocol: TCPname: http- containerPort: 443protocol: TCPname: https
apiVersion: v1
kind: Service
metadata:labels:app: nginx-service-labelname: nginx-service
spec:selector:app: nginxports:- name: httpprotocol: TCPport: 80targetPort: 80nodePort: 30030 #nortPort开在主机的端口- name: httpsport: 443protocol: TCPtargetPort: 443nodePort: 30443selector:app: nginxtype: NodePort # 这里使用LoadBalancer类型,如果在本地运行,可以使用NodePort类型或ClusterIP类型
查看创建是否成功。
部署自己的应用(微服务)
这里用我自己制作的一个网站镜像文件举例,下面是其 Dockerfile 内容。
这是其相关 yaml 文件的具体内容。
apiVersion: apps/v1
kind: Deployment
metadata:name: utopia-app-deployment labels:app: utopia-app
spec:replicas: 2selector:matchLabels:app: utopia-apptemplate:metadata:labels:app: utopia-appspec:containers:- name: utopia-app #pod名字 image: registry.cn-hangzhou.aliyuncs.com/syr030111/utopia:latestimagePullPolicy: IfNotPresentports:- containerPort: 8080 # 容器内部端口protocol: TCPname: http- containerPort: 999protocol: TCPname: https---
apiVersion: v1
kind: Service
metadata:name: utopia-app-service
spec:type: NodePortselector:app: utopia-app #选择有该标签的pod容器ports:- name: httpprotocol: TCPport: 888 #service的端口targetPort: 8080 #pod的端口,一般与pod内部容器的服务端口一致
其中 Deployment 负责创建和管理 Pod 的副本,确保指定数量的 Pod 始终在运行。如果 Pod崩溃或被删除,Deployment 会自动创建新的 Pod 来替换它们。
Service 允许我们访问 Pod 集合,并提供了负载均衡和访问控制的功能。这里的 Service 通过NodePort 类型在集群的每个节点上暴露了一个端口(通常是30000-32767之间的随机端口,但可以通过配置指定端口),从而允许从集群外部通过 IP:NodePort 的方式访问到 Pod 中的服务。
可以用下面几条命令查询是否创建成功。
如果出现类似下面的问题,即节点一直未准备好,可以用更下面的几个命令查询具体信息。
" kubectl describe nodes " 这个命令可以非常详细地查询各个节点的信息,也包括资源和内存使用情况。
下面这个可以简洁查询节点资源使用情况。
如果出现下面的超时错误可多尝试几次。
后续因为电脑空间不够,只能删除虚拟机,这个项目停在这里,之后有空间或者换电脑了继续。