kubernetes 集群由单 master 集群升级至多 master 集群

kubernetes, master

k8s 集群架构升级

环境准备

  • 至少三台用作 master 的主机
  • master 节点和 worker 节点全网络连接(公网或私网)
  • 已配置完成的 keepalived 环境(用于多 master 集群的负载均衡)

特别注意::搭建环境中 kubeadm,kubectl,kubelet 以及 kubernetes cluster version 均为 1.21.2。由于版本在命令上可能有所区别,因此,参考时需注意。

操作过程概述

  • 整个集群的升级过程:
    • 配置 configmap kubeadm-config (该 configmap 存放在 kube-system namespace 中)
    • 重新配置 cluster 中各组件服务的配置文件中对应的 apiserver ip/domain
    • 上传集群证书,并获取节点访问证书的秘钥
    • 获取加入集群节点的 token
    • other controlPlane 作为 master 加入集群,同时同步 etcd 的数据。

配置 kubeadm-config

  • 在 configmap kubeadm-config 中添加 controlPlaneEndpoint 参数
  • 配置 certSANs(配置该参数的目的是为了重新初始化包含负载均衡ip的 apiserver 的证书和秘钥)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 查看是否有 kubeadm-config 这个 configmap 存在
kubectl get configmap -n kube-system

kubectl edit cm kubeadm-config -n kube-system -o yaml
# 添加 controlPlaneEndpoint 参数
apiVersion: v1
data:
  ClusterConfiguration: |
    apiServer:
      certSANs:
      # 添加 certSANs,添加 load_balance_ip/master_node_ip/worker_node_ip/domains。
      - ip/domain
      - ip/domain
      extraArgs:
        authorization-mode: Node,RBAC
      timeoutForControlPlane: 4m0s
    apiVersion: kubeadm.k8s.io/v1beta2
    controlPlaneEndpoint: ip:port
    # 添加 load balance ip:port
    ...
  • 将修改后的 configmap 导出,同时使用该文件生成新的 apiserver key、cert
1
$ kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm.yaml
  • 移动旧的 apiserver 证书,并生成新的 apiserver key
1
2
3
4
5
$ sudo mv /etc/kubernetes/pki/apiserver.{crt,key} ~
# 删除或移动至其他目录,否则 kubeadm 检测到文件存在,则不会创建新的 cert key

$ sudo kubeadm init phase certs apiserver --config kubeadm.yaml
# 该命令会生成 apiserver.{crt,key} 两个文件。
  • 重新启动 apiserver container,重新加载 集群配置 container 被 kill 后,集群会重新启动一个 apiserver
1
2
$ docker ps | grep apiserver
$ docker kill  container_id/container_name

验证证书

验证证书是否存在已添加的 certSANs 列表

1
2
$ openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
# 输出内容中可以看到包含 certSANs 中写入的 ip 地址列表

配置新的 IP/Domain

  • 修改各组件服务对应的 apiserver ip address
  • 修改的文件包含以下几个部分
    • kubelet.conf
    • scheduler.conf
    • controller-manager.conf
    • .kube/config
    • cluster-info(in kube-public namespce)
    • kube-proxy(in kube-system namespace)
  • 修改并重新启动对应 container
1
2
3
4
5
6
7
8
$ sudo sed -i 's/old_apiserver_ip:port/new_load_balance_ip:port/' /etc/kubernetes/kubelet.conf
$ sudo sed -i 's/old_apiserver_ip:port/new_load_balance_ip:port/' /etc/kubernetes/controller-manager.conf
$ sudo sed -i 's/old_apiserver_ip:port/new_load_balance_ip:port/' /etc/kubernetes/scheduler.conf
$ sudo sed -i 's/old_apiserver_ip:port/new_load_balance_ip:port/' ~/.kube/config

# 修改包含旧 apiserver ip 的两个 configmap
$ kubectl edit cm cluster-info -n kube-public
$ kubectl edit cm kube-proxy -n kube-systen
  • 重新启动 container,验证相关服务 重新启动 container,以替换 container 中使用的 server ip
1
2
3
4
5
$ docker ps
$ docker kill controller-manager_container_id scheduler_container_id

$ sudo systemctl restart kubelet
# 重启 kubelet 服务,更新 server ip

验证 cluster-info 是否更新

1
2
3
4
5
6
$ kubectl cluster-info
    Kubernetes control plane is running at https://192.168.3.230:9443
    CoreDNS is running at https://192.168.3.230:9443/api/v1/namespaces/kube-
    system/services/kube-dns:dns/proxy

    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

上传集群证书

上传证书到集群,并获取其他 control Plane 访问集群证书的秘钥

1
2
3
4
5
$ sudo kubeadm init phase upload-certs --upload-certs
# 输出类似以下内容
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
24d6435f37e76458e267f479fac970640b0cbbb07787833e34fb529bdd0288e0

获取节点加入集群的 token

获取节点加入集群的 token,用做其他 control plane 加入集群

1
2
3
4
5
6
$ kubeadm token list
# 该命令可以查看集群的 token 有哪些

$ kubeadm token create --print-join-command
# 生成 token(生成的 token 只有 24h 的有效期) 并打印出加入集群节点的命令,输出类似以下内容
$ kubeadm join 192.168.3.230:9443 --token h3gpgk.x4quidbcuc3dxyek --discovery-token-ca-cert-hash sha256:2d1a25b512933cbd24f9b8945ae708b2b24a6e6857a57ff6cb7477e4600946d0

other controlPlane 作为 master 加入集群

  • other controlPlane join cluster
1
2
# 结合上面获取到的访问证书秘钥和加入集群的命令使用
$ sudo kubeadm join 192.168.3.230:9443 --token h3gpgk.x4quidbcuc3dxyek --discovery-token-ca-cert-hash sha256:2d1a25b512933cbd24f9b8945ae708b2b24a6e6857a57ff6cb7477e4600946d0 --control-plane --certificate-key 24d6435f37e76458e267f479fac970640b0cbbb07787833e34fb529bdd0288e0
  • 同步 master 中 etcd 的配置 由于 control Plane 的3个节点是先后安装的,所以前面两个节点的 etcd 中并不包含其他 etcd 节点的信息。所以需要同步所有控制平面节点的 etcd 集群配置
1
2
3
4
$ cat /etc/kubernetes/manifests/etcd.yaml
...
- --initial-cluster=master=https://ip:2380,master2=https://ip:2380,master3=https://ip:2380
...

参考

Adding a Name to the Kubernetes API Server Certificate Creating Highly Available clusters with kubeadm 如何将单 master 升级为多 master 集群

Built with Hugo
Theme Stack designed by Jimmy