實作細節

功能狀態: Kubernetes v1.10 [stable]

kubeadm initkubeadm join 一起為從頭開始建立裸機 Kubernetes 叢集提供了良好的使用者體驗,這符合最佳實務。但是,kubeadm *如何*做到這一點可能並不顯而易見。

本文檔提供了幕後發生情況的更多詳細資訊,旨在分享有關 Kubernetes 叢集最佳實務的知識。

核心設計原則

kubeadm initkubeadm join 設定的叢集應為

  • 安全:它應採用最新的最佳實務,例如
    • 強制執行 RBAC
    • 使用節點授權器
    • 在控制平面元件之間使用安全通訊
    • 在 API 伺服器和 kubelet 之間使用安全通訊
    • 鎖定 kubelet API
    • 鎖定對系統元件(如 kube-proxy 和 CoreDNS)的 API 存取
    • 鎖定 Bootstrap 權杖可以存取的內容
  • 使用者友善:使用者不應執行超過幾個指令
    • kubeadm init
    • export KUBECONFIG=/etc/kubernetes/admin.conf
    • kubectl apply -f <network-plugin-of-choice.yaml>
    • kubeadm join --token <token> <endpoint>:<port>
  • 可擴展:
    • 它*不*應偏愛任何特定的網路提供者。設定叢集網路超出範圍
    • 它應提供使用組態檔自訂各種參數的可能性

常數與眾所周知的值和路徑

為了降低複雜性並簡化建構於 kubeadm 之上的更高層級工具的開發,它對眾所周知的路徑和檔案名稱使用有限的常數值集。

Kubernetes 目錄 /etc/kubernetes 是應用程式中的常數,因為它顯然是大多數情況下的給定路徑,也是最直觀的位置;其他常數路徑和檔案名稱為

  • /etc/kubernetes/manifests 作為 kubelet 應尋找靜態 Pod 資訊清單的路徑。靜態 Pod 資訊清單的名稱為

    • 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 子指令需要不同的組態檔案 kind。例如,kubeadm initInitConfigurationkubeadm joinJoinConfigurationkubeadm upgradeUpgradeConfigurationkubeadm resetResetConfiguration

指令 kubeadm config migrate 可用於將較舊格式的組態檔案遷移到較新(目前)的組態格式。kubeadm 工具僅支援從已棄用的組態格式遷移到目前格式。

請參閱kubeadm 組態參考頁面以取得更多詳細資訊。

kubeadm init 工作流程內部設計

kubeadm init 由一系列要執行的原子工作任務組成,如 kubeadm init 內部工作流程中所述。

kubeadm init phase 指令允許使用者個別調用每個任務,最終提供可重複使用和可組合的 API/工具箱,可供其他 Kubernetes 引導工具、任何 IT 自動化工具或進階使用者用於建立自訂叢集。

預檢檢查

Kubeadm 在啟動初始化之前執行一組預檢檢查,旨在驗證先決條件並避免常見的叢集啟動問題。使用者可以使用 --ignore-preflight-errors 選項略過特定的預檢檢查或所有預檢檢查。

  • [警告] 如果要使用的 Kubernetes 版本(使用 --kubernetes-version 旗標指定)比 kubeadm CLI 版本至少高一個次要版本。
  • Kubernetes 系統需求
    • 如果在 Linux 上執行
      • [錯誤] 如果核心版本低於最低要求版本
      • [錯誤] 如果未設定所需的 cgroups 子系統
  • [錯誤] 如果 CRI 端點沒有回應
  • [錯誤] 如果使用者不是 root
  • [錯誤] 如果機器主機名稱不是有效的 DNS 子網域
  • [警告] 如果無法透過網路查詢找到主機名稱
  • [錯誤] 如果 kubelet 版本低於 kubeadm 支援的最低 kubelet 版本 (目前次要版本 -1)
  • [錯誤] 如果 kubelet 版本至少比要求的控制平面版本高一個次要版本 (不支援的版本偏差)
  • [警告] 如果 kubelet 服務不存在或已停用
  • [警告] 如果 firewalld 處於啟用狀態
  • [錯誤] 如果使用了 API 伺服器綁定埠或埠 10250/10251/10252
  • [錯誤] 如果 /etc/kubernetes/manifest 資料夾已存在且非空
  • [錯誤] 如果 swap 已開啟
  • [錯誤] 如果命令路徑中不存在 ipiptablesmountnsenter 命令
  • [警告] 如果命令路徑中不存在 ethtooltctouch 命令
  • [警告] 如果 API 伺服器、控制器管理員、排程器的額外引數標記包含一些無效選項
  • [警告] 如果連線到 https://API.AdvertiseAddress:API.BindPort 透過了 Proxy
  • [警告] 如果連線到 services 子網路透過了 Proxy (僅檢查第一個位址)
  • [警告] 如果連線到 Pods 子網路透過了 Proxy (僅檢查第一個位址)
  • 如果提供了外部 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 服務的內部叢集 IP (服務 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.svckubernetes.defaultkubernetes
    • 節點名稱
    • --apiserver-advertise-address
    • 使用者指定的其他替代名稱
  • API 伺服器連線到 kubelet 的用戶端憑證,以確保安全,使用 ca.crt 作為 CA 產生,並儲存到 apiserver-kubelet-client.crt 檔案及其私密金鑰 apiserver-kubelet-client.key。此憑證應位於 system:masters 組織中

  • 用於簽署 ServiceAccount 權杖的私密金鑰,儲存到 sa.key 檔案及其公開金鑰 sa.pub

  • 前端 Proxy 的憑證授權單位,儲存到 front-proxy-ca.crt 檔案及其金鑰 front-proxy-ca.key

  • 前端 Proxy 用戶端的用戶端憑證,使用 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,這也表示 controller-manager 中的 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。在此檔案內,有一個 bootstrap-token 或嵌入式用戶端憑證,用於向叢集驗證此節點。

    此用戶端憑證應

    • 位於 system:nodes 組織中,這是 節點授權模組的要求
    • 具有通用名稱 (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-adminkubeadm:cluster-admins 是由 kubeadm 管理的群組。它在 kubeadm init 期間使用 super-admin.conf 檔案 (不需要 RBAC) 繫結到 cluster-admin ClusterRole。此 admin.conf 檔案必須保留在控制平面節點上,且不應與其他使用者共用。

kubeadm init 期間,會產生另一個 kubeconfig 檔案並儲存在 /etc/kubernetes/super-admin.conf 中。此檔案包含一個憑證,其 Subject: O = system:masters, CN = kubernetes-super-adminsystem:masters 是一個超級使用者群組,它繞過 RBAC,並使 super-admin.conf 在因 RBAC 設定錯誤而鎖定叢集時很有用。super-admin.conf 檔案必須儲存在安全的位置,且不應與其他使用者共用。

有關 RBAC 和內建 ClusterRole 和群組的更多資訊,請參閱 RBAC 使用者面向的角色繫結

您可以執行 kubeadm kubeconfig user 來為其他使用者產生 kubeconfig 檔案。

另請注意

  1. ca.crt 憑證嵌入在所有 kubeconfig 檔案中。
  2. 如果給定的 kubeconfig 檔案存在,並且評估其內容符合上述規格,則將使用現有檔案,並跳過給定 kubeconfig 的產生階段
  3. 如果 kubeadm 在 ExternalCA 模式下執行,則也必須由使用者提供所有需要的 kubeconfig,因為 kubeadm 無法自行產生任何 kubeconfig
  4. 如果 kubeadm 在 --dry-run 模式下執行,kubeconfig 檔案將寫入暫存資料夾中
  5. 可以使用 kubeadm init phase kubeconfig all 命令個別調用 kubeconfig 檔案的產生

為控制平面元件產生靜態 Pod 清單

Kubeadm 將控制平面元件的靜態 Pod 清單檔案寫入 /etc/kubernetes/manifests。kubelet 監看此目錄,以便在啟動時建立 Pod。

靜態 Pod 清單共用一組通用屬性

  • 所有靜態 Pod 都部署在 kube-system 命名空間中

  • 所有靜態 Pod 都取得 tier:control-planecomponent:{component-name} 標籤

  • 所有靜態 Pod 都使用 system-node-critical 優先順序類別

  • hostNetwork: true 設定在所有靜態 Pod 上,以允許在設定網路之前啟動控制平面;因此

    • 控制器管理員和排程器用來參考 API 伺服器的 address127.0.0.1
    • 如果在本機設定 etcd 伺服器,則 etcd-server 位址將設定為 127.0.0.1:2379
  • 控制器管理員和排程器都啟用了領導者選舉

  • 控制器管理員和排程器將參考具有各自唯一身分識別的 kubeconfig 檔案

  • 所有靜態 Pod 都會取得您指定的任何額外標記或修補程式,如 將自訂引數傳遞到控制平面元件中所述

  • 所有靜態 Pod 都會取得使用者指定的任何額外磁碟區 (主機路徑)

請注意

  1. 所有映像檔預設都將從 registry.k8s.io 中提取。有關自訂映像檔儲存庫,請參閱使用自訂映像檔
  2. 如果 kubeadm 在 --dry-run 模式下執行,靜態 Pod 檔案將寫入暫存資料夾中
  3. 可以使用 kubeadm init phase control-plane all 命令個別調用控制平面元件的靜態 Pod 清單產生

API 伺服器

API 伺服器的靜態 Pod 清單受使用者提供的以下參數影響

  • 要綁定的 apiserver-advertise-addressapiserver-bind-port;如果未提供,這些值預設為機器上預設網路介面的 IP 位址和埠 6443
  • 用於服務的 service-cluster-ip-range
  • 如果指定了外部 etcd 伺服器,則為 etcd-servers 位址和相關 TLS 設定 (etcd-cafileetcd-certfileetcd-keyfile);如果未提供外部 etcd 伺服器,將使用本機 etcd (透過主機網路)
  • 如果指定了雲端供應商,則會設定對應的 --cloud-provider 參數,以及 --cloud-config 路徑 (如果此類檔案存在) (這是實驗性、Alpha 版本,將在未來版本中移除)

其他無條件設定的 API 伺服器標記為

  • --insecure-port=0,以避免與 API 伺服器的不安全連線

  • --enable-bootstrap-token-auth=true,以啟用 BootstrapTokenAuthenticator 驗證模組。有關更多詳細資訊,請參閱 TLS 啟動引導

  • --allow-privilegedtrue (例如,kube Proxy 需要)

  • --requestheader-client-ca-filefront-proxy-ca.crt

  • --enable-admission-plugins

  • --kubelet-preferred-address-typesInternalIP,ExternalIP,Hostname;,這使得 kubectl logs 和其他 API 伺服器-kubelet 通訊在節點主機名稱無法解析的環境中運作

  • 用於使用先前步驟中產生的憑證的標記

    • --client-ca-fileca.crt
    • --tls-cert-fileapiserver.crt
    • --tls-private-key-fileapiserver.key
    • --kubelet-client-certificateapiserver-kubelet-client.crt
    • --kubelet-client-keyapiserver-kubelet-client.key
    • --service-account-key-filesa.pub
    • --requestheader-client-ca-filefront-proxy-ca.crt
    • --proxy-client-cert-filefront-proxy-client.crt
    • --proxy-client-key-filefront-proxy-client.key
  • 用於保護前端 Proxy (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 清單受使用者提供的以下參數影響

  • 如果調用 kubeadm 時指定了 --pod-network-cidr,則透過設定以下內容啟用某些 CNI 網路外掛程式所需的子網路管理員功能

    • --allocate-node-cidrs=true
    • 根據給定的 CIDR 的 --cluster-cidr--node-cidr-mask-size 標記

其他無條件設定的標記為

  • --controllers 啟用所有預設控制器,加上用於 TLS 啟動引導的 BootstrapSignerTokenCleaner 控制器。有關更多詳細資訊,請參閱 TLS 啟動引導

  • --use-service-account-credentialstrue

  • 用於使用先前步驟中產生的憑證的標記

    • --root-ca-fileca.crt
    • --cluster-signing-cert-fileca.crt (如果停用外部 CA 模式),否則為 ""
    • --cluster-signing-key-fileca.key (如果停用外部 CA 模式),否則為 ""
    • --service-account-private-key-filesa.key

排程器

排程器的靜態 Pod 清單不受使用者提供的參數影響。

為本機 etcd 產生靜態 Pod 清單

如果您指定了外部 etcd,則將跳過此步驟,否則 kubeadm 會產生靜態 Pod 清單檔案,以建立在本機 etcd 執行個體,該執行個體在具有以下屬性的 Pod 中執行

  • 監聽 localhost:2379 並使用 HostNetwork=true
  • dataDir 到主機的檔案系統進行 hostPath 掛載
  • 使用者指定的任何額外標記

請注意

  1. etcd 容器映像檔預設將從 registry.gcr.io 中提取。有關自訂映像檔儲存庫,請參閱使用自訂映像檔
  2. 如果您在 --dry-run 模式下執行 kubeadm,則 etcd 靜態 Pod 清單將寫入暫存資料夾中。
  3. 您可以使用 kubeadm init phase etcd local 命令直接調用本機 etcd 的靜態 Pod 清單產生。

等待控制平面啟動

在控制平面節點上,kubeadm 最多等待 4 分鐘,讓控制平面元件和 kubelet 可用。它透過對各個元件 /healthz/livez 端點執行健康檢查來完成此操作。

控制平面啟動後,kubeadm 會完成以下段落中描述的工作。

將 kubeadm ClusterConfiguration 儲存在 ConfigMap 中以供日後參考

kubeadm 將傳遞到 kubeadm init 的組態儲存在名為 kubeadm-config 的 ConfigMap 中,位於 kube-system 命名空間下。

這將確保未來執行的 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-Bootstrapping 以加入節點

Kubeadm 使用 使用 Bootstrap 權杖進行驗證,以將新節點加入現有叢集;有關更多詳細資訊,另請參閱 設計提案

kubeadm init 確保為此程序正確設定所有內容,這包括以下步驟以及設定先前段落中已描述的 API 伺服器和控制器標記。

建立 Bootstrap 權杖

kubeadm init 建立第一個 Bootstrap 權杖,可以自動產生或由使用者使用 --token 標記提供;如 Bootstrap 權杖規格中所述,權杖應儲存為機密,名稱為 bootstrap-token-<token-id>,位於 kube-system 命名空間下。

請注意

  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 來實作的。

設定新 Bootstrap 權杖的自動核准

Kubeadm 確保 Bootstrap 權杖的 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 控制器自動核准其 CSR 請求。

這是透過在 system:nodes 群組和預設角色 system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 之間建立名為 kubeadm:node-autoapprove-certificate-rotation 的 ClusterRoleBinding 來實作的。

建立公開叢集資訊 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 的支援。即使相關服務命名為 kube-dns,您也可以將 CoreDNS 與 kubeadm 搭配使用。

kubeadm join 階段內部設計

kubeadm init 類似,kubeadm join 內部工作流程也包含要執行的一系列原子工作任務。

這分為探索 (讓節點信任 Kubernetes API 伺服器) 和 TLS 啟動引導 (讓 Kubernetes API 伺服器信任節點)。

請參閱 使用 Bootstrap 權杖進行驗證或對應的 設計提案

預檢檢查

kubeadm 在開始加入之前執行一組預檢,目的是驗證先決條件並避免常見的叢集啟動問題。

另請注意

  1. kubeadm join 預檢基本上是 kubeadm init 預檢的子集
  2. 如果您要加入 Windows 節點,則會跳過特定於 Linux 的控制項。
  3. 在任何情況下,使用者都可以使用 --ignore-preflight-errors 選項跳過特定的預檢 (或最終跳過所有預檢)。

探索叢集資訊

有 2 種主要的探索方案。第一種是搭配 API 伺服器的 IP 位址使用共用權杖。第二種是提供檔案 (這是標準 kubeconfig 檔案的子集)。

共用權杖探索

如果調用 kubeadm join 時使用 --discovery-token,則使用權杖探索;在這種情況下,節點基本上從 kube-public 命名空間中的 cluster-info ConfigMap 擷取叢集 CA 憑證。

為了防止「中間人」攻擊,採取了幾個步驟

  • 首先,透過不安全的連線擷取 CA 憑證 (這是可行的,因為 kubeadm init 被授予 cluster-info 使用者對 system:unauthenticated 的存取權)

  • 然後,CA 憑證會經過以下驗證步驟

    • 基本驗證:使用權杖 ID 對 JWT 簽章進行驗證
    • 公開金鑰驗證:使用提供的 --discovery-token-ca-cert-hash。此值可在 kubeadm init 的輸出中找到,或可以使用標準工具計算 (雜湊是根據 RFC7469 中的主體公開金鑰資訊 (SPKI) 物件的位元組計算的)。--discovery-token-ca-cert-hash 標記可以重複多次,以允許多個公開金鑰。
    • 作為額外的驗證,透過安全連線擷取 CA 憑證,然後與最初擷取的 CA 進行比較

檔案/HTTPS 探索

如果調用 kubeadm join 時使用 --discovery-file,則使用檔案探索;此檔案可以是本機檔案,也可以透過 HTTPS URL 下載;如果是 HTTPS,則使用主機安裝的 CA 捆綁包來驗證連線。

使用檔案探索時,叢集 CA 憑證會提供到檔案本身中;實際上,探索檔案是一個 kubeconfig 檔案,僅設定了 kubeadm join 參考文件中描述的 servercertificate-authority-data 屬性;當與叢集的連線建立時,kubeadm 會嘗試存取 cluster-info ConfigMap,如果可用,則會使用它。

TLS 啟動引導

一旦叢集資訊已知,就會寫入檔案 bootstrap-kubelet.conf,從而允許 kubelet 執行 TLS 啟動引導。

TLS 啟動引導機制使用共用權杖與 Kubernetes API 伺服器進行臨時驗證,以提交本機建立的金鑰對的憑證簽署請求 (CSR)。

然後自動核准請求,並且操作完成,儲存 ca.crt 檔案和 kubelet.conf 檔案供 kubelet 用於加入叢集,同時刪除 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 清單的差異。執行相同操作的更詳細方法是執行 kubeadm upgrade apply --dry-runkubeadm upgrade node --dry-run

kubeadm upgrade apply

kubeadm upgrade apply 為所有節點的升級準備叢集,並升級執行它的控制平面節點。它執行的步驟是

  • 執行預檢,類似於 kubeadm initkubeadm join,確保下載容器映像檔,且叢集處於良好的可升級狀態。
  • 升級 /etc/kubernetes/manifests 中磁碟上的控制平面清單檔案,並等待 kubelet 重新啟動元件 (如果檔案已變更)。
  • 將更新的 kubeadm 和 kubelet 組態上傳到 kubeadm-configkubelet-config ConfigMap (均位於 kube-system 命名空間中) 的叢集中。
  • 在此節點的 /var/lib/kubelet/config.yaml 中寫入更新的 kubelet 組態。
  • 設定 Bootstrap 權杖和 cluster-info ConfigMap 的 RBAC 規則。這與 kubeadm init 階段相同,並確保叢集繼續支援使用 Bootstrap 權杖加入的節點。
  • 有條件地升級 kube-proxy 和 CoreDNS 附加元件 (如果叢集中所有現有的 kube-apiserver 都已升級到目標版本)。
  • 執行任何升級後工作,例如,清理已棄用的功能 (特定於版本)。

kubeadm upgrade node

在叢集升級開始後 (透過執行 kubeadm upgrade apply),kubeadm upgrade node 升級單一控制平面或工作節點。該命令透過檢查檔案 /etc/kubernetes/manifests/kube-apiserver.yaml 是否存在來偵測節點是否為控制平面節點。在找到該檔案時,kubeadm 工具會推斷此節點上正在執行 kube-apiserver Pod。

  • 執行預檢,類似於 kubeadm upgrade apply
  • 對於控制平面節點,升級 /etc/kubernetes/manifests 中磁碟上的控制平面清單檔案,並等待 kubelet 重新啟動元件 (如果檔案已變更)。
  • 在此節點的 /var/lib/kubelet/config.yaml 中寫入更新的 kubelet 組態。
  • (對於控制平面節點) 有條件地升級 kube-proxy 和 CoreDNS 附加元件,前提是叢集中所有現有的 API 伺服器都已升級到目標版本。
  • 執行任何升級後工作,例如清理已棄用的功能 (特定於版本)。

kubeadm reset 工作流程內部設計

您可以在先前執行過 kubeadm 命令的節點上使用 kubeadm reset 子命令。此子命令對節點執行盡力而為的清理。如果某些動作失敗,您必須介入並執行手動清理。

該命令支援階段。有關更多詳細資訊,請參閱 kubeadm reset phase

該命令支援組態檔。

此外

  • IPVS、iptables 和 nftables 規則清理。
  • CNI (網路外掛程式) 組態清理。
  • 使用者主目錄中的 .kube/ 清理。

該命令具有以下階段

  • 在節點上執行預檢,以判斷其是否健康。
  • 對於控制平面節點,移除任何本機 etcd 成員資料。
  • 停止 kubelet。
  • 停止執行中的容器。
  • 卸載 /var/lib/kubelet 中任何已掛載的目錄。
  • 刪除 /var/lib/kubelet/etc/kubernetes 中由 kubeadm 管理的任何檔案和目錄。
上次修改時間:2024 年 11 月 11 日上午 11:04 PST:kubeadm:更新 1.32 的撰寫文件 (bbdb8dd9f3)