Qingular

kubeadm 创建和管理集群

·CKAk8s练习

使用 kubeadm 初始化集群、添加节点、管理令牌以及安装 CNI 网络插件的完整流程。

← 返回 CKA 练习目录

概述

kubeadm 是 Kubernetes 官方提供的集群引导工具,用于快速创建符合最佳实践的集群。它处理了证书、kubeconfig、控制平面组件等复杂配置。CKA 考试中 kubeadm 相关操作是核心考试内容。


1. kubeadm init -- 初始化控制平面

1.1 基本初始化

# 最简初始化
sudo kubeadm init

# 指定 Pod 网络 CIDR(取决于 CNI 插件要求)
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 指定 API Server 地址
sudo kubeadm init --apiserver-advertise-address=192.168.1.10

# 指定 Kubernetes 版本
sudo kubeadm init --kubernetes-version=v1.31.0

1.2 初始化输出解析

# 初始化成功后的输出示例(每个部分都很重要):
Your Kubernetes control-plane has been initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

# CNI 网络插件需要安装
You can now join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.10:6443 --token <token> \
        --discovery-token-ca-cert-hash sha256:<hash>

1.3 初始化后配置

# 配置 kubectl 访问集群
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证集群状态
kubectl cluster-info
kubectl get nodes
kubectl get pods -n kube-system

1.4 自定义 kubeadm-config.yaml

# kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: "192.168.1.10"
  bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: "v1.31.0"
controlPlaneEndpoint: "192.168.1.10:6443"
networking:
  serviceSubnet: "10.96.0.0/12"
  podSubnet: "10.244.0.0/16"
  dnsDomain: "cluster.local"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: "systemd"
# 使用配置初始化
sudo kubeadm init --config=kubeadm-config.yaml

# 查看默认配置
kubeadm config print init-defaults
kubeadm config print join-defaults

# 查看集群配置
kubectl -n kube-system get configmap kubeadm-config -o yaml

2. kubeadm join -- 添加工作节点

2.1 基本用法

# 使用 kubeadm init 输出的令牌加入
sudo kubeadm join 192.168.1.10:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

# 使用配置文件加入
sudo kubeadm join --config=join-config.yaml

2.2 join-config.yaml

apiVersion: kubeadm.k8s.io/v1beta4
kind: JoinConfiguration
discovery:
  bootstrapToken:
    token: "<token>"
    apiServerEndpoint: "192.168.1.10:6443"
    caCertHashes:
    - "sha256:<hash>"
nodeRegistration:
  name: "worker-1"
  criSocket: "unix:///var/run/containerd/containerd.sock"

2.3 添加控制平面节点(高可用)

# 添加额外的控制平面节点(需要先有证书和密钥)
sudo kubeadm join 192.168.1.10:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --control-plane

# 或者使用 --certificate-key 参数
sudo kubeadm join 192.168.1.10:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --control-plane \
    --certificate-key <certificate-key>

3. kubeadm token -- 令牌管理

3.1 令牌操作命令

# 列出所有令牌
kubeadm token list

# 创建新令牌
kubeadm token create

# 创建永不过期的令牌
kubeadm token create --ttl 0

# 指定令牌有效期
kubeadm token create --ttl 4h

# 删除令牌
kubeadm token delete <token>

# 查看令牌详细信息
kubeadm token describe <token>

3.2 获取加入集群所需信息

# 获取令牌
kubeadm token list

# 如果没有令牌,创建一个新的
kubeadm token create

# 获取 CA 证书哈希
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
    openssl rsa -pubin -outform der 2>/dev/null | \
    openssl dgst -sha256 -hex | sed 's/^.* //'

# 或者使用 kubeadm 命令生成完整的 join 命令
kubeadm token create --print-join-command

# 获取控制平面 join 命令
kubeadm init phase upload-certs --upload-certs
kubeadm token create --print-join-command

4. kubeadm reset -- 重置集群

4.1 重置节点

# 重置控制平面节点
sudo kubeadm reset

# 非交互式重置
sudo kubeadm reset -f

# 清理网络配置(重置 CNI)
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
sudo rm -rf $HOME/.kube

# 如果使用 iptables,清理规则
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

4.2 重置工作节点

# 在工作节点上
sudo kubeadm reset
sudo rm -rf /etc/cni/net.d
sudo systemctl restart containerd

# 在控制平面上删除节点
kubectl delete node worker-1

5. TLS Bootstrapping

TLS bootstrapping 允许工作节点自动请求证书,简化节点加入流程。

# 查看证书签名请求
kubectl get csr
kubectl describe csr <csr-name>

# 批准 CSR
kubectl certificate approve <csr-name>

# 拒绝 CSR
kubectl certificate deny <csr-name>

# 查看节点使用的证书
ls -la /var/lib/kubelet/pki/

节点证书自动续期配置

# /etc/kubernetes/kubelet-config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
rotateCertificates: true
serverTLSBootstrap: true

6. CNI 网络插件安装

6.1 Calico

# 安装 Tigera Operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/tigera-operator.yaml

# 下载自定义资源
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/custom-resources.yaml

# 修改 Pod CIDR(如果需要)
sed -i 's|192.168.0.0/16|10.244.0.0/16|g' custom-resources.yaml

# 应用配置
kubectl create -f custom-resources.yaml

# 验证
kubectl get pods -n calico-system
kubectl get nodes

6.2 Flannel

# 安装 Flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# 验证
kubectl get pods -n kube-flannel
kubectl get nodes

6.3 Cilium

# 使用 Helm 安装 Cilium
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --namespace kube-system

# 验证 Cilium 状态
cilium status
kubectl get pods -n kube-system | grep cilium

7. 镜像管理

# 查看 kubeadm 需要的镜像
kubeadm config images list

# 查看指定版本的镜像
kubeadm config images list --kubernetes-version=v1.31.0

# 拉取所需镜像
kubeadm config images pull

# 指定镜像仓库拉取(适用于国内环境)
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers

8. 常见问题排查

# 初始化失败排查步骤
# 1. 检查 containerd 状态
sudo systemctl status containerd

# 2. 检查 containerd 配置(SystemdCgroup)
sudo cat /etc/containerd/config.toml | grep SystemdCgroup

# 3. 查看 kubelet 日志
sudo journalctl -u kubelet -n 100 --no-pager

# 4. 检查端口占用
sudo ss -tulpn | grep -E "6443|2379|2380|10250"

# 5. 检查容器运行时
sudo crictl info

# 6. 重置后重试
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes/
sudo rm -rf /var/lib/etcd/

CKA 考试要点

  1. --pod-network-cidr 必须与 CNI 插件要求一致(Calico 默认使用 192.168.0.0/16,Flannel 使用 10.244.0.0/16
  2. 生成 join 命令使用 kubeadm token create --print-join-command 是最快捷的方式
  3. 控制平面 join 时需要 --control-plane--certificate-key
  4. 初始化前先 pull 镜像kubeadm config images pull,避免超时
  5. kubeadm reset 后清理:需要手动清理 /etc/kubernetes//var/lib/etcd/

🧪 完整操作实例:用 kubeadm 初始化单控制平面集群

场景描述

在已配置好基础设施的节点上,使用 kubeadm 初始化一个单控制平面集群,并安装 Calico CNI 插件。

前置条件

  • 节点已完成基础设施配置(swap 关闭、containerd 已安装并配置 SystemdCgroup)
  • 已安装 kubeadm、kubelet、kubectl

操作步骤

Step 1: 拉取必要镜像

# 提前拉取镜像避免初始化超时
sudo kubeadm config images pull
# [config/images] Pulled registry.k8s.io/kube-apiserver:v1.31.0
# [config/images] Pulled registry.k8s.io/kube-controller-manager:v1.31.0
# ...

Step 2: 初始化控制平面

# 使用 Calico 的默认 Pod CIDR
sudo kubeadm init --pod-network-cidr=192.168.0.0/16

# 输出示例(关键部分):
# Your Kubernetes control-plane has been initialized successfully!
# ...
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
# ...
# kubeadm join 192.168.1.10:6443 --token <token> \
#     --discovery-token-ca-cert-hash sha256:<hash>

Step 3: 配置 kubeconfig

# 安装成功后配置 kubectl 访问
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证集群状态
kubectl cluster-info
# Kubernetes control plane is running at https://192.168.1.10:6443
# CoreDNS is running at https://192.168.1.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Step 4: 安装 Calico CNI

# 安装 Tigera Operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/tigera-operator.yaml

# 下载并应用自定义资源
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/custom-resources.yaml

# 如果 kubeadm init 使用了不同的 pod CIDR,需要修改
# sed -i 's|192.168.0.0/16|10.244.0.0/16|g' custom-resources.yaml

kubectl create -f custom-resources.yaml

# 等待 Calico Pod 就绪
kubectl get pods -n calico-system -w
# NAME                                      READY   STATUS    RESTARTS   AGE
# calico-kube-controllers-xxxxxxxxx-xxxxx   1/1     Running   0          2m
# calico-node-xxxxx                         1/1     Running   0          2m
# calico-typha-xxxxx                        1/1     Running   0          2m

Step 5: 验证节点状态

# 等待节点 Ready
kubectl get nodes
# NAME              STATUS   ROLES           AGE   VERSION
# control-plane-1   Ready    control-plane   5m    v1.31.0

# 查看系统 Pod
kubectl get pods -n kube-system
# NAME                                      READY   STATUS    RESTARTS   AGE
# coredns-xxxxxxxxx-xxxxx                   1/1     Running   0          5m
# coredns-xxxxxxxxx-xxxxx                   1/1     Running   0          5m
# etcd-control-plane-1                      1/1     Running   0          5m
# kube-apiserver-control-plane-1            1/1     Running   0          5m
# kube-controller-manager-control-plane-1   1/1     Running   0          5m
# kube-proxy-xxxxx                          1/1     Running   0          5m
# kube-scheduler-control-plane-1            1/1     Running   0          5m

Step 6: 生成工作节点加入命令

# 创建新 token 并打印完整 join 命令
kubeadm token create --print-join-command
# kubeadm join 192.168.1.10:6443 --token <new-token> --discovery-token-ca-cert-hash sha256:<hash>

验证结果

kubectl get nodes -o wide
# 确认节点 Ready,版本正确
kubectl get pods --all-namespaces | grep -v Completed

考试提示

  • --pod-network-cidr 必须与 CNI 插件要求一致:Calico 默认 192.168.0.0/16,Flannel 默认 10.244.0.0/16
  • 务必在 kubeadm init 前运行 kubeadm config images pull,避免网络超时
  • 保存 kubeadm init 输出中的 join 命令,或使用 kubeadm token create --print-join-command 重新生成
  • 初始化后先配置 kubeconfig 再安装 CNI,否则 kubectl get nodes 会显示 NotReady

官方文档