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

# 验证:无任何输出

总结

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

相关推荐
殇尘1 小时前
Docker + VSCode 搭建开发环境沙箱
vscode·docker·容器
颯沓如流星2 小时前
ZKube:优雅易用的 ZooKeeper 可视化管理工具
分布式·zookeeper·云原生
汪汪大队u2 小时前
从 Docker Compose 到 Kubernetes:物联网管理系统迁移实战(3)—— 两个运维坑
运维·docker·kubernetes
团象科技3 小时前
跨境业务运维压力攀升,云原生运维补齐 AI 出海底层支撑短板
运维·人工智能·云原生
小夏子_riotous3 小时前
Kubernetes学习路径——5. Kubernetes 实战入门:Namespace、Pod、Label、Deployment 与 Service 全解析
学习·贪心算法·kubernetes
念恒123063 小时前
Docker基础
运维·docker·容器
杂家4 小时前
Docker 容器端口无法从外部访问
运维·服务器·docker·容器
其实防守也摸鱼4 小时前
[特殊字符] Docker + LMArena2API 部署全流程:从环境准备到接口调用,一步到位
运维·网络·安全·web安全·docker·容器·大模型
炸裂狸花猫5 小时前
开源身份认证与访问管理平台 - Keycloak(三)公有云Console集成实践(AWS / 阿里云 / OCI)
阿里云·云原生·keycloak·aws·oci·sso