1. 程式人生 > 其它 >kube-apiserver詳解

kube-apiserver詳解

API Server

kube-apiserver 是 Kubernetes 最重要的核心元件之一,主要提供以下的功能

  • 提供叢集管理的 REST API 介面,包括認證授權、資料校驗以及叢集狀態變更等
  • 提供其他模組之間的資料互動和通訊的樞紐(其他模組通過 API Server 查詢或修改資料,只有 API Server 才直接操作 etcd)

REST API

詳情:https://www.bookstack.cn/read/feiskyer-kubernetes-handbook-202005/components-apiserver.md

kube-apiserver 支援同時提供 https(預設監聽在 6443 埠)和 http API(預設監聽在 127.0.0.1 的 8080 埠),其中 http API 是非安全介面,不做任何認證授權機制,不建議生產環境啟用。兩個介面提供的 REST API 格式相同,參考

Kubernetes API Reference檢視所有 API 的呼叫格式。

在實際使用中,通常通過kubectl來訪問 apiserver,也可以通過 Kubernetes 各個語言的 client 庫來訪問 apiserver。在使用 kubectl 時,開啟除錯日誌也可以看到每個 API 呼叫的格式,比如

1 kubectl --v=8 get pods

可通過kubectl api-versionskubectl api-resources查詢 Kubernetes API 支援的 API 版本以及資源物件。

kubectl api-versions
admissionregistration.k8s.io
/v1beta1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 apps/v1beta1 apps/v1beta2 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 batch/v1 batch/v1beta1 certificates.k8s.io/v1beta1 events.k8s.io
/v1beta1 extensions/v1beta1 metrics.k8s.io/v1beta1 networking.k8s.io/v1 policy/v1beta1 rbac.authorization.k8s.io/v1 rbac.authorization.k8s.io/v1beta1 scheduling.k8s.io/v1beta1 storage.k8s.io/v1 storage.k8s.io/v1beta1 v1 $ kubectl api-resources --api-group=storage.k8s.io NAME SHORTNAMES APIGROUP NAMESPACED KIND storageclasses sc storage.k8s.io false StorageClass volumeattachments storage.k8s.io false VolumeAttachment

OpenAPI 和 Swagger

通過/swaggerapi可以檢視 Swagger API,/openapi/v2檢視 OpenAPI。

開啟--enable-swagger-ui=true後還可以通過/swagger-ui訪問 Swagger UI。

根據 OpenAPI 也可以生成各種語言的客戶端,比如可以用下面的命令生成 Go 語言的客戶端:

 1 git clone https://github.com/kubernetes-client/gen /tmp/gen
 2 cat >go.settings <<EOF
 3 # Kubernetes branch name
 4 export KUBERNETES_BRANCH="release-1.11"
 5 # client version for packaging and releasing.
 6 export CLIENT_VERSION="1.0"
 7 # Name of the release package
 8 export PACKAGE_NAME="client-go"
 9 EOF
10 /tmp/gen/openapi/go.sh ./client-go ./go.settings

訪問控制

Kubernetes API 的每個請求都會經過多階段的訪問控制之後才會被接受,這包括認證、授權以及准入控制(Admission Control)等。

認證

開啟 TLS 時,所有的請求都需要首先認證。Kubernetes 支援多種認證機制,並支援同時開啟多個認證外掛(只要有一個認證通過即可)。如果認證成功,則使用者的username會傳入授權模組做進一步授權驗證;而對於認證失敗的請求則返回 HTTP 401。

Kubernetes 不直接管理使用者

雖然 Kubernetes 認證和授權用到了 username,但 Kubernetes 並不直接管理使用者,不能建立 user 物件,也不儲存 username。

更多認證模組的使用方法可以參考Kubernetes 認證外掛

詳情

授權

認證之後的請求就到了授權模組。跟認證類似,Kubernetes 也支援多種授權機制,並支援同時開啟多個授權外掛(只要有一個驗證通過即可)。如果授權成功,則使用者的請求會發送到准入控制模組做進一步的請求驗證;而對於授權失敗的請求則返回 HTTP 403.

更多授權模組的使用方法可以參考Kubernetes 授權外掛

准入控制

准入控制(Admission Control)用來對請求做進一步的驗證或新增預設引數。不同於授權和認證只關心請求的使用者和操作,准入控制還處理請求的內容,並且僅對建立、更新、刪除或連線(如代理)等有效,而對讀操作無效。准入控制也支援同時開啟多個外掛,它們依次呼叫,只有全部外掛都通過的請求才可以放過進入系統。

更多准入控制模組的使用方法可以參考Kubernetes 准入控制

啟動 apiserver 示例

 1 kube-apiserver --feature-gates=AllAlpha=true --runtime-config=api/all=true \
 2 --requestheader-allowed-names=front-proxy-client \
 3 --client-ca-file=/etc/kubernetes/pki/ca.crt \
 4 --allow-privileged=true \
 5 --experimental-bootstrap-token-auth=true \
 6 --storage-backend=etcd3 \
 7 --requestheader-username-headers=X-Remote-User \
 8 --requestheader-extra-headers-prefix=X-Remote-Extra- \
 9 --service-account-key-file=/etc/kubernetes/pki/sa.pub \
10 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
11 --tls-private-key-file=/etc/kubernetes/pki/apiserver.key \
12 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt \
13 --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt \
14 --insecure-port=8080 \
15 --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds \
16 --requestheader-group-headers=X-Remote-Group \
17 --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key \
18 --secure-port=6443 \
19 --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \
20 --service-cluster-ip-range=10.96.0.0/12 \
21 --authorization-mode=RBAC \
22 --advertise-address=192.168.0.20--etcd-servers=http://127.0.0.1:2379

工作原理

kube-apiserver 提供了 Kubernetes 的 REST API,實現了認證、授權、准入控制等安全校驗功能,同時也負責叢集狀態的儲存操作(通過 etcd)。

/apis/batch/v2alpha1/jobs為例,GET 請求的處理過程如下圖所

API 訪問

有多種方式可以訪問 Kubernetes 提供的 REST API:

kubectl

1 kubectl get --raw /api/v1/namespaces
2 kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
3 kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods

kubectl proxy

1 $ kubectl proxy --port=8080&
2 $ curl http://localhost:8080/api/
3 {
4 "versions":[
5 "v1"
6 ]
7 }

curl

 1 # In Pods with service account.
 2 $ TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
 3 $ CACERT=/run/secrets/kubernetes.io/serviceaccount/ca.crt
 4 $ curl --cacert $CACERT --header "Authorization: Bearer $TOKEN"  https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api
 5 {
 6 "kind":"APIVersions",
 7 "versions":[
 8 "v1"
 9 ],
10 "serverAddressByClientCIDRs":[
11 {
12 "clientCIDR":"0.0.0.0/0",
13 "serverAddress":"10.0.1.149:443"
14 }
15 ]
16 }
 1 # Outside of Pods.
 2 $ APISERVER=$(kubectl config view | grep server | cut -f 2--d ":"| tr -d " ")
 3 $ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ')| grep -E '^token'| cut -f2 -d':'| tr -d '\t')
 4 $ curl $APISERVER/api --header "Authorization: Bearer $TOKEN"--insecure
 5 {
 6 "kind":"APIVersions",
 7 "versions":[
 8 "v1"
 9 ],
10 "serverAddressByClientCIDRs":[
11 {
12 "clientCIDR":"0.0.0.0/0",
13 "serverAddress":"10.0.1.149:443"
14 }
15 ]
16 }

API 參考文件

最近 3 個穩定版本的 API 參考文件為: