k8s TLS bootstrap解析-k8s TLS bootstrap流程分析
k8s TLS bootstrap解析-k8s TLS bootstrap流程分析
概述
當k8s叢集開啟了TLS認證後,每個節點的kubelet元件都要使用由kube-apiserver的CA簽發的有效證書才能與kube-apiserver通訊;當節點非常多的時候,為每個節點都單獨簽署證書是一件非常繁瑣而又耗時的事情。
此時k8s TLS bootstrap功能應運而生。
k8s TLS bootstrap功能就是讓kubelet先使用一個預先商定好的低許可權的bootstrap token連線到kube-apiserver,向kube-apiserver申請證書,然後kube-controller-manager給kubelet動態簽署證書,後續kubelet都將通過動態簽署的證書與kube-apiserver通訊。
TLS bootstrap涉及元件相關引數
1.kube-apiserver
(1) --client-ca-file
:認證客戶端證書的CA證書;
(2) --enable-bootstrap-token-auth
:設定為true則代表開啟TLS bootstrap特性;
2.kube-controller-manager
(1) --cluster-signing-cert-file
、 --cluster-signing-key-file
:用來簽發kubelet證書的CA證書和私鑰,這裡的kubelet證書指的是用來跟kube-apiserver通訊,kube-apiserver認證kubelet身份的證書,所以--cluster-signing-cert-file指定的值與kube-apiserver的--client-ca-file指定值一致,而私鑰則也是對應的私鑰;
(2) --cluster-signing-duration
:簽發給kubelet的證書有效期;
3.kubelet
(1) --bootstrap-kubeconfig
:TLS bootstrap的配置檔案,檔案中一般包含bootstrap token和master url等資訊;
(2) --kubeconfig
:在kubelet的CSR被批覆並被kubelet取回時,一個引用所生成的金鑰和所獲得證書的kubeconfig檔案會被寫入到通過 --kubeconfig所指定的檔案路徑下,而證書和金鑰檔案會被放到--cert-dir所指定的目錄中;
(3) --rotate-certificates
:開啟證書輪換,kubelet在其現有證書即將過期時通過建立新的CSR來輪換其客戶端證書。
詳細流程解析
下面以kubeadm使用k8s TLS bootstrap將一個node節點加入已有的master為例,對TLS bootstrap部分進行詳細流程解析。
1.RBAC相關操作
(1)生成bootstrap token,建立bootstrap token secret;
bootstrap token secret模板:
apiVersion: v1 data: auth-extra-groups: system:bootstrappers:kubeadm:default-node-token expiration: 2022-04-03T11:13:09+08:00 token-id: {token-id} token-secret: {token-secret} usage-bootstrap-authentication: "true" usage-bootstrap-signing: "true" kind: Secret metadata: name: bootstrap-token-{token-id} namespace: kube-system type: bootstrap.kubernetes.io/token
關於bootstrap token secret相關的格式說明:
secret的name格式為 bootstrap-token-{token-id}
的格式;
secret的type固定為 bootstrap.kubernetes.io/token
;
secret data中的token-id為6位數字字母組合字串,token-secret為16位數字字母組合字串;
secret data中的 auth-extra-groups
定義了bootstrap token所代表使用者所屬的的group,kubeadm使用了 system:bootstrappers:kubeadm:default-node-token
;
secret所對應的bootstrap token為 {token-id}.{token-secret}
;
bootstrap token secret示例:
apiVersion: v1 data: auth-extra-groups: system:bootstrappers:kubeadm:default-node-token expiration: 2022-04-03T11:13:09+08:00 token-id: abcdef token-secret: 0123456789abcdef usage-bootstrap-authentication: "true" usage-bootstrap-signing: "true" kind: Secret metadata: name: bootstrap-token-abcdef namespace: kube-system type: bootstrap.kubernetes.io/token
上述secret示例中,kubeadm生成的bootstrap token為 abcdef.0123456789abcdef
,其代表的使用者所在使用者組為 system:bootstrappers:kubeadm:default-node-token
;
(2)授予bootstrap token建立CSR證書籤名請求的許可權,即授予kubelet建立CSR證書籤名請求的許可權;
即建立ClusterRoleBinding -- kubeadm:kubelet-bootstrap
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubeadm:kubelet-bootstrap ... roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:node-bootstrapper subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:bootstrappers:kubeadm:default-node-token
kubeadm生成的bootstrap token所代表的使用者所在使用者組為 system:bootstrappers:kubeadm:default-node-token
,所以這裡繫結許可權的時候將許可權繫結給了使用者組 system:bootstrappers:kubeadm:default-node-token
;
接下來看下被授予的許可權ClusterRole -- system:node-bootstrapper
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:node-bootstrapper ... rules: - apiGroups: - certificates.k8s.io resources: - certificatesigningrequests verbs: - create - get - list - watch
(3)授予bootstrap token許可權,讓kube-controller-manager可以自動審批其發起的CSR;
即建立ClusterRoleBinding -- kubeadm:node-autoapprove-bootstrap
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubeadm:node-autoapprove-bootstrap ... roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:nodeclient subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:bootstrappers:kubeadm:default-node-token
kubeadm生成的bootstrap token所代表的使用者所在使用者組為 system:bootstrappers:kubeadm:default-node-token
,所以這裡繫結許可權的時候將許可權繫結給了使用者組 system:bootstrappers:kubeadm:default-node-token
;
接下來看下被授予的許可權ClusterRole -- system:certificates.k8s.io:certificatesigningrequests:nodeclient
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:certificates.k8s.io:certificatesigningrequests:nodeclient ... rules: - apiGroups: - certificates.k8s.io resources: - certificatesigningrequests/nodeclient verbs: - create
(4)授予kubelet許可權,讓kube-controller-manager自動批覆kubelet的證書輪換請求;
即建立ClusterRoleBinding -- kubeadm:node-autoapprove-certificate-rotation
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubeadm:node-autoapprove-certificate-rotation ... roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:nodes
kubelet建立的CSR使用者名稱格式為 system:node:<name>
,使用者組為 system:nodes
,所以kube-controller-manager為kubelet生成的證書所代表的使用者所在使用者組為 system:nodes
,所以這裡繫結許可權的時候將許可權繫結給了使用者組 system:nodes
;
接下來看下被授予的許可權ClusterRole -- system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient ... rules: - apiGroups: - certificates.k8s.io resources: - certificatesigningrequests/selfnodeclient verbs: - create
2.啟動kubelet,開始TLS bootstrap
(0)根據bootstrap token以及master url等資訊生成bootstrap-kubeconfig檔案;
(1)啟動kubelet,配置了kubeconfig檔案目錄,但kubeconfig檔案為空,再指定bootstrap-kubeconfig檔案為上述步驟生成的bootstrap-kubeconfig檔案;
(2)kubelet發現配置的kubeconfig檔案為空,則載入bootstrap-kubeconfig檔案,讀取其中的bootstrap token以及master url;
(3)kubelet使用bootstrap token與apiserver通訊,建立CSR證書籤名請求;
(4)kube-controller-manager批覆CSR證書籤名請求,為其簽發相關證書;
(5)kubelet取回kube-controller-manager生成的相關證書,預設存放在/var/lib/kubelet/pki 目錄下,然後根據證書生成kubeconfig檔案,後續kubelet將使用該kubeconfig檔案與kube-apiserver進行認證通訊;
# ls /var/lib/kubelet/pki/ kubelet-client-2022-03-18-14-29-00.pem kubelet-client-current.pem kubelet.crt kubelet.key
kubelet-client-current.pem是個軟鏈,指向kubelet-client-2022-03-18-14-29-00.pem檔案,kubelet-client-2022-03-18-14-29-00.pem檔名記錄的是證書建立時間,後續kubelet將會根據證書過期時間,在證書臨過期前向kube-apiserver重新申請證書,然後自動輪換該證書;
# cat /etc/kubernetes/kubelet.conf apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0F... server: http://192.168.1.10:6443 name: test-cluster contexts: - context: cluster: test-cluster user: system:node:test-cluster-node-1 name: system:node:test-cluster-node-1 current-context: system:node:test-cluster-node-1 kind: Config preferences: {} users: - name: system:node:test-cluster-node-1 user: client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
3.kubelet自動輪換證書
(1)kubelet在證書接近於過期時自動向kube-apiserver請求更新證書;
(2)kube-controller-manager自動批覆,為其簽發新的證書;
(3)kubelet取回kube-controller-manager生成的相關證書,替換掉本地的舊證書,後續kubelet將使用新證書來與kube-apiserver進行認證通訊;
總結
最後以一幅圖來總結一下k8s TLS bootstrap的整個流程。
- 記一次批量更新整型型別的列 → 探究 UPDATE 的使用細節
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- Django 之路由層
- 【前端必會】webpack loader 到底是什麼
- day42-反射01
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 設計模式---享元模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- [ML從入門到入門] 支援向量機:從SVM的推導過程到SMO的收斂性討論
- 從應用訪問Pod元資料-DownwardApi的應用
- Springboot之 Mybatis 多資料來源實現
- Java 泛型程式設計
- CAS核心思想、底層實現