比起君子讷于言而敏于行我更喜欢君子善于言且敏于行。文章目录目录文章目录前言一、集群现状摸底1. 基础信息确认master 执行2. 安装方式确认master 执行3. etcd 类型与状态确认master 执行4. kubelet 配置确认所有 master 和 node 都要执行5. 证书信息确认master 执行6. 负载均衡与网络确认7. 业务风险确认master 执行8. 控制平面组件状态确认master 执行二、etcd / 集群备份1. 确认etcd的版本2. 备份etcd全量快照最关键3. 备份kubeadm配置4. 备份完整PKI证书目录三、环境校准1. 验证版本一致性必须与北京master完全一致2. 关闭swap必须3. 验证kubelet服务正常4. 验证与北京master网络互通四、新增 control-plane1. 生成有效期24小时的加入token2. 获取CA证书哈希。3. 上传控制平面证书并获取certificate-key五、驱逐上海node节点1. 驱逐上海124上的业务Pod2. 从集群中删除上海的worker节点对象3. 停止kubelet服务4. 只清理kubeadm和kubelet的状态文件关键不碰CNI和iptables5. 重新加载systemd配置6. 确认10250端口已释放总结前言原来k8s是单master设备逐渐多起来开始考虑拿几台node出来做多master的形式是一个比较繁琐的活儿记录一下。本质上是在做“etcd 集群扩容 control-plane 转移”。原来只有北京的一台master现在要把上海node节点加入成master丝滑剔除北京master。最终还要做高可用当然了高可用的内容可能得很久以后再补充了涉及到证书的问题目前没有这个时间和精力去做这个大动作。更多的是希望丝滑的切换master。一、集群现状摸底1. 基础信息确认master 执行# 集群基本信息 kubectl cluster-info # 所有节点详细信息 kubectl get nodes -o wide # 集群版本 kubectl version --short2. 安装方式确认master 执行# 检查是否为kubeadm安装核心验证 ls -la /etc/kubernetes/manifests/ # 预期输出包含kube-apiserver.yaml、etcd.yaml等静态Pod文件 # 检查kubeadm版本 kubeadm version # 检查静态Pod路径配置 ps aux | grep kubelet | grep pod-manifest-path # 预期输出--pod-manifest-path/etc/kubernetes/manifests ubuntuubuntu-R730xd-01:~$ ps aux | grep kubelet | grep pod-manifest-path3. etcd 类型与状态确认master 执行# 检查是否为stacked etcd与master同节点 kubectl get pods -n kube-system | grep etcd # 预期输出etcd-master-hostname 1/1 Running 1/1 Running 30 200d # 检查etcd集群成员 ETCDCTL_API3 etcdctl member list \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key # 检查etcd健康状态 ETCDCTL_API3 etcdctl endpoint health \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key4. kubelet 配置确认所有 master 和 node 都要执行# 4.1 查看kubelet当前连接的apiserver地址 grep server /etc/kubernetes/kubelet.conf # 4.2 查看kubelet配置 cat /var/lib/kubelet/config.yaml # 4.3 查看kubelet服务状态 systemctl status kubelet # 4.4 查看kubelet节点租约时间 ps aux | grep kubelet | grep node-status-update-frequency # 默认值10秒5. 证书信息确认master 执行# 列出所有证书文件 ls -la /etc/kubernetes/pki/ ls -la /etc/kubernetes/pki/etcd/ # 检查apiserver证书SAN扩展非常重要 openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A 10 X509v3 Subject Alternative Name # 检查所有证书有效期 for cert in /etc/kubernetes/pki/*.crt /etc/kubernetes/pki/etcd/*.crt; do echo $cert openssl x509 -in $cert -noout -dates done6. 负载均衡与网络确认# 检查是否有本地负载均衡master执行 systemctl status haproxy nginx keepalived # 检查kube-proxy模式**所有node执行** kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode # 预期输出mode: iptables 或 mode: ipvs # 检查CNI插件master执行 kubectl get pods -n kube-system | grep -E calico|flannel|cilium|weave # 检查CoreDNS状态 kubectl get pods -n kube-system | grep coredns 1/1 Running 3 171d7. 业务风险确认master 执行# 查找所有单副本Deployment kubectl get deployment --all-namespaces -o json | jq .items[] | select(.spec.replicas 1) | .metadata.namespace / .metadata.name # 查找所有单副本StatefulSet kubectl get statefulset --all-namespaces -o json | jq .items[] | select(.spec.replicas 1) | .metadata.namespace / .metadata.name # 查找所有没有副本控制器的独立Pod kubectl get pods --all-namespaces -o json | jq .items[] | select(.metadata.ownerReferences null) | .metadata.namespace / .metadata.name # 检查所有Service和Ingress kubectl get svc --all-namespaces kubectl get ingress --all-namespaces8. 控制平面组件状态确认master 执行# 所有控制平面Pod状态 kubectl get pods -n kube-system # cheduler和controller-manager leader状态 kubectl get leases -n kube-system # 检查所有事件 kubectl get events --all-namespaces --sort-by.lastTimestamp | tail -50二、etcd / 集群备份1. 确认etcd的版本ETCDCTL_API3 etcdctl version2. 备份etcd全量快照最关键ETCDCTL_API3 etcdctl snapshot save /root/etcd-snapshot-$(date %Y%m%d-%H%M).db \ --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key # 验证输出 Snapshot saved at /root/etcd-snapshot-xxx.db3. 备份kubeadm配置kubectl get cm kubeadm-config -n kube-system -o yaml /root/kubeadm-config-cm-$(date %Y%m%d-%H%M).yaml4. 备份完整PKI证书目录cp -r /etc/kubernetes/pki /root/pki-backup-$(date %Y%m%d-%H%M)三、环境校准执行节点上海master1. 验证版本一致性必须与北京master完全一致kubeadm version kubelet --version docker --version # 验证输出均为v1.21.10docker版本为19.3.15或20.10.212. 关闭swap必须free -h# 如果swap不为0执行swapoff -a sed -ri /swap/s/^/#/ /etc/fstab3. 验证kubelet服务正常systemctl status kubelet # 验证active (running)4. 验证与北京master网络互通telnet 北京master-ip 6443 telnet 北京master-ip 2379 telnet 北京master-ip 2380 # 验证全部显示Connected四、新增 control-plane执行节点北京 master1. 生成有效期24小时的加入tokenkubeadm token create # 输出示例abcdef.012389absvef复制保存这个token2. 获取CA证书哈希。命令是在计算 Kubernetes 集群根 CAca.crt的 SHA256 指纹fingerprint/hash。它的作用是让新节点在 kubeadm join 时确认自己连接的 master 是“真正的你的集群”而不是假的 APIServer。“防中间人攻击MITM验证”。openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \ openssl rsa -pubin -outform der 2/dev/null | \ openssl dgst -sha256 -hex | sed s/^.* // # 输出示例a1b2c3d4e5f6a7b8c9d0e1f2a3b7d8e9f0a1b2复制保存这个哈希值3. 上传控制平面证书并获取certificate-key作用是把当前 master 的 control-plane 证书加密上传到集群方便新的master自动下载和恢复。kubeadm init phase upload-certs --upload-certs # 输出最后一行示例Using certificate key: 1234567890abcdef12345ef1234567890abcdef复制保存这个certificate-key五、驱逐上海node节点# 北京master执行1. 驱逐上海124上的业务Pod注意一定一定一定要确认好自己的pod驱逐之后依旧是有符合规则的其他机器能run的kubectl drain sh-ip \ --ignore-daemonsets \ --delete-emptydir-data \ --force # 验证除了DaemonSet外所有普通Pod都已被驱逐2. 从集群中删除上海的worker节点对象把它从之前的node节点踢出来kubectl delete node sh-ip3. 停止kubelet服务【上海执行root 用户】systemctl stop kubelet4. 只清理kubeadm和kubelet的状态文件关键不碰CNI和iptablesmv /etc/kubernetes /etc/kubernetes-node.$(date %Y.%m.%d_%H:%M).bak mv /var/lib/kubelet/pki /var/lib/kubelet/pki-node.$(date %Y.%m.%d_%H:%M).bak mv /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml-node.$(date %Y.%m.%d_%H:%M).bak5. 重新加载systemd配置systemctl daemon-reload6. 确认10250端口已释放ss -lntp | grep 10250 # 验证无任何输出总结干不动了暂时先写到这儿下周接着补