Lazy loaded image
使用 kubeadm 创建和管理 Kubernetes 集群
Words 4941Read Time 13 min
2025-12-8
2025-12-8
date
related_level
slug
k8s_kubeadm
type
Post
relate_date
summary
涵盖 Kubernetes 集群的创建、管理和维护全流程
status
Published
tags
k8s
系统管理
实用教程
最新推荐
category
运维管理
last_updated
Dec 8, 2025 09:35 AM
是否已更新
orginal_page
是否推荐
参考资料
前置:内核加载模块并修改内核参数配置
  • lsmod | \grep -E 'overlay|nf_nat|br_netfilter|xt_conntrack|aufs'
    • 查看需要的模块是否已加载
  • sysctl vm.swappiness net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv6.conf.all.accept_ra
    • 查看内核配置
vim /etc/modules-load.d/modules.conf
  • 加载模块
vim /etc/sysctl.d/systcl.conf
  • sysctl --system
    • 重新加载内核参数配置
    • 如果 ipv6 默认路由是通过路由器通告 (RA) 设置,需要 net.ipv6.conf.all.accept_ra=2
前置:移除交换分区,顺便调整磁盘空间
移除 swap 交换分区
  • swapoff -a
    • 卸载所有 swap 交换分区
  • DEV_SWAP=$(cat /etc/fstab | grep swap | awk '{print $1}')
    • 根据对应 swap 物理卷名称修改关键字
  • lvchange -a n $DEV_SWAP
  • lvremove $DEV_SWAP
  • lvdisplay | grep swap
    • 查看是否已移除
  • vim /etc/fstab
    • 注释对应部分,禁用开机自动挂载
可选:调整磁盘空间
  • 以 VM 为例,分别挂载了两个逻辑组 vg-rootvg-home//home
    • 如果需要缩容根目录需要进入救援模式
  • DEV_HOME=$(cat /etc/fstab | grep vg-home | awk '{print $1}')
  • DEV_ROOT=$(cat /etc/fstab | grep vg-root | awk '{print $1}')
  • umount /home
    • lsof +D /home
  • 缩小 vg-home 空间
    • e2fsck -f $DEV_HOME
    • resize2fs $DEV_HOME 5G
    • lvreduce -L 5G $DEV_HOME
  • 扩容至 vg-root
    • lvextend -l +100%FREE $DEV_ROOT
    • resize2fs $DEV_ROOT
  • 重新挂载并查看调整结果
    • mount /home && df -h | grep /dev
前置:安装了容器运行时和 kubeadm, kubelet
  • 参考资料
安装 containerd 并启用 SystemdCgroup
安装 containerd 二进制文件
  • 最新版本
  • CONTAINERD_VERSION=$(curl -s https://api.github.com/repos/containerd/containerd/releases/latest | jq -r '.tag_name' | sed 's/v//')
    • echo $CONTAINERD_VERSION
  • wget https://github.com/containerd/containerd/releases/download/v$CRI_VERSION/containerd-$CONTAINERD_VERSION-linux-amd64.tar.gz
  • sudo tar Cxzvf /usr/local containerd-$CONTAINERD_VERSION-linux-amd64.tar.gz
containerd 生成默认配置文件并启用 SystemdCgroup
  • containerd config default | \ sed 's/SystemdCgroup = false/SystemdCgroup = true/' | \ sudo tee /etc/containerd/config.toml
安装 containerd systemd 服务文件并启用 containerd 服务
  • sudo mkdir -p /usr/local/lib/systemd/system
  • sudo curl -Lo /usr/local/lib/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
  • sudo systemctl daemon-reload
  • sudo systemctl enable --now containerd
安装 kubeadm, kubelet
  • 以 1.34 版本为例
    • K8S_VERSION=1.34
添加 Kubernetes 官方仓库
  • sudo apt-get update
  • sudo apt-get install -y apt-transport-https ca-certificates curl gpg
  • mkdir -p /etc/apt/keyrings
  • curl -fsSL https://pkgs.k8s.io/core:/stable:/v$K8S_VERSION/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
  • echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$K8S_VERSION/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
  • K8STOOL_VERSION=$(apt-cache madison kubectl | awk '{print $3}' | grep $K8S_VERSION | head -n 1)
    • echo $K8STOOL_VERSION
  • sudo apt-get update
  • sudo apt-get install -y kubectl=$K8STOOL_VERSION \ kubelet=$K8STOOL_VERSION \ kubeadm=$K8STOOL_VERSION
    • 版本要尽量一致
  • sudo apt-mark hold kubelet kubeadm kubectl
    • 锁定当前版本
  • sudo systemctl enable --now kubelet
    • 可选,先启用 kubelet 服务,再运行 kubeadm
可选:安装 docker 运行时 (不推荐,Kubernetes 原生已移除 dockershim 兼容层)
docker 一键安装脚本
  • bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ --source "mirrors.huaweicloud.com/docker-ce" \ --source-registry "registry.cn-shanghai.aliyuncs.com" \ --install-latest true --use-intranet-source false \ --ignore-backup-tips
    • 选择华为云,否则容易出现解析错误
其他可选项
修改 docker daemon.json 开启 ipv6
  • ls -al /lib/systemd/system/docker.service
vim /etc/docker/daemon.json
  • default-gateway-v6 不能与已有的地址一致
获取并安装 cri-dockerd 插件
  • 最新版本
  • CRI_VERSION=$(curl -s https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest | jq -r '.tag_name' | sed 's/v//')
    • echo $CRI_VERSION
  • wget https://github.com/Mirantis/cri-dockerd/releases/download/v$CRI_VERSION/cri-dockerd-$CRI_VERSION.amd64.tgz
  • tar xzf cri-dockerd-$CRI_VERSION.amd64.tgz --strip-components=1 && \ sudo mv cri-dockerd /usr/local/bin/
  • cri-dockerd --version
  • docker info
  • docker network ls
  • docker inspect network bridge
  • 可选:外部高可用的 etcd 集群
    • 详见 etcd 对应内容
其他:安装常用的 CNI 插件
  • kubeadm 安装没有提供 CNI 插件,自己选择一个安装即可
flannel:简单可靠的 Overlay 网络
  • 如果使用 apply 安装的话需要注意是否自定义了 pod CIDR
calico:高性能、企业级网络与安全方案
  • kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.2/manifests/tigera-operator.yaml
  • kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.2/manifests/custom-resources.yaml
cilium:基于 eBPF 的下一代云原生网络
  • ciliumprojectciliumprojectCilium Quick Installation — Cilium 1.18.4 documentation
Kubernetes 组件版本兼容性
  • Kubernetes 遵循 "N-1" 兼容原则,即客户端版本可以比服务器版本高或低一个次要版本
  • 以 kube-apiserver 为核心版本
    • kubectl, kube-controller-manager 和 kube-scheduler 不能相差一个次要版本
    • kubelet 和 kube-proxy 不能相差两个次要版本
kubeadm init 初始化一个 Kubernetes 控制平面节点
  • kubeadm init phase 分阶段初始化控制平面节点
init 会执行以下阶段
常用选项
  • --apiserver-advertise-address string
    • API 服务器所公布的其正在监听的 IP 地址
  • --apiserver-bind-port int32
    • API 服务器绑定的端口,默认值:6443
  • --apiserver-cert-extra-sans strings
    • 用于 API Server 服务证书的可选附加主题备用名称(SAN)
    • 可以是 IP 地址和 DNS 名称
  • --control-plane-endpoint string
    • 为控制平面指定一个稳定的 IP 地址或 DNS 名称
  • --pod-network-cidr string
    • 指明 Pod 网络可以使用的 IP 地址段
  • --service-cidr string
    • 为服务的虚拟 IP 地址另外指定 IP 地址段
  • --service-dns-domain string
    • 为服务另外指定域名,默认为 "cluster.local"
选项和参数
  • --config string
    • kubeadm 配置文件位置
  • --node-name string
    • 指定节点的名称
  • --kubernetes-version string
    • 为控制平面选择一个特定的 Kubernetes 版本,默认为 "stable-1"
  • --image-repository string
    • 选择用于拉取控制平面镜像的容器仓库
  • --token string
    • 用于建立控制平面节点与工作节点间的双向通信的令牌
    • token 格式为 [a-z0-9]{6}.[a-z0-9]{16}
      • kubeadm token generate 生成并打印一个引导令牌,但不要在服务器上创建它
  • --token-ttl duration
    • 令牌被自动删除之前的持续时间,默认为 "24h0m0s"
    • 设置为 '0',则令牌将永不过期
  • --cert-dir string
    • 保存和存储证书的路径,默认为 "/etc/kubernetes/pki"
  • --upload-certs
    • 将控制平面证书上传到 kubeadm-certs Secret
  • --certificate-key string
    • 用于加密 kubeadm-certs Secret 中的控制平面证书的密钥
    • 证书密钥为十六进制编码的字符串,是大小为 32 字节的 AES 密钥
  • --feature-gates string
    • 用来描述各种特性门控的键值(key=value)对
    • 可用选项
      • ControlPlaneKubeletLocalMode=true|false (ALPHA - 默认值=false)
      • EtcdLearnerMode=true|false (默认值=true)
      • NodeLocalCRISocket=true|false (ALPHA - 默认值=false)
      • PublicKeysECDSA=true|false (DEPRECATED - 默认值=false)
      • RootlessControlPlane=true|false (ALPHA - 默认值=false)
      • WaitForAllControlPlaneComponents=true|false (ALPHA - 默认值=false)
  • --cri-socket string
    • 要连接的 CRI 套接字的路径
      • 如果为空,则 kubeadm 将尝试自动检测此值
    • 仅当安装了多个 CRI 或存在非标准的 CRI 套接字时,才使用此选项
  • --skip-phases strings
    • 要跳过的阶段列表
kubeadm init 使用配置文件初始化一个 Kubernetes 控制平面节点
kubeadm config print 打印默认值
  • kubeadm config print init-defaults
  • kubeadm config print join-defaults
  • kubeadm config print reset-defaults
  • kubeadm config print upgrade-defaults
kubeadm init --config <配置文件> 的四种配置类型
  • 至少需要提供 InitConfiguration 或 ClusterConfiguration 中的一个
  • InitConfiguration
    • 用于控制 kubeadm init 本身的运行行为
  • ClusterConfiguration
    • 用于定义整个集群的全局设置
  • KubeProxyConfiguration
    • 用于自定义 kube-proxy 的配置
  • KubeletConfiguration
    • 用于自定义所有节点上 kubelet 的默认配置
完整样例
kubeadm token 管理引导令牌
  • kubeadm token generate 生成并打印一个引导令牌,但不要在服务器上创建它
    • token 形式为 [a-z0-9]{6}.[a-z0-9]{16}
      • 前 6 位为 token id
  • kubeadm token create [token] 在服务器上创建引导令牌
    • token 可选,没有提供则 kubeadm 将生成一个随机令牌
  • kubeadm token list 列出服务器上的引导令牌
  • kubeadm token delete [token-value] 删除对应令牌
    • token-value 是完整令牌或者令牌 ID
kubeadm join 初始化一个 Kubernetes 节点加入已有集群
  • 关键是建立当前节点和控制平面节点的双向信任
    • 发现要信任的集群 CA(让待加入节点信任 Kubernetes 控制平面节点)
    • 集群 CA TLS 引导(让 Kubernetes 控制平面节点信任待加入节点)
两种集群 CA 发现方案
使用共享令牌和 API 服务器的 IP 地址
  • kubeadm join 1.2.3.4:6443 \ --discovery-token <token> \ --discovery-token-ca-cert-hash sha256:<hex_encoded_hash>
    • --control-plane 作为控制平面加入节点
    • --discovery-token-unsafe-skip-ca-verification 不验证 CA 公钥
      • --discovery-token-ca-cert-hash 冲突
基于 HTTPS 或文件发现
  • kubeadm join 1.2.3.4:6443 \ --discovery-file <filepath>|<urlpath>
    • 可以是文本本地路径 path/to/file.conf 也可以是文件 url 路径 https://url/file.conf
join 工作流
  • 工作节点加入流程
      1. 从 API 服务器获取集群信息(默认通过引导令牌和 CA 哈希验证)。
      1. kubelet 使用共享令牌临时认证,发起 TLS 引导并提交证书签名请求(CSR)。
      1. 控制平面自动批准 CSR,完成身份认证。
      1. 配置 kubelet 使用唯一标识连接 API 服务器。
  • 控制平面节点额外步骤
      1. (可选)下载集群共享的控制平面证书。
      1. 生成本地控制平面组件的配置、证书和 kubeconfig。
      1. 将本地 etcd 实例作为新成员加入 etcd 集群
  • kubeadm join phase 分阶段将节点加入集群
join 会执行以下阶段
选项和参数
  • --node-name string
    • 指定节点的名称
  • --discovery-file string
    • 对于基于文件的发现,给出用于加载集群信息的文件或者 URL
  • --discovery-token string
    • 对于基于令牌的发现,该令牌用于验证从 API 服务器获取的集群信息
  • --discovery-token-ca-cert-hash stringSlice
    • 对于基于令牌的发现,验证根 CA 公钥是否与此哈希匹配
  • --discovery-token-unsafe-skip-ca-verification
    • 对于基于令牌的发现,允许在未关联 --discovery-token-ca-cert-hash 参数的情况下添加节点
  • --tls-bootstrap-token string
    • 指定在加入节点时用于临时通过 Kubernetes 控制平面进行身份验证的令牌
  • --certificate-key string
    • 使用此密钥可以解密由 init 上传的证书 Secret
  • --control-plane
    • 在此节点上创建一个新的控制平面实例
  • --apiserver-advertise-address string
    • 如果托管一个新的控制平面实例,则 API 服务器将公布其正在侦听的 IP 地址
  • --apiserver-bind-port int32
    • API 服务器绑定的端口,默认值:6443
  • --cri-socket string
    • 要连接的 CRI 套接字的路径
      • 如果为空,则 kubeadm 将尝试自动检测此值
    • 仅当安装了多个 CRI 或存在非标准的 CRI 套接字时,才使用此选项
  • --config string
    • kubeadm 配置文件位置
  • --skip-phases strings
    • 要跳过的阶段列表
kubeadm certs 管理证书
kubeadm 使用 TLS 证书详细一览
需要以下证书
默认 CN
父级 CA
O(位于 Subject 中)
kind
主机(SAN)
kube-etcd
etcd-ca
server、client
<hostname><Host_IP>localhost127.0.0.1
kube-etcd-peer
etcd-ca
server、client
<hostname><Host_IP>localhost127.0.0.1
kube-etcd-healthcheck-client
etcd-ca
client
kube-apiserver-etcd-client
etcd-ca
client
kube-apiserver
kubernetes-ca
server
<hostname><Host_IP><advertise_IP>1
kube-apiserver-kubelet-client
kubernetes-ca
system:masters
client
front-proxy-client
kubernetes-front-proxy-ca
client
证书路径
默认 CN
建议的密钥路径
建议的证书路径
命令
密钥参数
证书参数
etcd-ca
etcd/ca.key
etcd/ca.crt
kube-apiserver
--etcd-cafile
kube-apiserver-etcd-client
apiserver-etcd-client.key
apiserver-etcd-client.crt
kube-apiserver
--etcd-keyfile
--etcd-certfile
kubernetes-ca
ca.key
ca.crt
kube-apiserver
--client-ca-file
kubernetes-ca
ca.key
ca.crt
kube-controller-manager
--cluster-signing-key-file
--client-ca-file, --root-ca-file, --cluster-signing-cert-file
kube-apiserver
apiserver.key
apiserver.crt
kube-apiserver
--tls-private-key-file
--tls-cert-file
kube-apiserver-kubelet-client
apiserver-kubelet-client.key
apiserver-kubelet-client.crt
kube-apiserver
--kubelet-client-key
--kubelet-client-certificate
front-proxy-ca
front-proxy-ca.key
front-proxy-ca.crt
kube-apiserver
--requestheader-client-ca-file
front-proxy-ca
front-proxy-ca.key
front-proxy-ca.crt
kube-controller-manager
--requestheader-client-ca-file
front-proxy-client
front-proxy-client.key
front-proxy-client.crt
kube-apiserver
--proxy-client-key-file
--proxy-client-cert-file
etcd-ca
etcd/ca.key
etcd/ca.crt
etcd
--trusted-ca-file, --peer-trusted-ca-file
kube-etcd
etcd/server.key
etcd/server.crt
etcd
--key-file
--cert-file
kube-etcd-peer
etcd/peer.key
etcd/peer.crt
etcd
--peer-key-file
--peer-cert-file
etcd-ca
etcd/ca.crt
etcdctl
--cacert
kube-etcd-healthcheck-client
etcd/healthcheck-client.key
etcd/healthcheck-client.crt
etcdctl
--key
--cert
notion image
  • kubeadm certs check-expiration 检查证书是否以及何时过期
  • kubeadm certs renew 续订 Kubernetes 证书
  • kubeadm certs certificate-key 生成一个新的控制面证书密钥
  • kubeadm certs generate-csr 为所有控制面证书和 kubeconfig 文件生成密钥和 CSR
kubeadm reset 尽力还原由 kubeadm init 或 kubeadm join 所做的更改
reset 会执行以下阶段
选项和参数
  • --cri-socket string
    • 要连接的 CRI 套接字的路径
      • 如果为空,则 kubeadm 将尝试自动检测此值
    • 仅当安装了多个 CRI 或存在非标准的 CRI 套接字时,才使用此选项
  • --cert-dir string
    • 默认为 "/etc/kubernetes/pki"
  • --config string
    • kubeadm 配置文件位置
  • --kubeconfig string
    • kubeconfig 配置文件位置
      • 如果未设置该标志, 则可以在一组标准位置中搜索现有的 kubeconfig 文件
    • 默认为 "/etc/kubernetes/admin.conf"
  • --cleanup-tmp-dir
    • 清理 "/etc/kubernetes/tmp" 目录
  • --skip-phases strings
    • 要跳过的阶段列表
kubeadm reset 不会删除的一些东西
  • 如果使用了外部 etcd,kubeadm reset 将不会删除任何 etcd 中的数据
  • kubeadm reset 命令不会清理 CNI 插件配置
    • CNI 插件使用 /etc/cni/net.d 目录来存储其配置
  • kubeadm reset 命令不会清理由 kube-proxy 应用到主机的任何 iptables、nftables 或 IPVS 规则
  • kubeadm reset 命令不会清理 $HOME/.kube 目录中的任何内容
kubeadm upgrade 升级 Kubernetes 集群版本
参考资料
  • 建议按照次要版本一步步升级,且 kubeadm 本身也需要匹配对应版本
    • 下文假设次要版本为 1.34
upgrade 会执行以下阶段
  • kubeadm upgrade apply phase <phase-name> 执行某个特定升级阶段
ubuntu/debian 升级 kubeadm
  • apt update
  • apt-cache madison kubeadm
    • 查看可用版本,假设次要版本为 1.34
  • apt-mark unhold kubeadm && \ apt-get install -y kubeadm='1.34.x-*' && \ apt-mark hold kubeadm
  • kubeadm upgrade plan
    • 检查可用升级以及升级建议,并取回要升级的目标版本
    • 还会自动对 kubeadm 在节点上所管理的证书执行续约操作
    • CNI 驱动插件需要手动升级
升级首个控制平面需要执行 kubeadm upgrade apply v1.34.Z
  • kubeadm upgrade apply 会执行以下操作
    • 检查您的集群是否处于可升级状态
      • API 服务器可访问
      • 所有节点均处于 Ready 状态
      • 控制平面运行正常
    • 强制执行版本偏差策略
    • 确保控制平面图像可用或可供拉取到机器
    • 如果组件配置需要版本升级,则生成替换项和/或使用用户提供的覆盖项
    • 升级控制平面组件,如果其中任何组件启动失败,则进行回滚
    • 应用新的 CoreDNS 和 kube-proxy 清单,并确保创建所有必要的 RBAC 规则
    • 为 API 服务器创建新的证书和密钥文件,并备份即将在 180 天内过期的旧文件
后续其他控制平面只需要 kubeadm upgrade node
  • kubeadm upgrade node 在其他控制平面会执行以下操作
    • 从集群中获取 kubeadm ClusterConfiguration 
    • (可选)备份 kube-apiserver 证书
    • 升级控制平面组件的静态 Pod 清单
    • 升级此节点的 kubelet 配置
  • kubectl drain <node-to-drain> --ignore-daemonsets
    • 腾空节点准备升级 kubelet
ubuntu/debian 升级 kubelet 和 kubectl
  • apt-mark unhold kubelet kubectl && \ apt-get install -y kubelet='1.34.x-*' kubectl='1.34.x-*' && \ apt-mark hold kubelet kubectl
  • systemctl daemon-reload
  • systemctl restart kubelet
  • kubectl uncordon <node-to-uncordon>
    • 工作节点恢复为可调度状态
如果升级失败可以再次执行 kubeadm upgrade apply --force
  • kubeadm upgrade 指令是幂等(exactly once)的,并最终确保实际状态是声明的期望状态
  • 在升级期间,kubeadm 会写入备份到 /etc/kubernetes/tmp 文件夹
    • kubeadm-backup-etcd-<date>-<time>
      • 仅当使用内部 etcd 时非空,包含当前控制平面节点本地 etcd 成员数据的备份
      • 如果升级失败且自动回滚无法修复,可以复制到 /var/lib/etcd 进行手工修复
    • kubeadm-backup-manifests-<date>-<time>
      • 包含当前控制平面节点的静态 Pod 清单文件的备份版本
      • 如果升级失败且自动回滚无法修复,可以复制到 /etc/kubernetes/manifests 目录实现手工恢复
  •  升级后,备份目录 /etc/kubernetes/tmp 将保留,需要手动清理
 
上一篇
CKA & CKAD 备考笔记
下一篇
k8s Pod 和容器管理

Comments
Loading...