實作細節
Kubernetes v1.10 [stable]
kubeadm init
和 kubeadm join
一起為從頭開始建立裸機 Kubernetes 叢集提供了良好的使用者體驗,這符合最佳實務。但是,kubeadm
*如何*做到這一點可能並不顯而易見。
本文檔提供了幕後發生情況的更多詳細資訊,旨在分享有關 Kubernetes 叢集最佳實務的知識。
核心設計原則
kubeadm init
和 kubeadm 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 init
的 InitConfiguration
、kubeadm join
的 JoinConfiguration
、kubeadm upgrade
的 UpgradeConfiguration
和 kubeadm reset
的 ResetConfiguration
。
指令 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 子系統
- 如果在 Linux 上執行
- [錯誤] 如果 CRI 端點沒有回應
- [錯誤] 如果使用者不是 root
- [錯誤] 如果機器主機名稱不是有效的 DNS 子網域
- [警告] 如果無法透過網路查詢找到主機名稱
- [錯誤] 如果 kubelet 版本低於 kubeadm 支援的最低 kubelet 版本 (目前次要版本 -1)
- [錯誤] 如果 kubelet 版本至少比要求的控制平面版本高一個次要版本 (不支援的版本偏差)
- [警告] 如果 kubelet 服務不存在或已停用
- [警告] 如果 firewalld 處於啟用狀態
- [錯誤] 如果使用了 API 伺服器綁定埠或埠 10250/10251/10252
- [錯誤] 如果
/etc/kubernetes/manifest
資料夾已存在且非空 - [錯誤] 如果 swap 已開啟
- [錯誤] 如果命令路徑中不存在
ip
、iptables
、mount
、nsenter
命令 - [警告] 如果命令路徑中不存在
ethtool
、tc
、touch
命令 - [警告] 如果 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 init phase preflight
命令個別調用預檢。產生必要的憑證
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.svc
、kubernetes.default
、kubernetes
- 節點名稱
--apiserver-advertise-address
- 使用者指定的其他替代名稱
- Kubernetes 服務的內部叢集 IP (服務 CIDR 中的第一個位址,例如,如果服務子網路為
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
標記設定此目錄。
請注意
- 如果給定的憑證和私密金鑰對都存在,並且評估其內容符合上述規格,則將使用現有檔案,並跳過給定憑證的產生階段。這表示使用者可以例如將現有的 CA 複製到
/etc/kubernetes/pki/ca.{crt,key}
,然後 kubeadm 將使用這些檔案來簽署其餘憑證。另請參閱使用自訂憑證 - 對於 CA,可以提供
ca.crt
檔案,但不提供ca.key
檔案。如果所有其他憑證和 kubeconfig 檔案都已就位,kubeadm 會識別此情況並啟用 ExternalCA,這也表示 controller-manager 中的csrsigner
控制器將不會啟動 - 如果 kubeadm 在 外部 CA 模式下執行;所有憑證都必須由使用者提供,因為 kubeadm 無法自行產生它們
- 如果 kubeadm 在
--dry-run
模式下執行,憑證檔案將寫入暫存資料夾中 - 可以使用
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
;此檔案內部嵌入了具有控制器管理員身分識別的用戶端憑證。此用戶端憑證應具有 CNsystem:kube-controller-manager
,如預設 RBAC 核心元件角色所定義排程器的 kubeconfig 檔案,
/etc/kubernetes/scheduler.conf
;此檔案內部嵌入了具有排程器身分識別的用戶端憑證。此用戶端憑證應具有 CNsystem: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
檔案 (不需要 RBAC) 繫結到 cluster-admin
ClusterRole。此 admin.conf
檔案必須保留在控制平面節點上,且不應與其他使用者共用。
在 kubeadm init
期間,會產生另一個 kubeconfig 檔案並儲存在 /etc/kubernetes/super-admin.conf
中。此檔案包含一個憑證,其 Subject: O = system:masters, CN = kubernetes-super-admin
。system:masters
是一個超級使用者群組,它繞過 RBAC,並使 super-admin.conf
在因 RBAC 設定錯誤而鎖定叢集時很有用。super-admin.conf
檔案必須儲存在安全的位置,且不應與其他使用者共用。
有關 RBAC 和內建 ClusterRole 和群組的更多資訊,請參閱 RBAC 使用者面向的角色繫結。
您可以執行 kubeadm kubeconfig user
來為其他使用者產生 kubeconfig 檔案。
注意
產生的組態檔包含嵌入式驗證金鑰,您應將其視為機密。另請注意
ca.crt
憑證嵌入在所有 kubeconfig 檔案中。- 如果給定的 kubeconfig 檔案存在,並且評估其內容符合上述規格,則將使用現有檔案,並跳過給定 kubeconfig 的產生階段
- 如果 kubeadm 在 ExternalCA 模式下執行,則也必須由使用者提供所有需要的 kubeconfig,因為 kubeadm 無法自行產生任何 kubeconfig
- 如果 kubeadm 在
--dry-run
模式下執行,kubeconfig 檔案將寫入暫存資料夾中 - 可以使用
kubeadm init phase kubeconfig all
命令個別調用 kubeconfig 檔案的產生
為控制平面元件產生靜態 Pod 清單
Kubeadm 將控制平面元件的靜態 Pod 清單檔案寫入 /etc/kubernetes/manifests
。kubelet 監看此目錄,以便在啟動時建立 Pod。
靜態 Pod 清單共用一組通用屬性
所有靜態 Pod 都部署在
kube-system
命名空間中所有靜態 Pod 都取得
tier:control-plane
和component:{component-name}
標籤所有靜態 Pod 都使用
system-node-critical
優先順序類別hostNetwork: true
設定在所有靜態 Pod 上,以允許在設定網路之前啟動控制平面;因此- 控制器管理員和排程器用來參考 API 伺服器的
address
是127.0.0.1
- 如果在本機設定 etcd 伺服器,則
etcd-server
位址將設定為127.0.0.1:2379
- 控制器管理員和排程器用來參考 API 伺服器的
控制器管理員和排程器都啟用了領導者選舉
控制器管理員和排程器將參考具有各自唯一身分識別的 kubeconfig 檔案
所有靜態 Pod 都會取得您指定的任何額外標記或修補程式,如 將自訂引數傳遞到控制平面元件中所述
所有靜態 Pod 都會取得使用者指定的任何額外磁碟區 (主機路徑)
請注意
- 所有映像檔預設都將從 registry.k8s.io 中提取。有關自訂映像檔儲存庫,請參閱使用自訂映像檔
- 如果 kubeadm 在
--dry-run
模式下執行,靜態 Pod 檔案將寫入暫存資料夾中 - 可以使用
kubeadm init phase control-plane all
命令個別調用控制平面元件的靜態 Pod 清單產生
API 伺服器
API 伺服器的靜態 Pod 清單受使用者提供的以下參數影響
- 要綁定的
apiserver-advertise-address
和apiserver-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
為NamespaceLifecycle
,例如,避免刪除系統保留的命名空間LimitRanger
和ResourceQuota
,以強制命名空間的限制ServiceAccount
,以強制服務帳戶自動化PersistentVolumeLabel
將區域或區域標籤附加到 PersistentVolume,如雲端供應商所定義 (此准入控制器已棄用,並將在未來版本中移除。從 v1.9 開始,當未明確選擇使用gce
或aws
作為雲端供應商時,kubeadm 預設不會部署它)DefaultStorageClass
,以在PersistentVolumeClaim
物件上強制預設儲存類別DefaultTolerationSeconds
NodeRestriction
,以限制 kubelet 可以修改的內容 (例如,僅限於此節點上的 Pod)
--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
用於保護前端 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 啟動引導的BootstrapSigner
和TokenCleaner
控制器。有關更多詳細資訊,請參閱 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 清單不受使用者提供的參數影響。
為本機 etcd 產生靜態 Pod 清單
如果您指定了外部 etcd,則將跳過此步驟,否則 kubeadm 會產生靜態 Pod 清單檔案,以建立在本機 etcd 執行個體,該執行個體在具有以下屬性的 Pod 中執行
- 監聽
localhost:2379
並使用HostNetwork=true
- 從
dataDir
到主機的檔案系統進行hostPath
掛載 - 使用者指定的任何額外標記
請注意
- etcd 容器映像檔預設將從
registry.gcr.io
中提取。有關自訂映像檔儲存庫,請參閱使用自訂映像檔。 - 如果您在
--dry-run
模式下執行 kubeadm,則 etcd 靜態 Pod 清單將寫入暫存資料夾中。 - 您可以使用
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
) 將能夠判斷實際/目前的叢集狀態,並根據該資料做出新的決策。
請注意
- 在儲存 ClusterConfiguration 之前,會從組態中剝離敏感資訊,例如權杖
- 可以使用命令
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 伺服器和控制器標記。
注意
可以使用命令kubeadm init phase bootstrap-token
設定節點的 TLS 啟動引導,執行以下段落中描述的所有組態步驟;或者,可以個別調用每個步驟。建立 Bootstrap 權杖
kubeadm init
建立第一個 Bootstrap 權杖,可以自動產生或由使用者使用 --token
標記提供;如 Bootstrap 權杖規格中所述,權杖應儲存為機密,名稱為 bootstrap-token-<token-id>
,位於 kube-system
命名空間下。
請注意
kubeadm init
建立的預設權杖將用於在 TLS 啟動引導程序期間驗證暫時使用者;這些使用者將是system:bootstrappers:kubeadm:default-node-token
群組的成員- 權杖具有有限的有效期限,預設為 24 小時 (可以使用
—token-ttl
標記變更間隔) - 可以使用
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 的權限。
注意
對cluster-info
ConfigMap 的存取未受到速率限制。如果您將叢集的 API 伺服器暴露於網際網路,這可能會也可能不會成為問題;這裡最壞的情況是 DoS 攻擊,攻擊者使用 kube-apiserver 可以處理的所有執行中請求來服務 cluster-info
ConfigMap。安裝附加元件
Kubeadm 透過 API 伺服器安裝內部 DNS 伺服器和 kube-proxy 附加元件。
注意
可以使用命令kubeadm init phase addon all
個別調用此階段。Proxy
在 kube-system
命名空間中為 kube-proxy
建立 ServiceAccount;然後將 kube-proxy 部署為 DaemonSet
- 控制平面的憑證 (
ca.crt
和token
) 來自 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
在開始加入之前執行一組預檢,目的是驗證先決條件並避免常見的叢集啟動問題。
另請注意
kubeadm join
預檢基本上是kubeadm init
預檢的子集- 如果您要加入 Windows 節點,則會跳過特定於 Linux 的控制項。
- 在任何情況下,使用者都可以使用
--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 進行比較
注意
您可以透過在命令列上傳遞--discovery-token-unsafe-skip-ca-verification
標記來跳過 CA 驗證。這會削弱 kubeadm 安全模型,因為其他人可能會冒充 Kubernetes API 伺服器。檔案/HTTPS 探索
如果調用 kubeadm join
時使用 --discovery-file
,則使用檔案探索;此檔案可以是本機檔案,也可以透過 HTTPS URL 下載;如果是 HTTPS,則使用主機安裝的 CA 捆綁包來驗證連線。
使用檔案探索時,叢集 CA 憑證會提供到檔案本身中;實際上,探索檔案是一個 kubeconfig 檔案,僅設定了 kubeadm join
參考文件中描述的 server
和 certificate-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 init
程序期間儲存的權杖 (或使用kubeadm token
命令建立的其他權杖) 驗證臨時驗證 - 臨時驗證解析為
system:bootstrappers:kubeadm:default-node-token
群組的成員使用者,該群組在kubeadm init
程序期間被授予對 CSR API 的存取權 - 自動 CSR 核准由 csrapprover 控制器管理,根據
kubeadm init
程序中存在的組態
kubeadm upgrade 工作流程內部設計
kubeadm upgrade
具有子命令,用於處理由 kubeadm 建立的 Kubernetes 叢集的升級。您必須在控制平面節點上執行 kubeadm upgrade apply
(您可以選擇在哪個節點上執行);這會啟動升級程序。然後,您在所有剩餘節點 (工作節點和控制平面節點) 上執行 kubeadm upgrade node
。
kubeadm upgrade apply
和 kubeadm upgrade node
都具有 phase
子命令,該子命令提供對升級程序內部階段的存取。有關更多詳細資訊,請參閱 kubeadm upgrade phase
。
其他實用程式升級命令為 kubeadm upgrade plan
和 kubeadm upgrade diff
。
所有升級子命令都支援傳遞組態檔。
kubeadm upgrade plan
您可以選擇在執行 kubeadm upgrade apply
之前執行 kubeadm upgrade plan
。plan
子命令檢查哪些版本可升級,並驗證您目前的叢集是否可升級。
kubeadm upgrade diff
這會顯示將套用到控制平面節點的現有靜態 Pod 清單的差異。執行相同操作的更詳細方法是執行 kubeadm upgrade apply --dry-run
或 kubeadm upgrade node --dry-run
。
kubeadm upgrade apply
kubeadm upgrade apply
為所有節點的升級準備叢集,並升級執行它的控制平面節點。它執行的步驟是
- 執行預檢,類似於
kubeadm init
和kubeadm join
,確保下載容器映像檔,且叢集處於良好的可升級狀態。 - 升級
/etc/kubernetes/manifests
中磁碟上的控制平面清單檔案,並等待 kubelet 重新啟動元件 (如果檔案已變更)。 - 將更新的 kubeadm 和 kubelet 組態上傳到
kubeadm-config
和kubelet-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 管理的任何檔案和目錄。