RHEL9 基于 kubeadm 部署 Kubernetes 集群
一、Kubernetes 基本概念1.1.Kubernetes 架构与核心组件Master 节点API Serverkube-apiserver集群的“入口”接收所有 REST 请求并验证权限是唯一与etcd通信的组件。Schedulerkube-scheduler负责将 Pod 调度到合适的 Node 上基于资源需求、亲和性规则等策略。Controller Managerkube-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.3K8S-masterRHEL 9.3K8S-node1RHEL 9.3K8S-node2RHEL 9.3harbor2.1.克隆虚拟机配置原因 Kubernetes 集群需要多个节点协同工作克隆虚拟机可快速创建相同配置的环境避免手动重复配置带来的差异。实现功能标准化硬件资源Master 节点分配更高资源4GB 内存以运行控制平面组件Node 节点分配较低资源2GB 内存专注于运行工作负载。网络一致性所有节点使用 NAT 模式确保在同一子网内通信便于后续 IP 和主机名配置。2.1.1.K8S_master2.1.2.K8S_node2.2.配置 IP 和主机名IP主机名192.168.67.100K8S-master192.168.67.10K8S-node1192.168.67.20K8S-node2192.168.67.141harbor2.3.Harbor 主机搭建 Harbor详细参考如下基于认证的 Harbor 容器镜像仓库_harbor容器镜像仓库-CSDN博客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 EOF2.5.K8S 主机安装 Docker配置原因Kubernetes 不直接管理容器而是通过容器运行时如 Docker操作容器。Docker 是 Kubernetes 支持的主流运行时之一。构建 Docker 软件仓库用于下载 Docker。cat /etc/yum.repos.d/docker.repo EOF [docker] namedocker baseurlhttps://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/9.3/x86_64/stable/ gpgcheck0 EOF安装 Docker-ce。yum install docker-ce -y2.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 root192.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 根据节点的可用内存调度 PodSwap 的存在会干扰资源统计。性能抖动频繁的内存交换可能拖慢容器性能。实现功能临时禁用swapoff -a 关闭当前 Swap。永久禁用注释 /etc/fstab 中的 Swap 行防止重启后恢复。swapon -s systemctl list-unit-files | grep swapsystemctl mask dev-rhel-swap.swap vim /etc/fstab # 注释掉 swapswapoff /dev/dm-1 swapon -sswapon -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.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, storage-driver: overlay2 } EOF systemctl daemon-reload systemctl restart docker四、下载 K8S4.1.配置 K8S 仓库所有 K8S 节点下载 K8S。cat /etc/yum.repos.d/k8s.repo EOF [k8s] namek8s baseurlhttps://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/ gpgcheck0 EOFyum 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 -y4.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.service4.3.设置 kubectl 命令补全功能所有 K8S 节点配置。yum install bash-completion echo source (kubectl completion bash) ~/.bashrc source ~/.bashrc4.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-socketunix:///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、镜像 IDIMAGE 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.servicesystemctl daemon-reload systemctl restart cri-docker.service初始化过程指定信息将刚刚上传的镜像下载到本机用这个镜像开启容器。要先开启 master 节点才能将 node 节点加入集群。kubeadm init --pod-network-cidr10.244.0.0/16 \ # Flannel 默认使用 10.244.0.0/16 --image-repository reg.harbor.org/k8s \ --kubernetes-version v1.30.0 \ --cri-socketunix:///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-socketunix:///var/run/cri-dockerd.sock4.6.配置网络插件 flannel配置原因Kubernetes 集群需要 Overlay 网络实现 Pod 跨节点通信。Flannel 提供简单的网络模型如 host-gw 或 VXLAN分配 Pod 子网并维护路由表。实现功能修改 kube-flannel.yml 中的镜像地址适配私有 Harbor 仓库。应用 Flannel 配置后集群内 Pod 获得唯一 IP跨节点通信正常。下载地址flannel-0.25.5docker.io/flannel/flannel:v0.25.5 - 镜像下载 | docker.ioflannel-cni-plugin:v1.5.1-flannel1docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1 - 镜像下载 | docker.iokube-flannel.ymlhttps://github.com/flannel-io/flannel/releasesdocker 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-flannel1vim 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-socketunix:///var/run/cri-dockerd.sock kubeadm join 192.168.67.100:6443 --token xxwmbp.g9lsrtvoic3dmyar --discovery-token-ca-cert-hash sha256:8bf6b80bb676e3879ccc98cd82fa5c2f8d2bccac9c7f7e938931492578955c51 --cri-socketunix:///var/run/cri-dockerd.sock5.2.查看集群状态kubectl get nodes如果刚加入集群的 nodeSTATUS 是 NotReady因为节点加入是需要一定时间的等待一分钟即可恢复 Ready 状态。kubectl get pod -ASTATUS 是全 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