4. kubeadm 部署 Master 节点:kubeadm init 流程详解、控制平面组件高可用配置、etcd 集群部署与验证
本章聚焦于使用 kubeadm 工具初始化 Kubernetes 控制平面的完整流程。我们将深入剖析 kubeadm init 命令背后的执行阶段,并详细阐述如何配置高可用的控制平面组件以及部署与验证 etcd 集群。这是从单节点测试环境迈向生产级多 Master 集群的关键一步。
4.1 kubeadm init 流程详解
kubeadm init 并非一个单一操作,而是一系列预检、生成、部署和配置步骤的自动化组合。理解其内部阶段有助于在出现故障时精准定位问题。
| 阶段序号 | 阶段名称 | 核心操作 | 关键输出/产物 |
|---|---|---|---|
| 1 | preflight | 检查系统环境、容器运行时、网络、端口冲突、cgroup 驱动一致性等 | 通过/失败报告 |
| 2 | certs | 生成 CA 证书以及 API Server、kubelet、controller-manager、scheduler 等组件证书 | /etc/kubernetes/pki/ 目录下的 .crt 和 .key 文件 |
| 3 | kubeconfig | 为 admin、kubelet、controller-manager、scheduler 生成 kubeconfig 文件 | /etc/kubernetes/ 目录下的 .conf 文件 |
| 4 | kubelet-start | 生成 kubelet 的配置文件并启动 kubelet 服务 | /var/lib/kubelet/config.yaml |
| 5 | control-plane | 以静态 Pod 形式部署 API Server、Controller Manager、Scheduler | /etc/kubernetes/manifests/ 下的 YAML 清单 |
| 6 | etcd | 以静态 Pod 形式部署本地 etcd 成员 | /etc/kubernetes/manifests/ 下的 etcd.yaml |
| 7 | upload-config | 将 kubeadm 配置上传至集群中的 ConfigMap | kube-system 命名空间下的 kubeadm-config |
| 8 | mark-control-plane | 为当前节点添加 node-role.kubernetes.io/control-plane 标签和污点 | 节点标签与污点 |
| 9 | bootstrap- | 创建用于节点加入的引导令牌 | Bootstrap |
| 10 | kubelet-finalize | 更新 kubelet 配置以使用集群 CA | kubelet 配置更新 |
| 11 | addons | 部署 CoreDNS 和 kube-proxy 附加组件 | CoreDNS Pod 与 kube-proxy DaemonSet |
kubeadm init 失败,不要盲目重试。首先检查 kubelet 日志(journalctl -u kubelet -f),然后根据失败阶段定位问题。例如,证书阶段失败通常与主机名或 IP 变更有关;etcd 阶段失败则需检查磁盘性能和网络连通性。
4.2 控制平面组件高可用配置
生产环境要求控制平面组件具备高可用性。kubeadm 支持两种模式:堆叠式 etcd(默认)和 外部 etcd。堆叠式 etcd 将 etcd 与控制平面组件部署在同一节点上,而外部 etcd 则将 etcd 集群独立部署。
以下 SVG 图展示了堆叠式 etcd 的高可用控制平面架构,这是生产中最常用的模式之一。
4.2.1 使用配置文件初始化高可用集群
要初始化高可用集群,需要创建一个 kubeadm-config.yaml 配置文件,并在其中指定 ControlPlaneEndpoint 和 etcd 配置。以下是一个堆叠式 etcd 的配置示例:
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "192.168.1.10" # 当前节点 IP
bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: "v1.28.0"
controlPlaneEndpoint: "192.168.1.100:6443" # 负载均衡器地址
apiServer:
certSANs:
- "192.168.1.100"
- "10.96.0.1"
- "127.0.0.1"
controllerManager:
extraArgs:
bind-address: "0.0.0.0"
scheduler:
extraArgs:
bind-address: "0.0.0.0"
etcd:
local:
extraArgs:
listen-client-urls: "https://127.0.0.1:2379,https://192.168.1.10:2379"
advertise-client-urls: "https://192.168.1.10:2379"
listen-peer-urls: "https://192.168.1.10:2380"
initial-advertise-peer-urls: "https://192.168.1.10:2380"
initial-cluster: "master1=https://192.168.1.10:2380"
initial-cluster-state: "new"
networking:
serviceSubnet: "10.96.0.0/12"
podSubnet: "10.244.0.0/16"
dnsDomain: "cluster.local"
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
- controlPlaneEndpoint 必须指向负载均衡器的 VIP 或 DNS 名称,不能是单个 Master 节点的 IP。
- certSANs 必须包含所有可能的 API Server 访问地址,包括负载均衡器 IP、所有 Master 节点 IP 以及 Service IP(10.96.0.1)。
- etcd 的 initial-cluster 参数在第一个节点上只需包含自身;后续节点加入时需更新此参数。
4.2.2 后续 Master 节点加入
在第一个 Master 节点初始化成功后,使用 kubeadm join 命令并指定 --control-plane 标志来添加其他 Master 节点:
# 在第一个 Master 节点上生成 join 命令
kubeadm init phase upload-config --config kubeadm-config.yaml
kubeadm create --print-join-command
# 在第二个 Master 节点上执行(示例)
kubeadm join 192.168.1.100:6443 -- <> \
--discovery--ca-cert-hash sha256:<hash> \
--control-plane \
--certificate-key <certificate-key>
--certificate-key 参数可以自动将控制平面证书从第一个 Master 节点分发到新加入的节点。该密钥通过 kubeadm init phase upload-certs --upload-certs 生成。
4.3 etcd 集群部署与验证
etcd 是 Kubernetes 集群的基石,存储所有集群状态。无论是堆叠式还是外部 etcd,都需要确保其健康运行。
4.3.1 外部 etcd 集群部署
对于大规模生产环境,推荐使用外部 etcd 集群。以下是在三台独立节点上部署外部 etcd 的步骤概要:
- 准备证书: 生成 etcd 的 CA 证书、服务端证书和客户端证书。
- 配置 etcd 成员: 在每个 etcd 节点上创建配置文件
/etc/etcd/etcd.conf。 - 启动 etcd 服务: 使用 systemd 管理 etcd 服务。
- 验证集群状态: 使用
etcdctl命令检查成员列表和健康状态。
以下是一个 etcd 节点的配置示例:
# /etc/etcd/etcd.conf
name: 'etcd-node1'
data-dir: '/var/lib/etcd'
listen-client-urls: 'https://0.0.0.0:2379'
advertise-client-urls: 'https://192.168.1.21:2379'
listen-peer-urls: 'https://0.0.0.0:2380'
initial-advertise-peer-urls: 'https://192.168.1.21:2380'
initial-cluster: 'etcd-node1=https://192.168.1.21:2380,etcd-node2=https://192.168.1.22:2380,etcd-node3=https://192.168.1.23:2380'
initial-cluster-: 'etcd-cluster'
initial-cluster-state: 'new'
client-transport-security:
cert-file: '/etc/etcd/pki/etcd-server.crt'
key-file: '/etc/etcd/pki/etcd-server.key'
trusted-ca-file: '/etc/etcd/pki/etcd-ca.crt'
client-cert-auth: true
peer-transport-security:
cert-file: '/etc/etcd/pki/etcd-peer.crt'
key-file: '/etc/etcd/pki/etcd-peer.key'
trusted-ca-file: '/etc/etcd/pki/etcd-ca.crt'
peer-cert-auth: true
4.3.2 etcd 集群验证
部署完成后,必须进行全面的验证。以下 SVG 图展示了 etcd 集群验证的完整流程。
以下是具体的验证命令及其预期输出:
# 1. 查看成员列表
etcdctl --endpoints=https://192.168.1.21:2379,https://192.168.1.22:2379,https://192.168.1.23:2379 \
--cacert=/etc/etcd/pki/etcd-ca.crt \
--cert=/etc/etcd/pki/etcd-client.crt \
--key=/etc/etcd/pki/etcd-client.key \
member list
# 预期输出:显示三个成员,状态均为 started
# 2. 检查端点健康
etcdctl --endpoints=https://192.168.1.21:2379,https://192.168.1.22:2379,https://192.168.1.23:2379 \
--cacert=/etc/etcd/pki/etcd-ca.crt \
--cert=/etc/etcd/pki/etcd-client.crt \
--key=/etc/etcd/pki/etcd-client.key \
endpoint health
# 预期输出:所有端点均为 healthy
# 3. 查看端点状态(包括 Raft 术语)
etcdctl --endpoints=https://192.168.1.21:2379,https://192.168.1.22:2379,https://192.168.1.23:2379 \
--cacert=/etc/etcd/pki/etcd-ca.crt \
--cert=/etc/etcd/pki/etcd-client.crt \
--key=/etc/etcd/pki/etcd-client.key \
endpoint status -w table
# 预期输出:显示每个端点的版本、DB 大小、leader 信息等
- DB SIZE: 各节点 DB 大小应基本一致,差异过大可能表示数据同步异常。
- IS LEADER: 只有一个节点为 true,其他为 false。
- RAFT TERM: 所有节点应处于相同的 Raft 任期。
4.3.3 将外部 etcd 集成到 kubeadm
如果使用外部 etcd,需要在 kubeadm-config.yaml 中指定 etcd 的外部端点:
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
etcd:
external:
endpoints:
- https://192.168.1.21:2379
- https://192.168.1.22:2379
- https://192.168.1.23:2379
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/etcd/server.crt
keyFile: /etc/kubernetes/pki/etcd/server.key
4.4 本章小结
本章详细介绍了 kubeadm init 的 11 个执行阶段,并提供了高可用控制平面的配置方法。通过堆叠式或外部 etcd 的部署与验证,你可以构建一个生产就绪的 Kubernetes 控制平面。记住,etcd 的健康是集群稳定的前提,务必定期执行验证流程并建立完善的备份策略。