在后續集群安裝kubelet時有些參數 ,建議通過配置文件的方式提供參數,因為這樣可以簡化節點部署和配置管理
具體參考文檔
https://kubernetes.io/zh/docs/tasks/administer-cluster/kubelet-config-file/
https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/
相應配置參數的字段類型都可以在這里面找到
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubelet/config/v1beta1/types.go
https://blog.csdn.net/qq_38496902/article/details/106560163
KubeletConfiguration
結構體定義了可以通過文件配置的 Kubelet 配置子集、
提示一下:types.go出現的配置字段 ,如果要寫入yaml文件參考后面json 格式配置文件必須是這個結構體中參數的 JSON 或 YAML 表現形式
https://github.com/ReSearchITEng/kubeadm-playbook/blob/master/group_vars/all/KubeletConfiguration.yml
最終的kubelet 相應的配置文件截圖
相應的配置文件說明
https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kubelet/
同理 kube-proxy也通過配置文件來啟動,啟動的時候有提示
https://github.com/kubernetes/kube-proxy/blob/master/config/v1alpha1/types.go
https://pkg.go.dev/k8s.io/kube-proxy/config/v1alpha1#KubeProxyConfiguration
配置文件格式
https://github.com/ReSearchITEng/kubeadm-playbook/blob/master/group_vars/all/KubeProxyConfiguration.yml
https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/
啟動腳本
相關的啟動參數說明:
https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-proxy/
Kubelet 認證/鑒權
在通過kubectl訪問pod信息,例如執行kubectl logs,常常會遇到類似如下錯誤:
Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log tiller-deploy-6b5ffb6f-lg9jb)
-tools-reference/kubelet-authentication-authorization/
網上搜索可以通過啟用anonymous訪問,也就是使用--anonymous-auth=true
或者配置文件添加:
authentication: anonymous: enabled: true
但是設置之后錯誤依舊,為此我探究了一下kubelet的認證機制,終於將問題解決,其實很簡單,答案后面揭曉。
官方文檔介紹:
https://kubernetes.io/zh/docs/reference/command-line
我們知道kubectl只會和apiserver交互,對於kubectl logs kubectl exec等需要訪問pod的這些命令,實際上是apiserver調用kubelet接口完成的,上述錯誤正是出在這個過程,而不是kubectl到apiserver的過程。
kubelet通過port指定的端口(默認10250)對外暴露服務,這個服務是需要TLS認證的,同時也可以通過 readOnlyPort 端口(默認10255,0表示關閉)對外暴露只讀服務,這個服務是不需要認證的。
apiserver通過 --kubelet-https 參數指定調用哪個服務,true為前者,false為后者,此時只能執行只讀操作。
認證過程
配置認證方式
有三種可配置認證方式:
-
TLS認證,這也是默認的
authentication: anonymous: enabled: false webhook: enabled: false x509: clientCAFile: xxxx
-
允許anonymous,這時可不配置客戶端證書
authentication: anonymous: enabled: true
-
webhook,這時可不配置客戶端證書
authentication: webhook: enabled: true
這時kubelet通過bearer tokens,找apiserver認證,如果存在對應的serviceaccount,則認證通過
如果2開啟,則忽略x509和webhook認證;否則,如果1和3同時開啟,則按1、3的順序依次認證,任何一個認證通過則返回通過,否則認證不通過。
通過kubectl命令行訪問kubelet時,無法傳遞bearer tokens,所以無法使用webhook認證,這時只能使用x509認證
默認情況下,到kubelet HTTPS endpoints
且沒有被其他配置的認證方法拒絕的請求被視為匿名請求。
對於匿名請求會給定system:anonymous
的用戶名和system:unauthenticated
用戶組
禁止匿名用戶訪問,對不可靠的請求返回401 Unauthorized
:
啟動kubelet的時候添加--anonymous-auth=false
參數
開啟X509
客戶端證書認證:
- 添加啟動參數--client-ca-file
, 並提供一個驗證客戶端證書的CA。
- 啟動apiserver
時需添加--kubelet-client-certificate
和 --kube-client-key
參數
- 詳情參考 apiserver authentication documentation
kubelet對外暴露https服務,必須設置服務端證書,如果通過x509證書認證客戶端,那么還需要配置客戶端證書。
下面說明證書配置的三種方法:
手工指定證書
假設ca的證書和key:ca.pem,ca-key.pem
用上述ca生成kubelet服務端證書和key:kubelet-server.pem、kubelet-server-key.pem
用上述ca生成apiserver使用的客戶端證書和key:kubelet-client.pem、kubelet-client-key.pem,證書CN為kubelet-client
修改kubelet的配置文件:
tlsCertFile: kubelet-server.pem
tlsPrivateKeyFile: kubelet-server-key.pem
authentication:
x509:
clientCAFile: ca.pem
修改apiserver參數:
--kubelet-certificate-authority=ca.pem --kubelet-client-certificate=kubelet-client.pem --kubelet-client-key=kubelet-client-key.pem
授權kubelet-client用戶:
kubectl create clusterrolebinding kubelet-admin --clusterrole=system:kubelet-api-admin --user=kubelet-client
經過上面5步,認證的過程實際已經OK了,第6步是為授權過程服務的,kubelet的授權是通過webhook委托給apiserver的。
自簽名證書和key
實際上是上述過程的特化,不指定tlsCertFile和tlsPrivateKeyFile時,kubelet會自動生成服務端證書保存在--cert-dir指定目錄中,文件名為kubelet.crt和kubelet.key,這個證書是自簽名的,所以apiserver不需要指定--kubelet-certificate-authority,其他配置是一樣的
通過TLS bootstrap機制
還可以通過TLS bootstrap機制分配kubelet服務證書。配置分配訪問apiserver的客戶端證書方法是一樣的(參考官方文檔)或者我前面寫的文章
之后在相應kubelet的--cert-dir目錄可以看到服務端證書已經生成。
配置客戶端證書和前面的方法是一樣的,上面3步只是生成服務端證書。
選擇哪種方式
客戶端證書配置是免不了的,區別是在服務端證書,顯然自動生成更加方便,TLS bootstrap相對於自簽名證書更加安全,集群統一使用信任的CA簽名。
授權過程
配置授權方式
可配置兩種授權方式:
-
AlwaysAllow:從字面意思就可知道
authorization: mode: AlwaysAllow
-
Webhook:這是默認模式
authorization: mode: Webhook
這時授權過程是委托給apiserver的,使用apiserver一樣的授權模式,也就是RBAC。
配置權限
如果通過Webhook授權,就需要通過RBAC為用戶配置權限。
首先要弄清楚通過認證的用戶是什么,通過x509證書認證的用戶名是客戶端證書中的CN字段,用戶組為O字段;通過webhook認證的用戶是token對應的serviceaccount;沒有通過認證或使能anonymous,則用戶為system:anonymous。
其次要弄清楚應該授權什么權限,系統已經存在一個system:kubelet-api-admin角色,這是最高的權限,可以根據需要創建低權限角色。
如果不創建權限會報相應的錯誤
確保傳遞給apiserver的--kubelet-client-certificate
和--kubelet-client-key
標志所標識的用戶具有以下屬性的權限:
- verb=*, resource=nodes, subresource=proxy
- verb=*, resource=nodes, subresource=stats
- verb=*, resource=nodes, subresource=log
- verb=*, resource=nodes, subresource=spec
- verb=*, resource=nodes, subresource=metrics
kubectl create clusterrolebinding kubernetes --clusterrole=system:kubelet-api-admin --user=kubernetes
這邊吧kubelet-api-admin的權限用戶給到證書里標識的用戶
最終kubelet 的配置文件:
總結
如何配置kubelet的認證和授權,歸結起來常用如下2種做法:
-
省事型,可用於開發環境
authentication: anonymous: enabled: true authorization: mode: AlwaysAllow
一開始出現的Forbidden問題就是沒有配置AlwaysAllow,默認是Webhook。
-
安全型,生產環境使用
authentication: anonymous: enabled: false authorization: mode: Webhook
服務端證書通過TLS bootstrap,客戶端證書需要手工配置。
參考文檔:
https://www.cnblogs.com/zhongpan/p/11964017.html
https://blog.csdn.net/mailjoin/article/details/79679882