惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

TaoSecurity Blog
TaoSecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Secure Thoughts
美团技术团队
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
Engineering at Meta
Engineering at Meta
人人都是产品经理
人人都是产品经理
月光博客
月光博客
T
Tor Project blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
I
Intezer
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
罗磊的独立博客
V
V2EX
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
A
About on SuperTechFans
Scott Helme
Scott Helme
Vercel News
Vercel News
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
B
Blog
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
IT之家
IT之家
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
小众软件
小众软件
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
AWS News Blog
AWS News Blog

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
如何修复变更 IP 之后的 Kubernetes 集群
微信公众号 · 2022-10-25 · via 陈少文的网站

Please enable Javascript to view the contents

记录一次因为 IP 变更导致集群故障的修复过程。有两个集群,一个是单节点(allinone),另一个是四节点(3 master 1 node)的集群。

1. 更新 Etcd 证书

  • 【在每个 Etcd 节点】备份 Etcd 证书
1
cp -R /etc/ssl/etcd/ssl /etc/ssl/etcd/ssl-bak
  • 查看 Etcd 证书中的域
1
2
3
openssl x509 -in /etc/ssl/etcd/ssl/node-node1.pem -noout -text|grep DNS

                DNS:etcd, DNS:etcd.kube-system, DNS:etcd.kube-system.svc, DNS:etcd.kube-system.svc.cluster.local, DNS:localhost, DNS:node1, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, IP Address:x.x.x.1

需要记录下全部的 DNS、IP 值,用于生成新的证书。

  • 【在每个 Etcd 节点】清理旧的 Etcd 证书
1
rm -f /etc/ssl/etcd/ssl/*
  • 【在一个 Etcd 节点】生成 Etcd 证书配置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
vim /etc/ssl/etcd/ssl/openssl.conf

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names

[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer

[alt_names]
DNS.1 = localhost
DNS.2 = etcd.kube-system.svc.cluster.local
DNS.3 = etcd.kube-system.svc
DNS.4 = etcd.kube-system
DNS.5 = etcd
DNS.6 = xxx
IP.1 = 127.0.0.1
IP.2 = x.x.x.x

需要包含所有部署 Etcd 节点的主机名和 IP 地址。

  • 【在一个 Etcd 节点】生成 Etcd 的 CA 证书
1
2
3
cd /etc/ssl/etcd/ssl
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 3650 -out ca.pem -subj "/CN=etcd-ca"
  • 【在一个 Etcd 节点】给每个节点生成 Etcd 的 Admin 证书

通过 export host=node1 设置不同环境变量,给每一个节点生成证书。这里的 node1 是主机名,保持与之前一致,避免因改名找不到证书。

1
2
3
openssl genrsa -out admin-${host}-key.pem 2048
openssl req -new -key admin-${host}-key.pem -out admin-${host}.csr -subj "/CN=etcd-admin-${host}"
openssl x509 -req -in admin-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin-${host}.pem -days 3650 -extensions ssl_client  -extfile openssl.conf
  • 【在一个 Etcd 节点】给每个节点生成 Etcd 的 Member 证书

通过 export host=node1 切换节点,给每一个节点生成证书。

1
2
3
openssl genrsa -out member-${host}-key.pem 2048
openssl req -new -key member-${host}-key.pem -out member-${host}.csr -subj "/CN=etcd-member-${host}" -config openssl.conf
openssl x509 -req -in member-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out member-${host}.pem -days 3650 -extensions ssl_client -extfile openssl.conf
  • 【在一个 Etcd 节点】给每个节点生成 Etcd 的 Node 证书

通过 export host=node1 切换节点,给每一个节点生成证书。

1
2
3
openssl genrsa -out node-${host}-key.pem 2048
openssl req -new -key node-${host}-key.pem -out node-${host}.csr -subj "/CN=etcd-node-${host}"
openssl x509 -req -in node-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out node-${host}.pem -days 3650 -extensions ssl_client  -extfile openssl.conf
  • 【在一个 Etcd 节点】分发生成的证书

需要将 /etc/ssl/etcd/ssl/ 下的证书,分发到各个 Etcd 节点上。

  • 【在一个 Etcd 节点】查看 etcd 配置

这里 Etcd 是以二进制启动的,在 systemd 中可以找到 etcd 配置文件的存放位置。

1
2
3
4
cat /etc/systemd/system/etcd.service

...
EnvironmentFile=/etc/etcd.env
  • 【每个 Etcd 节点】替换 IP

由于有多个 Etcd 节点,因此需要替换多组 IP,这里以三节点为例。

1
2
3
4
5
6
7
8
export oldip1=x.x.x.1
export newip1=x.x.10.1

export oldip2=x.x.x.2
export newip2=x.x.10.2

export oldip3=x.x.x.3
export newip3=x.x.10.3
1
2
3
sed -i "s/$oldip1/$newip1/" /etc/etcd.env
sed -i "s/$oldip2/$newip2/" /etc/etcd.env
sed -i "s/$oldip3/$newip3/" /etc/etcd.env

/etc/hosts 也需要替换 IP,因为有时配置文件中使用的是主机名。

1
2
3
sed -i "s/$oldip1/$newip1/" /etc/hosts
sed -i "s/$oldip2/$newip2/" /etc/hosts
sed -i "s/$oldip3/$newip3/" /etc/hosts

如果有定时备份任务,也需要替换下相关 IP。

1
2
3
sed -i "s/$oldip1/$newip1/" /usr/local/bin/kube-scripts/etcd-backup.sh
sed -i "s/$oldip2/$newip2/" /usr/local/bin/kube-scripts/etcd-backup.sh
sed -i "s/$oldip3/$newip3/" /usr/local/bin/kube-scripts/etcd-backup.sh
  • 【每个 Etcd 节点】从备份中恢复 Etcd 数据

如果是单节点的 Etcd 可以跳过此步骤。由于节点 IP 发生变化,Etcd 集群已经无法运行。多节点 Etcd 需要使用备份数据才能够恢复,这是因为 Etcd 的节点信息被存在磁盘数据中,仅修改配置文件并没有用。

将 Etcd 备份文件 snapshot.db 分发到每个 Etcd 节点上。

在每个节点上执行如下命令:

1
2
3
4
5
etcdctl snapshot restore snapshot.db --name etcd-node1 \
        --initial-cluster "etcd-node1=https://x.x.10.1:2380,etcd-node2=https://x.x.10.2:2380,etcd-node3=https://x.x.10.3:2380" \
        --initial-cluster-token k8s_etcd \
        --initial-advertise-peer-urls https://x.x.10.1:2380 \
        --data-dir=/var/lib/etcd

需要注意,每个节点上的 etcd-node1 名字, --initial-advertise-peer-urls 参数会有差异。

  • 【每个 Etcd 节点】重启 etcd
  • 【每个 Etcd 节点】查看 etcd 状态

2. 更新 K8s 证书

  • 备份证书
1
cp -R /etc/kubernetes/ /etc/kubernetes-bak
  • 【每个 Kubernetes 节点】替换相关文件中的 IP 地址
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# master 节点
export oldip1=x.x.x.1
export newip1=x.x.10.1

export oldip2=x.x.x.2
export newip2=x.x.10.2

export oldip3=x.x.x.3
export newip3=x.x.10.3

# node 节点
export oldip4=x.x.x.4
export newip4=x.x.10.4
1
2
3
4
find /etc/kubernetes -type f | xargs sed -i "s/$oldip1/$newip1/"
find /etc/kubernetes -type f | xargs sed -i "s/$oldip2/$newip2/"
find /etc/kubernetes -type f | xargs sed -i "s/$oldip3/$newip3/"
find /etc/kubernetes -type f | xargs sed -i "s/$oldip4/$newip4/"
1
2
3
4
sed -i "s/$oldip1/$newip1/" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sed -i "s/$oldip2/$newip2/" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sed -i "s/$oldip3/$newip3/" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sed -i "s/$oldip4/$newip4/" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
1
2
3
4
sed -i "s/$oldip1/$newip1/" /etc/kubernetes/kubeadm-config.yaml
sed -i "s/$oldip2/$newip2/" /etc/kubernetes/kubeadm-config.yaml
sed -i "s/$oldip3/$newip3/" /etc/kubernetes/kubeadm-config.yaml
sed -i "s/$oldip4/$newip4/" /etc/kubernetes/kubeadm-config.yaml
1
2
3
4
sed -i "s/$oldip1/$newip1/" /etc/hosts
sed -i "s/$oldip2/$newip2/" /etc/hosts
sed -i "s/$oldip3/$newip3/" /etc/hosts
sed -i "s/$oldip4/$newip4/" /etc/hosts
  • 【在一个 master 节点】生成证书
1
rm -f /etc/kubernetes/pki/apiserver*
1
kubeadm init phase certs all --config /etc/kubernetes/kubeadm-config.yaml
  • 【每个 Kubernetes 节点】将生成的证书分发到节点上

node 节点不需要 key,只需要 crt。

3. 更新集群组件的 Conf 文件

  • 【在一个 master 节点】生成新的配置文件
1
2
cd /etc/kubernetes
rm -f admin.conf kubelet.conf controller-manager.conf scheduler.conf
1
kubeadm init phase kubeconfig all --config /etc/kubernetes/kubeadm-config.yaml
  • 【每个 Kubernetes 节点】将新的配置文件分发到每个节点

每个节点都需要 /etc/kubernetes/kubelet.conf,每个 master 节点都需要 /etc/kubernetes/controller-manager.conf/etc/kubernetes/scheduler.conf

  • 【在需要使用 kubectl 的节点】 配置用户访问凭证
1
2

cp /etc/kubernetes/admin.conf $HOME/.kube/config
  • 【每个 Kubernetes 节点】重启 kubelet
1
2
systemctl daemon-reload
systemctl restart kubelet
  • 【每个 Kubernetes 节点】查看 kubelet 状态
1
systemctl status kubelet

4. 修复 ConfigMap

  • 替换 IP
1
kubectl -n kube-system edit cm kube-proxy

kube-proxy 会影响节点通信。如果使用的 LB 或者域名作为 Apiserver 入口,也可以不进行替换。至于 kubeadm-config ,在上面步骤中已经自动替换,因此也不需要额外处理。

5. 总结

强烈建议,不要修改集群主机的 IP 地址。如果是预期内的主机 IP 变更,可以通过备份-恢复的方式重建集群。

如果是非预期的主机 IP 变更,建议按照上述顺序进行修复:

  1. Etcd
  2. K8s 证书
  3. K8s Master 节点、Node 节点核心组件
  4. 集群 ConfigMap 配置

上述内容虽然记录了修复过程。但多 master 节点修复时,现场很复杂。容器在不断重启,期间还一直报错端口冲突,为此我还重启了一次机器。修复过程记录可能有不完善的地方,但是只需要按照顺序,一个组件一个组件修复应该问题不大。


微信公众号