kubernetes容器集羣 - HTTPS認證和受權機制學習

 

在學習和搭建二進制Kubernetes集羣過程當中,對其中涉及到的一推證書每每很懵,雖然參考網上大量的部署教程最後會成功部署並正常運行起來,但對其中的部署流程和原理細節等仍是很模糊,下面根據蒐集網上資料和kubernetes相關書籍特地梳理下kubernetes認證受權機制的基礎知識,重點關注TLS Bootstrapping (TLS 引導)證書自動頒發、證書輪換認證過程的RBAC受權, 以便後續深刻理解和運用~node

Kubernetes通過一系列認證受權機制來實現集羣的安全機制,包括API Server的認證、受權、准入控制機制等。集羣的安全性必須考慮如下的幾個目標:
-> 保證容器與其所在宿主機的隔離;
-> 限制容器給基礎設施及其餘容器帶來消極影響的能力;
-> 最小權限原則,合理限制全部組件權限,確保組件只執行它被受權的行爲,經過限制單個組件的能力來限制他所能達到的權限範圍;
-> 明確組件間邊界的劃分;
-> 劃分普通用戶和管理員角色;
-> 在必要的時候容許將管理員權限賦給普通用戶;
-> 容許擁有Secret數據(Keys、Certs、Passwords)的應用在集羣中運行;算法

1、HTTPS 數字證書認證 
bootstrap

HTTPS工做流程
1.   瀏覽器發起https請求,將本身支持的一套加密規則發送給服務端。
2.  服務端從中選出一組加密算法與HASH算法,並將本身的身份信息以證書的形式發回給瀏覽器證書裏面包含了服務端地址,加密公鑰,以及證書的頒發機構等信息。
3.  得到服務端證書以後瀏覽器要作如下工做:
-> 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的服務端地址是否與正在訪問的地址一致等),若是證書受信任,則瀏覽器欄裏面會顯示一個小鎖頭,不然會給出證書不受信的提示。
-> 若是證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機數的密碼,並用證書中提供的公鑰加密。
-> 使用約定好的HASH計算握手消息,並使用生成的隨機數對消息進行加密,最後將以前生成的全部信息發送給服務端。
4.  服務端接收瀏覽器發來的數據以後要作如下的操做:
-> 使用本身的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發來的握手消息,並驗證HASH是否與瀏覽器發來的一致。
-> 使用密碼加密一段握手消息,發送給瀏覽器。
5.  瀏覽器解密並計算握手消息的HASH,若是與服務端發來的HASH一致,則此時握手過程結束,以後全部通訊數據將由以前瀏覽器生成的隨機密碼並利用加密算法進行加密。api

2、Kubernetes加密解密原理
kubernetes內部經常使用的加解密算法爲非對稱加密算法RSA。瀏覽器

1.  每一個用戶都有一對私鑰和公鑰。
-> 私鑰用來進行解密和簽名,是給本身用的。
-> 公鑰由本人公開,用於加密和驗證簽名,是給別人用的。
2.  當該用戶發送文件時,用私鑰簽名,別人用他給的公鑰解密,能夠保證該信息是由他發送的。即數字簽名。
3.  當該用戶接受文件時,別人用他的公鑰加密,他用私鑰解密,能夠保證該信息只能由他看到。即安全傳輸安全

3、 數字證書
數字證書則是由證書認證機構(CA)對證書申請者真實身份驗證以後,用CA的根證書對申請人的一些基本信息以及申請人的公鑰進行簽名(至關於加蓋發證書機 構的公章)後造成的一個數字文件。CA完成簽發證書後,會將證書發佈在CA的證書庫(目錄服務器)中,任何人均可以查詢和下載,所以數字證書和公鑰同樣是公開的。實際上,數字證書就是通過CA認證過的公鑰bash

4、CA認證流程服務器

SSL雙向認證步驟
1.  HTTPS通訊雙方的服務器端向CA機構申請證書,CA機構是可信的第三方機構,它能夠是一個公認的權威的企業,也能夠是企業自身。企業內部系統通常都使用企業自身的認證系統。CA機構下發根證書、服務端證書及私鑰給申請者;
2.  HTTPS通訊雙方的客戶端向CA機構申請證書,CA機構下發根證書、客戶端證書及私鑰個申請者;
3.  客戶端向服務器端發起請求,服務端下發服務端證書給客戶端。客戶端接收到證書後,經過私鑰解密證書,並利用服務器端證書中的公鑰認證證書信息比較證書裏的消息,例如域名和公鑰與服務器剛剛發送的相關消息是否一致,若是一致,則客戶端認爲這個服務器的合法身份;
4.  客戶端發送客戶端證書給服務器端,服務端接收到證書後,經過私鑰解密證書,得到客戶端的證書公鑰,並用該公鑰認證證書信息,確認客戶端是否合法;
5.  客戶端經過隨機祕鑰加密信息,併發送加密後的信息給服務端。服務器端和客戶端協商好加密方案後,客戶端會產生一個隨機的祕鑰,客戶端經過協商好的加密方案,加密該隨機祕鑰,併發送該隨機祕鑰到服務器端。服務器端接收這個祕鑰後,雙方通訊的全部內容都都經過該隨機祕鑰加密;併發

5、Kubernetes幾個重要的認證憑據app

ca.pem & ca-key.pem & ca.csr
有上文咱們能夠知道,創建完整TLS加密通訊,須要有一個CA認證機構,會向客戶端下發根證書、服務端證書以及簽名私鑰給客戶端。ca.pem & ca-key.pem & ca.csr組成了一個自簽名的CA機構。

token.csv
該文件爲一個用戶的描述文件,基本格式爲 Token,用戶名,UID,用戶組;這個文件在 apiserver 啓動時被 apiserver 加載,而後就至關於在集羣內建立了一個這個用戶;接下來就能夠用 RBAC 給他受權

bootstrap.kubeconfig
該文件中內置了 token.csv 中用戶的 Token,以及 apiserver CA 證書;kubelet 首次啓動會加載此文件,使用 apiserver CA 證書創建與 apiserver 的 TLS 通信,使用其中的用戶 Token 做爲身份標識像 apiserver 發起 CSR 請求

kubelet-client-current.pem
這是一個軟鏈接文件,當 kubelet 配置了 --feature-gates=RotateKubeletClientCertificate=true選項後,會在證書總有效期的 70%~90% 的時間內發起續期請求,請求被批准後會生成一個 kubelet-client-時間戳.pem;kubelet-client-current.pem 文件則始終軟鏈接到最新的真實證書文件,除首次啓動外,kubelet 一直會使用這個證書同 apiserver 通信

kubelet-server-current.pem
一樣是一個軟鏈接文件,當 kubelet 配置了 --feature-gates=RotateKubeletServerCertificate=true 選項後,會在證書總有效期的 70%~90% 的時間內發起續期請求,請求被批准後會生成一個 kubelet-server-時間戳.pem;kubelet-server-current.pem 文件則始終軟鏈接到最新的真實證書文件,該文件將會一直被用於 kubelet 10250 api 端口鑑權

6、組件證書 及 配置參數
全部客戶端的證書首先要通過Kubernetes集羣CA的簽署,不然不會被集羣承認 .

kubectl
kubectl只是個go編寫的可執行程序,只要爲kubectl配置合適的kubeconfig,就能夠在集羣中的任意節點使用 。kubectl的權限爲admin,具備訪問kubernetes全部api的權限。

--certificate-authority=/etc/kubernetes/ssl/ca.pem 設置了該集羣的根證書路徑, --embed-certs爲true表示將--certificate-authority證書寫入到kubeconfig中;
--client-certificate=/etc/kubernetes/ssl/admin.pem 指定kubectl證書;
--client-key=/etc/kubernetes/ssl/admin-key.pem 指定kubectl私鑰;

kubelet

當成功簽發證書後,目標節點的 kubelet 會將證書寫入到 --cert-dir= 選項指定的目錄中;此時若是不作其餘設置應當生成上述除ca.pem之外的4個文件。
-> kubelet-client.crt 該文件在 kubelet 完成 TLS bootstrapping 後生成,此證書是由 controller manager 簽署的,此後 kubelet 將會加載該證書,用於與 apiserver 創建 TLS 通信,同時使用該證書的 CN 字段做爲用戶名,O 字段做爲用戶組向 apiserver 發起其餘請求。
-> kubelet.crt 該文件在 kubelet 完成 TLS bootstrapping 後而且沒有配置 --feature-gates=RotateKubeletServerCertificate=true 時纔會生成;這種狀況下該文件爲一個獨立於 apiserver CA 的自籤 CA 證書,有效期爲 1 年;被用做 kubelet 10250 api 端口。

kube-apiserver
kube-apiserver是咱們在部署kubernetes集羣是最須要先啓動的組件,也是咱們和集羣交互的核心組件。
如下是kube-apiserver所使用的證書:

--token-auth-file=/etc/kubernetes/token.csv 指定了token.csv的位置,用於kubelet 組件 第一次啓動時沒有證書如何鏈接 apiserver 。 Token 和 apiserver 的 CA 證書被寫入了 kubelet 所使用的 bootstrap.kubeconfig 配置文件中;這樣在首次請求時,kubelet 使用 bootstrap.kubeconfig 中的 apiserver CA 證書來與 apiserver 創建 TLS 通信,使用 bootstrap.kubeconfig 中的用戶 Token 來向 apiserver 聲明本身的 RBAC 受權身份
--tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem 指定kube-apiserver證書地址
--tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem 指定kube-apiserver私鑰地址
--client-ca-file=/etc/kubernetes/ssl/ca.pem 指定根證書地址
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem 包含PEM-encoded x509 RSA公鑰和私鑰的文件路徑,用於驗證Service Account的token,若是不指定,則使用--tls-private-key-file指定的文件
--etcd-cafile=/etc/kubernetes/ssl/ca.pem 到etcd安全鏈接使用的SSL CA文件
--etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem 到etcd安全鏈接使用的SSL 證書文件
--etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem 到etcd安全鏈接使用的SSL 私鑰文件

kube-controller-manager
kubelet 發起的 CSR 請求都是由 kube-controller-manager 來作實際簽署的,全部使用的證書都是根證書的密鑰對 。因爲kube-controller-manager是和kube-apiserver部署在同一節點上,且使用非安全端口通訊,故不須要證書。

--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem 指定簽名的CA機構根證書,用來簽名爲 TLS BootStrap 建立的證書和私鑰;
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem 指定簽名的CA機構私鑰,用來簽名爲 TLS BootStrap 建立的證書和私鑰;
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem 同上;
--root-ca-file=/etc/kubernetes/ssl/ca.pem 根CA證書文件路徑 ,用來對 kube-apiserver 證書進行校驗,指定該參數後,纔會在Pod 容器的 ServiceAccount 中放置該 CA 證書文件
--kubeconfig kubeconfig 配置文件路徑,在配置文件中包括Master的地址信息及必要認證信息;

kube-scheduler && kube-proxy
kube-scheduler是和kube-apiserver通常部署在同一節點上,且使用非安全端口通訊,故啓動參參數中沒有指定證書的參數可選 。 若分離部署,可在kubeconfig文件中指定證書,使用kubeconfig認證,kube-proxy相似
配置示例:

設置集羣參數
# kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig

設置客戶端認證參數
# kubectl config set-credentials kube-proxy \
  --client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
  --client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig

設置上下文參數
# kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig

設置默認上下文
# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
# mv kube-proxy.kubeconfig /etc/kubernetes/

TLS Bootstrapping
每一個 Kubernetes 集羣都有一個集羣根證書頒發機構(CA)。 集羣中的組件一般使用 CA 來驗證 API server 的證書,由API服務器驗證 kubelet 客戶端證書等。爲了支持這一點,CA 證書包被分發到集羣中的每一個節點,並做爲一個 secret 附加分發到默認 service account 上 。
->  想要與 apiserver 通信就必須採用由 apiserver CA 簽發的證書,這樣才能造成信任關係,創建 TLS 鏈接;
->  證書的 CN、O 字段來提供 RBAC 所需的用戶與用戶組;

kubelet首次啓動流程
第一次啓動時沒有證書如何鏈接 apiserver ?     這個問題實際上能夠去查看一下 bootstrap.kubeconfig 和 token.csv, 能夠獲得以下答案:
在 apiserver 配置中指定了一個 token.csv 文件,該文件中是一個預設的用戶配置;同時該用戶的 Token 和 apiserver 的 CA 證書被寫入了 kubelet 所使用的 bootstrap.kubeconfig 配置文件中;這樣在首次請求時,kubelet 使用 bootstrap.kubeconfig 中的 apiserver CA 證書來與 apiserver 創建 TLS 通信,使用 bootstrap.kubeconfig 中的用戶 Token 來向 apiserver 聲明本身的 RBAC 受權身份。以下圖所示:

在首次啓動時,可能與遇到 kubelet 報 401 無權訪問 apiserver 的錯誤;這是由於在默認狀況下,kubelet 經過 bootstrap.kubeconfig 中的預設用戶 Token 聲明瞭本身的身份,而後建立 CSR 請求;可是不要忘記這個用戶在咱們不處理的狀況下他沒任何權限的,包括建立 CSR 請求;因此須要以下命令建立一個 ClusterRoleBinding,將預設用戶 kubelet-bootstrap 與內置的 ClusterRole system:node-bootstrapper 綁定到一塊兒,使其可以發起 CSR 請求。

kubectl create clusterrolebinding kubelet-bootstrap \
  --clusterrole=system:node-bootstrapper \
  --user=kubelet-bootstrap

CSR請求類型
kubelet 發起的 CSR 請求都是由 controller manager 來作實際簽署的,對於 controller manager 來講,TLS bootstrapping 下 kubelet 發起的 CSR 請求大體分爲如下三種
-> nodeclient: kubelet 以 O=system:nodes 和 CN=system:node:(node name) 形式發起的 CSR 請求
-> selfnodeclient: kubelet client renew 本身的證書發起的 CSR 請求(與上一個證書就有相同的 O 和 CN)
-> selfnodeserver: kubelet server renew 本身的證書發起的 CSR 請求

手動簽發
在 kubelet 首次啓動後,若是用戶 Token 沒問題,而且 RBAC 也作了相應的設置,那麼此時在集羣內應該能看到 kubelet 發起的 CSR 請求 ,必須經過後kubernetes 系統纔會將該 Node 加入到集羣。查看未受權的CSR 請求:

# kubectl get csr
NAME                                                   AGE       REQUESTOR           CONDITION
node-csr--k3G2G1EoM4h9w1FuJRjJjfbIPNxa551A8TZfW9dG-g   2m        kubelet-bootstrap   Pending

# kubectl get nodes
No resources found.

經過CSR 請求:

# kubectl certificate approve node-csr--k3G2G1EoM4h9w1FuJRjJjfbIPNxa551A8TZfW9dG-g
certificatesigningrequest "node-csr--k3G2G1EoM4h9w1FuJRjJjfbIPNxa551A8TZfW9dG-g" approved

# kubectl get nodes
NAME            STATUS    ROLES     AGE       VERSION
172.30.195.89   Ready     <none>    48s       v1.10.0

自動生成了kubelet kubeconfig 文件和公私鑰:

# ls -l /etc/kubernetes/kubelet.kubeconfig
-rw------- 1 root root 2280 Nov  7 10:26 /etc/kubernetes/kubelet.kubeconfig

# ls -l /etc/kubernetes/ssl/kubelet*
-rw-r--r-- 1 root root 1046 Nov  7 10:26 /etc/kubernetes/ssl/kubelet-client.crt
-rw------- 1 root root  227 Nov  7 10:22 /etc/kubernetes/ssl/kubelet-client.key
-rw-r--r-- 1 root root 1115 Nov  7 10:16 /etc/kubernetes/ssl/kubelet.crt
-rw------- 1 root root 1675 Nov  7 10:16 /etc/kubernetes/ssl/kubelet.key

當成功簽發證書後,目標節點的 kubelet 會將證書寫入到 --cert-dir= 選項指定的目錄中;注意此時若是不作其餘設置應當生成四個文件 .kubelet 與 apiserver 通信所使用的證書爲 kubelet-client.crt,剩下的 kubelet.crt 將會被用於 kubelet server(10250) 作鑑權使用;注意,此時 kubelet.crt 這個證書是個獨立於 apiserver CA 的自籤 CA,而且刪除後 kubelet 組件會從新生成它。

自動簽發
上面提到,kubelet首次啓動時會發起CSR請求,若是咱們未作任何配置,則須要手動簽發,若集羣龐大,那麼手動簽發的請求就會不少,來了解一下自動簽發

RBAC受權
kubelet 所發起的 CSR 請求是由 controller manager 簽署的;若是想要是實現自動簽發,就須要讓 controller manager 可以在 kubelet 發起證書請求的時候自動幫助其簽署證書;那麼 controller manager 不可能對全部的 CSR 證書申請都自動簽署,這時候就須要配置 RBAC 規則,保證 controller manager 只對 kubelet 發起的特定 CSR 請求自動批准便可;針對上面 提出的 3 種 CSR 請求分別給出了 3 種對應的 ClusterRole,以下所示:

# A ClusterRole which instructs the CSR approver to approve a user requesting
# node client credentials.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: approve-node-client-csr
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/nodeclient"]
  verbs: ["create"]
---
# A ClusterRole which instructs the CSR approver to approve a node renewing its
# own client credentials.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: approve-node-client-renewal-csr
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/selfnodeclient"]
  verbs: ["create"]
---
# A ClusterRole which instructs the CSR approver to approve a node requesting a
# serving cert matching its client cert.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: approve-node-server-renewal-csr
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/selfnodeserver"]
  verbs: ["create"]

RBAC 中 ClusterRole 只是描述或者說定義一種集羣範圍內的能力,這三個 ClusterRole 在 1.7 以前須要本身手動建立,在 1.8 後 apiserver 會自動建立前兩個;以上三個 ClusterRole 含義以下:
-> approve-node-client-csr: 具備自動批准 nodeclient 類型 CSR 請求的能力;
-> approve-node-client-renewal-csr: 具備自動批准 selfnodeclient 類型 CSR 請求的能力;
-> approve-node-server-renewal-csr: 具備自動批准 selfnodeserver 類型 CSR 請求的能力;

因此,若是想要 kubelet 可以自動簽發,那麼就應當將適當的 ClusterRole 綁定到 kubelet 自動續期時所所採用的用戶或者用戶組身上。

CluserRole 綁定
要實現自動簽發,建立的 RBAC 規則,則至少能知足四種狀況:
自動批准 kubelet 首次用於與 apiserver 通信證書的 CSR 請求(nodeclient)
自動批准 kubelet 首次用於 10250 端口鑑權的 CSR 請求(實際上這個請求走的也是 selfnodeserver 類型 CSR)

基於以上2種狀況,實現自動簽發須要建立 2個 ClusterRoleBinding,建立以下:

自動批准 kubelet 的首次 CSR 請求(用於與 apiserver 通信的證書)
# kubectl create clusterrolebinding node-client-auto-approve-csr --clusterrole=approve-node-client-csr --group=system:bootstrappers

自動批准 kubelet 發起的用於 10250 端口鑑權證書的 CSR 請求(包括後續 renew)
# kubectl create clusterrolebinding node-server-auto-renew-crt --clusterrole=approve-node-server-renewal-csr --group=system:nodes

證書輪換
開啓證書輪換下的引導過程
-> kubelet 讀取 bootstrap.kubeconfig,使用其 CA 與 Token 向 apiserver 發起第一次 CSR 請求(nodeclient);
-> apiserver 根據 RBAC 規則自動批准首次 CSR 請求(approve-node-client-csr),並下發證書(kubelet-client.crt);
-> kubelet 使用剛剛簽發的證書(O=system:nodes, CN=system:node:NODE_NAME)與 apiserver 通信,併發起申請 10250 server 所使用證書的 CSR 請求;
-> apiserver 根據 RBAC 規則自動批准 kubelet 爲其 10250 端口申請的證書(kubelet-server-current.crt);
-> 證書即將到期時,kubelet 自動向 apiserver 發起用於與 apiserver 通信所用證書的 renew CSR 請求和 renew 自己 10250 端口所用證書的 CSR 請求;
-> apiserver 根據 RBAC 規則自動批准兩個證書;
-> kubelet 拿到新證書後關閉全部鏈接,reload 新證書,之後便一直如此;

從以上流程咱們能夠看出,實現證書輪換建立 的RBAC 規則,則至少能知足四種狀況:
-> 自動批准 kubelet 首次用於與 apiserver 通信證書的 CSR 請求(nodeclient);
-> 自動批准 kubelet 首次用於 10250 端口鑑權的 CSR 請求(實際上這個請求走的也是 selfnodeserver 類型 CSR);
-> 自動批准 kubelet 後續 renew 用於與 apiserver 通信證書的 CSR 請求(selfnodeclient);
-> 自動批准 kubelet 後續 renew 用於 10250 端口鑑權的 CSR 請求(selfnodeserver);

基於以上四種狀況,咱們只需在開啓了自動簽發的基礎增長一個ClusterRoleBinding:

自動批准 kubelet 後續 renew 用於與 apiserver 通信證書的 CSR 請求
# kubectl create clusterrolebinding node-client-auto-renew-crt --clusterrole=approve-node-client-renewal-csr --group=system:nodes

開啓證書輪換的配置
kubelet 啓動時增長 --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true 選項,則 kubelet 在證書即將到期時會自動發起一個 renew 本身證書的 CSR 請求;增長--rotate-certificates 參數,kubelet 會自動重載新證書;

同時 controller manager 須要在啓動時增長 --feature-gates=RotateKubeletServerCertificate=true 參數,再配合上面建立好的 ClusterRoleBinding,kubelet client 和 kubelet server 證才書會被自動簽署;

證書過時時間
TLS bootstrapping 時的證書實際是由 kube-controller-manager 組件來簽署的,也就是說證書有效期是 kube-controller-manager 組件控制的;kube-controller-manager 組件提供了一個 --experimental-cluster-signing-duration 參數來設置簽署的證書有效時間;默認爲 8760h0m0s,將其改成 87600h0m0s 即 10 年後再進行 TLS bootstrapping 簽署證書便可。

7、TLS Bootstrapping總結
=========================== 流程總結 =========================
1)kubelet 首次啓動經過加載 bootstrap.kubeconfig 中的用戶 Token 和 apiserver CA 證書發起首次 CSR 請求,這個 Token 被預先內置在 apiserver 節點的 token.csv 中,其身份爲 kubelet-bootstrap 用戶和 system:bootstrappers 用戶組;想要首次 CSR 請求能成功(成功指的是不會被 apiserver 401 拒絕),則須要先將 kubelet-bootstrap 用戶和 system:node-bootstrapper 內置 ClusterRole 綁定;
2)對於首次 CSR 請求能夠手動簽發,也能夠將 system:bootstrappers 用戶組與 approve-node-client-csr ClusterRole 綁定實現自動簽發(1.8 以前這個 ClusterRole 須要手動建立,1.8 後 apiserver 自動建立,並改名爲 system:certificates.k8s.io:certificatesigningrequests:nodeclient)
3)默認簽署的的證書只有 1 年有效期,若是想要調整證書有效期能夠經過設置 kube-controller-manager 的 --experimental-cluster-signing-duration 參數實現,該參數默認值爲 8760h0m0s。
4)對於證書輪換,須要經過協調兩個方面實現;第一,想要 kubelet 在證書到期後自動發起續期請求,則須要在 kubelet 啓動時增長 --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true 來實現;第二,想要讓 controller manager 自動批准續簽的 CSR 請求須要在 controller manager 啓動時增長 --feature-gates=RotateKubeletServerCertificate=true 參數,並綁定對應的 RBAC 規則;同時須要注意的是 1.7 版本的 kubelet 自動續簽後須要手動重啓 kubelet 以使其從新加載新證書,而 1.8 後只須要在 kublet 啓動時附帶 --rotate-certificates 選項就會自動從新加載新證書。

8、kubernetes配置總結
apiserver 預先放置 token.csv,內容樣例以下:

6df3c701f979cee17732c30958745947,kubelet-bootstrap,10001,"system:bootstrappers"

容許 kubelet-bootstrap 用戶建立首次啓動的 CSR 請求 和RBAC受權規則

# kubectl create clusterrolebinding kubelet-bootstrap \
  --clusterrole=system:node-bootstrapper \
  --user=kubelet-bootstrap
  
# kubectl create clusterrolebinding kubelet-nodes \ 
  --clusterrole=system:node \ 
  --group=system:nodes

配置 kubelet 自動續期,RotateKubeletClientCertificate 用於自動續期 kubelet 鏈接 apiserver 所用的證書(kubelet-client-xxxx.pem),RotateKubeletServerCertificate 用於自動續期 kubelet 10250 api 端口所使用的證書(kubelet-server-xxxx.pem),--rotate-certificates 選項使得 kubelet 可以自動重載新證書。

KUBELET_ARGS="--cgroup-driver=cgroupfs \
              --cluster-dns=10.254.0.2 \
              --resolv-conf=/etc/resolv.conf \
              --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
              --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true \
              --rotate-certificates \
              --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
              --fail-swap-on=false \
              --cert-dir=/etc/kubernetes/ssl \
              --cluster-domain=cluster.local. \
              --hairpin-mode=promiscuous-bridge \
              --serialize-image-pulls=false \
              --pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.0"

配置 controller manager 自動批准相關 CSR 請求,若是不配置 --feature-gates=RotateKubeletServerCertificate=true 參數,則即便配置了相關的 RBAC 規則,也只會自動批准 kubelet client 的 renew 請求:

KUBE_CONTROLLER_MANAGER_ARGS="--address=0.0.0.0 \
                              --service-cluster-ip-range=10.254.0.0/16 \
                              --cluster-name=kubernetes \
                              --cluster-signing-cert-file=/etc/kubernetes/ssl/k8s-root-ca.pem \
                              --cluster-signing-key-file=/etc/kubernetes/ssl/k8s-root-ca-key.pem \
                              --service-account-private-key-file=/etc/kubernetes/ssl/k8s-root-ca-key.pem \
                              --feature-gates=RotateKubeletServerCertificate=true \
                              --root-ca-file=/etc/kubernetes/ssl/k8s-root-ca.pem \
                              --leader-elect=true \
                              --experimental-cluster-signing-duration 10m0s \
                              --node-monitor-grace-period=40s \
                              --node-monitor-period=5s \
                              --pod-eviction-timeout=5m0s"

建立自動批准相關 CSR 請求的 ClusterRole,1.8 的 apiserver 自動建立了前兩條 ClusterRole,因此只須要建立一條就好了。

# A ClusterRole which instructs the CSR approver to approve a node requesting a
# serving cert matching its client cert.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/selfnodeserver"]
  verbs: ["create"]

將 ClusterRole 綁定到適當的用戶組,以完成自動批准相關 CSR 請求

自動批准 system:bootstrappers 組用戶 TLS bootstrapping 首次申請證書的 CSR 請求
# kubectl create clusterrolebinding node-client-auto-approve-csr --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient --group=system:bootstrappers

自動批准 system:nodes 組用戶更新 kubelet 自身與 apiserver 通信證書的 CSR 請求
# kubectl create clusterrolebinding node-client-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --group=system:nodes

自動批准 system:nodes 組用戶更新 kubelet 10250 api 端口證書的 CSR 請求
# kubectl create clusterrolebinding node-server-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeserver --group=system:nodes
相關文章
相關標籤/搜索