概述本实现基于openEuler 22.03 LTS系统下的 Kubernetes 1.26 集群安装。安装方法方法复杂度说明Kubeadm简单官方推荐自动化程度高二进制安装复杂手动部署每个组件适合深入学习Kubernetes 组件架构Kubernetes 集群由控制节点和工作节点组成核心组件包括master主节点组件apiserver集群的统一入口提供 REST APIcontroller-manager控制器管理器维护集群状态scheduler调度器将 Pod 分配到合适节点etcd分布式键值存储保存集群数据kubelet管理控制平面的静态 Podapiserver、etcd 等确保控制平面组件正常运行kube-proxy在主节点上配置网络规则保证控制平面组件的 Service 访问和网络通信node工作节点组件kubelet节点代理管理 Pod 生命周期kube-proxy网络代理实现 Service 负载均衡容器运行时运行容器的底层引擎如 Docker、containerdk8s在v1.24版本之前默认容器运行时是Docker-cev1.24版本之后默认是containerd 是工作节点上的一个基础软件组件它负责创建、运行和管理容器它是容器得以存在的前提条件。网络插件Calico提供 Pod 网络通信和网络策略环境规划注意要使用纯净的环境进行配置避免干扰建议恢复到仅配置好网络的阶段K8S 集群角色IP 地址主机名安装的主要组件控制节点192.168.1.11hd1apiserver、controller-manager、scheduler、kubelet、etcd、kube-proxy、容器运行时、calico、coredns工作节点192.168.1.12hd2kubelet、kube-proxy、calico、coredns、容器运行时工作节点192.168.1.13hd3kubelet、kube-proxy、calico、coredns、容器运行时一、环境准备1.1 更新系统所有节点# 只是更新系统软件不更新内核yum update-y1.2 安装基础软件包所有节点yuminstall-ydevice-mapper-persistent-data lvm2wgetnet-tools nfs-utils lrzsz gcc gcc-cmakecmake libxml2-devel openssl-develcurlcurl-develunzipsudontp libaio-develwgetvimncurses-devel autoconf automake zlib-devel openssh-server socat ipvsadm conntrack telnet ipvsadm1.3 关闭 SELinux所有节点需重启# 修改 SELinux 配置文件重启后永久生效sed-is/SELINUXenforcing/SELINUXdisabled/g/etc/selinux/configreboot# 查看是否关闭getenforce#输出为Disabled即是成功1.4 配置主机名加上 bash可以让主机名修改立即在前台生效# 在 192.168.1.11 上执行hostnamectl set-hostname hd1bash# 在 192.168.1.12 上执行hostnamectl set-hostname hd2bash# 在 192.168.1.13 上执行hostnamectl set-hostname hd3bash1.5 配置 hosts 文件所有节点cat/etc/hostsEOF 192.168.1.11 hd1 192.168.1.12 hd2 192.168.1.13 hd3 EOF1.6 配置 SSH 免密登录在 hd1 上执行因为我们要将hd1作为控制主机所以只在hd1做免密即可# 生成密钥对一路回车不输入密码[roothd1 ~]# ssh-keygen# 把公钥拷贝到远程主机[roothd1 ~]# ssh-copy-id hd2[roothd1 ~]# ssh-copy-id hd31.7 关闭交换分区 Swap所有节点Kubernetes 要求关闭 Swap 以提升性能。# 永久关闭注释 swap 挂载行[roothd1 ~]# vim /etc/fstab# /dev/mapper/centos-swap swap swap defaults 0 0 # 注释掉这一行# 临时关闭[roothd1 ~]# swapoff -a[roothd2 ~]# swapoff -a[roothd3 ~]# swapoff -a#注意这两步都要做1.8 修改内核参数所有节点加载内核模块并配置网络参数使 Kubernetes 能够正确处理网络流量。# 加载 br_netfilter 内核模块modprobe br_netfilter# 创建内核参数配置文件cat/etc/sysctl.d/k8s.confEOF net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 EOF# 重新加载内核参数sysctl-p/etc/sysctl.d/k8s.conf1.9 关闭 Firewalld 防火墙所有节点[roothd1 ~]# systemctl stop firewalld systemctl disable firewalld[roothd2 ~]# systemctl stop firewalld systemctl disable firewalld[roothd3 ~]# systemctl stop firewalld systemctl disable firewalld1.10 配置 YUM 源所有节点Docker CE 源华为云cat/etc/yum.repos.d/docker-ce.repoEOF [docker-ce-stable] nameDocker CE Stable - \$basearchbaseurlhttps://mirrors.huaweicloud.com/docker-ce/linux/rhel/8.8/x86_64/stable/ enabled1 gpgcheck0 EOFKubernetes 源阿里云cat/etc/yum.repos.d/kubernetes.repoEOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled1 gpgcheck0 EOF1.11 配置时间同步所有节点# 安装 ntpdateyuminstallntpdate-y# 同步网络时间ntpdate ntp.aliyun.com# 添加计划任务每分钟同步一次crontab-e* * * * * /usr/sbin/ntpdate ntp.aliyun.com# 重启 crond 服务servicecrond restart二、Docker 相关软件安装2.1 安装 Docker CE所有节点yuminstalldocker-ce-ysystemctlenabledocker--now2.2 安装 cri-dockerd所有节点背景知识在k8s中docker是默认的容器运行时k8s早期版本在kubelet程序中开发了一个名字为dockershim的代理程序负责kubelet和docker之间的通信。从Kubernetes 1.20版本开始宣布将在1.24版本中移除 dockershim。Docker 官方为解决此问题开发了cri-dockerd代理程序替代原来的 dockershim 功能。容器运行时调用链对比容器运行时调用链Dockerkubelet → cri-dockerd → dockerd → containerd → containercontainerdkubelet → containerd → containerDocker 方式比 containerd 方式多了一层调用链。虽然containerd会更加轻便但目前Docker的市场占有率更高。所以未来想追求极致性能可以考虑切换到 containerd但目前依旧是以Docker为主安装 cri-dockerd从 GitHub 下载 cri-dockerd RPM 包https://github.com/Mirantis/cri-dockerd/releases[roothd1 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm[roothd2 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm[roothd3 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm修改 cri-docker 服务配置hd1实施分发到hd2hd3将 pause 镜像地址指定为阿里云镜像源避免因网络问题拉取失败。# 修改 /usr/lib/systemd/system/cri-docker.service[roothd1 ~]# cat /usr/lib/systemd/system/cri-docker.service#只修改[Service]这个模块[Service]TypenotifyExecStart/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-imageregistry.aliyuncs.com/google_containers/pause:3.9# 同步到 hd2 和 hd3[roothd1 ~]# scp /usr/lib/systemd/system/cri-docker.service hd2:/usr/lib/systemd/system/[roothd1 ~]# scp /usr/lib/systemd/system/cri-docker.service hd3:/usr/lib/systemd/system/# 重启并启用服务所有节点systemctl daemon-reloadsystemctl start cri-docker.servicesystemctlenablecri-docker.service2.3 配置 Docker 镜像加速器所有节点vim/etc/docker/daemon.json{registry-mirrors:[https://docker.m.daocloud.io,https://docker.1ms.run,https://docker.xuanyuan.me]}# 重启 Dockersystemctl restartdocker三、初始化 Kubernetes 集群3.1 安装 Kubeadm、Kubelet、Kubectl所有节点所有节点安装Kubeadm、Kubelet、Kubectl是为了让他们具备运行 Kubernetes 的环境软件包作用kubeadm集群初始化工具用于初始化 Kubernetes 集群kubelet安装在集群所有节点上用于启停 Podkubectl管理工具可部署和管理应用、查看资源、创建/删除/更新组件# 安装指定版本1.26.0[roothd1 ~]# yum install -y kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0# 设置 kubelet 启动与开机自启此时尚未启动需等到集群初始化后才真正运行[roothd1 ~]# systemctl start kubelet[roothd1 ~]# systemctl enable kubelet3.2 初始化集群仅在 Master 节点 hd1 执行#查看可能要下载的镜像版本[roothd1 ~]# kubeadm config images list --image-repositoryregistry.aliyuncs.com/google_containers#命令显示如下结果registry.aliyuncs.com/google_containers/kube-apiserver:v1.26.15 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.26.15 registry.aliyuncs.com/google_containers/kube-scheduler:v1.26.15 registry.aliyuncs.com/google_containers/kube-proxy:v1.26.15 registry.aliyuncs.com/google_containers/pause:3.9 registry.aliyuncs.com/google_containers/etcd:3.5.6-0 registry.aliyuncs.com/google_containers/coredns:v1.9.3#查看kubelet的版本号k8s的版本号和kubelet保持一致[roothd1 ~]# rpm -qa | grep kubeletkubelet-1.26.0-0.x86_64#切记这里的kubernetes-version的版本一定要和要下载的k8s组件镜像一致否则报错[rooth1 ~]# kubeadm init --image-repositoryregistry.aliyuncs.com/google_containers --control-plane-endpoint 192.168.1.100:80 --upload-certs --token-ttl0 --kubernetes-versionv1.26.15 --pod-network-cidr10.244.0.0/16 --service-cidr10.96.0.0/16 --cri-socketunix:///var/run/cri-dockerd.sock参数说明了解由于参数过多过于复杂目前仅了解大致作用即可参数说明--apiserver-advertise-addressAPI Server 监听地址Master 节点 IP--image-repository镜像仓库地址使用阿里云加速--token-ttl共享令牌token的过期时长默认为24小时0表示永不过期--kubernetes-versionK8s 版本号--pod-network-cidrPod 网络 CIDR需与网络插件一致--service-cidrService 网络 CIDR--cri-socketCRI 套接字路径使用 cri-dockerd补充内容了解–cri-socket是v1.24版之后指定连接cri的socket文件路径不同的CRI连接文件是不同的如果是CRI是containerd则使用–cri-socket unix:///run/containerd/containerd.sockk8s-1.24后版本此值是默认值如果是CRI是docker则使用–cri-socket unix:///var/run/cri-dockerd.sock如果是CRI是CRI-o则使用–cri-socket unix:///var/run/crio/crio.sock保存初始化信息初始化成功后会输出类似如下 Join 命令。要保存好用于后续添加工作节点kubeadmjoin192.168.1.11:6443--tokeneyzo6e.bihj65mqdimn1ktq\--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da3.3 踩坑记录先是在安装软件时报错然后尝试重置kubeadm环境kubeadm reset --cri-socketunix:///var/run/cri-dockerd.sock结果报错显示重置环境没有清理干净# 删除 CNI 网络配置必须[roothd1 ~]# rm -rf /etc/cni/net.d#删除 kubeconfig 文件必须[roothd1 ~]# rm -rf $HOME/.kube/config#清理 iptables 规则建议如果有的话[roothd1 ~]# iptables -F iptables -t nat -F iptables -t mangle -F#如果使用过 IPVS清理 IPVS 表可选[roothd1 ~]# ipvsadm --clear 2/dev/null#确认 swap 已禁用必须[roothd1 ~]# free -h | grep SwapSwap: 0B 0B 0B# 如果显示不为 0执行swapoff-ased-i/swap/s/^/#//etc/fstab#查看是否残留容器包括已经停止的[roothd1 ~]# docker ps -a# 如果有残留可以批量删除[roothd1 ~]# docker rm -f $(docker ps -aq) 2/dev/null再次尝试依旧报错经过解读发现是因为我下载的kubeadm 版本与目标 Kubernetes 版本不匹配。我原先使用的下载命令中指定的是v1.28.2版本kubeadm init --image-repositoryregistry.aliyuncs.com/google_containers --control-plane-endpoint192.168.1.100:80 --upload-certs --token-ttl0--kubernetes-versionv1.28.2 --pod-network-cidr10.244.0.0/16 --service-cidr10.96.0.0/16 --cri-socketunix:///var/run/cri-dockerd.sock我们把要下载的kubeadm的版本改成1.26.15[rooth1 ~]# kubeadm init --image-repositoryregistry.aliyuncs.com/google_containers --control-plane-endpoint 192.168.1.100:80 --upload-certs --token-ttl0 --kubernetes-versionv1.26.15 --pod-network-cidr10.244.0.0/16 --service-cidr10.96.0.0/16 --cri-socketunix:///var/run/cri-dockerd.sock就可以正常下载了。为此我增加了查看可能要下载的镜像版本的步骤3.4 配置 Kubectl仅在 Master 节点 hd1 执行配置 kubectl 的配置文件config相当于对 kubectl 进行授权使其能够管理 Kubernetes 集群。#kubectl 默认会在 $HOME/.kube/config 路径下查找配置文件[roothd1 ~]# mkdir -p $HOME/.kube#把管理员凭证文件复制到 kubectl 的默认读取位置[roothd1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config#把配置文件的拥有权交给当前用户确保 kubectl 能正常读取[roothd1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config验证集群状态[roothd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 2m25s v1.26.0此时节点状态为NotReady因为尚未安装网络插件CNI。四、集群扩容添加工作节点4.1 将 hd2、hd3 加入集群在 hd2 和 hd3 上执行 kubeadm init 输出的 join 命令注意需要用到 步骤 3.2 的初始化信息# hd2 加入集群[roothd2 ~]# kubeadm join 192.168.1.11:6443 --token eyzo6e.bihj65mqdimn1ktq \--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da\--cri-socketunix:///var/run/cri-dockerd.sock# hd3 加入集群[roothd3 ~]# kubeadm join 192.168.1.11:6443 --token eyzo6e.bihj65mqdimn1ktq \--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da\--cri-socketunix:///var/run/cri-dockerd.sock4.2 查看集群节点状态在 hd1 执行[roothd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 49m v1.26.0 hd2 NotReadynone39s v1.26.0 hd3 NotReadynone39s v1.26.04.3 给节点打标签可选为工作节点添加角色标签work便于识别和管理。[roothd1 ~]# kubectl label nodes hd2 node-role.kubernetes.io/workwork[roothd1 ~]# kubectl label nodes hd3 node-role.kubernetes.io/workwork# 再次查看节点状态[roothd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 10m v1.26.0 hd2 NotReady work 27s v1.26.0 hd3 NotReady work 27s v1.26.0五、网络组件 Calico在 K8s 1.26 集群中安装 Calico主要就是为了实现这两点功能打通网络让集群中所有 Pod 能够通过 IP 直接互相访问为服务发现和负载均衡等更高级的功能打下基础。保障安全提供实施网络策略的能力实现 Pod 间的访问控制与隔离。5.1 加载 Calico 镜像所有节点上传七个 Calico 镜像包直接拉到root目录执行和**calico.yaml用于部署和启动Calico服务**到各节点然后加载dockerload-icalico-cni.tardockerload-icalico-dikastes.tardockerload-icalico-flannel-migration-controller.tardockerload-icalico-kube-controllers.tardockerload-icalico-node.tardockerload-icalico-pod2daemon.tardockerload-icalico-typha.tar下载 Calico 配置文件的地址是https://docs.projectcalico.org/manifests/calico.yaml5.2 部署 Calico 网络插件在 hd1 执行[roothd1 ~]# kubectl apply -f calico.yaml5.3 验证节点状态hd1等待 Calico 部署完成后节点状态变为Ready[roothd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 Ready control-plane 41m v1.26.0 hd2 Ready work 21m v1.26.0 hd3 Ready work 21m v1.26.05.4 测试 Pod 网络连通性把busybox-1-28.tar.gz上传到hd2、hd3节点并在 hd2、hd3 上加载 busybox 镜像[roothd2 ~]# docker load -i busybox-1-28.tar.gz[roothd3 ~]# docker load -i busybox-1-28.tar.gz在 hd1 上创建测试 Pod 并验证网络[roothd1 ~]# kubectl run busybox --image docker.io/library/busybox:1.28 \--image-pull-policyIfNotPresent\--restartNever\--rm-itbusybox --sh# --rm容器退出后自动删除If you dont see acommandprompt, try pressing enter.# ping www.baidu.com验证网络插件已经正常安装/# ping www.baidu.comPING www.baidu.com(36.152.44.132):56data bytes64bytes from36.152.44.132:seq0ttl127time78.099ms64bytes from36.152.44.132:seq1ttl127time57.193ms....../# exitpodbusyboxdeleted#查看pod没有pod存在。因为之前创建制定了--rm退出pod会自动删除[roothd1 ~]# kubectl get podsNo resources foundindefault namespace.--image-pull-policyIfNotPresent如果本地已有镜像则不拉取如果不存在则从远程仓库拉取。这样在有离线包的情况下可以加速部署。六、补充配置6.1 配置 Kubectl 命令自动补全即tap补齐在hd1 执行# 安装 bash-completionyum-yinstallbash-completion# 加载 bash-completionsource/usr/share/bash-completion/bash_completion# 配置 kubectl 自动补全kubectl completionbash|sudotee/etc/bash_completion.d/kubectl/dev/nullsudochmodar /etc/bash_completion.d/kubectl# 加载配置source/etc/bash_completion.d/kubectl# 测试 Tab 补全[roothd1 ~]# kubectl get deployments.apps6.2 集群重置如果集群搭建失败需要重置可在各节点执行[roothd1 ~]# kubeadm reset --cri-socketunix:///var/run/cri-dockerd.sock这会清除集群配置恢复到初始化前的状态以便重新初始化。如果报错显示没有清理干净就进行更深一步的清理# 删除 CNI 网络配置必须[roothd1 ~]# rm -rf /etc/cni/net.d#删除 kubeconfig 文件必须[roothd1 ~]# rm -rf $HOME/.kube/config#清理 iptables 规则建议如果有的话[roothd1 ~]# iptables -F iptables -t nat -F iptables -t mangle -F#如果使用过 IPVS清理 IPVS 表可选[roothd1 ~]# ipvsadm --clear 2/dev/null#确认 swap 已禁用必须[roothd1 ~]# free -h | grep SwapSwap: 0B 0B 0B# 如果显示不为 0执行swapoff-ased-i/swap/s/^/#//etc/fstab#查看是否残留容器包括已经停止的[roothd1 ~]# docker ps -a# 如果有残留可以批量删除[roothd1 ~]# docker rm -f $(docker ps -aq) 2/dev/null核心知识点总结Kubernetes 核心组件组件作用部署位置kube-apiserver集群统一 API 入口Masteretcd分布式键值存储保存集群状态Masterkube-schedulerPod 调度Masterkube-controller-manager控制器管理维护集群状态Masterkubelet节点代理管理 PodAllkube-proxy网络代理实现 Service 负载均衡All容器运行时运行容器的底层引擎AllCNI 插件CalicoPod 网络通信AllKubeadm 安装流程1. 环境准备主机名、hosts、免密、swap、内核参数、防火墙、时间同步 ↓ 2. 安装 Docker cri-dockerd ↓ 3. 安装 kubeadm/kubelet/kubectl ↓ 4. kubeadm init 初始化 Master 节点 ↓ 5. 配置 kubectl ↓ 6. kubeadm join 添加 Worker 节点 ↓ 7. 安装 CNI 网络插件Calico ↓ 8. 验证集群状态关键命令速查命令作用kubeadm init初始化集群kubeadm join将节点加入集群kubeadm reset重置集群kubectl get nodes查看节点状态kubectl label nodes给节点打标签kubectl apply -f calico.yaml部署网络插件kubectl run创建测试 Pod注意事项SELinux 必须关闭Kubernetes 与 SELinux 存在兼容性问题。Swap 必须关闭kubelet 要求禁用 Swap。网络插件必须在集群初始化后立即安装否则节点状态为NotReady。cri-dockerd 必须指定正确的 socket 路径--cri-socketunix:///var/run/cri-dockerd.sock。Pod 网络 CIDR 必须与网络插件配置一致此处为10.244.0.0/16。