系統環境:
- 部署方式:二進制
- Docker 版本:19.03.8
- kubernetes 版本:1.20.1
- 操作系統版本:CentOS 7.8
- metrics server 版本:0.4.1
參考地址:
一、問題描述
通過二進制方式部署完成 kubernetes
后,部署 Metrics Server
后,查看日志出現下面錯誤信息:
E1231 10:33:31.978715 1 configmap_cafile_content.go:243] key failed with:
missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file" E1231 10:34:22.710836 1 configmap_cafile_content.go:243] kube-system/extension-apiserver-authentication failed with: missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file" E1231 10:34:31.978769 1 configmap_cafile_content.go:243] key failed with: missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file"
根據錯誤日志信息,可以知道是缺少認證的證書文件,導致不能訪問 kube-apiserver
而出現的問題。
二、問題分析
1、查找資料分析原因
經過網上查找搜尋,從一篇博客中 https://www.lingjie.tech/article/2020-11-07/20 找到答案。之所以出現這個錯誤是因為 kube-apiserver 沒有開啟 API
聚合功能。所以需要配置 kube-apiserver
參數,開啟聚合功能即可。
2、什么是 API 聚合
這里的 API 聚合機制
是 Kubernetes 1.7 版本引入的特性,能夠將用戶擴展的 API
注冊到 kube-apiserver
上,仍然通過 API Server
的 HTTP URL
對新的 API
進行訪問和操作。為了實現這個機制,Kubernetes 在 kube-apiserver
服務中引入了一個 API 聚合層(API Aggregation Layer)
,用於將 擴展 API
的訪問請求轉發到用戶服務的功能。
為了能夠將用戶自定義的 API 注冊到 Master
的 API Server
中,首先需要在 Master 節點所在服務器,配置 kube-apiserver
應用的啟動參數來啟用 API 聚合
功能,參數如下:
--runtime-config=api/all=true --requestheader-allowed-names=aggregator --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-client-ca-file=/etc/kubernetes/pki/ca.pem --proxy-client-cert-file=/etc/kubernetes/pki/proxy-client.pem --proxy-client-key-file=/etc/kubernetes/pki/proxy-client-key.pem
如果 kube-apiserver
所在的主機上沒有運行 kube-proxy
,即無法通過服務的 ClusterIP
進行訪問,那么還需要設置以下啟動參數:
--enable-aggregator-routing=true
在設置完成重啟 kube-apiserver
服務,就啟用 API 聚合
功能了。
$ systemctl daemon-reload && systemctl restart kube-apiserver
三、解決問題
按照上面的解決問題思路,我們可以開啟 API 聚合功能,然后重啟 Metrics Server 服務,步驟如下:
1、安裝 cfssl 工具
## 下載三個組件 $ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O cfssl $ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O cfssljson $ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O cfssl-certinfo ## 復制到 bin 目錄下 $ chmod +x ./cfssl* $ mv ./cfssl* /usr/local/bin/
2、創建 cfssl 配置文件
創建 proxy-client-csr.json 文件:
{
"CN": "aggregator", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:masters", "OU": "System" } ] }
生成證書和秘鑰:
## Master1 執行下面命令生成證書 $ cfssl gencert \ -profile=kubernetes \ -ca=/etc/kubernetes/pki/ca.pem \ -ca-key=/etc/kubernetes/pki/ca-key.pem \ proxy-client-csr.json
查看生產的證書:
$ ls -l
-rw-r--r-- 1 root root 1017 12月 31 11:20 proxy-client.csr
-rw-r--r-- 1 root root 236 12月 31 11:07 proxy-client-csr.json
-rw------- 1 root root 1675 12月 31 11:20 proxy-client-key.pem
-rw-r--r-- 1 root root 1411 12月 31 11:20 proxy-client.pem
將證書訪問指定的目錄下,這里我將其放到 /etc/kubernetes/pki 下:
$ cp * /etc/kubernetes/pki/
復制到其它 Master 節點服務器中:
## 復制到 Master2 $ scp * 192.168.2.11:/etc/kubernetes/pki/ ## 復制到 Master3 $ scp * 192.168.2.12:/etc/kubernetes/pki/
3、修改 kube-apiserver 參數
修改三個 Master 節點中全部 kube-apiserver 配置參數:
vi /etc/kubernetes/manifests/kube-apiserver.yaml
...
--runtime-config=api/all=true \ --requestheader-allowed-names=aggregator \ --requestheader-group-headers=X-Remote-Group \ --requestheader-username-headers=X-Remote-User \ --requestheader-extra-headers-prefix=X-Remote-Extra- \ --requestheader-client-ca-file=/etc/kubernetes/pki/ca.pem \ --proxy-client-cert-file=/etc/kubernetes/pki/proxy-client.pem \ --proxy-client-key-file=/etc/kubernetes/pki/proxy-client-key.pem \ ...
參數說明:
- –requestheader-client-ca-file: 客戶端CA證書。
- –requestheader-allowed-names: 允許訪問的客戶端 common names 列表,通過 header 中 –requestheader-username-headers 參數指定的字段獲取。客戶端 common names 的名稱需要在 client-ca-file 中進行設置,將其設置為空值時,表示任意客戶端都可訪問。
- –requestheader-username-headers: 參數指定的字段獲取。
- –requestheader-extra-headers-prefix: 請求頭中需要檢查的前綴名。
- –requestheader-group-headers 請求頭中需要檢查的組名。
- –requestheader-username-headers 請求頭中需要檢查的用戶名。
- –proxy-client-cert-file: 在請求期間驗證Aggregator的客戶端CA證書。
- –proxy-client-key-file: 在請求期間驗證Aggregator的客戶端私鑰。
- –requestheader-allowed-names: 允許訪問的客戶端 common names 列表,通過 header 中 –requestheader-username-headers 參數指定的字段獲取。客戶端 common names 的名稱需要在 client-ca-file 中進行設置,將其設置為空值時,表示任意客戶端都可訪問。
4、重啟 kube-apiserver 組件
重啟三個 Master 服務器中全部 kube-apiserver 組件:
$ systemctl daemon-reload && systemctl restart kube-apiserver
5、重啟 Metrics Server 應用
查看已有的 metrics server 的 pod:
$ kubectl get pods -n kube-system | grep metrics-server
metrics-server-7455879dcc-w9dw7 1/1 Running 0 1d
刪掉已有的 metrics server 的 pod,使其重新生成新的 pod 資源:
$ kubectl delete pods metrics-server-7455879dcc-w9dw7 -n kube-system
6、輸入命令進行驗證
等一段時間,然后輸入下面命令進行測試:
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master-10 300m 3% 4788Mi 30%
k8s-master-11 800m 5% 5218Mi 31%
k8s-master-12 500m 4% 4900Mi 31%
k8s-woker-021 81m 1% 2930Mi 9%
k8s-woker-022 61m 0% 1658Mi 5%
k8s-woker-023 62m 0% 6061Mi 22%
可以觀察到命令已經可以正常使用。