k8s集群切换master

比起君子讷于言而敏于行,我更喜欢君子善于言且敏于行。

文章目录

目录

文章目录

前言

一、集群现状摸底

[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)

五、驱逐上海node节点

[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

# 验证:无任何输出

总结

干不动了,暂时先写到这儿,下周接着补

相关推荐
小肥君9 小时前
docker无法连接GPU资源解决方案
docker·容器·eureka
liux35289 小时前
K8s存储卷全解析:PV/PVC/StorageClass 关系
kubernetes
江华森12 小时前
从零搭建 Kubernetes 集群并部署 Kuboard v3 管理面板 —— 国内环境完整实战教程
容器·kubernetes
友莘居士13 小时前
KingbaseES Docker速查表
运维·docker·容器
小肥君14 小时前
docker镜像配置
运维·docker·容器
某林21216 小时前
Isaac Lab (v2.3.2) Docker 本地化部署与底层排障全解析
运维·docker·容器·架构·iassc
iDao技术魔方18 小时前
WSL 配 GPU 用 Docker 的折腾指南(2026 年版)
运维·docker·容器
步步为营DotNet19 小时前
.NET 11 中 Native AOT 在云原生场景下的深度剖析与实践
云原生·.net
跳动的世界线19 小时前
WSL 2 + Docker 本地全栈开发环境配置指南
运维·docker·容器