一、Kubernetes 基本概念
1.1.Kubernetes 架构与核心组件
-
Master 节点:
-
API Server(kube-apiserver):集群的“入口”,接收所有 REST 请求并验证权限,是唯一与
etcd
通信的组件。 -
Scheduler(kube-scheduler):负责将 Pod 调度到合适的 Node 上,基于资源需求、亲和性规则等策略。
-
Controller Manager(kube-controller-manager):运行各类控制器(如 Deployment、Node 控制器),确保集群状态与期望一致。
-
etcd:分布式键值存储,保存集群的所有配置和状态数据。
-
-
Node 节点:
-
kubelet:与 Master 通信的代理,负责管理本节点上的 Pod 生命周期(如启动、停止容器)。
-
kube-proxy:维护节点网络规则,实现 Service 的负载均衡和流量转发(如 iptables/IPVS)。
-
容器运行时(Docker/containerd):实际运行容器的引擎,负责拉取镜像、创建容器等。
-
1.2.核心资源对象
-
Pod:
-
最小调度单元,包含一个或多个共享网络和存储的容器。
-
示例:一个 Web 应用 Pod 可能包含 Nginx 容器和日志收集容器。
-
-
Service:
-
定义一组 Pod 的访问策略,提供稳定的 IP 和 DNS 名称。
-
类型包括 ClusterIP(内部访问)、NodePort(节点端口暴露)、LoadBalancer(云厂商负载均衡)。
-
-
Deployment:
-
管理 Pod 的副本数量和滚动更新,确保应用的高可用性。
-
二、运行 K8S 环境搭建
版本 | 主机名 |
---|---|
RHEL 9.3 | K8S-master |
RHEL 9.3 | K8S-node1 |
RHEL 9.3 | K8S-node2 |
RHEL 9.3 | harbor |
2.1.克隆虚拟机
-
配置原因: Kubernetes 集群需要多个节点协同工作,克隆虚拟机可快速创建相同配置的环境,避免手动重复配置带来的差异。
-
实现功能:
-
标准化硬件资源:Master 节点分配更高资源(4GB 内存),以运行控制平面组件;Node 节点分配较低资源(2GB 内存),专注于运行工作负载。
-
网络一致性:所有节点使用 NAT 模式,确保在同一子网内通信,便于后续 IP 和主机名配置。
-
2.1.1.K8S_master
2.1.2.K8S_node
2.2.配置 IP 和主机名
IP | 主机名 |
---|---|
192.168.67.100 | K8S-master |
192.168.67.10 | K8S-node1 |
192.168.67.20 | K8S-node2 |
192.168.67.141 | harbor |
2.3.Harbor 主机搭建 Harbor
详细参考:如下
基于认证的 Harbor 容器镜像仓库_harbor容器镜像仓库-优快云博客
2.4.hosts 解析
K8S 每个主机都需配置
cat >> /etc/hosts << EOF
192.168.67.100 K8S-master
192.168.67.10 K8S-node1
192.168.67.20 K8s-node2
192.168.67.141 reg.harbor.org
EOF
2.5.K8S 主机安装 Docker
-
配置原因: Kubernetes 不直接管理容器,而是通过容器运行时(如 Docker)操作容器。Docker 是 Kubernetes 支持的主流运行时之一。
构建 Docker 软件仓库,用于下载 Docker。
cat >> /etc/yum.repos.d/docker.repo << EOF
[docker]
name=docker
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/9.3/x86_64/stable/
gpgcheck=0
EOF
安装 Docker-ce。
yum install docker-ce -y
2.6.连接 Harbor 仓库
-
配置原因: Harbor 是企业级私有镜像仓库,用于存储自定义镜像(如业务应用镜像)。K8S 节点需信任 Harbor 的 HTTPS 证书,才能安全拉取镜像。
-
实现功能:
-
证书信任配置:
将 Harbor 的 CA 证书拷贝到 Docker 的信任目录,解决 x509: certificate signed by unknown authority 错误。
-
镜像仓库优先级:在 daemon.json 中设置 registry-mirrors,使 Docker 优先从 Harbor 拉取镜像。
-
K8S 主机需要连接 Harbor 仓库,每个 K8S 主机都需配置。
# K8S 主机建立存放 Harbor 证书的目录
mkdir /etc/docker/certs.d/reg.harbor.org/ -p
# Harbor 主机拷贝证书到 K8S 主机
scp /data/certs/harbor.org.crt root@192.168.67.100:/etc/docker/certs.d/reg.harbor.org/ca.crt
# K8S 主机添加 Harbor 仓库为默认仓库
cat >> /etc/docker/daemon.json << EOF
{
"registry-mirrors": [
"https://reg.harbor.org"
]
}
EOF
# K8S 主机启动 Docker
systemctl enable --now docker
# K8S 主机登录 Harbor
docker login reg.harbor.org
登陆成功。
查看添加的 Docker 默认仓库。
三、K8S 集群环境初始化
3.1.禁止 swap
-
配置原因: Kubernetes 要求节点禁用 Swap 分区,因为内存交换可能导致以下问题:
-
调度器误判:kube-scheduler 根据节点的可用内存调度 Pod,Swap 的存在会干扰资源统计。
-
性能抖动:频繁的内存交换可能拖慢容器性能。
-
-
实现功能:
-
临时禁用:swapoff -a 关闭当前 Swap。
-
永久禁用:注释 /etc/fstab 中的 Swap 行,防止重启后恢复。
-
swapon -s
systemctl list-unit-files | grep swap
systemctl mask dev-rhel-swap.swap
vim /etc/fstab # 注释掉 swap
swapoff /dev/dm-1
swapon -s
swapon -s 看不到任何返回则禁用成功。
3.2.设定 cgroup
-
配置原因: Kubernetes 和 Docker 的 cgroup 驱动需保持一致。RHEL/CentOS 默认使用 systemd 初始化系统,而非 cgroupfs。
-
实现功能:
-
驱动一致性配置:
修改 Docker 的 daemon.json,强制使用 systemd 驱动,避免因驱动不一致导致的资源管理冲突。
-
查看 docker cgroup 是否为 systemd,如果是就不需要特殊设定(跳过此步骤)。
如果不是,则需设置 docker cgroup 为 systemd,设置步骤如下。
cat >> /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://reg.harbor.org"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
systemctl daemon-reload
systemctl restart docker
四、下载 K8S
4.1.配置 K8S 仓库
所有 K8S 节点下载 K8S。
cat >> /etc/yum.repos.d/k8s.repo << EOF
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/
gpgcheck=0
EOF
yum search kubelet --showduplicates # 查看所需版本,需与 K8S 1.30 版本契合
yum install kubelet-1.30.0-150500.1.1.x86_64 kubeadm-1.30.0-150500.1.1.x86_64 kubectl-1.30.0-150500.1.1.x86_64 -y
4.2.下载 docker 插件
所有 K8S 节点下载 docker 插件,以及插件依耐。
cri-dockerd 插件下载地址:https://github.com/Mirantis/cri-dockerd/releases
插件依耐下载地址:阿里巴巴开源镜像站-阿里云官网开发者社区_云计算社区
cri-dockerd 作用:
-
容器运行时接口(CRI)实现:在 Kubernetes 1.24 版本之前,Kubernetes 内置支持 Docker 作为容器运行时。但从 1.24 版本开始,Kubernetes 移除了对 Docker 的直接支持,引入了容器运行时接口(CRI)标准。cri-dockerd 是一个将 Docker 适配到 CRI 标准的中间层,它允许 Kubernetes 通过 CRI 与 Docker 进行交互,从而继续使用 Docker 作为容器运行时。
-
保持兼容性:对于已经熟悉 Docker 并且在生产环境中广泛使用 Docker 的用户来说,cri-dockerd 提供了一种平滑过渡的方式,使得他们可以继续在 Kubernetes 集群中使用 Docker 来运行容器,而无需立即切换到其他容器运行时(如 containerd 或 CRI-O)。
libcgroup 作用:
-
资源管理基础:libcgroup 是 Linux 内核中控制组(Control Groups,简称 cgroups)的用户空间工具集和开发库。cgroups 是 Linux 内核提供的一种机制,用于限制和隔离一组进程所使用的资源(如 CPU、内存、磁盘 I/O 等)。libcgroup 提供了一系列命令行工具和库函数,允许用户方便地创建、管理和操作 cgroups。
-
细粒度资源控制:通过 libcgroup,系统管理员可以根据不同的需求,为不同的进程或进程组分配特定的资源配额。例如,可以限制某个进程组最多只能使用 20% 的 CPU 时间,或者最多只能使用 512MB 的内存。
wget https://mirrors.aliyun.com/centos-vault/centos/8-stream/BaseOS/x86_64/os/Packages/libcgroup-0.41-19.el8.x86_64.rpm
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14-3.el8.x86_64.rpm
yum install *.rpm -y
systemctl enable --now cri-docker.service
4.3.设置 kubectl 命令补全功能
所有 K8S 节点配置。
yum install bash-completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
4.4.在 master 节点拉取 K8S 所需镜像
kubeadm 是 Kubernetes 官方提供的用于快速搭建 Kubernetes 集群的工具,config images pull 这个子命令的作用是根据指定的配置信息,从镜像仓库中拉取初始化集群所必需的镜像。这些镜像包含了 Kubernetes 控制平面组件(如 kube-apiserver、kube-controller-manager、kube-scheduler 等)以及其他相关组件的镜像。
-
配置原因: 默认的 Google 镜像仓库(如 k8s.gcr.io)在国内访问受限,通过阿里云或 Harbor 私有仓库加速镜像拉取。
-
实现功能:
-
使用 kubeadm config images pull 从阿里云拉取镜像。
-
重新打标签并推送至 Harbor,确保后续集群初始化时从私有仓库拉取镜像。
-
# 拉取 K8S 集群所需镜像
kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
# 上传镜像到 Harbor 仓库
docker images | awk '/google/{print $1":"$2}' | awk -F "/" '{system("docker tag "$0" reg.harbor.org/k8s/"$3)}'
docker images | awk '/k8s/{system("docker push "$1":"$2)}'
docker images | awk '/google/{print $1":"$2}' | awk -F "/" '{system("docker tag "$0" reg.harbor.org/k8s/"$3)}' 命令详解:
-
docker images
-
功能:这是 Docker 提供的一个命令,用于列出本地主机上所有的 Docker 镜像。该命令会输出一个表格,包含镜像的仓库名(REPOSITORY)、标签(TAG)、镜像 ID(IMAGE ID)、创建时间(CREATED)和大小(SIZE)等信息。
-
-
awk '/google/{print $1":"$2}'
-
功能:awk 是一个强大的文本处理工具,这里使用 awk 对 docker images 输出的内容进行筛选和处理。
-
解释:
-
/google/:这是一个正则表达式,用于匹配包含 google 的行。只有当某一行包含 google 时,才会执行后续的操作。
-
{print $1":"$2}:当匹配到包含 google 的行后,会打印该行的第一个字段(即镜像的仓库名)和第二个字段(即镜像的标签),中间用冒号 : 连接起来。例如,如果有一个镜像的仓库名是 gcr.io/google-containers/pause,标签是 3.2,那么经过这一步处理后会输出 gcr.io/google-containers/pause:3.2。
-
-
-
awk -F "/" '{system("docker tag "$0" OpenLabTest/z-k8s/"$3)}'
-
功能:再次使用 awk 对前一个命令的输出进行处理,并调用 docker tag 命令为镜像添加新的标签。
-
解释:
-
-F "/":指定字段分隔符为斜杠 /。这样 awk 会将输入的每一行按照斜杠进行分割,得到多个字段。
-
{system("docker tag "$0" OpenLabTest/z-k8s/"$3)}:对于每一行输入,会执行 system 函数,该函数用于执行系统命令。这里执行的系统命令是 docker tag,具体解释如下:
-
$0:表示当前行的全部内容,即前一个 awk 命令输出的镜像名和标签组合,如 gcr.io/google-containers/pause:3.2。
-
OpenLabTest/z-k8s/:这是新标签的仓库名前缀。
-
$3:表示按照斜杠分割后的第三个字段。例如,对于 gcr.io/google-containers/pause:3.2,分割后第三个字段是 pause。
-
最终执行的 docker tag 命令类似于 docker tag gcr.io/google-containers/pause:3.2 OpenLabTest/z-k8s/pause:3.2,即给原镜像添加一个新的标签,新标签的仓库名变为 OpenLabTest/z-k8s/。
-
-
-
4.5.集群初始化
所有 K8S 节点配置,指定网络插件及基础容器镜像。
vim /lib/systemd/system/cri-docker.service
systemctl daemon-reload
systemctl restart cri-docker.service
初始化过程:指定信息,将刚刚上传的镜像下载到本机,用这个镜像开启容器。
要先开启 master 节点,才能将 node 节点加入集群。
kubeadm init --pod-network-cidr=10.244.0.0/16 \ # Flannel 默认使用 10.244.0.0/16
--image-repository reg.harbor.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
注意:上述命令会生成一个 token。
如果此 token 找不到了可以重新生成。
# 重新生成 token
kubeadm token create --print-join-command
# 指定集群配置文件变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
kubectl get nodes
状态:未准备就绪,因为集群缺少网络插件
如需重置初始化,使用以下命令(此时不需要做以下指令):
# 重置 Kubernetes 集群初始化状态的命令
kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
4.6.配置网络插件 flannel
-
配置原因:
-
Kubernetes 集群需要 Overlay 网络实现 Pod 跨节点通信。Flannel 提供简单的网络模型(如 host-gw 或 VXLAN),分配 Pod 子网并维护路由表。
-
-
实现功能:
-
修改 kube-flannel.yml 中的镜像地址,适配私有 Harbor 仓库。
-
应用 Flannel 配置后,集群内 Pod 获得唯一 IP,跨节点通信正常。
-
下载地址:
flannel-0.25.5:docker.io/flannel/flannel:v0.25.5 - 镜像下载 | docker.io
flannel-cni-plugin:v1.5.1-flannel1:docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1 - 镜像下载 | docker.io
kube-flannel.yml:https://github.com/flannel-io/flannel/releases
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel:v0.25.5
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1
wget https://github.com/flannel-io/flannel/releases/download/v0.25.5/kube-flannel.yml
# 推送 flannel 镜像到 harbor 仓库
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel:v0.25.5 reg.harbor.org/flannel/flannel:v0.25.5
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1 reg.harbor.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
docker push reg.harbor.org/flannel/flannel:v0.25.5
docker push reg.harbor.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
vim kube-flannel.yml # 修改 yml 文件,将 image: 改为自己的 harbor 镜像地址(以下三个位置都需更改)
# 部署
kubectl apply -f kube-flannel.yml
网络插件在 master 主机已安装好,网络插件是一个 democet,当新的节点加入 K8S 集群当中,会自动部署网络插件。
五、节点加入集群
5.1.Node 加入集群
-
配置原因: Node 节点需通过 Token 和 CA 证书认证加入集群,确保通信安全性。
-
实现功能:
-
Master 生成 Token 和证书哈希,Node 使用 kubeadm join 命令加入。
-
添加 --cri-socket 参数指定容器运行时接口(CRI),适配 cri-dockerd 插件。
-
如过上述 3.5 步骤的初始化生成的 token 找不到了,现在可以重新生成 token。
kubeadm token create --print-join-command
在 node 节点执行下命令:
node 主机加入集群(node1 和 node2 同样的命令)。
# 上述 master 生成的 token 最后加上 --cri-socket=unix:///var/run/cri-dockerd.sock
kubeadm join 192.168.67.100:6443 --token xxwmbp.g9lsrtvoic3dmyar --discovery-token-ca-cert-hash sha256:8bf6b80bb676e3879ccc98cd82fa5c2f8d2bccac9c7f7e938931492578955c51 --cri-socket=unix:///var/run/cri-dockerd.sock
5.2.查看集群状态
kubectl get nodes
如果刚加入集群的 node,STATUS 是 NotReady,因为节点加入是需要一定时间的,等待一分钟,即可恢复 Ready 状态。
kubectl get pod -A
STATUS 是全 Running 则说明 K8S 集群配置成功。
5.3.测试集群运行状况
kubectl run nginx --image nginx # 建立 pods
kubectl get pods -o wide # 查看 pods
kubectl run nginx1 --image nginx
kubectl get pods -o wide
半分钟查看 STATUS 编程 Running 运行状况正常。
kubectl delete pods nginx --force # 删除 pods
kubectl delete pods nginx1 --force
kubectl get pods -o wide
注意:
后续重启集群,node 节点不会自动加入集群,解决方法:后端 node 节点设置开机自启 kubelet 服务即可。
systemctl enable --now kubelet