實現細節

特性狀態: 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)