kubernetes關鍵概念總結


  • 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:serviceaccountssystem: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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM