API Server簡介 k8s API Server提供了k8s各類資源對象(pod,RC,Service等)的增刪改查及watch等HTTP Rest接口,是整個系統的數據總線和數據中心。
kubernetes API Server的功能:
提供了集群管理的REST API接口(包括認證授權、數據校驗以及集群狀態變更); 提供其他模塊之間的數據交互和通信的樞紐(其他模塊通過API Server查詢或修改數據,只有API Server才直接操作etcd); 是資源配額控制的入口; 擁有完備的集群安全機制. kube-apiserver工作原理圖
如何訪問kubernetes API k8s通過kube-apiserver這個進程提供服務,該進程運行在單個k8s-master節點上。默認有兩個端口。
k8s通過kube-apiserver這個進程提供服務,該進程運行在單個k8s-master節點上。默認有兩個端口。
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/
1.?curl curl localhost:8080/api
curl localhost:8080/api/v1/pods
curl localhost:8080/api/v1/services
curl localhost:8080/api/v1/replicationcontrollers
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.?編程方式調用 使用場景:
1、運行在Pod里的用戶進程調用kubernetes API,通常用來實現分布式集群搭建的目標。
2、開發基于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 \ --v=4 直接訪問?8080?端口,API Server 會返回它提供了哪些接口:
[root@localhost vagrant]# curl http://192.168.8.100:8080 { "paths": [ "/api", "/api/v1", "/apis", "/apis/apps", "/apis/apps/v1alpha1", "/apis/autoscaling", "/apis/autoscaling/v1", "/apis/batch", "/apis/batch/v1", "/apis/batch/v2alpha1", "/apis/extensions", "/apis/extensions/v1beta1", "/apis/policy", "/apis/policy/v1alpha1", "/apis/rbac.authorization.k8s.io", "/apis/rbac.authorization.k8s.io/v1alpha1", "/healthz", "/healthz/ping", "/logs/", "/metrics", "/swaggerapi/", "/ui/", "/version" ] } 而目前最重要的路徑是?/api/v1,里面包含了 kubernetes 所有資源的操作,比如下面的 nodes:
? ~ http http://192.168.8.100:8080/api/v1/nodes HTTP/1.1 200 OK Content-Length: 112 Content-Type: application/json Date: Thu, 08 Sep 2016 08:14:45 GMT { "apiVersion": "v1", "items": [], "kind": "NodeList", "metadata": { "resourceVersion": "12", "selfLink": "/api/v1/nodes" } } ?API 以 json 的形式返回,會通過?apiVersion?來說明 API 版本號,kind?說明請求的是什么資源。不過這里面的內容是空的,因為目前還沒有任何 kubelet 節點接入到我們的 API Server。對應的,pod 也是空的:
? ~ http http://192.168.8.100:8080/api/v1/pods HTTP/1.1 200 OK Content-Length: 110 Content-Type: application/json Date: Thu, 08 Sep 2016 08:18:53 GMT { "apiVersion": "v1", "items": [], "kind": "PodList", "metadata": { "resourceVersion": "12", "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 HTTP/1.1 200 OK Content-Type: application/json Date: Thu, 08 Sep 2016 08:27:44 GMT Transfer-Encoding: chunked { "apiVersion": "v1", "items": [ { "metadata": { "annotations": { "volumes.kubernetes.io/controller-managed-attach-detach": "true" }, "creationTimestamp": "2016-09-08T08:23:01Z", "labels": { "beta.kubernetes.io/arch": "amd64", "beta.kubernetes.io/os": "linux", "kubernetes.io/hostname": "192.168.8.100" }, "name": "192.168.8.100", "resourceVersion": "65", "selfLink": "/api/v1/nodes/192.168.8.100", "uid": "74e16eba-759d-11e6-b463-080027c09e5b" }, "spec": { "externalID": "192.168.8.100" }, "status": { "addresses": [ { "address": "192.168.8.100", "type": "LegacyHostIP" }, { "address": "192.168.8.100", "type": "InternalIP" } ], "allocatable": { "alpha.kubernetes.io/nvidia-gpu": "0", "cpu": "1", "memory": "502164Ki", "pods": "110" }, "capacity": { "alpha.kubernetes.io/nvidia-gpu": "0", "cpu": "1", "memory": "502164Ki", "pods": "110" }, "conditions": [ { "lastHeartbeatTime": "2016-09-08T08:27:36Z", "lastTransitionTime": "2016-09-08T08:23:01Z", "message": "kubelet has sufficient disk space available", "reason": "KubeletHasSufficientDisk", "status": "False", "type": "OutOfDisk" }, { "lastHeartbeatTime": "2016-09-08T08:27:36Z", "lastTransitionTime": "2016-09-08T08:23:01Z", "message": "kubelet has sufficient memory available", "reason": "KubeletHasSufficientMemory", "status": "False", "type": "MemoryPressure" }, { "lastHeartbeatTime": "2016-09-08T08:27:36Z", "lastTransitionTime": "2016-09-08T08:24:56Z", "message": "kubelet is posting ready status", "reason": "KubeletReady", "status": "True", "type": "Ready" } ], "daemonEndpoints": { "kubeletEndpoint": { "Port": 10250 } }, "images": [ { "names": [ "172.16.1.41:5000/nginx:latest" ], "sizeBytes": 425626718 }, { "names": [ "172.16.1.41:5000/hyperkube:v0.18.2" ], "sizeBytes": 207121551 }, { "names": [ "172.16.1.41:5000/etcd:v3.0.4" ], "sizeBytes": 43302056 }, { "names": [ "172.16.1.41:5000/busybox:latest" ], "sizeBytes": 1092588 }, { "names": [ "172.16.1.41:5000/google_containers/pause:0.8.0" ], "sizeBytes": 241656 } ], "nodeInfo": { "architecture": "amd64", "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" } } } ], "kind": "NodeList", "metadata": { "resourceVersion": "65", "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 apiVersion: v1 kind: Pod metadata: name: nginx-server spec: NodeName: 192.168.8.100 containers: - name: nginx-server image: 172.16.1.41:5000/nginx ports: - containerPort: 80 volumeMounts: - mountPath: /var/log/nginx name: nginx-logs - name: log-output image: 172.16.1.41:5000/busybox command: - bin/sh args: [-c, 'tail -f /logdir/access.log'] volumeMounts: - mountPath: /logdir name: nginx-logs volumes: - name: nginx-logs emptyDir: {} ?
使用 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 { "kind": "Pod", "apiVersion": "v1", "metadata": { "name": "nginx-server", "namespace": "default", "selfLink": "/api/v1/namespaces/default/pods/nginx-server", "uid": "888e95d0-75a9-11e6-b463-080027c09e5b", "resourceVersion": "573", "creationTimestamp": "2016-09-08T09:49:28Z" }, "spec": { "volumes": [ { "name": "nginx-logs", "emptyDir": {} } ], "containers": [ { "name": "nginx-server", "image": "172.16.1.41:5000/nginx", "ports": [ { "containerPort": 80, "protocol": "TCP" } ], "resources": {}, "volumeMounts": [ { "name": "nginx-logs", "mountPath": "/var/log/nginx" } ], "terminationMessagePath": "/dev/termination-log", "imagePullPolicy": "Always" } ], "restartPolicy": "Always", "terminationGracePeriodSeconds": 30, "dnsPolicy": "ClusterFirst", "nodeName": "192.168.8.100", "securityContext": {} }, "status": { "phase": "Pending" } } 返回中包含了我們提交 pod 的信息,并且添加了?status、metadata?等額外信息。
等一段時間去查詢 pod,就可以看到 pod 的狀態已經更新了:
? http http://192.168.8.100:8080/api/v1/namespaces/default/pods HTTP/1.1 200 OK Content-Type: application/json Date: Thu, 08 Sep 2016 09:51:29 GMT Transfer-Encoding: chunked { "apiVersion": "v1", "items": [ { "metadata": { "creationTimestamp": "2016-09-08T09:49:28Z", "name": "nginx-server", "namespace": "default", "resourceVersion": "592", "selfLink": "/api/v1/namespaces/default/pods/nginx-server", "uid": "888e95d0-75a9-11e6-b463-080027c09e5b" }, "spec": { "containers": [ { "image": "172.16.1.41:5000/nginx", "imagePullPolicy": "Always", "name": "nginx-server", "ports": [ { "containerPort": 80, "protocol": "TCP" } ], "resources": {}, "terminationMessagePath": "/dev/termination-log", "volumeMounts": [ { "mountPath": "/var/log/nginx", "name": "nginx-logs" } ] }, { "args": [ "-c", "tail -f /logdir/access.log" ], "command": [ "bin/sh" ], "image": "172.16.1.41:5000/busybox", "imagePullPolicy": "Always", "name": "log-output", "resources": {}, "terminationMessagePath": "/dev/termination-log", "volumeMounts": [ { "mountPath": "/logdir", "name": "nginx-logs" } ] } ], "dnsPolicy": "ClusterFirst", "nodeName": "192.168.8.100", "restartPolicy": "Always", "securityContext": {}, "terminationGracePeriodSeconds": 30, "volumes": [ { "emptyDir": {}, "name": "nginx-logs" } ] }, "status": { "conditions": [ { "lastProbeTime": null, "lastTransitionTime": "2016-09-08T09:49:28Z", "status": "True", "type": "Initialized" }, { "lastProbeTime": null, "lastTransitionTime": "2016-09-08T09:49:44Z", "status": "True", "type": "Ready" }, { "lastProbeTime": null, "lastTransitionTime": "2016-09-08T09:49:44Z", "status": "True", "type": "PodScheduled" } ], "containerStatuses": [ { "containerID": "docker://8b79eeea60f27b6d3f0a19cbd1b3ee3f83709bcf56574a6e1124c69a6376972d", "image": "172.16.1.41:5000/busybox", "imageID": "docker://sha256:8c566faa3abdaebc33d40c1b5e566374c975d17754c69370f78c00c162c1e075", "lastState": {}, "name": "log-output", "ready": true, "restartCount": 0, "state": { "running": { "startedAt": "2016-09-08T09:49:43Z" } } }, { "containerID": "docker://96e64cdba7b05d4e30710a20e958ff5b8f1f359c8d16d32622b36f0df0cb353c", "image": "172.16.1.41:5000/nginx", "imageID": "docker://sha256:51d764c1fd358ce81fd0e728436bd0175ff1f3fd85fc5d1a2f9ba3e7dc6bbaf6", "lastState": {}, "name": "nginx-server", "ready": true, "restartCount": 0, "state": { "running": { "startedAt": "2016-09-08T09:49:36Z" } } } ], "hostIP": "192.168.8.100", "phase": "Running", "podIP": "172.17.0.2", "startTime": "2016-09-08T09:49:28Z" } } ], "kind": "PodList", "metadata": { "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 <!DOCTYPE html> <html> <head> <title>Welcome to nginx on Debian!</title> <style> kubectl -s http:
轉載于:https://www.cnblogs.com/Su-per-man/p/10942783.html
總結
以上是生活随笔 為你收集整理的k8s 组件介绍-API Server 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。