- service
每個service對應一個cluster IP,cluster IP對應的服務網段最初是在配置kube-apiserver、kube-controller-manager和kube-proxy的systemd unit時指定的,如kube-apiserver參數為--service-cluster-ip-range。
Service提供提供了一種穩定訪問一組pod的方式。Service使用clusterIP:port(默認方式)對外暴露服務,將外部流量從clusterIP:port導入到service中定義的selector標簽指定的endpoint的targetport端口上(默認情況下targetport將被設置為與port字段相同的值)。Kube-proxy則為service提供了一種實現負載均衡的策略。Endpoint會在service創建后被自動創建。
- kube-dns
集群中可以通過配置Kube-dns來實現服務發現的功能。Kube-dns實現了服務名到cluster IP的映射關系。Kube-dns通常會為service賦予一個名為“service名稱.namespace.svc.cluster.local”的A記錄,用來解析service的cluster IP。如果訪問default namespace下的服務,可以通過“service名稱”直接訪問;如果訪問其他namespace下的服務,可以通過“service名稱.namespace”訪問。k8s會為每個容器提供默認的/etc/resolv.conf配置,內容為:
search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.0.0.10 options ndots:5
集群通過查詢/etc/resolv.conf文件的nameserver字段來確定dns服務器,該文件是在kubelet服務啟動配置中指定—cluster-dns,並在服務啟動后自動生成的。當用“service名稱”訪問服務時,最終會使用default.svc.cluster.local這條search記錄拼接完整的服務名稱;當使用“service名稱.namespace”時,最終會使用svc.cluster.local這條search記錄。
- serviceaccount
Serviceaccount就是pod中的process訪問kubernetes API的account。Serviceaccount只關聯了一個secret資源作為token,該token也叫service-account-token,是真正在API server驗證環節起作用的。
service-account-token分為3部分:
ca.crt:API Server的CA公鑰證書,用於POD的process對API server服務端數字證書進行校驗使用,由kube-controller-manager參數--root-ca-file指定;
namespace:secret所在的namespace值的base64編碼
token:用API server私鑰簽發(sign)的bearer tokens的base64編碼,用於POD訪問API server的身份驗證(Authorization header首部)
一旦API Server發現client發起的request使用的是service account token的方式,API Server就會自動采用signed bearer token方式進行身份校驗。而request就會使用攜帶的service account token參與驗證。該token是API Server在創建service account時用kube-controller-manager啟動參數:--service-account-private-key-file指定的私鑰簽署(sign)的,同時必須指定kube-apiserver參數--service-account-key-file(如果沒指定的話,會使用–tls-private-key-file替代)為該私鑰對應的公鑰,用來在認證階段驗證token(You must pass a service account private key file to the token controller in the controller-manager by using the --service-account-private-key-file
option. The private key will be used to sign generated service account tokens. Similarly, you must pass the corresponding public key to the kube-apiserver using the --service-account-key-file
option. The public key will be used to verify the tokens during authentication),也就是說該證書對通過CN和O指定了serviceaccount的授權權限。
通過authenticating后,API Server將根據Pod username所在的group system:serviceaccounts和system:serviceaccounts:(NAMESPACE)的權限對其進行authority 和admission control兩個環節的處理。(Service Accounts have usernames with the system:serviceaccount: prefix and belong to groups with the system:serviceaccounts: prefix,形如system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT))
不管是自動生成的token還是手動創建的token的值都是一樣的,因為進行簽署token的–service-account-key-file是同一個。
Serviceaccount中的token是API server私鑰簽署的,POD在對API Server發起請求的時候會帶上該token,以確保能夠通過API server的認證。對serviceaccount的授權通過對serviceaccount對應的用戶或組進行RBAC控制即可
參見: https://k8smeetup.github.io/docs/admin/authorization/rbac/
- tls-bootstrapping
當前該功能僅支持為kubelet生成證書。Bootstrap-token是在新建集群或者在現有集群中添加新節點時使用的,為kubelet提供tls客戶端證書。Bootstrap-token被定義成一個特定類型的 secrets(bootstrap.kubernetes.io/token)。
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),kubelet renew 自己作為 client 跟 apiserver 通訊時使用的證書產生;
- selfnodeserver: kubelet server renew 自己的證書發起的 CSR 請求,kubelet 首次申請或后續 renew 自己的 10250 api 端口證書時產生
首次啟動時,kube-apiserver會指定--token-auth-file=FILENAME來啟用用戶的token,同時該用戶的token和apiserver的CA證書被寫入了kubelet的bootstrap.kubeconfig文件中,這樣在首次請求時,kubelet 使用 bootstrap.kubeconfig 中的 apiserver CA 證書來與 apiserver 建立 TLS 通訊,使用 bootstrap.kubeconfig 中的用戶kubelet-bootstrap(需要創建clusterRoBingding來將預設用戶與內置的system:node-bootstrapper綁定到一起) 的Token 來向 apiserver 聲明自己的 RBAC 授權身份(用戶為kubelet-bootstrap,組為system:kubelet-bootstrap)。
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') cat > token.csv <<EOF ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
綁定用戶kubelet-bootstrap到內置ClusterRole(system:node-bootstrapper):kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
對於bootstrap下的kubelet的CSR的審批可以手動審批,也可以自動審批:
手動審批:
需要將用戶與內置的clusterrole system:node-strapper綁定,並注意設置證書過期時間(默認有效期為1年):設置kube-controller-manager參數--experimental-cluster-signing-duration設置為10年(防止證書過期):8760h0m0s
手動簽發證書命令為:kubectl certificate approve XXX (xxx為CSR,使用kubectl get csr獲取)
自動審批:
k8s針對bootstrap下kubelet發起的3種CSR給出了3種對應的clusterrole,想要kubelet能夠自動續期,只要將適當的clusterrole綁定到kubelet自動續期時采用的用戶或用戶組上即可。基於3種clusterrole需要創建3個clusterrolebinding。1.8中已經創建了前兩條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"]
3個clusterrole對應的clusterbingding如下:
# 自動批准 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
啟動自動續期:kubelet啟動時增加--feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true,--rotate-certificates;kube-controller-manager啟動時增加--feature-gates=RotateKubeletServerCertificate=true
- kubelet端口
10250 kubelet API –kublet暴露出來的端口,通過該端口可以訪問獲取node資源以及狀態
10255 readonly API –kubelet暴露出來的只讀端口,訪問該端口不需要認證和鑒權,該http server提供查詢資源以及狀態的能力
-
參考:
https://mritd.me/2018/01/07/kubernetes-tls-bootstrapping-note/
https://kubernetes.io/docs/tasks/tls/certificate-rotation/