如何将 Kubernetes 非 HA 控制平面转换为 HA 控制平面? 更新 kube-apiserver 证书更新 kubelet、调度程序和控制器管理器 kubeconfig 文件更新 kube-proxy kubeconfig 文件更新 kubeadm-config 配置映射

问题描述

将 kubernetes 非 HA 控制平面转换为 HA 控制平面的最佳方法是什么?

我已经开始将我的集群作为一个非 HA 控制平面 - 一个主节点和几个工作节点。集群已经运行了很多服务。

现在我想添加额外的主节点以将我的集群转换为 HA 控制平面。我已经设置并配置了负载均衡器。 但我不知道如何将 -control-plane-endpoint 更改为现有主节点的负载均衡器 IP 地址。

调用 kubeadm 导致以下错误

sudo kubeadm init --control-plane-endpoint "my-load-balancer:6443" --upload-certs
[init] Using Kubernetes version: v1.20.1
[preflight] Running pre-flight checks
    [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some Fatal errors occurred:
    [ERROR Port-6443]: Port 6443 is in use
    [ERROR Port-10259]: Port 10259 is in use
    [ERROR Port-10257]: Port 10257 is in use
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-controller-manager.yaml]: /etc/kubernetes/manifests/kube-controller-manager.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists
    [ERROR FileAvailable--etc-kubernetes-manifests-etcd.yaml]: /etc/kubernetes/manifests/etcd.yaml already exists
    [ERROR Port-10250]: Port 10250 is in use
    [ERROR Port-2379]: Port 2379 is in use
    [ERROR Port-2380]: Port 2380 is in use
    [ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty
[preflight] If you kNow what you are doing,you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

错误消息似乎很清楚,因为我的主人已经在运行。 有没有一种方法可以轻松地告诉我现有的主节点使用新的负载均衡器作为 HA 控制平面运行?

解决方法

我认为最好的解决方案

非HA控制平面convert变成HA控制平面的最佳方法是创建一个全新的HA > 控制平面,然后将您的所有应用程序迁移到那里。

可能的解决方案

下面我将尝试帮助您实现目标,但我不建议在任何将被视为生产集群的集群上使用此过程。它适用于我的场景,也可能帮助你。

更新 kube-apiserver 证书

首先,kube-apiserver 使用 certificate 来加密控制平面流量,而这个 certificate 具有称为 SAN 的东西(主题备用名称)。 SAN 是您将用于访问 API 的 IP 地址列表,因此您需要在那里添加您的 LoadBalancer 的 IP 地址,也可能是您的 hostnameLB

为此,您必须获得 kubeadm 配置,例如使用命令:

   $ kubeadm config view > kubeadm-config.yaml

然后将 certSANs 添加到 kubeadm-config.yaml 部分下的 apiServer 配置文件,它应该如下例所示:(您可能还需要添加 controlPlaneEndpoint 以指向您的LB).

apiServer:
  certSANs:
  - "192.168.0.2" # your LB address
  - "loadbalancer" # your LB hostname
  extraArgs:
    authorization-mode: Node,RBAC
    ...
 controlPlaneEndpoint: "loadbalancer" # your LB DNS name or DNS CNAME
    ...

现在您可以使用以下方法更新 kube-apiserver 证书:
但请记住您必须先从 kube-apiserver 删除/移动旧的 /etc/kubernetes/pki/ 证书和密钥!

$ kubeadm init phase certs apiserver --config kubeadm-config.yaml。

最后重新启动您的 kube-apiserver

更新 kubelet、调度程序和控制器管理器 kubeconfig 文件

下一步是更新 kubeletschedulercontroller manager 以使用 kube-apiserverLoadBalancer 通信。
所有这三个组件都使用标准的 kubeconfig 文件:
/etc/kubernetes/kubelet.conf/etc/kubernetes/scheduler.conf/etc/kubernetes/controller-manager.confkube-apiserver 通信。
唯一要做的就是将 server: 行编辑为直接指向 LB 而不是 kube-apiserver,然后重新启动这些组件。

kubeletsystemd 服务,因此要重新启动它,请使用:

systemctl restart kubelet 

controller managerschedulers 被部署为 pod。

更新 kube-proxy kubeconfig 文件

接下来是更新 kubeconfigkube-proxy 文件,和以前一样 - 唯一要做的就是编辑 server: 行以指向 LoadBalancer kube-apiserver 的直接。

这个 kubeconfig 实际上是一个 configmap,因此您可以直接使用:

$ kubectl edit cm kube-proxy -n kube-system

或先将其另存为清单文件:

$ kubectl get cm kube-proxy -n kube-system -o yaml > kube-proxy.yml 

然后应用更改。

不要忘记在这些更改后重新启动 kube-proxy

更新 kubeadm-config 配置映射

最后将新的 kubeadm-config configmap(带有 certSANscontrolPlaneEndpoint 条目)上传到集群,当您想向集群添加新节点时尤其重要.

$ kubeadm config upload from-file --config kubeadm-config.yaml

如果上面的命令不起作用,试试这个:

$ kubeadm upgrade apply --config kubeadm-config.yaml