本文讲述了使用 kubeadm 设置一个高可用的 Kubernetes 集群的两种不同方式:
如果你在安装 HA 集群时遇到问题,请在 kubeadm 问题跟踪里向我们提供反馈。
Caution: 这篇文档没有讲述在云提供商上运行集群的问题。在云环境中,此处记录的方法不适用于类型为 LoadBalancer 的服务对象,或者具有动态的 PersistentVolumes。
根据集群控制平面所选择的拓扑结构不同,准备工作也有所差异:
需要准备:
sudo
举例kubeadm
和 kubelet
需要准备:
sudo
举例kubeadm
和 kubelet
还需要准备:
kubeadm
和 kubelet
。每台主机需要能够从 Kubernetes 容器镜像仓库( k8s.gcr.io
)读取和拉取镜像。 想要在无法拉取 Kubernetes 仓库镜像的机器上部署高可用集群也是可行的。通过其他的手段保证主机上已经有对应的容器镜像即可。
一旦集群创建成功,需要在 PC 上安装 kubectl 用于管理 Kubernetes。为了方便故障排查,也可以在每个控制平面节点上安装 kubectl
。
Note: 使用负载均衡器需要许多配置。你的集群搭建可能需要不同的配置。 下面的例子只是其中的一方面配置。
:6443
) 上进行的一个 TCP 检查。ControlPlaneEndpoint
地址。nc -v LOAD_BALANCER_IP PORT
由于 apiserver 尚未运行,预期会出现一个连接拒绝错误。 然而超时意味着负载均衡器不能和控制平面节点通信。 如果发生超时,请重新配置负载均衡器与控制平面节点进行通信。
将其余控制平面节点添加到负载均衡器目标组。sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" --upload-certs
--kubernetes-version
标志来设置要使用的 Kubernetes 版本。 建议将 kubeadm、kebelet、kubectl 和 Kubernetes 的版本匹配。--control-plane-endpoint
标志应该被设置成负载均衡器的地址或 DNS 和端口。--upload-certs
标志用来将在所有控制平面实例之间的共享证书上传到集群。Note: 标志 kubeadm init
、--config
和 --certificate-key
不能混合使用, 因此如果你要使用 kubeadm 配置,你必须在相应的配置结构 (位于 InitConfiguration
和 JoinConfiguration: controlPlane
)添加 certificateKey
字段。 Note: 一些 CNI 网络插件如 Calico 需要 CIDR 例如 192.168.0.0/16
和一些像 Weave 没有。通过传递 --pod-network-cidr
标志添加 pod CIDR,或者你可以使用 kubeadm 配置文件,在 ClusterConfiguration
的 networking
对象下设置 podSubnet
字段。
...
You can now join any number of control-plane node by running the following command on each as a root:
kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
--upload-certs
调用 kubeadm init
时,主控制平面的证书被加密并上传到 kubeadm-certs
Secret 中。sudo kubeadm init phase upload-certs --upload-certs
init
期间指定自定义的 --certificate-key
,以后可以由 join
使用。 要生成这样的密钥,可以使用以下命令:kubeadm certs certificate-key
Note: kubeadm-certs
Secret 和解密密钥会在两个小时后失效。
Caution: 正如命令输出中所述,证书密钥可访问集群敏感数据。请妥善保管!
应用你所选择的 CNI 插件:安装 CNI 驱动。如果适用,请确保配置与 kubeadm 配置文件中指定的 Pod CIDR 相对应。
Note: 在进行下一步之前,必须选择并部署合适的网络插件。 否则集群不会正常运行。
输入以下内容,并查看控制平面组件的 Pods 启动:
kubectl get pod -n kube-system -w
Note: 从 kubeadm 1.15 版本开始,你可以并行加入多个控制平面节点。 在此版本之前,你必须在第一个节点初始化后才能依序的增加新的控制平面节点。
对于每个其他控制平面节点,你应该:
kubeadm init
输出提供给你的 join 命令。 它看起来应该像这样:sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07
--control-plane
标志通知 kubeadm join
创建一个新的控制平面。--certificate-key ...
将导致从集群中的 kubeadm-certs
Secret 下载控制平面证书并使用给定的密钥进行解密。使用外部 etcd 节点设置集群类似于用于堆叠 etcd 的过程, 不同之处在于你应该首先设置 etcd,并在 kubeadm 配置文件中传递 etcd 信息。
export CONTROL_PLANE="ubuntu@10.0.0.7"
scp /etc/kubernetes/pki/etcd/ca.crt "${CONTROL_PLANE}":
scp /etc/kubernetes/pki/apiserver-etcd-client.crt "${CONTROL_PLANE}":
scp /etc/kubernetes/pki/apiserver-etcd-client.key "${CONTROL_PLANE}":
user@host
替换 CONTROL_PLANE
的值。kubeadm-config.yaml
的文件:---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: stable
controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" # change this (see below)
etcd:
external:
endpoints:
- https://ETCD_0_IP:2379 # change ETCD_0_IP appropriately
- https://ETCD_1_IP:2379 # change ETCD_1_IP appropriately
- https://ETCD_2_IP:2379 # change ETCD_2_IP appropriately
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
Note: 这里的堆叠(stacked)etcd 和外部 etcd 之前的区别在于设置外部 etcd 需要一个 etcd
的 external
对象下带有 etcd 端点的配置文件。 如果是内部 etcd,是自动管理的。
在你的集群中,将配置模板中的以下变量替换为适当值:
LOAD_BALANCER_DNS
LOAD_BALANCER_PORT
ETCD_0_IP
ETCD_1_IP
ETCD_2_IP
以下的步骤与设置内置 etcd 的集群是相似的:
sudo kubeadm init --config kubeadm-config.yaml --upload-certs
命令。Note: 在进行下一步之前,必须选择并部署合适的网络插件。 否则集群不会正常运行。
步骤与设置内置 etcd 相同:
--certificate-key
中的解密秘钥会在两个小时后过期。你可以使用之前存储的 kubeadm init
命令的输出将工作节点加入集群中:
sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
如果你选择不将 kubeadm init
与 --upload-certs
命令一起使用, 则意味着你将必须手动将证书从主控制平面节点复制到 将要加入的控制平面节点上。
有许多方法可以实现这种操作。在下面的例子中我们使用 ssh
和 scp
:
如果要在单独的一台计算机控制所有节点,则需要 SSH。
eval $(ssh-agent)将 SSH 身份添加到会话中:
ssh-add ~/.ssh/path_to_private_key检查节点间的 SSH 以确保连接是正常运行的
-A
标志:ssh -A 10.0.0.7当在任何节点上使用 sudo 时,请确保保持环境变量设置,以便 SSH 转发能够正常工作:
sudo -E -s在所有节点上配置 SSH 之后,你应该在运行过
kubeadm init
命令的第一个 控制平面节点上运行以下脚本。 该脚本会将证书从第一个控制平面节点复制到另一个控制平面节点: 在以下示例中,用其他控制平面节点的 IP 地址替换 CONTROL_PLANE_IPS
。
USER=ubuntu # 可定制
CONTROL_PLANE_IPS="10.0.0.7 10.0.0.8"
for host in ${CONTROL_PLANE_IPS}; do
scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:
scp /etc/kubernetes/pki/ca.key "${USER}"@$host:
scp /etc/kubernetes/pki/sa.key "${USER}"@$host:
scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:
scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:
scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:
scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt
scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key
done
Caution: 只需要复制上面列表中的证书。kubeadm 将负责生成其余证书以及加入控制平面实例所需的 SAN。 如果你错误地复制了所有证书,由于缺少所需的 SAN,创建其他节点可能会失败。
然后,在每个即将加入集群的控制平面节点上,你必须先运行以下脚本,然后 再运行 kubeadm join
。 该脚本会将先前复制的证书从主目录移动到 /etc/kubernetes/pki
:
USER=ubuntu # 可定制
mkdir -p /etc/kubernetes/pki/etcd
mv /home/${USER}/ca.crt /etc/kubernetes/pki/
mv /home/${USER}/ca.key /etc/kubernetes/pki/
mv /home/${USER}/sa.pub /etc/kubernetes/pki/
mv /home/${USER}/sa.key /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key