比起君子讷于言而敏于行,我更喜欢君子善于言且敏于行。
文章目录
目录
[1. 基础信息确认(master 执行)](#1. 基础信息确认(master 执行))
[2. 安装方式确认(master 执行)](#2. 安装方式确认(master 执行))
[3. etcd 类型与状态确认(master 执行)](#3. etcd 类型与状态确认(master 执行))
[4. kubelet 配置确认(所有 master 和 node 都要执行)](#4. kubelet 配置确认(所有 master 和 node 都要执行))
[5. 证书信息确认(master 执行)](#5. 证书信息确认(master 执行))
[6. 负载均衡与网络确认](#6. 负载均衡与网络确认)
[7. 业务风险确认(master 执行)](#7. 业务风险确认(master 执行))
[8. 控制平面组件状态确认(master 执行)](#8. 控制平面组件状态确认(master 执行))
[二、etcd / 集群备份](#二、etcd / 集群备份)
[1. 确认etcd的版本](#1. 确认etcd的版本)
[2. 备份etcd全量快照(最关键)](#2. 备份etcd全量快照(最关键))
[3. 备份kubeadm配置](#3. 备份kubeadm配置)
[4. 备份完整PKI证书目录](#4. 备份完整PKI证书目录)
[1. 验证版本一致性(必须与北京master完全一致)](#1. 验证版本一致性(必须与北京master完全一致))
[2. 关闭swap(必须)](#2. 关闭swap(必须))
[3. 验证kubelet服务正常](#3. 验证kubelet服务正常)
[4. 验证与北京master网络互通](#4. 验证与北京master网络互通)
[四、新增 control-plane](#四、新增 control-plane)
[1. 生成有效期24小时的加入token](#1. 生成有效期24小时的加入token)
[2. 获取CA证书哈希。](#2. 获取CA证书哈希。)
[3. 上传控制平面证书并获取certificate-key](#3. 上传控制平面证书并获取certificate-key)
[1. 驱逐上海124上的业务Pod](#1. 驱逐上海124上的业务Pod)
[2. 从集群中删除上海的worker节点对象](#2. 从集群中删除上海的worker节点对象)
[3. 停止kubelet服务](#3. 停止kubelet服务)
[4. 只清理kubeadm和kubelet的状态文件(关键!不碰CNI和iptables)](#4. 只清理kubeadm和kubelet的状态文件(关键!不碰CNI和iptables))
[5. 重新加载systemd配置](#5. 重新加载systemd配置)
[6. 确认10250端口已释放](#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 --short
2. 安装方式确认(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
ubuntu@ubuntu-R730xd-01:~$ ps aux | grep kubelet | grep pod-manifest-path
3. 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_API=3 etcdctl member list \
--endpoints=https://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_API=3 etcdctl endpoint health \
--endpoints=https://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
4. 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
done
6. 负载均衡与网络确认
# 检查是否有本地负载均衡(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 171d
7. 业务风险确认(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-namespaces
8. 控制平面组件状态确认(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_API=3 etcdctl version
2. 备份etcd全量快照(最关键)
ETCDCTL_API=3 etcdctl snapshot save /root/etcd-snapshot-$(date +%Y%m%d-%H%M).db \
--endpoints=https://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.db"
3. 备份kubeadm配置
kubectl get cm kubeadm-config -n kube-system -o yaml > /root/kubeadm-config-cm-$(date +%Y%m%d-%H%M).yaml
4. 备份完整PKI证书目录
cp -r /etc/kubernetes/pki /root/pki-backup-$(date +%Y%m%d-%H%M)
三、环境校准
执行节点:上海master
1. 验证版本一致性(必须与北京master完全一致)
kubeadm version
kubelet --version
docker --version
# 验证:输出均为v1.21.10,docker版本为19.3.15或20.10.21
2. 关闭swap(必须)
free -h
如果swap不为0,执行:
swapoff -a
sed -ri '/swap/s/^/#/' /etc/fstab
3. 验证kubelet服务正常
systemctl status kubelet
# 验证:active (running)
4. 验证与北京master网络互通
telnet <北京master-ip> 6443
telnet <北京master-ip> 2379
telnet <北京master-ip> 2380
# 验证:全部显示Connected
四、新增 control-plane
执行节点:北京 master
1. 生成有效期24小时的加入token
kubeadm token create
# 输出示例:abcdef.012389absvef,复制保存这个token
2. 获取CA证书哈希。
命令是在计算 Kubernetes 集群根 CA(ca.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-ip>
3. 停止kubelet服务
【上海执行(root 用户)】
systemctl stop kubelet
4. 只清理kubeadm和kubelet的状态文件(关键!不碰CNI和iptables)
mv /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).bak
5. 重新加载systemd配置
systemctl daemon-reload
6. 确认10250端口已释放
ss -lntp | grep 10250
# 验证:无任何输出
总结
干不动了,暂时先写到这儿,下周接着补