使用 kubeadm 创建高可用集群
本页面介绍了两种使用 kubeadm 设置高可用 Kubernetes 集群的不同方法
- 使用堆叠的控制平面节点。这种方法需要更少的基础设施。etcd 成员和控制平面节点位于同一位置。
- 使用外部 etcd 集群。这种方法需要更多的基础设施。控制平面节点和 etcd 成员是分开的。
在继续之前,您应该仔细考虑哪种方法最符合您的应用程序和环境的需要。高可用拓扑选项概述了每种方法的优缺点。
如果您在设置 HA 集群时遇到问题,请在 kubeadm 的 问题跟踪器 中报告这些问题。
另请参阅 升级文档。
注意
本页面不介绍在云提供商上运行您的集群。在云环境中,此处记录的两种方法均不适用于类型为 LoadBalancer 的服务对象,也不适用于动态持久卷。在您开始之前
先决条件取决于您为集群的控制平面选择的拓扑结构
您需要
- 三台或更多台满足 kubeadm 最低要求 的机器作为控制平面节点。拥有奇数个控制平面节点可以帮助在机器或区域故障的情况下进行领导者选择。
- 包括一个 容器运行时,已经设置好并正常运行
- 三台或更多台满足 kubeadm 最低要求 的机器作为工作节点
- 包括一个容器运行时,已经设置好并正常运行
- 集群中所有机器之间的完整网络连接(公有或私有网络)
- 所有机器上的超级用户权限,使用
sudo
- 您可以使用其他工具;本指南在示例中使用
sudo
。
- 您可以使用其他工具;本指南在示例中使用
- 从一台设备到系统中所有节点的 SSH 访问
- 所有机器上已经安装了
kubeadm
和kubelet
。
请参阅 堆叠 etcd 拓扑 以了解上下文。
您需要
- 三台或更多台满足 kubeadm 最低要求 的机器作为控制平面节点。拥有奇数个控制平面节点可以帮助在机器或区域故障的情况下进行领导者选择。
- 包括一个 容器运行时,已经设置好并正常运行
- 三台或更多台满足 kubeadm 最低要求 的机器作为工作节点
- 包括一个容器运行时,已经设置好并正常运行
- 集群中所有机器之间的完整网络连接(公有或私有网络)
- 所有机器上的超级用户权限,使用
sudo
- 您可以使用其他工具;本指南在示例中使用
sudo
。
- 您可以使用其他工具;本指南在示例中使用
- 从一台设备到系统中所有节点的 SSH 访问
- 所有机器上已经安装了
kubeadm
和kubelet
。
您还需要
- 三台或更多台将成为 etcd 集群成员的附加机器。在 etcd 集群中拥有奇数个成员是实现最佳投票法定人数的要求。
- 这些机器同样需要安装
kubeadm
和kubelet
。 - 这些机器还需要一个容器运行时,该运行时已经设置好并正常运行。
- 这些机器同样需要安装
请参阅 外部 etcd 拓扑 以了解上下文。
容器镜像
每个主机都应该能够从 Kubernetes 容器镜像仓库 registry.k8s.io
读取和获取镜像。如果您想要部署一个主机无法访问拉取镜像的高可用集群,这是可能的。您必须通过其他方式确保相关主机上已经存在正确的容器镜像。
命令行界面
为了在集群设置好后管理 Kubernetes,您应该在您的 PC 上 安装 kubectl。在每个控制平面节点上安装 kubectl
工具也很有用,因为它可以帮助您进行故障排除。
两种方法的初始步骤
为 kube-apiserver 创建负载均衡器
注意
负载均衡器有许多配置。以下示例只是一种选择。您的集群需求可能需要不同的配置。创建一个 kube-apiserver 负载均衡器,其名称解析为 DNS。
在云环境中,您应该将控制平面节点放置在 TCP 转发负载均衡器之后。此负载均衡器将流量分配到目标列表中所有正常运行的控制平面节点。apiserver 的健康检查是对 kube-apiserver 侦听的端口(默认值为
:6443
)进行 TCP 检查。不建议在云环境中直接使用 IP 地址。
负载均衡器必须能够与所有控制平面节点上的 apiserver 端口进行通信。它还必须允许传入流量在其侦听端口上。
确保负载均衡器的地址始终与 kubeadm 的
ControlPlaneEndpoint
的地址匹配。阅读 软件负载均衡选项 指南以了解更多详细信息。
将第一个控制平面节点添加到负载均衡器,并测试连接
nc -v <LOAD_BALANCER_IP> <PORT>
连接拒绝错误是预期的,因为 API 服务器尚未运行。但是,超时表示负载均衡器无法与控制平面节点通信。如果发生超时,请重新配置负载均衡器以与控制平面节点进行通信。
将剩余的控制平面节点添加到负载均衡器目标组。
堆叠控制平面和 etcd 节点
第一个控制平面节点的步骤
初始化控制平面
sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" --upload-certs
您可以使用
--kubernetes-version
标志来设置要使用的 Kubernetes 版本。建议 kubeadm、kubelet、kubectl 和 Kubernetes 的版本匹配。--control-plane-endpoint
标志应设置为负载均衡器的地址或 DNS 和端口。--upload-certs
标志用于上传应在所有控制平面实例之间共享的证书到集群。如果您希望手动或使用自动化工具在控制平面节点之间复制证书,请删除此标志并参考下面 手动证书分发 部分。
注意
kubeadm init
标志--config
和--certificate-key
不能混合使用,因此如果您想使用 kubeadm 配置,您必须在适当的配置位置(在InitConfiguration
和JoinConfiguration: controlPlane
下)添加certificateKey
字段。注意
某些 CNI 网络插件需要额外的配置,例如指定 pod IP CIDR,而其他插件则不需要。请参阅 CNI 网络文档。要添加 pod CIDR,请传递标志--pod-network-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
证书密钥是一个十六进制编码的字符串,是一个大小为 32 字节的 AES 密钥。
注意
kubeadm-certs
Secret 和解密密钥将在两小时后过期。注意
如命令输出中所述,证书密钥可以访问集群敏感数据,请将其保密!应用您选择的 CNI 插件:按照这些说明 安装 CNI 提供程序。确保配置与 kubeadm 配置文件中指定的 Pod CIDR(如果适用)相对应。
注意
您必须选择一个适合您用例的网络插件,并在继续下一步之前部署它。如果您没有这样做,您将无法正确启动您的集群。键入以下内容,并观察控制平面组件的 Pod 开始运行
kubectl get pod -n kube-system -w
其余控制平面节点的步骤
对于每个额外的控制平面节点,您应该
执行之前在第一个节点上由
kubeadm init
输出给您的加入命令。它应该类似于以下内容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 的过程,但您应该先设置 etcd,并且应该在 kubeadm 配置文件中传递 etcd 信息。
设置 etcd 集群
按照这些 说明 设置 etcd 集群。
按照 此处 的描述设置 SSH。
将以下文件从集群中的任何 etcd 节点复制到第一个控制平面节点
export CONTROL_PLANE="[email protected]" 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}":
- 将
CONTROL_PLANE
的值替换为第一个控制平面节点的user@host
。
- 将
设置第一个控制平面节点
创建一个名为
kubeadm-config.yaml
的文件,其中包含以下内容--- apiVersion: kubeadm.k8s.io/v1beta4 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
注意
这里,堆叠式 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
。将返回的输出加入命令写入文本文件,以备后用。
应用您选择的 CNI 插件。
注意
您必须选择一个适合您用例的网络插件,并在继续下一步之前部署它。如果您没有这样做,您将无法正确启动您的集群。
其余控制平面节点的步骤
步骤与堆叠式 etcd 设置相同。
- 确保第一个控制平面节点已完全初始化。
- 使用您保存到文本文件的加入命令,将每个控制平面节点加入集群。建议一次加入一个控制平面节点。
- 不要忘记,默认情况下,
--certificate-key
中的解密密钥在两小时后过期。
引导控制平面后的常见任务
安装工作节点
可以使用之前存储的 kubeadm init
命令输出的命令,将工作节点加入集群。
sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
手动证书分发
如果您选择不使用带 --upload-certs
标志的 kubeadm init
,则意味着您需要手动将证书从主控制平面节点复制到加入的控制平面节点。
有很多方法可以做到这一点。以下示例使用 ssh
和 scp
如果您想从一台机器控制所有节点,则需要 SSH。
在您的主设备上启用 ssh-agent,该设备可以访问系统中的所有其他节点。
eval $(ssh-agent)
将您的 SSH 身份添加到会话中。
ssh-add ~/.ssh/path_to_private_key
在节点之间使用 SSH 检查连接是否正常工作。
当您通过 SSH 登录任何节点时,请添加
-A
标志。此标志允许您通过 SSH 登录的节点访问您 PC 上的 SSH 代理。如果您不完全信任节点上用户会话的安全性,请考虑使用其他方法。ssh -A 10.0.0.7
在任何节点上使用 sudo 时,请确保保留环境,以便 SSH 转发正常工作。
sudo -E -s
在所有节点上配置 SSH 后,您应该在第一个控制平面节点上运行以下脚本,在运行
kubeadm init
后运行。此脚本将把证书从第一个控制平面节点复制到其他控制平面节点。在以下示例中,将
CONTROL_PLANE_IPS
替换为其他控制平面节点的 IP 地址。USER=ubuntu # customizable 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 # Skip the next line if you are using external etcd scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key done
注意
仅复制上述列表中的证书。kubeadm 将负责使用加入的控制平面实例所需的 SAN 生成其余证书。如果您不小心复制了所有证书,则由于缺少所需的 SAN,创建其他节点可能会失败。然后,在每个加入的控制平面节点上,您必须在运行
kubeadm join
之前运行以下脚本。此脚本将把之前复制的证书从主目录移动到/etc/kubernetes/pki
USER=ubuntu # customizable 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 # Skip the next line if you are using external etcd mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key