k8s 综合项目笔记

综述

这篇笔记主要是为了记录下自己写 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 的运行。

bash 复制代码
# 临时关闭
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 可以简化网络管理,尤其是在调试和开发环境中。

bash 复制代码
systemctl stop firewalld 
systemctl disable firewalld
bash 复制代码
iptables -F

这条命令可以清除当前防火墙的所有规则。

下面是关闭交换分区的命令。

bash 复制代码
# 临时关闭
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 调度和管理,避免出现性能瓶颈或服务中断。

调整内核参数

具体修改和查看的命令如下。

这里解释一下这里调整各个参数和命令的作用。

bash 复制代码
# 内核参数设置
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 运行在容器之上,某些内核参数可能需要根据容器的特性进行调整,以确保容器能够高效运行。

自动加载内核模块

bash 复制代码
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

overlay,这个模块用于支持 Overlay 网络。它允许创建虚拟网络,以便在不同主机上的容器之间进行通信。

br_netfilter,这个模块用于确保网络流量通过 Linux 桥接网络时可以被正确过滤。Kubernetes 中的网络插件通常需要这个模块来正确处理网络策略和防火墙规则。

可以用这条命令查看 br_netfilter 和 overlay 模块是否加载成功。

更新和配置软件源

上面其实也提到过,这里就简单放个代码。

bash 复制代码
cd /etc/yum.repos.d
rm -rf *
curl  -O  http://mirrors.aliyun.com/repo/Centos-7.repo

这里是额外的操作,最好执行,会使后续操作更加方便。

bash 复制代码
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功能

bash 复制代码
# 安装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 重启之后再看模块是否加载成功。

配置时间同步

bash 复制代码
systemctl restart chronyd && systemctl enable chronyd

安装docker环境

如果之前安装过 docker,这里就需要先移除原有的环境,我这里因为都是全新安装的虚拟机,所以不需要,就只放个代码。

bash 复制代码
sudo yum remove docker \
     docker-client \
     docker-client-latest \
     docker-common \
     docker-latest \
     docker-latest-logrotate \
     docker-logrotate \
     docker-engine

移除后重新下载。

bash 复制代码
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服务自启动

bash 复制代码
# 启动docker
systemctl start docker
# 设置docker开机启动
systemctl enable docker
# 验证
systemctl status docker

启动 docker 并确保之后都会自启动后查看一下 docker 状态,是否在运行。

配置docker的国内镜像源加速

bash 复制代码
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成功了,所以上面的就没再继续。

bash 复制代码
# 下载
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

bash 复制代码
# 下载
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组件源

bash 复制代码
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
bash 复制代码
# 更新索引缓冲
yum makecache

安装

bash 复制代码
# 安装
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 节点执行。

bash 复制代码
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 节点加入集群

将上面的那段密钥复制粘贴到其他节点内部。

完成后应该能得到以下结果。

bash 复制代码
# 在master上执行
kubectl get nodes

分配 worker

bash 复制代码
# 在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网络插件

bash 复制代码
# master执行
wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
# 验证
kubectl get nodes

安装完成后,可以检查下。

这里发现有几个都拉起失败,这是因为我用的国内网,很多时候无法正常拉取国外镜像仓库的文件。暂时的解决办法是在网上另外下载缺失的这两个镜像文件,将其导入本地。

导入完成后可以再次检查,这时没有完成可能是需要等会儿,也可能是没有在所有节点导入,记得在所有节点导入需要的镜像文件。

下面这里就可以看出已经安装和启动完毕。

安装Dashboard

以下命令均只在 master 节点上执行。

下载安装

bash 复制代码
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

修改 Service 部分,改为 NodePort 对外暴露端口。

bash 复制代码
kind: Service
apiVersion: v1
metadata:
  ...
spec:
  type: NodePort  # 改为NodePort
bash 复制代码
kubectl apply -f recommended.yaml

查看

bash 复制代码
kubectl get pods,svc -n kubernetes-dashboard

这里可以等一等。

创建账号

创建 dashboard-access-token.yaml 文件。

bash 复制代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token

下面这一步是为了获取后面在网站上登录的 token 密码。

bash 复制代码
# 获取token
kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d

访问dashboard

bash 复制代码
# 获取端口
kubectl get svc -n kubernetes-dashboard

这里看得出端口是30275。

然后在浏览器上访问网址为 - " 集群ip:端口(https://ip:端口号)"(注意https)。

之后再输入上一步获取到的 token 即可。

安装Kuborad

任意节点执行,推荐 master 节点。

bash 复制代码
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命令自动补全

bash 复制代码
yum install bash-completion -y
# 临时设置自动补全
source <(kubectl completion bash) 
# 永久设置自动补全
echo "source <(kubectl completion bash)" >> ~/.bashrc && bash

部署metric-server

下载

在 master 节点上执行。

bash 复制代码
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.2/components.yaml

修改

修改140行左右。

bash 复制代码
原:

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  # 修改镜像仓库地址

应用

bash 复制代码
kubectl apply -f components.yaml

查看

bash 复制代码
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 文件中的具体内容。

bash 复制代码
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: prometheus
  labels:
    app: prometheus
spec:
  type: NodePort
  ports:
    - port: 9090
      targetPort: 9090
      protocol: TCP
  selector:
    app: prometheus
    component: server

然后创建 prometheus-deploy.yaml 文件,这一步是用来定义 Prometheus 在 Kubernetes 环境中的部署配置。

具体 yaml 文件内容如下。

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server
  namespace: prometheus
  labels:
    app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
      component: server
  template:
    metadata:
      labels:
        app: prometheus
        component: server
      annotations:
        prometheus.io/scrape: 'false'
    spec:
      serviceAccountName: prometheus
      containers:
      - name: prometheus
        image: prom/prometheus:v2.51.1
        imagePullPolicy: IfNotPresent
        command:
          - prometheus
          - --config.file=/etc/prometheus/prometheus.yml
          - --storage.tsdb.path=/prometheus
          - --storage.tsdb.retention=720h
          - --web.enable-lifecycle
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/prometheus
          name: prometheus-config
        - mountPath: /prometheus/
          name: prometheus-storage-volume
      volumes:
        - name: prometheus-config
          configMap:
            name: prometheus-config
        - name: prometheus-storage-volume
          hostPath:
           path: /data
           type: Directory

还需要创建一个 prometheus-config.yaml 文件,这是Prometheus监控系统的核心配置文件。它的主要作用是定义Prometheus的运行参数、监控目标(scrape targets)、告警规则等,内容如下。

bash 复制代码
kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: prometheus
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 10s
      evaluation_interval: 1m
    scrape_configs:
    - job_name: 'kubernetes-node'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: 'kubernetes-node-cadvisor'
      kubernetes_sd_configs:
      - role:  node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __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: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

然后需要在其它需要被监控的节点安装 node_exporter。

首先制作 node_exporter 镜像文件,具体内容如下。

bash 复制代码
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 文件里设置好镜像文件的名字和拉取方式。

bash 复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: prometheus
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
     name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image:  registry.cn-hangzhou.aliyuncs.com/syr030111/node_exporter:1.4.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9100
        securityContext:
          privileged: true
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

如果不行或者镜像拉取失败,大概率是需要制作拉取凭证,格式类似下面。

bash 复制代码
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 文件,具体内容如下。

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: docker.io/grafana/grafana:10.4.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/ssl/certs
          name: ca-certificates
          readOnly: true
        env:
        - name: INFLUXDB_HOST
          value: monitoring-influxdb
        - name: GF_SERVER_HTTP_PORT
          value: "3000"
        - name: GF_AUTH_BASIC_ENABLED
          value: "false"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ORG_ROLE
          value: Admin
        - name: GF_SERVER_ROOT_URL
          value: /
      volumes:
      - name: ca-certificates
        hostPath:
          path: /etc/ssl/certs
---
apiVersion: v1
kind: Service
metadata:
  labels:
    name: grafana
  name: grafana
  namespace: prometheus
spec:
  ports:
  - port: 3000
    targetPort: 3000
  selector:
    app: grafana
  type: NodePort

上面查询到端口号32463后去浏览器登录进入。

安装NFS服务

搭建NFS服务器

准备服务器,这一步可以在 kubernets 集群之外的虚拟机上进行,也可以在集群内的任一节点进行。

yum install nfs-utils -y

创建共享目录,给文件修改权限。

bash 复制代码
make -p /data/nfs
chmod 777 /data/nfs

添加共享目录的配置。

bash 复制代码
/data/nfs *(rw,sync,no_subtree_check)
# rw表示读写权限
# sync表示同步写入
# no_subtree_check表示不检查父目录的变化(提高性能)

创建持久卷

剩下的步骤主要是构建三个 yaml 文件。

创建一个 yaml 文件,定义 NFS 持久卷。

bash 复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 10Gi   # 指定存储容量  
  accessModes:
    - ReadWriteMany   # 指定访问模式  
  nfs:
    server: 192.168.31.192
    path: /data/nfs

创建一个 yaml 文件,定义持久卷声明。

bash 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany   # 与 PV 的访问模式匹配  
  resources:
    requests:
      storage: 5Gi

在 Pod 的定义文件中,添加对 NFS 持久卷的引用,这里为 nginx 添加提供静态文件服务。

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test-nfs-volume
spec:
  containers:
  - name: test-nfs
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      protocol: TCP
    volumeMounts:
    - name: nfs-volumes
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nfs-volumes
    nfs:
      path: /data/nfs
      server: 192.168.31.192

显示下面的状态表示前面的操作成功。

客户端挂载共享目录

客户端和服务器需要下载的内容一致。

bash 复制代码
sudo yum install nfs-utils

然后在其他节点需要挂载共享目录,挂载成功后即可实时共享、修改存储数据。

bash 复制代码
vim /etc/fstab
服务器虚拟机ip:服务器上共享目录的路径 /mnt/NFS共享在本地系统上的挂载路径 nfs defaults 0 0

访问上面显示的IP,出现原始界面内容。

修改页面内容,这一操作在共享的任一虚拟机都可执行,效果一样。再次访问时发现修改成,这里的第二个修改权限操作不用管。

部署nginx

需要的几个 yaml 文件内容如下。

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deployment-labels
  name: nginx-deployment
spec:
  replicas: 2  # 设置副本数量
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest #镜像拉取地址
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80 #监听端口
          protocol: TCP
          name: http
        - containerPort: 443
          protocol: TCP
          name: https
bash 复制代码
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-service-label
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30030 #nortPort开在主机的端口
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443
      nodePort: 30443
  selector:
    app: nginx
  type: NodePort  # 这里使用LoadBalancer类型,如果在本地运行,可以使用NodePort类型或ClusterIP类型

查看创建是否成功。

部署自己的应用(微服务)

这里用我自己制作的一个网站镜像文件举例,下面是其 Dockerfile 内容。

这是其相关 yaml 文件的具体内容。

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: utopia-app-deployment 
  labels:
    app: utopia-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: utopia-app
  template:
    metadata:
      labels:
        app: utopia-app
    spec:
      containers:
        - name: utopia-app #pod名字 
          image: registry.cn-hangzhou.aliyuncs.com/syr030111/utopia:latest
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 8080 # 容器内部端口
            protocol: TCP
            name: http
          - containerPort: 999
            protocol: TCP
            name: https

---
apiVersion: v1
kind: Service
metadata:
  name: utopia-app-service
spec:
  type: NodePort
  selector:
    app: utopia-app #选择有该标签的pod容器
  ports:
  - name: http
    protocol: TCP
    port: 888  #service的端口
    targetPort: 8080  #pod的端口,一般与pod内部容器的服务端口一致

其中 Deployment负责创建和管理 Pod 的副本,确保指定数量的 Pod 始终在运行。如果 Pod崩溃或被删除,Deployment 会自动创建新的 Pod 来替换它们。

Service允许我们访问 Pod 集合,并提供了负载均衡和访问控制的功能。这里的 Service 通过NodePort 类型在集群的每个节点上暴露了一个端口(通常是30000-32767之间的随机端口,但可以通过配置指定端口),从而允许从集群外部通过 IP:NodePort 的方式访问到 Pod 中的服务。

可以用下面几条命令查询是否创建成功。

如果出现类似下面的问题,即节点一直未准备好,可以用更下面的几个命令查询具体信息。

" kubectl describe nodes " 这个命令可以非常详细地查询各个节点的信息,也包括资源和内存使用情况。

下面这个可以简洁查询节点资源使用情况。

如果出现下面的超时错误可多尝试几次。

后续因为电脑空间不够,只能删除虚拟机,这个项目停在这里,之后有空间或者换电脑了继续。

相关推荐
weixin_478689765 分钟前
【二分查找】【刷题笔记】——灵神题单1
笔记
书埋不住我11 分钟前
java第三章
java·开发语言·servlet
boy快快长大13 分钟前
将大模型生成数据存入Excel,并用增量的方式存入Excel
java·数据库·excel
怡雪~16 分钟前
centos7.9搭建k8s集群
云原生·容器·kubernetes
孟秋与你16 分钟前
【spring】spring单例模式与锁对象作用域的分析
java·spring·单例模式
菜菜-plus19 分钟前
java 设计模式 模板方法模式
java·设计模式·模板方法模式
萨达大21 分钟前
23种设计模式-模板方法(Template Method)设计模式
java·c++·设计模式·软考·模板方法模式·软件设计师·行为型设计模式
tian-ming22 分钟前
(十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器
java·开发语言·前端
不能只会打代码25 分钟前
大学课程项目中的记忆深刻 Bug —— 一次意外的数组越界
java·github·intellij-idea·话题博客
快意咖啡~32 分钟前
java.nio.charset.MalformedInputException: Input length = 1
java·开发语言·nio