每一個service對應一個cluster IP,cluster IP對應的服務網段最初是在配置kube-apiserver、kube-controller-manager和kube-proxy的systemd unit時指定的,如kube-apiserver參數爲--service-cluster-ip-range。node
Service提供提供了一種穩定訪問一組pod的方式。Service使用clusterIP:port(默認方式)對外暴露服務,將外部流量從clusterIP:port導入到service中定義的selector標籤指定的endpoint的targetport端口上(默認狀況下targetport將被設置爲與port字段相同的值)。Kube-proxy則爲service提供了一種實現負載均衡的策略。Endpoint會在service建立後被自動建立。git
集羣中能夠經過配置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配置,內容爲:github
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記錄。bootstrap
Serviceaccount就是pod中的process訪問kubernetes API的account。Serviceaccount只關聯了一個secret資源做爲token,該token也叫service-account-token,是真正在API server驗證環節起做用的。api
service-account-token分爲3部分:bash
ca.crt:API Server的CA公鑰證書,用於POD的process對API server服務端數字證書進行校驗使用,由kube-controller-manager參數--root-ca-file指定;服務器
namespace:secret所在的namespace值的base64編碼app
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的受權權限。dom
經過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/
當前該功能僅支持爲kubelet生成證書。Bootstrap-token是在新建集羣或者在現有集羣中添加新節點時使用的,爲kubelet提供tls客戶端證書。Bootstrap-token被定義成一個特定類型的 secrets(bootstrap.kubernetes.io/token)。
kubelet 發起的 CSR 請求都是由 controller manager 來作實際簽署的,對於 controller manager 來講,TLS bootstrapping 下 kubelet 發起的 CSR 請求大體分爲如下三種
首次啓動時,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
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/