一、集群安装
1、k8s主要组件的镜像有哪些?
k8s主要组件的镜像是可以离线下载的,你可以手动下载这些镜像并上传到目标机器,以便在离线或受限网络环境中部署 Kubernetes 集群。
都需要下载哪些镜像呢?可以使用如下的命令查看,前提是已经安装kubeadm。
获取镜像列表的命令
# 以获取v1.26.0版本的组件镜像列表为例 kubeadm config images list --kubernetes-version v1.26.0 # 输出的示例如下 registry.k8s.io/kube-apiserver:v1.26.0 registry.k8s.io/kube-controller-manager:v1.26.0 registry.k8s.io/kube-scheduler:v1.26.0 registry.k8s.io/kube-proxy:v1.26.0 registry.k8s.io/pause:3.8 registry.k8s.io/etcd:3.5.7-0 registry.k8s.io/coredns/coredns:v1.9.3手动下载的步骤
1、在一个有网络的机器上拉取镜像
docker pull registry.k8s.io/kube-apiserver:v1.26.0 docker pull registry.k8s.io/kube-controller-manager:v1.26.0 docker pull registry.k8s.io/kube-scheduler:v1.26.0 docker pull registry.k8s.io/kube-proxy:v1.26.0 docker pull registry.k8s.io/pause:3.8 docker pull registry.k8s.io/etcd:3.5.7-0 docker pull registry.k8s.io/coredns/coredns:v1.9.3k8s的docker镜像仓在海外,下载会比较慢。可以选择国内的镜像仓拉取相关的镜像。
2、将拉取的镜像导出为tar文件
docker save registry.k8s.io/kube-apiserver:v1.26.0 > kube-apiserver.tar docker save registry.k8s.io/kube-controller-manager:v1.26.0 > kube-controller-manager.tar docker save registry.k8s.io/kube-scheduler:v1.26.0 > kube-scheduler.tar docker save registry.k8s.io/kube-proxy:v1.26.0 > kube-proxy.tar docker save registry.k8s.io/pause:3.8 > pause.tar docker save registry.k8s.io/etcd:3.5.7-0 > etcd.tar docker save registry.k8s.io/coredns/coredns:v1.9.3 > coredns.tar3、将镜像导出的tar文件上传到目标主机
4、在目标主机上加载镜像
docker load < /tmp/kube-apiserver.tar docker load < /tmp/kube-controller-manager.tar docker load < /tmp/kube-scheduler.tar docker load < /tmp/kube-proxy.tar docker load < /tmp/pause.tar docker load < /tmp/etcd.tar docker load < /tmp/coredns.tar5、修改配置文件中的镜像仓库地址
如果你使用的是私有镜像仓库,可以修改kubeadm-init.yaml中的imageRepository字段:
imageRepository: "your-registry.com/k8s"然后确保你已经将镜像推送到该私有仓库。
或者可以修改镜像的tag,改成默认的镜像仓库地址,或者国内好用的镜像仓库地址
6、初始化集群
kubeadm init --config=kubeadm-init.yaml
注意事项:
- 镜像标签必须一致:确保你下载的镜像版本与
kubeadm-init.yaml中指定的版一致。 - 镜像仓库地址一致:如果使用私有仓库,确保
imageRepository字段与镜像地址一致。 - 镜像加载后无需网络:只要镜像已加载到本地,
kubeadm就不会尝试从远程拉取。
2、容器运行时选择
Kubernetes 从 v1.20 开始逐步减少对 Docker 的直接支持,并在 v1.24 中完全移除了对 Docker 的内置支持。cri-docker是一个兼容 CRI 的适配器,允许 Kubernetes 使用 Docker 作为容器运行时。然而,随着 Kubernetes 对 Docker 的支持被移除,cri-docker也失去了其存在的必要性。
具体版本变化
v1.20:Kubernetes 开始逐步减少对 Docker 的支持。
v1.24:Kubernetes 完全移除了对 Docker 的内置支持,cri-docker也随之被移除。
v1.25+:Kubernetes 不再支持使用 Docker 作为容器运行时,推荐使用containerd或其他 CRI 兼容的运行时。
如果你在使用 Kubernetes v1.24 或更高版本,并且希望继续使用 Docker 作为容器运行时,可以使用cri-docker作为适配器。然而,需要注意的是,cri-docker并不是 Kubernetes 官方维护的项目,而是由社区维护的。
安装cri-docker
# 添加 cri-docker 的软件源 sudo dnf install -y https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_8/devel:kubic:libcontainers:stable.repo # 安装 cri-docker sudo dnf install -y cri-docker配置 Kubernetes 使用cri-docker
编辑 Kubernetes 的配置文件/etc/kubernetes/kubelet.conf,添加以下内容:
runtimeRequestTimeout: 15m runtime: cri-docker重启kubelet服务
systemctl restart kubelet
确保cri-docker服务已启用并运行:
systemctl enable cri-docker --now
systemctl status cri-docker
注意事项
cri-docker 是社区维护的项目,不推荐在生产环境中使用。
Kubernetes v1.28 不再官方支持 Docker 作为容器运行时。
推荐使用 containerd 或 CRI-O 作为容器运行时,以获得更好的性能和稳定性。
二、k8s+containerd部署
1、准备虚拟机
本次k8s集群环境部署使用的操作系统镜像是OpenEuler 22.03 LTS SP1
共准备三台虚拟机,一个作为master节点,规格是2U4G;两台worker节点,规格是2U2G。
| 节点名称 | 节点规格 | IP地址 |
|---|---|---|
| k8s-master | 2U4G | 192.168.232.130 |
| k8s-node1 | 2U2G | 192.168.232.131 |
| k8s-node2 | 2U2G | 192.168.232.132 |
使用VMware创建虚拟机的时候,注意OpenEuler 22.03的操作系统镜像属于rhel8,注意选择。
虚拟机创建的时候软件市场选择standard标准,这样安装后操作系统带有一些常用的命令。
网络设置注意启动网卡,否则等虚拟机创建完成后会无法登陆。
操作系统安装完成后,可以使用终端连接工具登陆虚拟机,这样就可以不用在vnware的虚拟化界面操作了,比较方便后续对虚拟机的配置和操作。
操作系统安装后,首先是给虚拟机设置静态IP,不要开启DHCP。目的是为了不想虚拟机的地址经常变化,否则可能每次开机,虚拟机的IP地址都不一样。
nmcli c m ens160 ipv4.address 192.168.232.131/24 nmcli c m ens160 ipv4.method manual nmcli c m ens160 ipv4.gateway 192.168.232.2 nmcli c m ens160 connection.autoconnect yes nmcli c m ens160 ipv4.dns 8.8.8.8修改后需要重启接口网卡,有的说重启NetWorkManager服务,但是我试了好像没有生效。所以还是使用nmcli命令重启了接口网卡。
nmcli c up ens160注意:以下操作中,标记所有节点的,代表每个节点都需要执行。
2、设置主机名(所有节点)
[root@localhost network-scripts]# hostnamectl hostname k8s-node1 [root@localhost network-scripts]# vi /etc/hosts [root@localhost network-scripts]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.232.130 k8s-master 192.168.232.131 k8s-node1 192.168.232.132 k8s-node2如果在初始化的时候指定了--control-plane-endpoint=cluster-endpoint参数,则还需要在/etc/hosts文件中添加,否则会导致初始化失败。kubelet启动状态中存在报错导致的初始化失败问题。
192.168.232.130 cluster-endpoint3、关闭防火墙(所有节点)
在安装 Kubernetes(k8s)时关闭防火墙通常有以下原因:
- 避免阻碍网络通信:Kubernetes 集群中的各个节点需要通过一系列网络端口进行通信,包括 API 服务器、kubelet、etcd 等。关闭防火墙可以避免阻碍节点之间的网络通信,确保集群的正常运行。
- 避免前后两代方案互斥冲突:如果防火墙指的是 firewalld,那就应该关闭,因为 firewalld 和 iptables 属于前后两代方案,互斥。k8s 通过 iptables 做 Pod 间流量的转发和端口映射,若使用 firewalld 可能导致冲突。当然,如果 k8s 没用 iptables,比如用了其他的方式那就不需要用到自然可以关掉1。
[root@localhost network-scripts]# systemctl stop firewalld [root@localhost network-scripts]# systemctl disable firewalld Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.4、关闭SELinux(所有节点)
- 在安装 Kubernetes(k8s)时执行 setenforce 0 操作,主要是为了临时关闭 SELinux(Security-Enhanced Linux)的强制模式,将其切换为宽容模式。SELinux 是 Linux 系统中一个强大的安全机制,它通过强制访问控制(MAC)来增强系统的安全性。然而,在安装 k8s 时关闭 SELinux 强制模式通常有以下原因:
- 避免策略限制:SELinux 的策略可能会限制 k8s 组件之间的网络通信和文件访问,导致组件无法正常工作。例如,k8s 的容器运行时(如 Docker)可能无法正常访问所需的文件系统路径,或者 kubelet 无法与 API 服务器进行通信。
- 减少配置复杂性:SELinux 的策略配置较为复杂,对于初学者来说,正确配置 SELinux 以适应 k8s 的运行环境可能会非常困难。临时关闭 SELinux 可以简化安装过程,减少因 SELinux 策略配置不当而导致的问题。
- 兼容性问题:某些 k8s 组件或插件可能与 SELinux 的策略存在兼容性问题。在这种情况下,关闭 SELinux 可以避免这些兼容性问题,确保 k8s 集群的正常安装和运行。
- 需要注意的是,setenforce 0 只是临时关闭 SELinux 的强制模式,系统重启后 SELinux 可能会恢复到原来的状态。如果需要永久关闭 SELinux,可以修改 /etc/selinux/config 文件,将 SELINUX=enforcing 改为 SELINUX=disabled。
# 临时关闭 setenforce 0 # 修改配置文件,永久关闭 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config [root@localhost network-scripts]# cat /etc/selinux/config | grep SELINUX # SELINUX= can take one of these three values: SELINUX=disabled # SELINUXTYPE= can take one of these three values: SELINUXTYPE=targeted5、关闭SWAP(所有节点)
部署K8s时关闭Swap的原因主要有以下几点:
- 确保集群行为一致性:K8s官方文档在安装前准备中明确要求 “禁用Swap”,这是从底层设计层面确保集群行为的一致性1。
- 避免性能下降和应用崩溃:在虚拟内存管理系统里,虽然Swap能在磁盘上增加系统可用内存量,但磁盘虚拟页面和内存页面交换过程会带来额外的磁盘I/O负载。而容器运行环境自身对磁盘吞吐量需求很高,所以Swap分区的使用在高负载情况下会使K8s系统整体性能下降,还可能导致应用程序崩溃2。
- 满足K8s性能设计要求:Swap是交换分区,当机器内存不够时会使用它,但Swap分区性能较低。K8s设计时为提升性能,默认不允许使用交换分区。Kubeadm初始化时会检测Swap是否关闭,若未关闭则初始化失败3。
- 利于负载均衡:如果内存满了,将一部分数据放到硬盘,会让scheduler误认为该节点资源空闲,从而放置更多的pod运行。在高负载情况下会导致部分pod性能极差,不利于负载均衡,而且K8s集群不在开启了交换分区的节点运行5。
# 临时关闭 swapoff -a # 写入系统配置文件 echo "vm.swappiness = 0" >> /etc/sysctl.conf # 检查挂载配置文件,注释掉swap分区挂载信息 vi /etc/fstab cat /etc/fstab # /etc/fstab # Created by anaconda on Sat Oct 25 12:44:22 2025 # # Accessible filesystems, by reference, are maintained under '/dev/disk/'. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info. # # After editing this file, run 'systemctl daemon-reload' to update systemd # units generated from this file. # /dev/mapper/openeuler-root / ext4 defaults 1 1 UUID=b3fa3f0e-20e8-449f-9690-be6c022c7ba6 /boot ext4 defaults 1 2 #/dev/mapper/openeuler-swap none swap defaults 0 06、加载内核参数(所有节点)
# 加载Linux内核的桥接网络过滤模块 modprobe br_netfilter echo "modprobe br_netfilter" >> /etc/profile # 添加系统的sysctl配置文件,是Kubernetes、Docker 等容器网络正常工作的内核参数配置 tee /etc/sysctl.d/k8s.conf << EOF net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF 加载配置,系统会读取该文件中的参数并将其应用到当前内核,使内核参数立即生效。 sysctl -p /etc/sysctl.d/k8s.conf7、配置yum源(所有节点)
根据操作系统版本,配置好yum源,方便后续安装一些必要的软件包。
以本次的OpenEuler 22.03 LTS SP1 操作系统版本为例,这里建议配置华为开发镜像站提供的配置方法,必将该操作系统是华为开源的OS操作系统。
华为开源镜像站的链接地址如下:
https://mirrors.huaweicloud.com/home使用说明
1、在/etc/yum.repos.d/目录下,创建文件openEuler.repo,根据 openEuler 版本及系统架构选择配置内容。
[openEuler-everything] name=openEuler-everything baseurl=https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP1/everything/x86_64/ enabled=1 gpgcheck=0 gpgkey=https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP1/everything/x86_64/RPM-GPG-KEY-openEuler [openEuler-EPOL] name=openEuler-epol baseurl=https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP1/EPOL/main/x86_64/ enabled=1 gpgcheck=0 [openEuler-update] name=openEuler-update baseurl=https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP1/update/x86_64/ enabled=1 gpgcheck=02、执行yum clean all清除原有 yum 缓存。
3、执行yum makecache生成新的缓存。
如果由于证书校验什么的导致无法下载包,可以根据下面的方式处理,编辑yum.conf文件,增加sslverify=False配置。
[root@localhost yum.repos.d]# vi /etc/yum.conf [root@localhost yum.repos.d]# cat /etc/yum.conf [main] gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False sslverify=False [root@localhost yum.repos.d]#8、安装ntpd服务(所有节点)
用于同步时钟源,确保集群节点的时间一致性
yum install -y ntp ntpdate ntpdate cn.pool.ntp.org systemctl start ntpd systemctl enable ntpd可以写一个脚本,配置定时任务定期执行时间同步。
另外,还可以根据需要选择部署chrony服务来保证时间同步,可以参考相关资料完成配置。
9、安装kubeadm、kubelet、kubectl(所有节点)
配置kubenetes的yum源
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/ enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key EOF# 关闭SELinux setenforce 0 # 安装kubelet kubeadm kubectl yum install -y kubelet kubeadm kubectl # 将kubelet设置开机自启,并启动 systemctl enable kubelet && systemctl start kubelet注意,安装的时候最好制定一下版本,免得不同主机安装的组件版本不一致
安装的时候最好制定一下想要安装的版本,本次以1.28.2版本为例 yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 systemctl enable kubelet systemctl start kubelet安装完成后,最好检查一下k8s主要组件的镜像以及版本信息,方便后边安装容器运行时,配置正确。
[root@localhost yum.repos.d]# kubeadm config images list --kubernetes-version v1.28.2 registry.k8s.io/kube-apiserver:v1.28.2 registry.k8s.io/kube-controller-manager:v1.28.2 registry.k8s.io/kube-scheduler:v1.28.2 registry.k8s.io/kube-proxy:v1.28.2 registry.k8s.io/pause:3.9 registry.k8s.io/etcd:3.5.9-0 registry.k8s.io/coredns/coredns:v1.10.110、安装docker-ce和containerd(所有节点)
首先配置docker-ce的yum源
登陆阿里巴巴开源镜像站,链接地址如下:
https://developer.aliyun.com/mirror/
# step 1: 安装必要的一些系统工具 yum install -y yum-utils # Step 2: 添加软件源信息 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 安装Docker yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Step 4: 开启Docker服务 service docker start # 注意: # vim /etc/yum.repos.d/docker-ce.repo # 将[docker-ce-test]下方的enabled=0修改为enabled=1 # # 安装指定版本的Docker-CE: # Step 1: 查找Docker-CE的版本: # yum list docker-ce.x86_64 --showduplicates | sort -r # Loading mirror speeds from cached hostfile # Loaded plugins: branch, fastestmirror, langpacks # docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable # docker-ce.x86_64 17.03.1.ce-1.el7.centos @docker-ce-stable # docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable # Available Packages # Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos) # sudo yum -y install docker-ce-[VERSION]注意:
dcoker-ce的yum源配置后,可能会遇到无法拉取镜像的情况。
以openeuler 22.03.sp1为例,这个操作系统是rel8的,所以文件中的内容要替换
$releasever替换成8
$basearch替换成实际的操作系统架构类型,比如x86_64
#启动docker systemctl start docker #设置开机自启 systemctl enable docker #验证安装 docker -v 配置阿里云镜像加速器 tee /etc/docker/daemon.json << EOF { "registry-mirrors": ["https://p59n3y39.mirror.aliyuncs.com"] } EOF 重新加载并重启 systemctl daemon-reload systemctl restart docker其实本次重点不是部署docker,而是containerd。本次是用containerd作为容器运行时的
11、配置和启动containerd
检查操作系统是否安装了containerd,如果没有可以使用下面的名安装 yum install -y containerd.io 配置containerd 生成containerd的默认配置文件: mkdir -p /etc/containerd containerd config default > /etc/containerd/config.toml 编辑/etc/containerd/config.toml配置文件,修改如下内容 修改cgroup Driver为systemd SystemdCgroup = true 修改镜像地址 sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" 注意: pause:xx版本需要注意,要用k8s组件中的配套。配置镜像加速(可选)
mkdir -p /etc/containerd/certs.d/{ghcr.io,docker.io} vi /etc/containerd/certs.d/ghcr.io/hosts.toml 添加如下内容 server = "https://ghcr.io" # 南京大学镜像站(推荐) [host."https://ghcr.nju.edu.cn"] capabilities = ["pull", "resolve"] skip_verify = true # 生产环境建议设为 false # OpenNeeds 公共镜像 [host."https://hub.openeeds.com"] capabilities = ["pull", "resolve"] skip_verify = true # Goops 镜像加速(备用) [host."https://dockerhub.goops.top"] capabilities = ["pull", "resolve"] skip_verify = true # Azure 中国镜像(可选) [host."https://ghcr.azk8s.cn"] capabilities = ["pull", "resolve"] skip_verify = truevi /etc/containerd/certs.d/docker.io/hosts.toml 添加如下内容: server = "https://registry-1.docker.io" # 南京大学镜像站(推荐) [host."https://ghcr.nju.edu.cn"] capabilities = ["pull", "resolve"] skip_verify = true # 生产环境建议设为 false # OpenNeeds 公共镜像 [host."https://hub.openeeds.com"] capabilities = ["pull", "resolve"] skip_verify = true # Goops 镜像加速(备用) [host."https://dockerhub.goops.top"] capabilities = ["pull", "resolve"] skip_verify = true # Azure 中国镜像(可选) [host."https://ghcr.azk8s.cn"] capabilities = ["pull", "resolve"] skip_verify = true [host."https://docker.nju.edu.cn"] capabilities = ["pull", "resolve"] skip_verify = true [host."https://docker.mirrors.ustc.edu.cn"] capabilities = ["pull", "resolve"] skip_verify = true [host."https://dockerproxy.com"] capabilities = ["pull","resolve"] skip_verify = true [host."https://docker.m.daocloud.io"] capabilities = ["pull","resolve"] skip_verify = true [host."http://hub-mirror.c.163.com"] capabilities = ["pull","resolve"] skip_verify = true# 加载配置,设置开机自己并启动 systemctl daemon-reload systemctl enable containerd systemctl start containerd11、初始化kubeadm(管理节点)
初始化有两种方式
一种是生成初始化配置文件:
kubeadm config print init-defaults 命令用于打印默认的初始化配置,这些默认配置可用于 kubeadm init 操作。通过该命令可以获取到初始化集群时的默认参数设置,还能将其输出重定向到一个文件中,生成默认初始化配置文件,例如使用 kubeadm config print init-defaults > kubeadm-config.yaml 就可生成默认初始化配置文件,之后便可以使用这个自定义配置文件来初始化集群,如 kubeadm init --config kubeadm-config.yaml 13。
另外一种方式就是在执行kubeadm init的时候,跟上数。
kubeadm init \ --apiserver-advertise-address=192.168.232.130 \ --control-plane-endpoint=cluster-endpoint \ --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-version v1.28.2 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=172.20.0.0/16如果初始化没有问题,会显示如下回显信息,需要记录就好
例如:
Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root: kubeadm join cluster-endpoint:6443 --token fpz82l.mdap323z7h1nkve5 \ --discovery-token-ca-cert-hash sha256:028a3df8f66f53fda563aee7281878ec028f544bf447be10a554da5a883579c6 \ --control-plane Then you can join any number of worker nodes by running the following on each as root: kubeadm join cluster-endpoint:6443 --token fpz82l.mdap323z7h1nkve5 \ --discovery-token-ca-cert-hash sha256:028a3df8f66f53fda563aee7281878ec028f544bf447be10a554da5a883579c6如果有多个管理节点的,需要在其他管理节点执行的命令是上面的
You can now join any number of control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root: kubeadm join cluster-endpoint:6443 --token fpz82l.mdap323z7h1nkve5 \ --discovery-token-ca-cert-hash sha256:028a3df8f66f53fda563aee7281878ec028f544bf447be10a554da5a883579c6 \ --control-plane如果要添加工作节点到集群中,需要到工作节点执行的命令是
Then you can join any number of worker nodes by running the following on each as root: kubeadm join cluster-endpoint:6443 --token fpz82l.mdap323z7h1nkve5 \ --discovery-token-ca-cert-hash sha256:028a3df8f66f53fda563aee7281878ec028f544bf447be10a554da5a883579c612、添加Node节点(node节点)
如果在工作节点执行命令有如下报错:
[root@k8s-node1 ~]# kubeadm join cluster-endpoint:6443 --token dwpm6b.g4nwlkv6c49wo3xv \ --discovery-token-ca-cert-hash sha256:54304a1370e45aa785699a83d0366c547151780c3bd4c8300f54c248865bd0cf [preflight] Running pre-flight checks error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap for token ID "dwpm6b" To see the stack trace of this error execute with --v=5 or higher # 分析 上面的报错是以内口令过期导致的,可以执行如下命令生成新的口令 kubeadm token create --print-join-command 注意:命令是在登陆管理节点执行的 [root@k8s-master ~]# kubeadm token create --print-join-command kubeadm join cluster-endpoint:6443 --token hj5r11.eytwy2wf7cokigmy --discovery-token-ca-cert-hash sha256:d14fe61d99e5b4f1015def139f3a70da9740cdd44e208ab676dc4d3dc9ef21d8 复制新生成的命令,到工作节点执行就可以了 [root@k8s-node1 ~]# kubeadm join cluster-endpoint:6443 --token hj5r11.eytwy2wf7cokigmy --discovery-token-ca-cert-hash sha256:d14fe61d99e5b4f1015def139f3a70da9740cdd44e208ab676dc4d3dc9ef21d8 [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.添加完成后,在管理节点执行命令,查看结果
[root@k8s-master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 36m v1.28.2 k8s-node1 NotReady <none> 5m29s v1.28.2 k8s-node2 NotReady <none> 14s v1.28.213、部署网络插件(所有节点)
在上述结果中,节点状态显示为NotReady,表示该节点尚未准备就绪。原因是以为kubelet服务未能发现网络插件导致的,kubelet日志中对此进行了说明。
Kubenetes网络插件主要用于实现集群内部Pod通信,负责配置和管理Pod网络。常见的网络插件包括calico、flannel等。本次选择使用Calico作为Kubenetes的网络插件。
在线安装会因为网络问题导致安装失败,本次演示如何离线安装。
# 本次下载的v 3.26.0版本,下载链接如下 https://github.com/projectcalico/calico/releases/tag/v3.26.0先进入首页https://github.com/projectcalico/calico
点击release去下载需要的版本
点击以后进入详情页面,选择需要的版本。
下载好之后,上传到所有节点。规划好一个目录存放,例如
[root@k8s-master calico-3.26.0]# pwd /data/calico-3.26.0 [root@k8s-master calico-3.26.0]# cd /data/calico-3.26.0 [root@k8s-master calico-3.26.0]# tar -xzvf release-v3.26.0.tgz [root@k8s-master calico-3.26.0]# ll total 1104456 drwxrwxr-x 5 1000 1000 4096 May 27 2023 release-v3.26.0 -rw-r--r-- 1 root root 1130953033 Oct 26 16:19 release-v3.26.0.tgz我们解压calico的离线包后会得到很多文件,并不是全部需要。
使用cat calico.yaml |grep image:命令查看calico所需的镜像包。
[root@k8s-master manifests]# pwd /data/calico-3.26.0/release-v3.26.0/manifests [root@k8s-master manifests]# cat calico.yaml |grep image: image: docker.io/calico/cni:v3.26.0 image: docker.io/calico/cni:v3.26.0 image: docker.io/calico/node:v3.26.0 image: docker.io/calico/node:v3.26.0 image: docker.io/calico/kube-controllers:v3.26.0使用ctr命令加载镜像,加载之前先查询一下namespace信息
[root@k8s-master release-v3.26.0]# ctr namespace ls NAME LABELS default k8s.io然后执行命令加载镜像到对应的命名空间。离线镜像导入containerd的k8s命名空间中
[root@k8s-master calico-3.26.0]# cd release-v3.26.0/ [root@k8s-master release-v3.26.0]# ll total 12 drwxrwxr-x 4 1000 1000 4096 May 27 2023 bin drwxrwxr-x 2 1000 1000 4096 May 27 2023 images drwxrwxr-x 5 1000 1000 4096 Oct 26 16:23 manifests [root@k8s-master release-v3.26.0]# cd images/ [root@k8s-master images]# ll total 773076 -rw------- 1 1000 1000 210411008 May 27 2023 calico-cni.tar -rw------- 1 1000 1000 45467136 May 27 2023 calico-dikastes.tar -rw------- 1 1000 1000 123216896 May 27 2023 calico-flannel-migration-controller.tar -rw------- 1 1000 1000 77480960 May 27 2023 calico-kube-controllers.tar -rw------- 1 1000 1000 249806336 May 27 2023 calico-node.tar -rw------- 1 1000 1000 14959616 May 27 2023 calico-pod2daemon.tar -rw------- 1 1000 1000 70275072 May 27 2023 calico-typha.tar [root@k8s-master images]# pwd /data/calico-3.26.0/release-v3.26.0/images # 里面有很多的镜像文件,查了很多文档说只需要加载以下三个就可以,其他的作用不知。后续了解 ctr -n k8s.io images import calico-cni.tar ctr -n k8s.io images import calico-kube-controllers.tar ctr -n k8s.io images import calico-node.tar在管理节点执行如下,部署网络插件
kubectl apply -f calico.yaml查看结果:
[root@k8s-master manifests]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 3h43m v1.28.2 k8s-node1 NotReady <none> 3h12m v1.28.2 k8s-node2 NotReady <none> 3h7m v1.28.2可以看到管理节点的状态已经就绪。到其他节点完成镜像的加载操作,再次回到管理节点检查就可以了。
[root@k8s-node2 release-v3.26.0]# cd images/ [root@k8s-node2 images]# ll total 773076 -rw------- 1 1000 1000 210411008 May 27 2023 calico-cni.tar -rw------- 1 1000 1000 45467136 May 27 2023 calico-dikastes.tar -rw------- 1 1000 1000 123216896 May 27 2023 calico-flannel-migration-controller.tar -rw------- 1 1000 1000 77480960 May 27 2023 calico-kube-controllers.tar -rw------- 1 1000 1000 249806336 May 27 2023 calico-node.tar -rw------- 1 1000 1000 14959616 May 27 2023 calico-pod2daemon.tar -rw------- 1 1000 1000 70275072 May 27 2023 calico-typha.tar [root@k8s-node2 images]# ctr ns ls NAME LABELS k8s.io [root@k8s-node2 images]# ctr -n k8s.io images import calico-cni.tar unpacking docker.io/calico/cni:v3.26.0 (sha256:233294f10079b643f21fb7eccdf3c960c93c72d4b3271fbeee78d91632ec5f47)...done [root@k8s-node2 images]# ctr -n k8s.io images import calico-kube-controllers.tar unpacking docker.io/calico/kube-controllers:v3.26.0 (sha256:54f001b1e8311afcc7615ef6e16fd3f3696fad1f131f7e663906164e08797fe4)...done [root@k8s-node2 images]# ctr -n k8s.io images import calico-node.tar unpacking docker.io/calico/node:v3.26.0 (sha256:c6c02eaf20a06080ea4f6feb2bd5b691874254c26316ebb7f811055a897e209f)...done[root@k8s-master calico-3.26.0]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 3h51m v1.28.2 k8s-node1 Ready <none> 3h20m v1.28.2 k8s-node2 Ready <none> 3h14m v1.28.2