实现细节

特性状态: Kubernetes v1.10 [稳定版]

kubeadm initkubeadm join 结合使用,为从头开始创建裸 Kubernetes 集群提供了一个很好的用户体验,符合最佳实践。然而,如何 kubeadm 实现这一点可能并不显而易见。

本文档提供了关于幕后操作的更多细节,旨在分享关于 Kubernetes 集群最佳实践的知识。

核心设计原则

kubeadm initkubeadm join 设置的集群应该是

  • 安全的:它应该采用最新的最佳实践,例如
    • 强制执行 RBAC
    • 使用 Node Authorizer
    • 在控制平面组件之间使用安全通信
    • 在 API 服务器和 kubelet 之间使用安全通信
    • 锁定 kubelet API
    • 锁定对 kube-proxy 和 CoreDNS 等系统组件的 API 访问
    • 锁定引导令牌 (Bootstrap Token) 可以访问的内容
  • 用户友好:用户只需运行几个命令即可
    • kubeadm init
    • export KUBECONFIG=/etc/kubernetes/admin.conf
    • kubectl apply -f <您选择的网络插件.yaml>
    • kubeadm join --token <token> <endpoint>:<port>
  • 可扩展的:
    • 它不应该偏向任何特定的网络提供商。配置集群网络超出了范围
    • 它应该提供使用配置文件来自定义各种参数的可能性

常量和知名值及路径

为了降低复杂性并简化基于 kubeadm 构建的更高级别工具的开发,它使用一组有限的常量值来表示知名的路径和文件名。

Kubernetes 目录 /etc/kubernetes 是应用程序中的一个常量,因为它在大多数情况下是明确给定的路径,也是最直观的位置;其他常量路径和文件名是

  • /etc/kubernetes/manifests 是 kubelet 查找静态 Pod manifest 的路径。静态 Pod manifest 的名称是

    • etcd.yaml
    • kube-apiserver.yaml
    • kube-controller-manager.yaml
    • kube-scheduler.yaml
  • /etc/kubernetes/ 是存储控制平面组件标识的 kubeconfig 文件的路径。kubeconfig 文件的名称是

    • kubelet.conf (TLS 引导期间为 bootstrap-kubelet.conf)
    • controller-manager.conf
    • scheduler.conf
    • admin.conf 用于集群管理员和 kubeadm 本身
    • super-admin.conf 用于集群超级管理员,可以绕过 RBAC
  • 证书和密钥文件的名称

    • ca.crt, ca.key 用于 Kubernetes 证书颁发机构
    • apiserver.crt, apiserver.key 用于 API 服务器证书
    • apiserver-kubelet-client.crt, apiserver-kubelet-client.key 用于 API 服务器安全连接 kubelet 所使用的客户端证书
    • sa.pub, sa.key 用于控制器管理器在签名 ServiceAccount 时使用的密钥
    • front-proxy-ca.crt, front-proxy-ca.key 用于前端代理证书颁发机构
    • front-proxy-client.crt, front-proxy-client.key 用于前端代理客户端

kubeadm 配置文件格式

大多数 kubeadm 命令支持 --config 标志,该标志允许从磁盘传递配置文件。配置文件格式遵循常见的 Kubernetes API apiVersion / kind 方案,但被视为组件配置文件格式。几个 Kubernetes 组件,例如 kubelet,也支持基于文件的配置。

不同的 kubeadm 子命令需要不同类型的配置文件。例如,InitConfiguration 用于 kubeadm initJoinConfiguration 用于 kubeadm joinUpgradeConfiguration 用于 kubeadm upgradeResetConfiguration 用于 kubeadm reset

kubeadm config migrate 命令可用于将旧格式的配置文件迁移到更新(当前)的配置格式。kubeadm 工具仅支持从已弃用的配置格式迁移到当前格式。

有关更多详细信息,请参阅 kubeadm 配置参考页面。

kubeadm init 工作流程内部设计

kubeadm init 由一系列原子工作任务组成,如 kubeadm init 内部工作流程中所述。

kubeadm init phase 命令允许用户单独调用每个任务,并最终提供一个可重用和可组合的 API/工具集,该工具集可供其他 Kubernetes 引导工具、任何 IT 自动化工具或高级用户用于创建自定义集群。

预检检查

Kubeadm 在启动 init 之前执行一系列预检检查,目的是验证先决条件并避免常见的集群启动问题。用户可以通过 --ignore-preflight-errors 选项跳过特定的预检检查或所有检查。

  • [警告] 如果要使用的 Kubernetes 版本(通过 --kubernetes-version 标志指定)比 kubeadm CLI 版本高至少一个次版本。
  • Kubernetes 系统要求
    • 如果运行在 Linux 上
      • [错误] 如果内核版本低于最低要求版本
      • [错误] 如果必需的 cgroups 子系统未设置
  • [错误] 如果 CRI 端点无响应
  • [错误] 如果用户不是 root
  • [错误] 如果机器主机名不是有效的 DNS 子域
  • [警告] 如果主机名无法通过网络查找到达
  • [错误] 如果 kubelet 版本低于 kubeadm 支持的最低 kubelet 版本(当前次版本 -1)
  • [错误] 如果 kubelet 版本比所需控制平面版本高至少一个次版本(不支持的版本偏差)
  • [警告] 如果 kubelet 服务不存在或已被禁用
  • [警告] 如果 firewalld 正在运行
  • [错误] 如果 API 服务器 bindPort 或端口 10250/10251/10252 已被使用
  • [错误] 如果 /etc/kubernetes/manifest 文件夹已存在且非空
  • [错误] 如果 swap 已开启
  • [错误] 如果 ip, iptables, mount, nsenter 命令不在命令路径中
  • [警告] 如果 ethtool, tc, touch 命令不在命令路径中
  • [警告] 如果 API 服务器、控制器管理器、调度器的附加参数标志包含一些无效选项
  • [警告] 如果连接到 https://API.AdvertiseAddress:API.BindPort 时经过代理
  • [警告] 如果连接到服务子网时经过代理(仅检查第一个地址)
  • [警告] 如果连接到 Pod 子网时经过代理(仅检查第一个地址)
  • 如果提供了外部 etcd
    • [错误] 如果 etcd 版本低于最低要求版本
    • [错误] 如果指定了 etcd 证书或密钥,但未提供
  • 如果未提供外部 etcd(因此将安装本地 etcd)
    • [错误] 如果端口 2379 已被使用
    • [错误] 如果 Etcd.DataDir 文件夹已存在且非空
  • 如果授权模式为 ABAC
    • [错误] 如果 abac_policy.json 不存在
  • 如果授权模式为 WebHook
    • [错误] 如果 webhook_authz.conf 不存在

生成必要的证书

Kubeadm 为不同目的生成证书和私钥对

  • 用于 Kubernetes 集群的自签名证书颁发机构,保存在 ca.crt 文件中,私钥为 ca.key 文件

  • API 服务器的服务证书,使用 ca.crt 作为 CA 生成,保存在 apiserver.crt 文件中,其私钥为 apiserver.key。此证书应包含以下备用名称

    • Kubernetes 服务的内部 ClusterIP(服务 CIDR 中的第一个地址,例如,如果服务子网是 10.96.0.0/12,则为 10.96.0.1
    • Kubernetes DNS 名称,例如,如果 --service-dns-domain 标志值为 cluster.local,则为 kubernetes.default.svc.cluster.local,再加上默认 DNS 名称 kubernetes.default.svc, kubernetes.default, kubernetes
    • 节点名称
    • --apiserver-advertise-address
    • 用户指定的其他备用名称
  • API 服务器安全连接 kubelet 的客户端证书,使用 ca.crt 作为 CA 生成,保存在 apiserver-kubelet-client.crt 文件中,其私钥为 apiserver-kubelet-client.key。此证书应属于 system:masters 组织

  • 用于签名 ServiceAccount Token 的私钥,保存在 sa.key 文件中,公钥为 sa.pub

  • 用于前端代理的证书颁发机构,保存在 front-proxy-ca.crt 文件中,私钥为 front-proxy-ca.key

  • 前端代理客户端的客户端证书,使用 front-proxy-ca.crt 作为 CA 生成,保存在 front-proxy-client.crt 文件中,私钥为 front-proxy-client.key

证书默认存储在 /etc/kubernetes/pki 中,但可以通过 --cert-dir 标志配置此目录。

请注意

  1. 如果给定的证书和私钥对都存在,并且其内容被评估为符合上述规范,则将使用现有文件,并跳过给定证书的生成阶段。这意味着用户可以例如将现有 CA 复制到 /etc/kubernetes/pki/ca.{crt,key},然后 kubeadm 将使用这些文件来签名其余证书。另请参阅 使用自定义证书
  2. 对于 CA,可以提供 ca.crt 文件但不能提供 ca.key 文件。如果所有其他证书和 kubeconfig 文件都已到位,kubeadm 将识别此条件并激活 ExternalCA,这也意味着控制器管理器中的 csrsigner 控制器将不会启动
  3. 如果 kubeadm 在 外部 CA 模式下运行;所有证书必须由用户提供,因为 kubeadm 无法自行生成它们
  4. 如果 kubeadm 在 --dry-run 模式下执行,证书文件将写入临时文件夹
  5. 可以通过 kubeadm init phase certs all 命令单独调用证书生成。

为控制平面组件生成 kubeconfig 文件

Kubeadm 为控制平面组件生成具有身份的 kubeconfig 文件

  • 用于 kubelet 在 TLS 引导期间使用的 kubeconfig 文件 - /etc/kubernetes/bootstrap-kubelet.conf。在此文件内部,有一个引导令牌或嵌入的客户端证书,用于将此节点与集群进行身份验证。

    此客户端证书应

    • 属于 system:nodes 组织,这是 Node Authorization 模块的要求
    • Common Name (CN) 为 system:node:<hostname-lowercased>
  • 用于控制器管理器的 kubeconfig 文件,/etc/kubernetes/controller-manager.conf;在此文件内部嵌入了一个具有控制器管理器身份的客户端证书。此客户端证书应具有 CN system:kube-controller-manager,如默认 RBAC 核心组件角色所定义

  • 用于调度器的 kubeconfig 文件,/etc/kubernetes/scheduler.conf;在此文件内部嵌入了一个具有调度器身份的客户端证书。此客户端证书应具有 CN system:kube-scheduler,如默认 RBAC 核心组件角色所定义

此外,还会生成一个用于 kubeadm 作为管理实体的 kubeconfig 文件,并存储在 /etc/kubernetes/admin.conf 中。此文件包含一个具有 Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin 的证书。kubeadm:cluster-admins 是由 kubeadm 管理的一个组。它在 kubeadm init 期间通过使用 super-admin.conf 文件绑定到 cluster-admin ClusterRole,该文件不需要 RBAC。此 admin.conf 文件必须保留在控制平面节点上,并且不应与额外的用户共享。

kubeadm init 期间,还会生成另一个 kubeconfig 文件并存储在 /etc/kubernetes/super-admin.conf 中。此文件包含一个具有 Subject: O = system:masters, CN = kubernetes-super-admin 的证书。system:masters 是一个超级用户组,可以绕过 RBAC,当集群因 RBAC 配置错误而锁定在紧急情况下,super-admin.conf 文件很有用。super-admin.conf 文件必须存储在安全的位置,并且不应与额外的用户共享。

有关 RBAC 和内置 ClusterRoles 及组的更多信息,请参阅 RBAC 用户可见角色绑定

您可以运行 kubeadm kubeconfig user 为其他用户生成 kubeconfig 文件。

另外请注意

  1. ca.crt 证书嵌入到所有 kubeconfig 文件中。
  2. 如果给定的 kubeconfig 文件存在,并且其内容被评估为符合上述规范,则将使用现有文件,并跳过给定 kubeconfig 的生成阶段
  3. 如果 kubeadm 在 ExternalCA 模式下运行;所有必需的 kubeconfig 也必须由用户提供,因为 kubeadm 无法自行生成任何它们
  4. 如果 kubeadm 在 --dry-run 模式下执行,kubeconfig 文件将写入临时文件夹
  5. 可以通过 kubeadm init phase kubeconfig all 命令单独调用 kubeconfig 文件的生成。

为控制平面组件生成静态 Pod manifest

Kubeadm 将控制平面组件的静态 Pod manifest 文件写入 /etc/kubernetes/manifests。kubelet 在启动时会监视此目录以创建 Pod。

静态 Pod manifest 共享一组通用属性

  • 所有静态 Pod 都部署在 kube-system 命名空间中

  • 所有静态 Pod 都具有 tier:control-planecomponent:{component-name} 标签

  • 所有静态 Pod 都使用 system-node-critical 优先级类

  • 所有静态 Pod 都设置 hostNetwork: true,以允许在配置网络之前启动控制平面;因此

    • 控制器管理器和调度器用来引用 API 服务器的 address127.0.0.1
    • 如果 etcd 服务器本地设置,etcd-server 地址将设置为 127.0.0.1:2379
  • 控制器管理器和调度器均启用 leader election

  • 控制器管理器和调度器将引用具有各自唯一身份的 kubeconfig 文件

  • 所有静态 Pod 都会获得您指定的任何额外标志或补丁,如 传递自定义参数给控制平面组件中所述

  • 所有静态 Pod 都会获得用户指定的任何额外卷(Host path)

请注意

  1. 默认情况下,所有镜像都将从 registry.k8s.io 拉取。有关自定义镜像仓库,请参阅 使用自定义镜像
  2. 如果 kubeadm 在 --dry-run 模式下执行,静态 Pod 文件将写入临时文件夹
  3. 可以通过 kubeadm init phase control-plane all 命令单独调用控制平面组件的静态 Pod manifest 生成。

API 服务器

API 服务器的静态 Pod manifest 受用户提供的以下参数影响

  • apiserver-advertise-addressapiserver-bind-port 用于绑定;如果未提供,则这些值默认为机器上的默认网络接口的 IP 地址和端口 6443
  • 用于服务的 service-cluster-ip-range
  • 如果指定了外部 etcd 服务器,则为 etcd-servers 地址和相关的 TLS 设置(etcd-cafile, etcd-certfile, etcd-keyfile);如果未提供外部 etcd 服务器,则使用本地 etcd(通过主机网络)
  • 如果指定了云提供商,则配置相应的 --cloud-provider 参数,如果存在此类文件,则配置 --cloud-config 路径(此功能是实验性的,alpha 版本,未来版本中将被移除)

其他无条件设置的 API 服务器标志是

  • --insecure-port=0 以避免对 api 服务器进行不安全连接

  • --enable-bootstrap-token-auth=true 以启用 BootstrapTokenAuthenticator 认证模块。有关更多详细信息,请参阅 TLS 引导

  • --allow-privileged 设置为 true(例如 kube proxy 所需)

  • --requestheader-client-ca-file 设置为 front-proxy-ca.crt

  • --enable-admission-plugins 设置为

  • --kubelet-preferred-address-types 设置为 InternalIP,ExternalIP,Hostname; 这使得 kubectl logs 以及其他 API 服务器-kubelet 通信在节点主机名无法解析的环境中能够正常工作

  • 用于使用前续步骤中生成的证书的标志

    • --client-ca-file 设置为 ca.crt
    • --tls-cert-file 设置为 apiserver.crt
    • --tls-private-key-file 设置为 apiserver.key
    • --kubelet-client-certificate 设置为 apiserver-kubelet-client.crt
    • --kubelet-client-key 设置为 apiserver-kubelet-client.key
    • --service-account-key-file 设置为 sa.pub
    • --requestheader-client-ca-file 设置为 front-proxy-ca.crt
    • --proxy-client-cert-file 设置为 front-proxy-client.crt
    • --proxy-client-key-file 设置为 front-proxy-client.key
  • 用于保护前端代理(API 聚合)通信的其他标志

    • --requestheader-username-headers=X-Remote-User
    • --requestheader-group-headers=X-Remote-Group
    • --requestheader-extra-headers-prefix=X-Remote-Extra-
    • --requestheader-allowed-names=front-proxy-client

控制器管理器

控制器管理器的静态 Pod manifest 受用户提供的以下参数影响

  • 如果调用 kubeadm 时指定了 --pod-network-cidr,则通过设置来启用某些 CNI 网络插件所需的子网管理器功能

    • --allocate-node-cidrs=true
    • --cluster-cidr--node-cidr-mask-size 标志,根据给定的 CIDR 进行设置

其他无条件设置的标志是

  • --controllers 启用所有默认控制器,加上用于 TLS 引导的 BootstrapSignerTokenCleaner 控制器。有关更多详细信息,请参阅 TLS 引导

  • --use-service-account-credentials 设置为 true

  • 用于使用前续步骤中生成的证书的标志

    • --root-ca-file 设置为 ca.crt
    • --cluster-signing-cert-file 设置为 ca.crt,如果外部 CA 模式被禁用,否则设置为 ""
    • --cluster-signing-key-file 设置为 ca.key,如果外部 CA 模式被禁用,否则设置为 ""
    • --service-account-private-key-file 设置为 sa.key

调度器

调度器的静态 Pod manifest 不受用户提供的参数影响。

生成本地 etcd 的静态 Pod manifest

如果您指定了外部 etcd,此步骤将被跳过,否则 kubeadm 将生成一个用于创建本地 etcd 实例的静态 Pod manifest 文件,该实例具有以下属性

  • 监听 localhost:2379 并使用 HostNetwork=true
  • dataDirhostPath 挂载到主机的​​文件系统
  • 用户指定的任何额外标志

请注意

  1. 默认情况下,etcd 容器镜像将从 registry.gcr.io 拉取。有关自定义镜像仓库,请参阅 使用自定义镜像
  2. 如果您在 --dry-run 模式下运行 kubeadm,etcd 静态 Pod manifest 将写入临时文件夹。
  3. 您可以使用 kubeadm init phase etcd local 命令直接调用本地 etcd 的静态 Pod manifest 生成。

等待控制平面启动

在控制平面节点上,kubeadm 最多等待 4 分钟,直到控制平面组件和 kubelet 可用。它通过对相应的组件 /healthz/livez 端点执行健康检查来完成此操作。

在控制平面启动后,kubeadm 将完成以下段落中描述的任务。

将 kubeadm ClusterConfiguration 保存到 ConfigMap 以供后续引用

kubeadm 将传递给 kubeadm init 的配置保存在 kube-system 命名空间下的名为 kubeadm-config 的 ConfigMap 中。

这将确保将来执行的 kubeadm 操作(例如 kubeadm upgrade)能够确定集群的实际/当前状态,并基于该数据做出新决策。

请注意

  1. 在保存 ClusterConfiguration 之前,令牌等敏感信息将从配置中剥离
  2. 可以通过命令 kubeadm init phase upload-config 单独调用控制平面节点配置的上传。

将节点标记为控制平面

一旦控制平面可用,kubeadm 将执行以下操作

  • 使用 node-role.kubernetes.io/control-plane="" 标签标记节点为控制平面
  • 使用 node-role.kubernetes.io/control-plane:NoSchedule 污点标记节点

请注意,标记控制平面节点的阶段可以通过命令 kubeadm init phase mark-control-plane 单独调用。

配置节点的 TLS 引导

Kubeadm 使用 通过引导令牌进行认证 来将新节点加入现有集群;有关更多详细信息,请参阅 设计提案

kubeadm init 确保一切都已正确配置以用于此过程,这包括以下步骤以及如前段所述设置 API 服务器和控制器标志。

创建引导令牌

kubeadm init 创建第一个引导令牌,该令牌要么自动生成,要么由用户通过 --token 标志提供;如引导令牌规范中所记录,令牌应以 bootstrap-token-<token-id> 的名称保存在 kube-system 命名空间下的 secret 中。

请注意

  1. kubeadm init 创建的默认令牌将用于验证 TLS 引导过程中的临时用户;这些用户将是 system:bootstrappers:kubeadm:default-node-token 组的成员
  2. 令牌的有效性有限,默认为 24 小时(可以通过 —token-ttl 标志更改间隔)
  3. 可以使用 kubeadm token 命令创建其他令牌,该命令还提供其他有用的令牌管理功能。

允许加入的节点调用 CSR API

Kubeadm 确保 system:bootstrappers:kubeadm:default-node-token 组中的用户能够访问证书签名 API。

这是通过在上述组和默认 RBAC 角色 system:node-bootstrapper 之间创建名为 kubeadm:kubelet-bootstrap 的 ClusterRoleBinding 来实现的。

设置新引导令牌的自动批准

Kubeadm 确保引导令牌的 CSR 请求将被 csrapprover 控制器自动批准。

这是通过在 system:bootstrappers:kubeadm:default-node-token 组和默认角色 system:certificates.k8s.io:certificatesigningrequests:nodeclient 之间创建名为 kubeadm:node-autoapprove-bootstrap 的 ClusterRoleBinding 来实现的。

角色 system:certificates.k8s.io:certificatesigningrequests:nodeclient 也应被创建,授予对 /apis/certificates.k8s.io/certificatesigningrequests/nodeclient 的 POST 权限。

设置节点证书自动批准轮换

Kubeadm 确保节点的证书轮换已启用,并且新节点证书请求将被 csrapprover 控制器自动批准。

这是通过在 system:nodes 组和默认角色 system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 之间创建名为 kubeadm:node-autoapprove-certificate-rotation 的 ClusterRoleBinding 来实现的。

创建公共 cluster-info ConfigMap

此阶段将在 kube-public 命名空间中创建 cluster-info ConfigMap。

此外,它还会创建一个 Role 和一个 RoleBinding,授予未认证用户(即 RBAC 组 system:unauthenticated 中的用户)对 ConfigMap 的访问权限。

安装插件

Kubeadm 通过 API 服务器安装内部 DNS 服务器和 kube-proxy 插件组件。

proxy

kube-system 命名空间中为 kube-proxy 创建了一个 ServiceAccount;然后 kube-proxy 作为 DaemonSet 部署

  • 到控制平面的凭证(ca.crttoken)来自 ServiceAccount
  • API 服务器的位置(URL)来自 ConfigMap
  • kube-proxy ServiceAccount 被绑定到 system:node-proxier ClusterRole 中的权限

DNS

  • CoreDNS 服务因与旧版 kube-dns 插件兼容性原因而命名为 kube-dns

  • kube-system 命名空间中为 CoreDNS 创建了一个 ServiceAccount。

  • coredns ServiceAccount 被绑定到 system:coredns ClusterRole 中的权限

在 Kubernetes 1.21 版本中,使用 kubeadm 的 kube-dns 支持已被移除。即使相关 Service 被命名为 kube-dns,您仍然可以使用 CoreDNS 与 kubeadm。

kubeadm join 阶段内部设计

kubeadm init 类似,kubeadm join 的内部工作流程也包含一系列原子工作任务。

这分为发现(让节点信任 Kubernetes API Server)和 TLS 引导(让 Kubernetes API Server 信任节点)。

请参阅 通过引导令牌进行认证 或相应的 设计提案

预检检查

kubeadm 在启动 join 之前执行一系列预检检查,目的是验证先决条件并避免常见的集群启动问题。

另外请注意

  1. kubeadm join 的预检检查基本上是 kubeadm init 预检检查的一个子集
  2. 如果您正在加入 Windows 节点,Linux 特定的控件将被跳过。
  3. 在任何情况下,用户都可以通过 --ignore-preflight-errors 选项跳过特定的预检检查(或最终所有预检检查)。

发现 cluster-info

有两种主要的发现方案。第一种是使用共享令牌以及 API 服务器的 IP 地址。第二种是提供一个文件(该文件是标准 kubeconfig 文件的子集)。

共享令牌发现

如果使用 --discovery-token 调用 kubeadm join,则使用令牌发现;在这种情况下,节点基本上从 kube-public 命名空间中的 cluster-info ConfigMap 中检索集群 CA 证书。

为了防止“中间人”攻击,采取了几个步骤

  • 首先,通过不安全连接检索 CA 证书(这是可能的,因为 kubeadm init 被授予了对 system:unauthenticated 用户的 cluster-info 访问权限)

  • 然后,CA 证书经过以下验证步骤

    • 基本验证:使用令牌 ID 对 JWT 签名进行验证
    • 公钥验证:使用提供的 --discovery-token-ca-cert-hash。此值在 kubeadm init 的输出中可用,或者可以使用标准工具计算(哈希是根据 Subject Public Key Info (SPKI) 对象的字节计算的,如 RFC7469 中所述)。--discovery-token-ca-cert-hash 标志可以重复多次以允许一个以上的公钥。
    • 作为额外的验证,通过安全连接检索 CA 证书,然后与最初检索的 CA 进行比较

文件/https 发现

如果使用 --discovery-file 调用 kubeadm join,则使用文件发现;此文件可以是本地文件,也可以通过 HTTPS URL 下载;对于 HTTPS,主机的​​安装 CA 捆绑包用于验证连接。

对于文件发现,集群 CA 证书包含在文件本身中;事实上,发现文件是一个只有 servercertificate-authority-data 属性设置的 kubeconfig 文件,如 kubeadm join 参考文档中所述;当与集群建立连接时,kubeadm 会尝试访问 cluster-info ConfigMap,如果可用,则使用它。

TLS 引导

一旦知道了集群信息,就会写入 bootstrap-kubelet.conf 文件,从而允许 kubelet 进行 TLS 引导。

TLS 引导机制使用共享令牌临时向 Kubernetes API Server 进行身份验证,以提交一个证书签名请求 (CSR) 来生成本地创建的密钥对。

然后,该请求会自动批准,操作完成,保存用于 kubelet 加入集群的 ca.crt 文件和 kubelet.conf 文件,同时删除 bootstrap-kubelet.conf

kubeadm upgrade 工作流程内部设计

kubeadm upgrade 具有用于处理 kubeadm 创建的 Kubernetes 集群升级的子命令。您必须在控制平面节点上运行 kubeadm upgrade apply(您可以选择其中一个);这将启动升级过程。然后,您在所有剩余节点(工作节点和控制平面节点)上运行 kubeadm upgrade node

kubeadm upgrade applykubeadm upgrade node 都具有 phase 子命令,可访问升级过程的内部阶段。有关更多详细信息,请参阅 kubeadm upgrade phase

其他实用的升级命令是 kubeadm upgrade plankubeadm upgrade diff

所有升级子命令都支持传递配置文件。

kubeadm upgrade plan

您可以在运行 kubeadm upgrade apply 之前选择性地运行 kubeadm upgrade planplan 子命令检查可用于升级的版本,并验证当前集群是否可升级。

kubeadm upgrade diff

这显示了将应用于现有控制平面节点静态 Pod manifest 的差异。更详细的方式是运行 kubeadm upgrade apply --dry-runkubeadm upgrade node --dry-run

kubeadm upgrade apply

kubeadm upgrade apply 准备集群以升级所有节点,并升级运行它的控制平面节点。它执行的步骤是

  • kubeadm initkubeadm join 一样运行预检检查,确保容器镜像已下载且集群状态良好,可以升级。
  • 升级磁盘上 /etc/kubernetes/manifests 中的控制平面 manifest 文件,并在文件更改时等待 kubelet 重启组件。
  • 将更新的 kubeadm 和 kubelet 配置上传到集群中的 kubeadm-configkubelet-config ConfigMaps(都在 kube-system 命名空间中)。
  • /var/lib/kubelet/config.yaml 中写入此节点的更新的 kubelet 配置,并读取节点的 /var/lib/kubelet/instance-config.yaml 文件,将 containerRuntimeEndpoint 等字段从此实例配置合并到 /var/lib/kubelet/config.yaml 中。
  • 配置 bootstrap token 和 cluster-info ConfigMap 以支持 RBAC 规则。这与 kubeadm init 阶段相同,并确保集群继续支持使用 bootstrap token 加入的节点。
  • 有条件地升级 kube-proxy 和 CoreDNS 插件,前提是集群中所有现有的 kube-apiservers 已升级到目标版本。
  • 执行任何升级后任务,例如清理特定于版本的已弃用功能。

kubeadm upgrade node

kubeadm upgrade node 在集群升级开始后(通过运行 kubeadm upgrade apply)升级单个控制平面或工作节点。该命令通过检查文件 /etc/kubernetes/manifests/kube-apiserver.yaml 是否存在来检测节点是否为控制平面节点。找到该文件后,kubeadm 工具推断该节点上有一个正在运行的 kube-apiserver Pod。

  • kubeadm upgrade apply 一样运行预检检查。
  • 对于控制平面节点,升级磁盘上 /etc/kubernetes/manifests 中的控制平面 manifest 文件,并在文件更改时等待 kubelet 重启组件。
  • /var/lib/kubelet/config.yaml 中写入此节点的更新的 kubelet 配置,并读取节点的 /var/lib/kubelet/instance-config.yaml 文件,将 containerRuntimeEndpoint 等字段从此实例配置合并到 /var/lib/kubelet/config.yaml 中。
  • (对于控制平面节点) 有条件地升级 kube-proxy 和 CoreDNS 插件,前提是集群中所有现有的 API 服务器都已升级到目标版本。
  • 执行任何升级后任务,例如清理特定于版本的已弃用功能。

kubeadm reset 工作流程内部设计

您可以在之前执行过 kubeadm 命令的节点上使用 kubeadm reset 子命令。此子命令执行 **尽力而为** 的节点清理。如果某些操作失败,您必须干预并执行手动清理。

该命令支持阶段。有关更多详细信息,请参阅 kubeadm reset phase

该命令支持配置文件。

此外

  • IPVS、iptables 和 nftables 规则 **不会** 被清理。
  • CNI(网络插件)配置 **不会** 被清理。
  • 用户主目录中的 .kube/ **不会** 被清理。

该命令包含以下阶段

  • 在节点上运行预检检查以确定其是否健康。
  • 对于控制平面节点,移除任何本地 etcd 成员数据。
  • 停止 kubelet。
  • 停止正在运行的容器。
  • 卸载 /var/lib/kubelet 中任何已挂载的目录。
  • 删除 kubeadm 在 /var/lib/kubelet/etc/kubernetes 中管理的所有文件和目录。
最后修改时间:2025 年 7 月 4 日太平洋标准时间晚上 11:28:添加 NodeLocalCRISocket 升级到 Beta 版的文档 (0135b1b08b)