API Server簡介
k8s API Server提供了k8s各種資源對象(pod,RC,Service等)的增刪改查及watch等HTTP Rest接口,是整個系統的數據總線和數據中心。html
kubernetes API Server的功能:java
- 提供了集羣管理的REST API接口(包括認證受權、數據校驗以及集羣狀態變動);
- 提供其餘模塊之間的數據交互和通訊的樞紐(其餘模塊經過API Server查詢或修改數據,只有API Server才直接操做etcd);
- 是資源配額控制的入口;
- 擁有完備的集羣安全機制.
kube-apiserver工做原理圖node
如何訪問kubernetes API
k8s經過kube-apiserver這個進程提供服務,該進程運行在單個k8s-master節點上。默認有兩個端口。mysql
k8s經過kube-apiserver這個進程提供服務,該進程運行在單個k8s-master節點上。默認有兩個端口。linux
1. 本地端口
- 該端口用於接收HTTP請求;
- 該端口默認值爲8080,能夠經過API Server的啓動參數「--insecure-port」的值來修改默認值;
- 默認的IP地址爲「localhost」,能夠經過啓動參數「--insecure-bind-address」的值來修改該IP地址;
- 非認證或受權的HTTP請求經過該端口訪問API Server。
2.安全端口
- 該端口默認值爲6443,可經過啓動參數「--secure-port」的值來修改默認值;
- 默認IP地址爲非本地(Non-Localhost)網絡端口,經過啓動參數「--bind-address」設置該值;
- 該端口用於接收HTTPS請求;
- 用於基於Tocken文件或客戶端證書及HTTP Base的認證;
- 用於基於策略的受權;
- 默認不啓動HTTPS安全訪問控制。
kubernetes API訪問方式
Kubernetes REST API可參考https://kubernetes.io/docs/api-reference/v1.6/nginx
1. curl
curl localhost: 8080 /api git curl localhost: 8080 /api/v1/pods github curl localhost: 8080 /api/v1/services web curl localhost: 8080 /api/v1/replicationcontrollers sql |
2. Kubectl Proxy
Kubectl Proxy代理程序既能做爲API Server的反向代理,也能做爲普通客戶端訪問API Server的代理。經過master節點的8080端口來啓動該代理程序。
kubectl proxy --port=8080 &
具體見kubectl proxy --help
3. kubectl客戶端
命令行工具kubectl客戶端,經過命令行參數轉換爲對API Server的REST API調用,並將調用結果輸出。
命令格式:kubectl [command] [options]
具體可參考Kubernetes經常使用命令
4. 編程方式調用
使用場景:
一、運行在Pod裏的用戶進程調用kubernetes API,一般用來實現分佈式集羣搭建的目標。
二、開發基於kubernetes的管理平臺,好比調用kubernetes API來完成Pod、Service、RC等資源對象的圖形化建立和管理界面。可使用kubernetes提供的Client Library。
具體可參考https://github.com/kubernetes/client-go。
經過API Server訪問Node、Pod和Service
k8s API Server最主要的REST接口是資源對象的增刪改查,另外還有一類特殊的REST接口—k8s Proxy API接口,這類接口的做用是代理REST請求,即kubernetes API Server把收到的REST請求轉發到某個Node上的kubelet守護進程的REST端口上,由該kubelet進程負責響應。
1. Node相關接口
關於Node相關的接口的REST路徑爲:/api/v1/proxy/nodes/{name},其中{name}爲節點的名稱或IP地址。
/api/v1/proxy/nodes/ {name} /pods/ #列出指定節點內全部Pod的信息 /api/v1/proxy/nodes/ {name} /stats/ #列出指定節點內物理資源的統計信息 /api/v1/prxoy/nodes/ {name} /spec/ #列出指定節點的概要信息 |
這裏獲取的Pod信息來自Node而非etcd數據庫,二者時間點可能存在誤差。若是在kubelet進程啓動時加--enable-debugging-handles=true參數,那麼kubernetes 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 #列出節點的各種日誌信息 /api/v1/proxy/nodes/ {name} /metrics #列出和該節點相關的Metrics信息 /api/v1/proxy/nodes/ {name} /runningpods #列出節點內運行中的Pod信息 /api/v1/proxy/nodes/ {name} /debug/pprof #列出節點內當前web服務的狀態,包括CPU和內存的使用狀況 |
2. Pod相關接口
/api/v1/proxy/namespaces/ {namespace} /pods/ {name}/{path:*} #訪問pod的某個服務接口 /api/v1/proxy/namespaces/ {namespace} /pods/ {name} #訪問Pod #如下寫法不一樣,功能同樣 /api/v1/namespaces/ {namespace} /pods/ {name} /proxy/ {path:*} #訪問pod的某個服務接口 /api/v1/namespaces/ {namespace} /pods/ {name} /proxy #訪問Pod |
3. Service相關接口
/api/v1/proxy/namespaces/ {namespace} /services/ {name} |
Pod的proxy接口的做用:在kubernetes集羣以外訪問某個pod容器的服務(HTTP服務),能夠用Proxy API實現,這種場景多用於管理目的,好比逐一排查Service的Pod副本,檢查哪些Pod的服務存在異常問題。
集羣功能模塊之間的通訊
kubernetes API Server做爲集羣的核心,負責集羣各功能模塊之間的通訊,集羣內各個功能模塊經過API Server將信息存入etcd,當須要獲取和操做這些數據時,經過API Server提供的REST接口(GET\LIST\WATCH方法)來實現,從而實現各模塊之間的信息交互。
1. kubelet與API Server交互
每一個Node節點上的kubelet按期就會調用API Server的REST接口報告自身狀態,API Server接收這些信息後,將節點狀態信息更新到etcd中。kubelet也經過API Server的Watch接口監聽Pod信息,從而對Node機器上的POD進行管理。
監聽信息 |
kubelet動做 |
備註 |
新的POD副本被調度綁定到本節點 |
執行POD對應的容器的建立和啓動邏輯 |
|
POD對象被刪除 |
刪除本節點上相應的POD容器 |
|
修改POD信息 |
修改本節點的POD容器 |
|
2. kube-controller-manager與API Server交互
kube-controller-manager中的Node Controller模塊經過API Server提供的Watch接口,實時監控Node的信息,並作相應處理。
3. kube-scheduler與API Server交互
Scheduler經過API Server的Watch接口監聽到新建Pod副本的信息後,它會檢索全部符合該Pod要求的Node列表,開始執行Pod調度邏輯。調度成功後將Pod綁定到目標節點上。
API Server參數介紹
API Server 主要是和 etcd 打交道,而且對外提供 HTTP 服務,以及進行安全控制,所以它的命令行提供的參數也主要和這幾個方面有關。下面是一些比較重要的參數以及說明(不一樣版本參數可能會有不一樣):
參數 |
含義 |
默認值 |
–advertise-address |
經過該 ip 地址向集羣其餘節點公佈 api server 的信息,必須可以被其餘節點訪問 |
nil |
–allow-privileged |
是否容許 privileged 容器運行 |
false |
–admission-control |
准入控制 |
AlwaysAdmit |
–authorization-mode |
受權模式 ,安全接口上的受權 |
AlwaysAllow |
–bind-address |
HTTPS 安全接口的監聽地址 |
0.0.0.0 |
–secure-port |
HTTPS 安全接口的監聽端口 |
6443 |
–cert-dir |
TLS 證書的存放目錄 |
/var/run/kubernetes |
–etcd-prefix |
信息存放在 etcd 中地址的前綴 |
「/registry」 |
–etcd-servers |
逗號分割的 etcd server 地址 |
[] |
–insecure-bind-address |
HTTP 訪問的地址 |
127.0.0.1 |
–insecure-port |
HTTP 訪問的端口 |
8080 |
–log-dir |
日誌存放的目錄 |
|
–service-cluster-ip-range |
service 要使用的網段,使用 CIDR 格式,參考 kubernetes 中 service 的定義 |
|
API Server安裝和運行
API Server 是經過提供的 kube-apiserver
二進制文件直接運行的,下面的例子指定了 service 分配的 ip 範圍,etcd 的地址,和對外提供服務的 ip 地址:
-
/usr/bin/kube-apiserver \
-
-
--service-cluster-ip-range=10.20.0.1/24 \
-
-
--etcd-servers=http://127.0.0.1:2379 \
-
-
--advertise-address=192.168.8.100 \
-
-
--bind-address=192.168.8.100 \
-
-
--insecure-bind-address=192.168.8.100 \
-
-
直接訪問 8080
端口,API Server 會返回它提供了哪些接口:
-
[root@localhost vagrant]# curl http://192.168.8.100:8080
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
"/apis/extensions/v1beta1",
-
-
-
"/apis/rbac.authorization.k8s.io",
-
"/apis/rbac.authorization.k8s.io/v1alpha1",
-
-
-
-
-
-
-
-
-
而目前最重要的路徑是 /api/v1
,裏面包含了 kubernetes 全部資源的操做,好比下面的 nodes:
-
➜ ~ http http://192.168.8.100:8080/api/v1/nodes
-
-
-
-
-
-
Content-Type: application/json
-
-
Date: Thu, 08 Sep 2016 08:14:45 GMT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
"selfLink": "/api/v1/nodes"
-
-
API 以 json 的形式返回,會經過 apiVersion
來講明 API 版本號,kind
說明請求的是什麼資源。不過這裏面的內容是空的,由於目前尚未任何 kubelet 節點接入到咱們的 API Server。對應的,pod 也是空的:
-
➜ ~ http http://192.168.8.100:8080/api/v1/pods
-
-
-
-
-
-
Content-Type: application/json
-
-
Date: Thu, 08 Sep 2016 08:18:53 GMT
-
-
-
-
-
-
-
-
-
-
-
-
-
-
"selfLink": "/api/v1/pods"
-
-
-
-
添加節點
添加節點也很是簡單,啓動 kubelet
的時候使用 --api-servers
指定要接入的 API Server 就行。kubelet 啓動以後,會把本身註冊到指定的 API Server,而後監聽 API 對應 pod 的變化,根據 API 中 pod 的實際信息來管理節點上 pod 的生命週期。
如今訪問 /api/v1/nodes
就能看到已經添加進來的節點:
-
➜ ~ http http://192.168.8.100:8080/api/v1/nodes
-
-
Content-Type: application/json
-
Date: Thu, 08 Sep 2016 08:27:44 GMT
-
Transfer-Encoding: chunked
-
-
-
-
-
-
-
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
-
-
"creationTimestamp": "2016-09-08T08:23:01Z",
-
-
"beta.kubernetes.io/arch": "amd64",
-
"beta.kubernetes.io/os": "linux",
-
"kubernetes.io/hostname": "192.168.8.100"
-
-
-
-
"selfLink": "/api/v1/nodes/192.168.8.100",
-
"uid": "74e16eba-759d-11e6-b463-080027c09e5b"
-
-
-
"externalID": "192.168.8.100"
-
-
-
-
-
"address": "192.168.8.100",
-
-
-
-
"address": "192.168.8.100",
-
-
-
-
-
"alpha.kubernetes.io/nvidia-gpu": "0",
-
-
-
-
-
-
"alpha.kubernetes.io/nvidia-gpu": "0",
-
-
-
-
-
-
-
"lastHeartbeatTime": "2016-09-08T08:27:36Z",
-
"lastTransitionTime": "2016-09-08T08:23:01Z",
-
"message": "kubelet has sufficient disk space available",
-
"reason": "KubeletHasSufficientDisk",
-
-
-
-
-
"lastHeartbeatTime": "2016-09-08T08:27:36Z",
-
"lastTransitionTime": "2016-09-08T08:23:01Z",
-
"message": "kubelet has sufficient memory available",
-
"reason": "KubeletHasSufficientMemory",
-
-
-
-
-
"lastHeartbeatTime": "2016-09-08T08:27:36Z",
-
"lastTransitionTime": "2016-09-08T08:24:56Z",
-
"message": "kubelet is posting ready status",
-
"reason": "KubeletReady",
-
-
-
-
-
-
-
-
-
-
-
-
-
"172.16.1.41:5000/nginx:latest"
-
-
-
-
-
-
"172.16.1.41:5000/hyperkube:v0.18.2"
-
-
-
-
-
-
"172.16.1.41:5000/etcd:v3.0.4"
-
-
-
-
-
-
"172.16.1.41:5000/busybox:latest"
-
-
-
-
-
-
"172.16.1.41:5000/google_containers/pause:0.8.0"
-
-
-
-
-
-
-
"bootID": "48955926-11dd-4ad3-8bb0-2585b1c9215d",
-
"containerRuntimeVersion": "docker://1.10.3",
-
"kernelVersion": "3.10.0-123.13.1.el7.x86_64",
-
"kubeProxyVersion": "v1.3.1-beta.0.6+fbf3f3e5292fb0",
-
"kubeletVersion": "v1.3.1-beta.0.6+fbf3f3e5292fb0",
-
"machineID": "b9597c4ae5f24494833d35e806e00b29",
-
"operatingSystem": "linux",
-
"osImage": "CentOS Linux 7 (Core)",
-
"systemUUID": "823EB67A-057E-4EFF-AE7F-A758140CD2F7"
-
-
-
-
-
-
-
-
"selfLink": "/api/v1/nodes"
-
-
咱們能夠看到,kubelet 收集了不少關於自身節點的信息,這些信息也會不斷更新。這些信息裏面不只包含節點的系統信息(系統架構,操做系統版本,內核版本等)、還有鏡像信息(節點上有哪些已經下載的 docker 鏡像)、資源信息(Memory 和 Disk 的總量和可用量)、以及狀態信息(是否正常,能夠分配 pod等)。
和 API Server 通訊
編寫的 yaml 文件轉換成 json 格式,保存到文件裏。主要注意的是,咱們指定了 nodeName 的名字,這個名字必須和以前經過 /api/v1/nodes
獲得的結果中 metadata.labels.kubernetes.io/hostname
保持一致:
-
[root@localhost vagrant]# cat nginx_pod.yml
-
-
-
-
-
-
-
-
-
image: 172.16.1.41:5000/nginx
-
-
-
-
- mountPath: /var/log/nginx
-
-
-
image: 172.16.1.41:5000/busybox
-
-
-
args: [-c, 'tail -f /logdir/access.log']
-
-
-
-
-
-
使用 curl 執行 POST 請求,設置頭部內容爲 application/json
,傳過去文件中的 json 值,能夠看到應答(其中 status
爲 pending
,表示以及接收到請求,正在準備處理):
-
# curl -s -X POST -H "Content-Type: application/json" http://192.168.8.100:8080/api/v1/namespaces/default/pods --data @nginx_pod.json
-
-
-
-
-
-
-
"selfLink": "/api/v1/namespaces/default/pods/nginx-server",
-
"uid": "888e95d0-75a9-11e6-b463-080027c09e5b",
-
"resourceVersion": "573",
-
"creationTimestamp": "2016-09-08T09:49:28Z"
-
-
-
-
-
-
-
-
-
-
-
-
"image": "172.16.1.41:5000/nginx",
-
-
-
-
-
-
-
-
-
-
-
"mountPath": "/var/log/nginx"
-
-
-
"terminationMessagePath": "/dev/termination-log",
-
"imagePullPolicy": "Always"
-
-
-
"restartPolicy": "Always",
-
"terminationGracePeriodSeconds": 30,
-
"dnsPolicy": "ClusterFirst",
-
"nodeName": "192.168.8.100",
-
-
-
-
-
-
返回中包含了咱們提交 pod 的信息,而且添加了 status
、metadata
等額外信息。
等一段時間去查詢 pod,就能夠看到 pod 的狀態已經更新了:
-
➜ http http://192.168.8.100:8080/api/v1/namespaces/default/pods
-
-
Content-Type: application/json
-
Date: Thu, 08 Sep 2016 09:51:29 GMT
-
Transfer-Encoding: chunked
-
-
-
-
-
-
"creationTimestamp": "2016-09-08T09:49:28Z",
-
-
-
"resourceVersion": "592",
-
"selfLink": "/api/v1/namespaces/default/pods/nginx-server",
-
"uid": "888e95d0-75a9-11e6-b463-080027c09e5b"
-
-
-
-
-
"image": "172.16.1.41:5000/nginx",
-
"imagePullPolicy": "Always",
-
-
-
-
-
-
-
-
-
"terminationMessagePath": "/dev/termination-log",
-
-
-
"mountPath": "/var/log/nginx",
-
-
-
-
-
-
-
-
"tail -f /logdir/access.log"
-
-
-
-
-
"image": "172.16.1.41:5000/busybox",
-
"imagePullPolicy": "Always",
-
-
-
"terminationMessagePath": "/dev/termination-log",
-
-
-
-
-
-
-
-
-
"dnsPolicy": "ClusterFirst",
-
"nodeName": "192.168.8.100",
-
"restartPolicy": "Always",
-
-
"terminationGracePeriodSeconds": 30,
-
-
-
-
-
-
-
-
-
-
-
-
"lastTransitionTime": "2016-09-08T09:49:28Z",
-
-
-
-
-
-
"lastTransitionTime": "2016-09-08T09:49:44Z",
-
-
-
-
-
-
"lastTransitionTime": "2016-09-08T09:49:44Z",
-
-
-
-
-
-
-
"containerID": "docker://8b79eeea60f27b6d3f0a19cbd1b3ee3f83709bcf56574a6e1124c69a6376972d",
-
"image": "172.16.1.41:5000/busybox",
-
"imageID": "docker://sha256:8c566faa3abdaebc33d40c1b5e566374c975d17754c69370f78c00c162c1e075",
-
-
-
-
-
-
-
"startedAt": "2016-09-08T09:49:43Z"
-
-
-
-
-
"containerID": "docker://96e64cdba7b05d4e30710a20e958ff5b8f1f359c8d16d32622b36f0df0cb353c",
-
"image": "172.16.1.41:5000/nginx",
-
"imageID": "docker://sha256:51d764c1fd358ce81fd0e728436bd0175ff1f3fd85fc5d1a2f9ba3e7dc6bbaf6",
-
-
-
-
-
-
-
"startedAt": "2016-09-08T09:49:36Z"
-
-
-
-
-
"hostIP": "192.168.8.100",
-
-
-
"startTime": "2016-09-08T09:49:28Z"
-
-
-
-
-
-
-
"resourceVersion": "602",
-
"selfLink": "/api/v1/namespaces/default/pods"
-
-
能夠看到 pod 已經在運行,而且給分配了 ip:172.17.0.2
,經過 curl 也能夠訪問它的服務:
-
[root@localhost vagrant]# curl -s http://172.17.0.2 | head -n 5
-
-
-
-
<title>Welcome to nginx on Debian!</title>
-
kubectl -s http: