Kubernetes目前大约每年发布三次,由于迭代速度快,目前市场上绝大部分的教程相对陈旧。更重要的是,从Kubernetes 1.20开始,Kubernetes官方宣布逐步弃用Docker作为容器运行时,并计划在Kubernetes 1.24版本中完全移除对Docker作为容器运行时的支持。这意味着,从Kubernetes 1.24版本开始,将不能使用Docker作为容器运行时来运行Kubernetes节点上的Pods。因此,市场上关于直接使用containerd容器运行时的新版Kubernetes教程几乎没有,更重要的是因为的Kubernetes涉及到镜像需要单独配置才能获取,这无疑拉高了初学者门槛。本教程采用互联网的形式进行发布,便于保持与Kubernetes最新版的同步,尽量自包含,便于读者学习、实践。
关键字:Kubernetes 1.32; containerd; nerdctl; debain 12
整体规划
为方便后续内容学习,本部分将基于【Kubernetes部署与运维04 Kubernetes集群创建】中创建的三台虚拟机环境开展Kubernetes的部署与学习。整体规划如下:
| 虚拟机名称 | IP地址 | 主机名 | 域名 | CPU核心 | 内存 | 角色 |
|---|---|---|---|---|---|---|
K8s_Template | 192.168.152.5 | k8s | k8s.rz | 2 | 2GB | 模板 |
k8s_Master1_2G | 192.168.152.200 | master1 | master.rz | 2 | 2GB | master |
K8s_Worker1_2G | 192.168.152.201 | worker1 | worker1.rz | 1 | 2GB | worker |
K8s_Worker2_2G | 192.168.152.202 | worker2 | worker2.rz | 1 | 2GB | worker |
虽然
worker1、worker2分配内存1GB在控制平面初始化时不报错,但是在安装Metrics-Server插件时会报内存不足错误。因此,本部分最低内存要求设置为2GB。CPU核心数除K8s_Master1_2G虚拟机之外,K8s_Worker1_2G与K8s_Worker2_2G虚拟机均可以使用1核心或2核心,读者可根据自己电脑硬件配置灵活选择。
其中,各虚拟机的克隆关系如下:
| 源虚拟机 | 克隆机 |
|---|---|
K8s_Nerdctl_Base | K8s_Template |
K8s_Template | K8s_Master1_2G |
K8s_Template | K8s_Worker1_2G |
K8s_Template | K8s_Worker2_2G |
参见【Kubernetes部署与运维02 Nerdctl Rootful部署】,Kubernetes基础环境各组件与版本信息如下:
- nerdctl: v1.7.7
- containerd: v1.7.22
- runc: v1.1.14
- CNI plugins: v1.5.1
- BuildKit: v0.15.2
- Stargz Snapshotter: v0.15.1
- imgcrypt: v1.1.11
- RootlessKit: v2.3.1
- slirp4netns: v1.3.1
- bypass4netns: v0.4.1
- fuse-overlayfs: v1.13
- containerd-fuse-overlayfs: v1.0.8
- Kubo (IPFS): v0.29.0
- Tini: v0.19.0
- buildg: v0.4.1
Kubernetes版本号为1.32。
理论知识
当节点加入kubeadm初始化的集群时,需要建立双向信任。 这个过程可以分解为发现(让待加入节点信任Kubernetes控制平面节点)和TLS引导(让Kubernetes控制平面节点信任待加入节点)两个部分。
有两种主要的发现方案。 第一种方案是使用共享令牌和API服务器的IP地址(本教程使用该方案)。 第二种是以文件形式提供标准kubeconfig文件的一个子集。 发现/kubeconfig文件支持令牌、client-go鉴权插件(“exec”)、“tokenFile” 和“authProvider”。该文件可以是本地文件,也可以通过HTTPS URL下载。 格式是kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443、 kubeadm join --discovery-file path/to/file.conf或者kubeadm join --discovery-file https://url/file.conf。 只能使用其中一种。 如果发现信息是从URL加载的,必须使用HTTPS。 此外,在这种情况下,主机安装的CA包用于验证连接。
如果使用共享令牌进行发现,还应该传递--discovery-token-ca-cert-hash参数来验证Kubernetes控制平面节点提供的根证书颁发机构(CA)的公钥。 此参数的值指定为"<hash-type>:<hex-encoded-value>", 其中支持的哈希类型为 "sha256"。哈希是通过Subject Public Key Info(SPKI)对象的字节计算的(如RFC7469)。 这个值可以从 "kubeadm init" 的输出中获得,或者可以使用标准工具进行计算。 可以多次重复--discovery-token-ca-cert-hash参数以允许多个公钥。
如果无法提前知道CA公钥哈希,则可以通过--discovery-token-unsafe-skip-ca-verification参数禁用此验证。 这削弱了kubeadm安全模型,因为其他节点可能会模仿Kubernetes控制平面节点。
TLS引导机制也通过共享令牌驱动。 这用于向Kubernetes控制平面节点进行临时的身份验证,以提交本地创建的密钥对的证书签名请求(CSR)。 默认情况下,kubeadm将设置Kubernetes控制平面节点自动批准这些签名请求。 这个令牌通过--tls-bootstrap-token abcdef.1234567890abcdef参数传入。
通常两个部分会使用相同的令牌。 在这种情况下可以使用--token参数,而不是单独指定每个令牌。
"kubeadm join [api-server-endpoint]" 命令执行下列阶段:
preflight:运行接入前检查;control-plane-prepare:准备用作控制平面的机器; a)download-certs:从kubeadm-certs Secret下载控制平面节点之间共享的证书; b)certs:为新的控制平面组件生成证书; c)kubeconfig:为新的控制平面组件生成kubeconfig; d)control-plane:生成新控制平面组件的清单;kubelet-start:写入kubelet设置、证书并(重新)启动kubelet;control-plane-join:将机器加入为控制平面实例; a)etcd:添加新的本地etcd成员; b)update-status:将新的控制平面节点注册到kubeadm-config ConfigMap中维护的ClusterStatus中(已弃用); c)mark-control-plane:将节点标记为控制平面;wait-control-plane:等待控制平面启动
案例实践
前期准备
同时启动master1、worker1与worker2三台虚拟机,使用MobaXterm同时登录至三台虚拟机。后续所有操作,均需注意命令提示符,以判断所有具体虚拟机,避免混乱。
自动生成加入命令加入控制平面
【实践01-自动生加入命令加入控制平面】
使用kubeadm token create --print-join-command命令生成节点加入命令,将节点worker1加入控制平面。
1)目前控制平面中仅一台虚拟机master1,作为集群,其他节点也需要加入到控制平面中。由于节点加入控制平面的命令比较复杂,因此,Kubernetes提供了更为便捷的方式,自动生成加入命令。在master1管理节点上生成加入控制平面命令:
root@master1:~# kubeadm token create --print-join-command
kubeadm join 192.168.152.200:6443 --token wju40t.n8j7g20okn5bli3c --discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
所生成的加入控制平面命令中的
--token、--discover-token-ca-cert-hash参数的含义与获取,参见后续示例。
2)现拟将worker1虚拟机加入控制平面,在worker1虚拟机上执行加入控制平面命令:
root@worker1:~# kubeadm join 192.168.152.200:6443 --token wju40t.n8j7g20okn5bli3c --discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
[preflight] Running pre-flight checks
[preflight] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[preflight] Use 'kubeadm init phase upload-config --config your-config.yaml' to re-upload it.
[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-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 504.188109ms
[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.
3)返回master1虚拟机,查看worker1虚拟机加入情况:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 15h v1.32.1
worker1 Ready <none> 5m25s v1.32.1
root@master1:~# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5745477d4d-x4dbj 1/1 Running 1 (8m12s ago) 13h
calico-node-d9sv5 1/1 Running 1 (8m12s ago) 13h
calico-node-zpbc2 1/1 Running 0 5m41s
coredns-6766b7b6bb-hqgsd 1/1 Running 1 (8m12s ago) 15h
coredns-6766b7b6bb-w8ztk 1/1 Running 1 (8m12s ago) 15h
etcd-master1 1/1 Running 2 (8m12s ago) 15h
kube-apiserver-master1 1/1 Running 2 (8m12s ago) 15h
kube-controller-manager-master1 1/1 Running 2 (8m12s ago) 15h
kube-proxy-h2v5l 1/1 Running 2 (8m12s ago) 15h
kube-proxy-jf5tm 1/1 Running 0 5m41s
kube-scheduler-master1 1/1 Running 2 (8m12s ago) 15h
所有
node均处于Ready状态,所有pod(后续将展开讲解),均处于1/1状态,表示worker1加入成功。 注意,工作节点加入控制平面需要一定的时间周期,因此,所有的pod不一定是马上处于1/1状态,需要等待一段时间。
手动生成加入命令加入控制平面
【实践02- 手动生加入命令加入控制平面】
手动生成节点加入命令,将节点worker2加入控制平面。
1)在【Kubernetes部署与运维04 Kubernetes集群创建-控制平面创建】部分,使用kubeadm init --config init-defaults.yaml命令初始化控制平面时,其输出内容的最后一部分为:
kubeadm join 192.168.152.200:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
其表示可以使用该命令在其他工作节点(worker node)上以root身份执行,来达到加入控制平面的目的。
控制平面服务器192.168.152.200及端口6443(Kubernetes API Server地址),已在/root/software/k8s/init-defaults.yaml配置文件第12行与第13行给出。
12 │ advertiseAddress: 192.168.152.200
13 │ bindPort: 6443
--token abcdef.0123456789abcdef,同时已在/root/software/k8s/init-defaults.yaml配置文件第5行给出:
5 │ token: abcdef.0123456789abcdef
6 │ ttl: 24h0m0s
但请注意第
6行表示该--token有效期仅为24小时。token是服务端生成的一串字符串,用作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个token便将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。
2)--token参数可以在master虚拟机上使用kubeadm token list命令查看:
root@master1:~# kubeadm token list
TOKEN TTL EXPIRES
abcdef.0123456789abcdef 8h 2025-01-30T09:16:08Z
wju40t.n8j7g20okn5bli3c 23h 2025-01-31T00:29:24Z
由于排版限制,仅给出了重要的几列内容,其他列内容已经省掉。 其中
abcdef.0123456789abcdef,有效期TTL还有8小时,是在初始化控制平面时通过init-defaults.yaml配置文件设置的,另一个wju40t.n8j7g20okn5bli3c,则是在【自动生成加入命令加入控制平面】部分自动生成的。
3)默认情况下,token的有效期限为24小时,所以查看到的TTL信息均在24小时之内,该token将在24小时之后失效。如果需要再使用,则需要重新创建。
root@master1:~# kubeadm token create
kdx6uz.hiom4kc572ikb94c
root@master1:~# kubeadm token list
TOKEN TTL EXPIRES
abcdef.0123456789abcdef 8h 2025-01-30T09:16:08Z
kdx6uz.hiom4kc572ikb94c 23h 2025-01-31T01:14:25Z
wju40t.n8j7g20okn5bli3c 23h 2025-01-31T00:29:24Z
4)若希望生成一个永久有效的token,可以使用--ttl 0参数:
root@master1:~# kubeadm token create --ttl 0
t4e260.nuy2xrkbdl10z646
root@master1:~# kubeadm token list
TOKEN TTL EXPIRES
abcdef.0123456789abcdef 7h 2025-01-30T09:16:08Z
kdx6uz.hiom4kc572ikb94c 23h 2025-01-31T01:14:25Z
t4e260.nuy2xrkbdl10z646 <forever> <never>
wju40t.n8j7g20okn5bli3c 23h 2025-01-31T00:29:24Z
新创建的
token,其TTL为<forever>(永久),而EXPIRES为<never>(永不超期)。
5)--discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9,其值截取于主节点master1的CA证书,可以使用openssl命令查看:
root@master1:~# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
注意,在向--discovery-token-ca-cert-hash给出具体参数值时,要在其前面加上sha256:。只要主节点master1的CA证书不变,则截取出来的hash值(SHA256)就不变。而CA证书的存储位置在:
root@master1:~# ls /etc/kubernetes/pki/ca.crt -l
-rw-r--r-- 1 root root 1107 Jan 29 17:15 /etc/kubernetes/pki/ca.crt
6)现在可以使用永久token将工作节点worker2加入到集群。在工作节点worker2上执行kubeadm join命令:
root@worker2:~# kubeadm join 192.168.152.200:6443 --token t4e260.nuy2xrkbdl10z646 --discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
[preflight] Running pre-flight checks
[preflight] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[preflight] Use 'kubeadm init phase upload-config --config your-config.yaml' to re-upload it.
[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-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 501.874443ms
[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.
7)返回主节点master1,查看工作节点worker2加入情况:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 16h v1.32.1
worker1 Ready <none> 82m v1.32.1
worker2 Ready <none> 2m10s v1.32.1
root@master1:~# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5745477d4d-x4dbj 1/1 Running 1 (85m ago) 14h
calico-node-d9sv5 1/1 Running 1 (85m ago) 14h
calico-node-dfjpj 0/1 Init:2/3 0 2m42s
calico-node-zpbc2 1/1 Running 0 82m
coredns-6766b7b6bb-hqgsd 1/1 Running 1 (85m ago) 16h
coredns-6766b7b6bb-w8ztk 1/1 Running 1 (85m ago) 16h
etcd-master1 1/1 Running 2 (85m ago) 16h
kube-apiserver-master1 1/1 Running 2 (85m ago) 16h
kube-controller-manager-master1 1/1 Running 2 (85m ago) 16h
kube-proxy-8vgtp 1/1 Running 0 2m42s
kube-proxy-h2v5l 1/1 Running 2 (85m ago) 16h
kube-proxy-jf5tm 1/1 Running 0 82m
kube-scheduler-master1 1/1 Running 2 (85m ago) 16h
root@master1:~# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5745477d4d-x4dbj 1/1 Running 1 (86m ago) 14h
calico-node-d9sv5 1/1 Running 1 (86m ago) 14h
calico-node-dfjpj 1/1 Running 0 4m4s
calico-node-zpbc2 1/1 Running 0 84m
coredns-6766b7b6bb-hqgsd 1/1 Running 1 (86m ago) 16h
coredns-6766b7b6bb-w8ztk 1/1 Running 1 (86m ago) 16h
etcd-master1 1/1 Running 2 (86m ago) 16h
kube-apiserver-master1 1/1 Running 2 (86m ago) 16h
kube-controller-manager-master1 1/1 Running 2 (86m ago) 16h
kube-proxy-8vgtp 1/1 Running 0 4m4s
kube-proxy-h2v5l 1/1 Running 2 (86m ago) 16h
kube-proxy-jf5tm 1/1 Running 0 84m
kube-scheduler-master1 1/1 Running 2 (86m ago) 16h
现在,控制平面中包含了三个节点,主节点master1,以及工作节点worker1与worker2,他们成型了Kubernetes集群。后文中将不再区分集群与控制平面,大部分场景中均使用集群 两字。
节点删除
【实践03- 从控制平面中删除节点】
将节点worker2 从控制平面中删除。
与工作节点加入集群时需要在待加入工作节点之上执行kubeadm join命令不同,将工作节点从集群中删除,需要先在主节点master1上使用kubectl delete nodes <nodeName>命令。
把工作节点worker2从集群中删除:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 16h v1.32.1
worker1 Ready <none> 97m v1.32.1
worker2 Ready <none> 16m v1.32.1
root@master1:~# kubectl delete nodes worker2
node "worker2" deleted
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 16h v1.32.1
worker1 Ready <none> 97m v1.32.1
节点重置
【实践04- 重置被删除掉的节点】
虽然在控制平面中已经删除了工作节点worker2,但是工作节点worker2上依然存留着Kubernetes集群相关的配置与文件、资源等。因此依然需要在工作节点worker2上进行相关的清理,以保证worker2后续可以加入其他控制平面。
1)使用kubeadm reset命令在工作节点worker2上进行重置,使节点恢复初始状态:
root@worker2:~# kubeadm reset
W0130 10:16:43.881148 10453 preflight.go:56] [reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] Are you sure you want to proceed? [y/N]: y
[preflight] Running pre-flight checks
W0130 10:17:00.848114 10453 removeetcdmember.go:106] [reset] No kubeadm config, using etcd pod spec to get data directory
[reset] Deleted contents of the etcd data directory: /var/lib/etcd
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Deleting contents of directories: [/etc/kubernetes/manifests /var/lib/kubelet /etc/kubernetes/pki]
[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/super-admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d
The reset process does not reset or clean up iptables rules or IPVS tables.
If you wish to reset iptables, you must do so manually by using the "iptables" command.
If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
to reset your system's IPVS tables.
The reset process does not clean your kubeconfig files and you must remove them manually.
Please, check the contents of the $HOME/.kube/config file.
2)清理相关网络:
root@worker2:~# rm -rf /etc/cni/net.d/*
3)清理iptables:
root@worker2:~# iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
4)最后,使用【自动生成加入命令加入控制平面】中的kubeadm join命令,在工作节点worker2上执行,将工作节点worker2重新加入集群:
root@worker2:~# kubeadm join 192.168.152.200:6443 --token wju40t.n8j7g20okn5bli3c --discovery-token-ca-cert-hash sha256:f7b874117486c07656a808a1cb1c9afd4e217fe08c6c086b0d07f502cfe580c9
[preflight] Running pre-flight checks
[preflight] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[preflight] Use 'kubeadm init phase upload-config --config your-config.yaml' to re-upload it.
[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-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 1.001546576s
[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.
5)在主节点master1上查看节点加入状态:
root@master1:~# kubectl get node
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 17h v1.32.1
worker1 Ready <none> 129m v1.32.1
worker2 Ready <none> 112s v1.32.1
root@master1:~# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5745477d4d-x4dbj 1/1 Running 1 (131m ago) 15h
calico-node-d9sv5 1/1 Running 1 (131m ago) 15h
calico-node-ntx28 1/1 Running 0 2m10s
calico-node-zpbc2 1/1 Running 0 129m
coredns-6766b7b6bb-hqgsd 1/1 Running 1 (131m ago) 17h
coredns-6766b7b6bb-w8ztk 1/1 Running 1 (131m ago) 17h
etcd-master1 1/1 Running 2 (131m ago) 17h
kube-apiserver-master1 1/1 Running 2 (131m ago) 17h
kube-controller-manager-master1 1/1 Running 2 (131m ago) 17h
kube-proxy-b8n2k 1/1 Running 0 2m10s
kube-proxy-h2v5l 1/1 Running 2 (131m ago) 17h
kube-proxy-jf5tm 1/1 Running 0 129m
kube-scheduler-master1 1/1 Running 2 (131m ago) 17h
所有节点均已经加入集群。
集群状态验证
【实践05- 验证集群健康状态】
在集群部署之后,需进行集群状态检查,以保障后续操作是在集群健康状态之下开展的。
1)检查组件状态是否正常:
root@master1:~# kubectl get componentstatuses
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy ok
该命令已经处于deprecated(弃用)状态,因此不推荐使用。
2)查看集群系统信息:
root@master1:~# kubectl cluster-info
Kubernetes control plane is running at https://192.168.152.200:6443
CoreDNS is running at https://192.168.152.200:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Kubernetes control plane is running,表明控制平面处于运行状态;KubeDNS is running,表明KubeDNS处于运行状态。
3)查看核心组件是否处于正常状态:
root@master1:~# kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5745477d4d-x4dbj 1/1 Running 1 (159m ago) 15h
calico-node-d9sv5 1/1 Running 1 (159m ago) 15h
calico-node-ntx28 1/1 Running 0 30m
calico-node-zpbc2 1/1 Running 0 157m
coredns-6766b7b6bb-hqgsd 1/1 Running 1 (159m ago) 17h
coredns-6766b7b6bb-w8ztk 1/1 Running 1 (159m ago) 17h
etcd-master1 1/1 Running 2 (159m ago) 17h
kube-apiserver-master1 1/1 Running 2 (159m ago) 17h
kube-controller-manager-master1 1/1 Running 2 (159m ago) 17h
kube-proxy-b8n2k 1/1 Running 0 30m
kube-proxy-h2v5l 1/1 Running 2 (159m ago) 17h
kube-proxy-jf5tm 1/1 Running 0 157m
kube-scheduler-master1 1/1 Running 2 (159m ago) 17h
当所有核心组件的READY列均为1/1、STATUS列均为Running时,集群状态才是完成进入到就绪、健康状态。此命令也是在集群重启之后,检查集群状态的最常用命令。kubectl命令中的-n kube-system参数表明是在kube-system系统核心命名空间中执行,关于命名空间的概念将在后续内容中展开讲解。
4)此外,kubelet作为Linux服务将运行于每个节点之上。当使用kubectl命令时,例如kubectl get nodes命令,若出现下列信息:
root@master1:~# kubectl get nodes
The connection to the server localhost:8080 was **refused** - did you specify the right host or port?
或使用kubectl get nodes出现之前已经加入的节点,节点状态变为NotReady等情况时,也可以在相应的节点上查看kubelet服务的状态:
root@master1:~# systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; preset: enabl>
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since Thu 2025-01-30 08:27:07 CST; 2h 43min ago
Docs: https://kubernetes.io/docs/
Main PID: 507 (kubelet)
Tasks: 13 (limit: 2264)
Memory: 91.3M
CPU: 2min 54.665s
CGroup: /system.slice/kubelet.service
└─507 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/boots>
需要确保kubelet服务的状态为active (running)运行状态。
至此,具有三台节点的集群环境已经部署完成。使用poweroff命令将三台节点全部关机,在VMware Workstation Pro中对三台虚拟机均拍摄快照,快照名为集群部署(三台)完成。
集群重启
【实践06- 重启集群】
重新开启三台虚拟机,查看集群重启之后的状态。
1)开启三台节点,或三台节点重启之后,在主节点master1启动之后立刻在主节点master1上查看节点信息,及集群系统信息:
root@master1:~# kubectl get nodes
The connection to the server 192.168.152.200:6443 **was refused** - did you specify the right host or port?
root@master1:~# kubectl cluster-info
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server 192.168.152.200:6443 **was refused** - did you specify the right host or port?
可以发现连接请求被拒绝。这是因为Kubernetes集群启动需要一定的时间周期。、
2)略等片刻,再次查看:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 17h v1.32.1
worker1 Ready <none> 166m v1.32.1
worker2 Ready <none> 38m v1.32.1
root@master1:~# kubectl cluster-info
Kubernetes control plane is running at https://192.168.152.200:6443
CoreDNS is running at https://192.168.152.200:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
现在,集群处于就绪状态。若集群未能按如期启动,或需要重启集群,也可以使用systemctl restart containerd.service命令来达到重启集群中某节点上对应的Kubernetes资源的目的。
节点资源信息查看
【实践07-查看节点资源信息】
通过节点资源信息查看,可以了解节点的状态、节点系统版本、内核版本等多方面信息。
1)查看节点资源简略信息:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 18h v1.32.1
worker1 Ready <none> 170m v1.32.1
worker2 Ready <none> 43m v1.32.1
其中,部分列的含义如下:
STATUS列:节点状态;ROLES列:节点角色,主要用于方便运维人员快速区分节点的角色,主节点master1为control-plane控制平面节点,其他节点worker1与worker2未进行角色赋值;AGE列:节点已加入到集群中时长;VERSION列:节点上Kubernetes的版本号。
2)查看节点资源扩展信息:
root@master1:~# kubectl get nodes -o wide
NAME INTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master1 192.168.152.200 Debian... 6.1.0-30-amd64 containerd://1.7.22
worker1 192.168.152.201 Debian... 6.1.0-30-amd64 containerd://1.7.22
worker2 192.168.152.202 Debian... 6.1.0-30-amd64 containerd://1.7.22
由于排版限制,略去部分列内容。部分列的含义如下:
INTERNAL-IP列:节点的IP地址;OS-IMAGE列:节点系统镜像版本号;KERNEL-VERSION列:节点系统内核版本;CONTAINER-RUNTIME列:节点容器运行时版本。
3)查看指定节点资源详细信息:
root@master1:~# kubectl describe nodes worker1
Name: worker1
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=worker1
kubernetes.io/os=linux
...
其Conditions(状态)部分:
Conditions:
Type Status Reason Message
---- ------ ------ -------
NetworkUnavailable False CalicoIsUp Calico is running...
MemoryPressure False KubeletHasSufficientMemory kubelet has suffi...
DiskPressure False KubeletHasNoDiskPressure kubelet has no di...
PIDPressure False KubeletHasSufficientPID kubelet has suffi...
Ready True KubeletReady kubelet is postin...
由于排版限制,略去部分列内容。部分列的含义如下:
Type列:状态类型;Status列:状态具体值;Reason列:当前状态取值的原因;Message列:状态具体描述。
可以发现NetworkUnavailable(网络不可用)状态为False(假,表示网络可用),类似的MemoryPressure(内存压力)、DiskPressure(磁盘压力)、PIDPressure(PID压力)、Ready(是否就绪)均为健康状态。这些信息通常在运维某个节点时需要关注。
【常识与技巧】
Linux中,PID是进程的代号,每个进程有唯一的PID编号。它是进程运行时系统随机分配的,在运行时PID是不会改变标识符的,但是进程退出或终止之后,PID标识符就会被系统回收。这样PID便可被继续分配给新运行的进程了。系统中所容纳的进程数量是有上限的,通常为32768个。当系统中PID数量过高后,系统将无法再为新启动的进程分配进程PID,新的进程更无法启动。因此,上述Conditions中含有PIDPressure,用以查看当前系统中是否PID过多,影响节点健康状态。
其Allocatable(可分配)部分:
Allocatable:
cpu: 2
ephemeral-storage: 33047717015
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 1876364Ki
pods: 110
该部分信息主要用于描述当前节点的可用资源。其ephemeral-storage表示磁盘存储,memory表示内存。
其中Events(事件)部分:
Events:
Type Reason From Message
---- ------ ---- -------
Normal Starting kube-proxy
Normal Starting kubelet Starting kubelet.
Normal NodeAllocatableEnforced kubelet Updated Node Allo...
Normal NodeHasSufficientMemory kubelet Node worker1 stat...
Normal NodeHasNoDiskPressure kubelet Node worker1 stat...
Normal NodeHasSufficientPID kubelet Node worker1 stat...
Warning Rebooted kubelet Node worker1 has ...
Normal RegisteredNode node-controller Node worker1 even...
由于排版限制,略去部分列内容。部分列的含义如下:
Type列:事件类型;Reason列:事件产生的原因;From列:产生当前事件的程序;Message列:事件的具体描述。
kubectl describe命令可用于故障排查,在其Events部分中查看节点、Pod等资源状态不符合预期的原因。
4)节点资源信息格式化输出,可以指定yaml格式或json格式。使用yaml格式输出节点资源信息:
root@master1:~# kubectl get nodes worker1 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: "0"
projectcalico.org/IPv4Address: 192.168.152.201/24
...
5)使用json格式输出节点资源信息:
root@master1:~# kubectl get nodes -o json
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Node",
"metadata": {
"annotations": {
...
在Kubernetes运维过程中,如果需要编写yaml格式或json格式的配置文件,可以从Kubernetes官方文档中查找示例,同样也可以使用以上命令从其他同类型的资源中以指定的格式输出文件,例如kubectl get nodes worker1 -o yaml > worker1.yaml。然后在通过编辑、修改该配置文件,以符合目的要求。
收尾工作
1)输入命令poweroff关闭三台虚拟机。
2)AI时代背景之下,运维将从传统CPU服务器切入到GPU服务器与端边设备,对于运维开发人员,技术玩家而言,也同步需要跟上新的技术栈。本学习内容涉及到的软件包、配置文件等资源,可以直接从百度网盘下载获取:
- 百度网盘分享文件:
Kubernetes1.32 - 链接:
https://pan.baidu.com/s/18XeGQ28BDPjHh8JKj0uZFQ?pwd=6x17提取码:6x17