「KUBERNETES」- 节点管理 | 添加节点 | 删除节点

节点的管理,我们主要是指增加节点、删除节点操作,并不包含其他操作;

该笔记将记录:在 Kubernetes Cluster 中,与节点(Node)有关的操作,如何管理集群节点,以及常见问题处理。

添加节点(增)

第一步、节点准备工作

确保已经对节点进行初始化,比如安装 Docker 环境、配置内核参数、网络预设置等等。

第二步、添加新的节点

添加 Worker 节点:

# 获取 TOKEN 参数
kubeadm token list                                                              # 查看已有 TOKEN
kubeadm token create                                                            # 创建新的 TOKEN
kubeadm token create --print-join-command                                       # 直接打印 Join 命令

添加 Control Plane 节点:

# 获取 certificate key 参数
kubeadm init phase upload-certs --upload-certs

# 获取加入集群的命令
kubeadm token create --print-join-command --certificate-key "<certificate key>"

# 执行输出的 kubeadm join 命令
kubeadm join ...

// ---------------------------------------------------------------------------- 如下为废弃的老办法,不建议使用,可能失败

# 在新的主机上执行,该主机会成为主节点加入
kubeadm join 10.10.50.91:6443 --experimental-control-plane \
    --token 608cyb.7polfq8iea971x9i \
    --discovery-token-ca-cert-hash sha256:8ff3e8899e47a10ee186319a737de85374ea7c4f4cf5276ef3d5b95f66b6ebbe

# 获取 discovery-token-ca-cert-hash 参数
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
   openssl dgst -sha256 -hex | sed 's/^.* //'

# 加入集群
kubeadm join "control-plane-endpoint.d3rm.org:8443" --token "4pedgf.a2uc2vvtrknce1wb" \
    --discovery-token-ca-cert-hash "sha256:0fce70ebfdc980066ea08cdfdc54a835215077834b54f10a36196c22a9dacb09"

补充说明

命令 kubeadm token create –print-join-command 将输出用于加入集群的命令,但是该命令中的 Control Plane 地址来自 kubeconfig 配置文件;

当添加节点时,会获取集群 kube-system/kubeadm-config ConfigMap 配置,所以修改其中的 imageRepository 参数,能够控制镜像拉去地址。

kubeadm token create –print-join-command xxxx

该命令生成的地址来自与 ~/.kube/config 文件中的地址。

当执行该命令时,其会读取 kube-public/cluster-info 中的配置地址。

删除节点(删)

删除 Control Plane 节点

假如移除 k8scp-02 节点:

# 在其他节点中执行,比如我们的 k8scp-01 节点
kubectl drain "k8scp-02" --delete-local-data --force --ignore-daemonsets

# 在被移出的节点上执行,这里 k8scp-02 节点
kubeadm reset                                               # 其将从 etcd 集群中移除该节点的 etcd 成员及其他清理工作,所以必须执行

# 在被移出的节点上执行,以清理网络转发策略
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
ipvsadm -C

kubeadm join is not fault tolerant to etcd endpoint failures · Issue #1432 · kubernetes/kubeadm
关于 kubeadm reset 问题:在我们重置集群时,命令 kubeadm reset 在处理 etcd 集群时,它会自动从 etcd 集群中删除当前 etcd 节点,但是有时会提示我们需要手动处理。如果操作不当,导致 etcd 集群未清理当前节点的 etcd 实例,当我们将该节点再次加入集群时,由于 etcd 冲突会导致节点加入失败,有时可能导致集群的失败。所有我们一般是:删除当前节点,然后重新新节点(新的虚拟机实例);或者,实验环境我们将重置整个集群;或者,退一步,修改主机名做相关的处理;

如果 etcd 节点未从集群中删除,则需要手动处理,参考该笔记处理 etcd 集群部分的内容。

删除 Worker 节点

Safely Drain a Node | Kubernetes
How to gracefully remove a node from Kubernetes? – Stack Overflow
How to gracefully remove a node from Kubernetes?

参考 Safely Drain a Node | Kubernetes 文档,安全的操作过程大致如下:
1)如果对服务可用性有要求,则建议开启 PodDisruptionBudget 功能;
2)然后,执行 kubectl drain <node name> 命令,以排空节点 Pod 实例;
3)最后,删除节点 kubectl delete node <node-name>,并对主机操作;

# kubectl get nodes

# kubectl drain <node-name> --delete-emptydir-data --ignore-daemonsets

# kubectl delete node <node-name> --delete-emptydir-data --ignore-daemonsets

# kubeadm reset

修改节点(改)

为节点添加标签(Label)

kubernetes – How to delete a node label by command and api? – Stack Overflow

kubectl label node <nodename> <labelname>=allow             # 添加标签
kubectl label node <nodename> <labelname>-                  # 删除标签

kubectl label nodes <your-node-name> disktype=ssd

查看节点(查)

# kubectl get nodes

// 显示节点标签

# kubectl get nodes --show-lables

查看 Master 节点

# kubectl get pods -n kube-system | grep etcd // 取决于部署架构,我们姑且将具有 etcd 服务的节点视为 Master 节点。

常见问题处理

[Sol.] … CRI v1 runtime API is not implemented for endpoint …

configuration – failed to run Kubelet: validate service connection: CRI v1 runtime API is not implemented for endpoint

问题描述

# kubeadm join 192.168.130.2:6443 --token du4nvx.xxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxx --control-plane --certificate-key xxxxxxx
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
	[ERROR CRI]: container runtime is not running: output: time="2023-05-04T06:01:21Z" level=fatal msg="validate service connection: CRI v1 runtime API is not implemented for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

解决方案
1)使用 containerd 1.6 版本