kubeadm join

此命令初始化 Kubernetes 工作节点并将其加入集群。

在要加入现有集群的任何机器上运行此命令

概要

加入 kubeadm 初始化的集群时,我们需要建立双向信任。这分为发现(让节点信任 Kubernetes 控制平面)和 TLS 引导(让 Kubernetes 控制平面信任节点)。

发现主要有两种方案。第一种是使用共享令牌以及 API 服务器的 IP 地址。第二种是提供一个文件 - 标准 kubeconfig 文件的子集。发现/kubeconfig 文件支持令牌、client-go 身份验证插件(“exec”)、“tokenFile”和“authProvider”。此文件可以是本地文件,也可以通过 HTTPS URL 下载。格式为 kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443、kubeadm join --discovery-file path/to/file.conf 或 kubeadm join --discovery-file https://url/file.conf。只能使用一种格式。如果从 URL 加载发现信息,则必须使用 HTTPS。此外,在这种情况下,将使用主机安装的 CA 包来验证连接。

如果使用共享令牌进行发现,则还应传递 --discovery-token-ca-cert-hash 标志以验证 Kubernetes 控制平面提供的根证书颁发机构 (CA) 的公钥。此标志的值指定为“<哈希类型>:<十六进制编码值>”,其中支持的哈希类型为“sha256”。哈希值是根据主题公钥信息 (SPKI) 对象的字节计算的(如 RFC7469 中所述)。此值可在“kubeadm init”的输出中找到,也可以使用标准工具计算。“--discovery-token-ca-cert-hash”标志可以重复多次,以允许多个公钥。

如果事先不知道 CA 公钥哈希值,则可以传递 --discovery-token-unsafe-skip-ca-verification 标志以禁用此验证。这会削弱 kubeadm 安全模型,因为其他节点可能会冒充 Kubernetes 控制平面。

TLS 引导机制也通过共享令牌驱动。这用于在加入节点时使用 Kubernetes 控制平面进行临时身份验证,以提交本地创建的密钥对的证书签名请求 (CSR)。默认情况下,kubeadm 将设置 Kubernetes 控制平面以自动批准这些签名请求。此令牌使用 --tls-bootstrap-token abcdef.1234567890abcdef 标志传递。

通常,这两个部分使用相同的令牌。在这种情况下,可以使用 --token 标志,而不是分别指定每个令牌。

“join [api-server-endpoint]”命令执行以下阶段

preflight              Run join pre-flight checks
control-plane-prepare  Prepare the machine for serving a control plane
  /download-certs        [EXPERIMENTAL] Download certificates shared among control-plane nodes from the kubeadm-certs Secret
  /certs                 Generate the certificates for the new control plane components
  /kubeconfig            Generate the kubeconfig for the new control plane components
  /control-plane         Generate the manifests for the new control plane components
kubelet-start          Write kubelet settings, certificates and (re)start the kubelet
control-plane-join     Join a machine as a control plane instance
  /etcd                  Add a new local etcd member
  /update-status         Register the new control-plane node into the ClusterStatus maintained in the kubeadm-config ConfigMap (DEPRECATED)
  /mark-control-plane    Mark a node as a control-plane
wait-control-plane     EXPERIMENTAL: Wait for the control plane to start
kubeadm join [api-server-endpoint] [flags]

选项

--apiserver-advertise-address 字符串

如果节点应托管新的控制平面实例,则为 API 服务器将通告其侦听的 IP 地址。如果未设置,则将使用默认网络接口。

--apiserver-bind-port int32 默认值:6443

如果节点应托管新的控制平面实例,则为 API 服务器要绑定的端口。

--certificate-key 字符串

使用此密钥解密 init 上传的证书密钥。证书密钥是一个十六进制编码的字符串,是一个大小为 32 字节的 AES 密钥。

--config 字符串

kubeadm 配置文件的路径。

--control-plane

在此节点上创建新的控制平面实例

--cri-socket 字符串

要连接的 CRI 套接字的路径。如果为空,kubeadm 将尝试自动检测此值;仅当您安装了多个 CRI 或具有非标准 CRI 套接字时才使用此选项。

--discovery-file 字符串

对于基于文件的发现,用于加载集群信息的文件或 URL。

--discovery-token 字符串

对于基于令牌的发现,用于验证从 API 服务器获取的集群信息的令牌。

--discovery-token-ca-cert-hash 字符串

对于基于令牌的发现,验证根 CA 公钥是否与此哈希值匹配(格式:“<类型>:<值>”)。

--discovery-token-unsafe-skip-ca-verification

对于基于令牌的发现,允许在没有 --discovery-token-ca-cert-hash 固定引脚的情况下加入。

--dry-run

不应用任何更改;仅输出将要执行的操作。

-h, --help

join 的帮助

--ignore-preflight-errors 字符串

其错误将显示为警告的检查列表。示例:'IsPrivilegedUser,Swap'。值“all”忽略所有检查的错误。

--node-name 字符串

指定节点名称。

--patches 字符串

包含名为“target[suffix][+patchtype].extension”的文件的目录的路径。例如,“kube-apiserver0+merge.yaml”或仅“etcd.json”。“target”可以是“kube-apiserver”、“kube-controller-manager”、“kube-scheduler”、“etcd”、“kubeletconfiguration”之一。“patchtype”可以是“strategic”、“merge”或“json”之一,它们匹配 kubectl 支持的补丁格式。默认的“patchtype”是“strategic”。“extension”必须是“json”或“yaml”。“suffix”是一个可选字符串,可用于按字母数字顺序确定首先应用哪些补丁。

--skip-phases 字符串

要跳过的阶段列表

--tls-bootstrap-token 字符串

指定用于在加入节点时使用 Kubernetes 控制平面进行临时身份验证的令牌。

--token 字符串

当未提供这些值时,将此令牌用于 discovery-token 和 tls-bootstrap-token。

从父命令继承的选项

--rootfs 字符串

【实验性】“真实”主机根文件系统的路径。

加入工作流程

kubeadm join 引导 Kubernetes 工作节点或控制平面节点并将其添加到集群。对于工作节点,此操作包括以下步骤

  1. kubeadm 从 API 服务器下载必要的集群信息。默认情况下,它使用引导令牌和 CA 密钥哈希值来验证该数据的真实性。也可以通过文件或 URL 直接发现根 CA。

  2. 一旦知道了集群信息,kubelet 就可以启动 TLS 引导过程。

    TLS 引导使用共享令牌使用 Kubernetes API 服务器进行临时身份验证以提交证书签名请求 (CSR);默认情况下,控制平面会自动签署此 CSR 请求。

  3. 最后,kubeadm 将本地 kubelet 配置为使用分配给节点的最终标识连接到 API 服务器。

对于控制平面节点,将执行其他步骤

  1. 从集群下载控制平面节点之间共享的证书(如果用户明确请求)。

  2. 生成控制平面组件清单、证书和 kubeconfig。

  3. 添加新的本地 etcd 成员。

在 kubeadm 中使用加入阶段

Kubeadm 允许您使用 kubeadm join phase 分阶段将节点加入集群。

要查看阶段和子阶段的有序列表,可以调用 kubeadm join --help。该列表将位于帮助屏幕的顶部,每个阶段旁边都有一个描述。请注意,通过调用 kubeadm join,所有阶段和子阶段都将按照此确切顺序执行。

某些阶段具有唯一的标志,因此,如果要查看可用选项列表,请添加 --help,例如

kubeadm join phase kubelet-start --help

kubeadm init phase 命令类似,kubeadm join phase 允许您使用 --skip-phases 标志跳过阶段列表。

例如

sudo kubeadm join --skip-phases=preflight --config=config.yaml
功能状态: Kubernetes v1.22 [测试版]

或者,您可以使用 JoinConfiguration 中的 skipPhases 字段。

发现要信任的集群 CA

kubeadm 发现有多种选择,每种选择都有安全权衡。适合您环境的方法取决于您如何配置节点以及您对网络和节点生命周期的安全预期。

使用 CA 固定引脚进行基于令牌的发现

这是 kubeadm 中的默认模式。在此模式下,kubeadm 下载集群配置(包括根 CA)并使用令牌对其进行验证,以及验证根 CA 公钥是否与提供的哈希值匹配,以及 API 服务器证书在根 CA 下是否有效。

CA 密钥哈希值的格式为 sha256:<hex_encoded_hash>。默认情况下,哈希值打印在 kubeadm init 命令的末尾或 kubeadm token create --print-join-command 命令的输出中。它采用标准格式(请参阅 RFC7469),也可以由第三方工具或配置系统计算。例如,使用 OpenSSL CLI

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 join --discovery-token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234..cdef 1.2.3.4:6443

对于控制平面节点

kubeadm join --discovery-token abcdef.1234567890abcdef --discovery-token-ca-cert-hash sha256:1234..cdef --control-plane 1.2.3.4:6443

您还可以使用 --certificate-key 为控制平面节点调用 join 以将证书复制到此节点,前提是使用 --upload-certs 调用了 kubeadm init 命令。

优点

  • 即使其他工作节点或网络受到攻击,也允许引导节点安全地发现控制平面节点的信任根。

  • 便于手动执行,因为所需的所有信息都包含在一个 kubeadm join 命令中。

缺点

  • CA 哈希通常在控制平面节点配置完成之前是未知的,这使得构建使用 kubeadm 的自动化配置工具变得更加困难。通过预先生成 CA,您可以解决此限制。

不使用 CA 固定进行基于令牌的发现

此模式仅依赖于对称令牌来对建立控制平面信任根的发现信息进行签名 (HMAC-SHA256)。要使用此模式,加入节点必须使用 --discovery-token-unsafe-skip-ca-verification 跳过 CA 公钥的哈希验证。如果可能,您应该考虑使用其他模式之一。

示例 kubeadm join 命令

kubeadm join --token abcdef.1234567890abcdef --discovery-token-unsafe-skip-ca-verification 1.2.3.4:6443

优点

  • 仍然可以防御许多网络级别的攻击。

  • 令牌可以提前生成并与控制平面节点和工作节点共享,然后它们可以在没有协调的情况下并行引导。这使得它可以在许多配置场景中使用。

缺点

  • 如果攻击者能够通过某些漏洞窃取引导令牌,他们可以使用该令牌(以及网络级别访问权限)向其他引导节点冒充控制平面节点。这在您的环境中可能是也可能不是一种适当的权衡。

基于文件或 HTTPS 的发现

这提供了一种带外方式来在控制平面节点和引导节点之间建立信任根。如果您正在使用 kubeadm 构建自动化配置,请考虑使用此模式。发现文件的格式是常规的 Kubernetes kubeconfig 文件。

如果发现文件不包含凭据,则将使用 TLS 发现令牌。

示例 kubeadm join 命令

  • kubeadm join --discovery-file path/to/file.conf(本地文件)

  • kubeadm join --discovery-file https://url/file.conf(远程 HTTPS URL)

优点

  • 允许引导节点安全地发现控制平面节点的信任根,即使网络或其他工作节点遭到破坏。

缺点

  • 要求您有某种方法将发现信息从控制平面节点传递到引导节点。如果发现文件包含凭据,您必须对其保密并通过安全通道传输。这可能可以通过您的云提供商或配置工具实现。

将自定义 kubelet 凭据与 kubeadm join 一起使用

要允许 kubeadm join 使用预定义的 kubelet 凭据并跳过新节点的客户端 TLS 引导和 CSR 批准

  1. 从集群中具有 /etc/kubernetes/pki/ca.key 的工作控制平面节点执行 kubeadm kubeconfig user --org system:nodes --client-name system:node:$NODE > kubelet.conf$NODE 必须设置为新节点的名称。
  2. 手动修改生成的 kubelet.conf 以调整集群名称和服务器端点,或运行 kubeadm kubeconfig user --config(它接受 InitConfiguration)。

如果您的集群没有 ca.key 文件,则必须在外部签署 kubelet.conf 中的嵌入式证书。有关其他信息,请参阅 PKI 证书和要求使用 kubeadm 进行证书管理

  1. 将生成的 kubelet.conf 复制到新节点上的 /etc/kubernetes/kubelet.conf
  2. 在新节点上使用标志 --ignore-preflight-errors=FileAvailable--etc-kubernetes-kubelet.conf 执行 kubeadm join

进一步保护您的安装

kubeadm 的默认设置可能不适用于所有人。本节介绍如何以牺牲一些可用性为代价来加强 kubeadm 安装。

关闭节点客户端证书的自动批准

默认情况下,启用了一个 CSR 自动批准器,当在身份验证时使用引导令牌时,它基本上会批准 kubelet 的任何客户端证书请求。如果您不希望集群自动批准 kubelet 客户端证书,则可以通过执行以下命令将其关闭

kubectl delete clusterrolebinding kubeadm:node-autoapprove-bootstrap

之后,kubeadm join 将阻塞,直到管理员手动批准正在进行的 CSR

  1. 使用 kubectl get csr,您可以看到原始 CSR 处于 Pending 状态。

    kubectl get csr
    

    输出类似于以下内容

    NAME                                                   AGE       REQUESTOR                 CONDITION
    node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ   18s       system:bootstrap:878f07   Pending
    
  2. kubectl certificate approve 允许管理员批准 CSR。此操作告诉证书签名控制器向请求者颁发证书,其中包含 CSR 中请求的属性。

    kubectl certificate approve node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ
    

    输出类似于以下内容

    certificatesigningrequest "node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ" approved
    
  3. 这会将 CRS 资源更改为 Active 状态。

    kubectl get csr
    

    输出类似于以下内容

    NAME                                                   AGE       REQUESTOR                 CONDITION
    node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ   1m        system:bootstrap:878f07   Approved,Issued
    

这会强制执行工作流程,即只有在运行 kubectl certificate approvekubeadm join 才会成功。

关闭对 cluster-info ConfigMap 的公共访问

为了实现使用令牌作为唯一验证信息的加入流程,默认情况下会公开一个 ConfigMap,其中包含一些用于验证控制平面节点身份所需的数据。虽然此 ConfigMap 中没有私有数据,但某些用户可能希望将其关闭。这样做将禁用使用 kubeadm join 流程的 --discovery-token 标志的功能。以下是执行此操作的步骤

  • 从 API 服务器获取 cluster-info 文件
kubectl -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}' | tee cluster-info.yaml

输出类似于以下内容

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: <ca-cert>
    server: https://<ip>:<port>
  name: ""
contexts: []
current-context: ""
preferences: {}
users: []
  • 使用 cluster-info.yaml 文件作为 kubeadm join --discovery-file 的参数。

  • 关闭对 cluster-info ConfigMap 的公共访问

kubectl -n kube-public delete rolebinding kubeadm:bootstrap-signer-clusterinfo

这些命令应该在 kubeadm init 之后但在 kubeadm join 之前运行。

将 kubeadm join 与配置文件一起使用

可以使用配置文件而不是命令行标志来配置 kubeadm join,并且某些更高级的功能可能仅作为配置文件选项可用。此文件使用 --config 标志传递,并且必须包含 JoinConfiguration 结构。在某些情况下,可能不允许将 --config 与其他标志混合使用。

可以使用 kubeadm config print 命令打印默认配置。

如果您的配置未使用最新版本,则建议您使用 kubeadm config migrate 命令进行迁移。

有关配置的字段和用法的更多信息,您可以导航到我们的 API 参考

下一步是什么

  • kubeadm init 用于引导 Kubernetes 控制平面节点。
  • kubeadm token 用于管理 kubeadm join 的令牌。
  • kubeadm reset 用于还原 kubeadm initkubeadm join 对此主机所做的任何更改。
上次修改时间:2024 年 4 月 11 日下午 1:09 PST:添加指向自定义外部证书的链接 (adc4a9a152)