Kubernetes API服務器為API對象驗證和配置數據,這些對象包含Pod、Service、ReplicationController等等。API Server提供REST操作以及前端到集群的共享狀態,所有其他組件可以通過這些共享狀態交互。
配置選項
- -admission-control:集群中資源的Admission Controller的插件的有序列表,分別使用逗號分隔;
- -advertise-address:廣播API Server給所有集群成員的IP地址,其他集群可以訪問該IP,如果為空,會使用
- -allow-privileged[=false]:true,表示允許特權容器;
- -authorization-mode=“AlwaysAllow”:安全端口授權插件的有序列表,分別以逗號分隔,AlwaysAllow,AlwaysDeny,ABAC-;
- authorization-policy-file=“”:授權策略的csv文件,使用於-authorization-mode=ABAC模式的配置;
- -basic-auth-file=“”:如果配置該選項,該文件會通過HTTP基本認證允許API Server安全端口的請求;
- -bind-address=0.0.0.0:服務-read-only-port和-secure-port端口的IP地址。相關端口必須是其他集群通過CLI/web客戶端;
- -cert-dir=“/var/run/kubernetes/”:TLS證書目錄(默認是/var/run/kubernetes)。
- -tls-cert-file和-tls-client-ca-file=“”:任何提交客戶端證書的請求都會驗證與相關客戶端證書的CommonName的身份。(在1.5版本中--client_ca_file);
- -cloud-provide:“”:雲提供商配置文件的路徑,空表示沒有該配置文件;
- -cloud-provider=””:雲服務提供商,空表示沒有該提供商;
- -cluster-name=“kubernetes”:集群實例的前綴;
- -cors-allowed-origins=[]:CORS的allowed origins的列表,用逗號分隔。一個allowed origins可以是-etcd-config=“”:ETCD客戶端的配置文件,與-etcd-servers配置項互斥。
- -etcd-prefix=“/registry”:ETCD中所有資源路徑的前綴;
- -etcd-servers=[]:ETCD服務器,與-etcd-config配置項互斥;
- -etcd-servers-overrides=[]:每個ETCD服務器覆蓋文件,以逗號分隔;
- -expermental-keystone-url=“”:如果Passwd,激活keystone認證插件;
- -external-hostname=“”:為Master生成外部URLs使用的主機名;
- -google-json-key=“”:用戶Google Cloud Platform Service Account JSON key認證;
- --insecure-bind-address=127.0.0.1:非安全端口(所有借口都設置為0.0.0.0)的服務IP地址,默認是本地地址。
- --insecure-port=8080:不安全且沒有認證的進程訪問端口,默認是8080;
- -kubelet-certificate-authority=“”:證書路徑,證書授權文件;
- -kubelet-client-certificate=“”:TLS客戶端證書文件路徑;
- -kubelet-client-key=“”:TLS客戶端秘鑰文件路徑;
- -kubelet--https[=true]:使用https建立Kubelet鏈接;
- -kubelet-port=10250:kubelet端口;
- -kubelet-timeout=5s:Kubelet操作Timeout值;
- -log-flush-frequency=5s:日志緩沖秒數的最大值;
- -long-running-request-regexp=“”:匹配長;
- -master-service-namespace=“default”:Namespace,該Namespace的Kubernetes主服務應該注入Pod;
- -max-connection-bytes-per-sec=0:如果非0,表示每個用戶鏈接的最大值,字節數/秒,當前只適用於長時間運行的請求;
- -max-request-inflight=400:給定時間內運行請求的最大值。如果超過該最大值,該請求被拒絕。0表示沒有限制;
- -min-request-timeout=1800:這是個可選字段,表示一個請求處理的最短時間,單位是秒,在超時之前,這個請求必須是激活的;
- -oidc-ca-file=“”:如果設置該選項,Oidc-ca-file中的相關機構會驗證O噴ID服務的證書。否則會使用主機的根證書。
- -oidc-client-id=“”:如果設置了oidc-issue-url字那段,該字段,OpenID連接客戶端的客戶ID也必須設置;
- -oidc-issuer-url=“”:OpenID發行的URL,只接受HTTPS協議。如果設置該字段,將被用來驗證OIDC JSON Web Token(JWT)
- -oidc-username-claim=“sub”:改進中;
- -runtime-config:key=value鍵值對集,描述運行時配置,也會回傳到APIServer。apis/鍵值用於打開-secure-port=6443:用於HTTPS的認證和授權。0表示不支持HTTPS服務;
- -service-account-key-file=“”:該文件包含RPM-encoded x509 RSA的私鑰和公鑰,用於驗證ServiceAccount的Token;
- -service-account-lookup[=false]:true,表示驗證ServiceAccount的Token作為Authentication一部分在ETCD中的;
- -service-cluster-ip-range:
- -service-node-port-range:
- -ssh-user=“”:如果非空,使用安全SSH代理到該節點,用該用戶名;
- -storage-versions:
- -tls-private-key-file:該文件包含x509私鑰匹項-tls-cert-file;
- -token-auth-file=“”:該文件使用Token驗證保護API Server的安全端口;
- -watch-cache[=true]:可以在API Server查看緩存;
Kubernetes API Server原理分析
總體來看,Kubernetes API Server的核心功能是提供了Kubernetes各類資源對象(如Pod、RC、Service等)的增、刪、改、查及Watch等HTTP Rest接口,成為集群內各個功能模塊之間數據交互和通信的中心樞紐,是整個系統的數據總線和數據中心。除此之外,他還有以下的特性:
- 是集群管理的API入口;
- 是資源配額控制的入口;
- 提供完備的集群安全機制;
Kubernetes API Server概述
Kubernetes API Server通過一個名為Kube-apiserver的進程提供服務,該進程運行在Master節點上。在默認情況下,kube-apiserver進程在本機的8080端口(對應參數--insecure-port)提供REST服務。我們可以同時啟動HTTPS安全端口(--secure-port=6443)來啟動安全機制,加強REST API訪問的安全性。
通常我們可以通過命令行工具kubectl來與kubernetes API Server交互,他們之間的接口是REST調用。測試和學習的情況下也可以使用curl命令行工具進行快速驗證。
比如,在Master節點上,運行下面的curl命令可以得到JSON方式返回的Kubernetes API的版本信息:
- curl localhost:8080/api
運行下面的命令查看Kubernetes API Server目前支持的資源對象的種類i:
- curl localhost:8080/api/v1
返回不同資源列表信息:
- curl localhost:8080/api/v1/pods
- curl localhost:8080/api/v1/services
- curl localhost:8080/api/v1/replicationcontrollers
如果我們只想對外暴露部分REST服務,則可以在Master或其他任何節點上通過運行kube-proxy進程啟動一個內部代理來實現。
運行下面的命令,我們在8001端口啟動代理,並且拒絕客戶端訪問RC的API:
- kubectl proxy --reject-paths=“^/api/v1/replicationcontrollers” --port=8001 --v=2
通過下面的命令進行驗證:
- curl localhost:8001/api/v1/replicationcontrollers
kubectl proxy具有很多特性,最實用的一個特性是提供簡單有效的安全機制,比如采用白名單來限制非法客戶端訪問時,只要采用下面的參數即可:
- --accept-host=“^localhost$,^127\\.0\\.0\\.1$,^\\[::1\\]$”
最后一種方式是通過b編程的方式調用Kubernetes API Server。具體使用場景又細分為以下兩種:
第一種使用場景:運行在Pod中的用戶進程調用Kubernetes API,通常用來實現分布式集群搭建的目標。Pod中的進程如何知道API Server的訪問地址呢,因為Kubernetes API Server本身也是一個Service,其名字就是Kubernetes,他的clusterIP地址是ClusterIP地址池中的第一個IP,他所服務的端口是HTTPS端口443,通過kubectl get svc可以確認這一點。
第二種使用場景:開發基於Kubernetes的管理平台。比如調用Kubernetes API 來完成Pod、Service、RC等資源對象的圖形化創建和管理界面,此時可以使用kubernetes及各開源社區為開發人員提供的各種語言版本的Client Library。
獨特的Kubernetes-Proxy API接口
這類接口的作用是代理REST請求,即kubernetes API Server把收到的REST請求轉發到某個Node上的kubelet守護進程的REST端口上,由該kubelet進程負責響應。
Kubernetes Proxy API中管理Node的相關接口,該接口的REST路徑為/api/v1/proxy/nodes/{name},其中name為節點名稱或IP地址,包括以下幾個具體的接口:
- /api/v1/proxy/nodes/{name}/pods #列出指定節點內的所有Pod的信息
- /api/v1/proxy/nodes/{name}/stats #列出指定節點內物理資源的統計信息
- /api/v1/proxy/nodes/{name}/spec #列出指定節點的概要信息
例:節點名為k8s-node-1,下面命令獲取該節點上所有運行中的pod:
- curl localhost:8080/api/v1/proxy/nodes/k8s-node-1/pods
需要說明的是,此處獲取pod信息數據來自Node而非etcd數據庫,所以兩者可能在某些時間點會有偏差。此外如果kubelet進程在啟東時包含--enable-debugging-handles=true,namekubernetes Proxy API 還會增加下面的接口:
- /api/v1/proxy/nodes/{name}/run #在節點上運行某個容器
- /api/v1/proxy/nodes/{name}/exec #在節點的某個容器中運行某條命令
- /api/v1/proxy/nodes/{name}/attach #在節點上attach某個容器
- /api/v1/proxy/nodes/{name}/portForward #實現節點上的Pod端口轉發
- /api/v1/proxy/nodes/{name}/logs #列出節點的各類日志信息,例如tallylog、lastlog、wtmp、ppp/、rhsm、audit、tuned、和anaconda等
- /api/v1/proxy/nodes/{name}/metrics #列出和該節點相關的Metrics信息
- /api/v1/proxy/nodes/{name}/runningpods #列出節點內運行中的Pod信息
- /api/v1/proxy/nodes/{name}/debug/pprof #列出節點內當前Web服務的狀態,包括CPU和內存的使用情況
Kubernetes Proxy API里關於Pod的相關接口,通過這些接口,我們可以訪問pod里某個容器提供的服務(如Tomcat在8080提供的服務)
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/{patch:*} #訪問pod的某個服務接口
- /api/v1/proxy/namespaces/{namespace}/pods/{name} #訪問pod
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/proxy/{patch:*} #訪問pod的某個服務接口
- /api/v1/proxy/namespaces/{namespace}/pods/{name}/proxy #訪問pod
在上面的4個接口中,后面兩個接口的功能和前面兩個完全一樣,只是寫法不同。
集群功能模塊之間的通信
集群內各個功能模塊通過API Server將信息存入etcd,當需要獲取和操作這些數據時,則通過API Server提供的REST接口(用GET/LIST/WTCH方法)來實現,從而實現各模之間的信息交互;
例:kubelet進程與API Server的交互:每個node上的kubelet每隔一個時間周期,就會調用一次API Server的REST接口報告自身狀態,API Server接收到這些信息后,將各節點信息更新到etcd中。此外kubelet也通過API Server的watch接口監聽pod信息,如果監聽到新的Pod副本被調度綁定到本節點,則執行Pod對應的容器的創建和啟動邏輯;如果監聽到Pod對象被刪除,則刪除本節點上的相應的Pod容器;如果監聽到修改Pod信息,則kubelet監聽到變化后,會相應的修改本節點的Pod容器。
例:另外一個交互場景:kube-controller-manager進程與API Server的交互。kube-controller-manager中的Node Controller模塊通過API Server提供的Watch接口,實時監控Node的信息並做相應的處理;
例:kube-scheduler與API Server交互的場景,當scheduler通過API Server的Watch接口監聽到新建Pod副本的信息后,他會檢索所有符合該Pod要求的Node列表,開始執行Pod調度邏輯,調度成功后將Pod綁定到目標節點上。為了緩解集群各模塊對API Server的壓力,各功能模塊都采用緩存的機制來緩存數據。各功能模塊定時從API Server獲取指定資源對象的信息(通過LIST或watch),然后將這些信息保存到本地緩存,功能模塊在某些情況下不直接訪問API Server,而是通過訪問緩存數據來間接訪問API Server