Kubernetes核心原理(一)之API Server

1. API Server簡介

k8s API Server提供了k8s各種資源對象(pod,RC,Service等)的增刪改查及watch等HTTP Rest接口,是整個系統的數據總線和數據中心。node

kubernetes API Server的功能:git

  1. 提供了集羣管理的REST API接口(包括認證受權、數據校驗以及集羣狀態變動);
  2. 提供其餘模塊之間的數據交互和通訊的樞紐(其餘模塊經過API Server查詢或修改數據,只有API Server才直接操做etcd);
  3. 是資源配額控制的入口;
  4. 擁有完備的集羣安全機制.

kube-apiserver工做原理圖github

kube-apiserver

2. 如何訪問kubernetes API

k8s經過kube-apiserver這個進程提供服務,該進程運行在單個k8s-master節點上。默認有兩個端口。web

2.1. 本地端口

  1. 該端口用於接收HTTP請求;
  2. 該端口默認值爲8080,能夠經過API Server的啓動參數「–insecure-port」的值來修改默認值;
  3. 默認的IP地址爲「localhost」,能夠經過啓動參數「–insecure-bind-address」的值來修改該IP地址;
  4. 非認證或受權的HTTP請求經過該端口訪問API Server。

2.2. 安全端口

  1. 該端口默認值爲6443,可經過啓動參數「–secure-port」的值來修改默認值;
  2. 默認IP地址爲非本地(Non-Localhost)網絡端口,經過啓動參數「–bind-address」設置該值;
  3. 該端口用於接收HTTPS請求;
  4. 用於基於Tocken文件或客戶端證書及HTTP Base的認證;
  5. 用於基於策略的受權;
  6. 默認不啓動HTTPS安全訪問控制。

2.3. 訪問方式

Kubernetes REST API可參考https://kubernetes.io/docs/api-reference/v1.6/數據庫

2.3.1. curl

1
2
3
4
curl localhost:8080/api
curl localhost:8080/api/v1/pods
curl localhost:8080/api/v1/services
curl localhost:8080/api/v1/replicationcontrollers

2.3.2. Kubectl Proxy

Kubectl Proxy代理程序既能做爲API Server的反向代理,也能做爲普通客戶端訪問API Server的代理。經過master節點的8080端口來啓動該代理程序。express

kubectl proxy --port=8080 &編程

具體見kubectl proxy --helpapi

 
[root@node5 ~]# kubectl proxy --help
To proxy all of the kubernetes api and nothing else, use:
kubectl proxy --api-prefix=/
To proxy only part of the kubernetes api and also some static files:
kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/
The above lets you 'curl localhost:8001/api/v1/pods'.
To proxy the entire kubernetes api at a different root, use:
kubectl proxy --api-prefix=/custom/
The above lets you 'curl localhost:8001/custom/api/v1/pods'
Usage:
kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] [flags]
Examples:
# Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/
$ kubectl proxy --port=8011 --www=./local/www/
# Run a proxy to kubernetes apiserver on an arbitrary local port.
# The chosen port for the server will be output to stdout.
$ kubectl proxy --port=0
# Run a proxy to kubernetes apiserver, changing the api prefix to k8s-api
# This makes e.g. the pods api available at localhost:8011/k8s-api/v1/pods/
$ kubectl proxy --api-prefix=/k8s-api
Flags:
--accept-hosts="^localhost$,^127//.0//.0//.1$,^//[::1//]$": Regular expression for hosts that the proxy should accept.
--accept-paths="^/.*": Regular expression for paths that the proxy should accept.
--api-prefix="/": Prefix to serve the proxied API under.
--disable-filter[=false]: If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port.
-p, --port=8001: The port on which to run the proxy. Set to 0 to pick a random port.
--reject-methods="POST,PUT,PATCH": Regular expression for HTTP methods that the proxy should reject.
--reject-paths="^/api/.*/exec,^/api/.*/run": Regular expression for paths that the proxy should reject.
-u, --unix-socket="": Unix socket on which to run the proxy.
-w, --www="": Also serve static files from the given directory under the specified prefix.
-P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified.

Global Flags:
--alsologtostderr[=false]: log to standard error as well as files
--api-version="": The API version to use when talking to the server
--certificate-authority="": Path to a cert. file for the certificate authority.
--client-certificate="": Path to a client key file for TLS.
--client-key="": Path to a client key file for TLS.
--cluster="": The name of the kubeconfig cluster to use
--context="": The name of the kubeconfig context to use
--insecure-skip-tls-verify[=false]: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
--kubeconfig="": Path to the kubeconfig file to use for CLI requests.
--log-backtrace-at=:0: when logging hits line file:N, emit a stack trace
--log-dir="": If non-empty, write log files in this directory
--log-flush-frequency=5s: Maximum number of seconds between log flushes
--logtostderr[=true]: log to standard error instead of files
--match-server-version[=false]: Require server version to match client version
--namespace="": If present, the namespace scope for this CLI request.
--password="": Password for basic authentication to the API server.
-s, --server="": The address and port of the Kubernetes API server
--stderrthreshold=2: logs at or above this threshold go to stderr
--token="": Bearer token for authentication to the API server.
--user="": The name of the kubeconfig user to use
--username="": Username for basic authentication to the API server.
--v=0: log level for V logs
--vmodule=: comma-separated list of pattern=N settings for file-filtered logging

2.3.3. kubectl客戶端

命令行工具kubectl客戶端,經過命令行參數轉換爲對API Server的REST API調用,並將調用結果輸出。緩存

命令格式:kubectl [command] [options]安全

具體可參考k8s經常使用命令

2.3.4. 編程方式調用

使用場景:

一、運行在Pod裏的用戶進程調用kubernetes API,一般用來實現分佈式集羣搭建的目標。

二、開發基於kubernetes的管理平臺,好比調用kubernetes API來完成Pod、Service、RC等資源對象的圖形化建立和管理界面。可使用kubernetes提供的Client Library。

具體可參考https://github.com/kubernetes/client-go

3. 經過API Server訪問Node、Pod和Service

k8s API Server最主要的REST接口是資源對象的增刪改查,另外還有一類特殊的REST接口—k8s Proxy API接口,這類接口的做用是代理REST請求,即kubernetes API Server把收到的REST請求轉發到某個Node上的kubelet守護進程的REST端口上,由該kubelet進程負責響應。

3.1. Node相關接口

關於Node相關的接口的REST路徑爲:/api/v1/proxy/nodes/{name},其中{name}爲節點的名稱或IP地址。

1
2
3
/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還會增長如下接口:

1
2
3
4
5
6
7
8
/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和內存的使用狀況

3.2. Pod相關接口

1
2
3
4
5
/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.3. Service相關接口

1
/api/v1/proxy/namespaces/{namespace}/services/{name}

Pod的proxy接口的做用:在kubernetes集羣以外訪問某個pod容器的服務(HTTP服務),能夠用Proxy API實現,這種場景多用於管理目的,好比逐一排查Service的Pod副本,檢查哪些Pod的服務存在異常問題。

4. 集羣功能模塊之間的通訊

kubernetes API Server做爲集羣的核心,負責集羣各功能模塊之間的通訊,集羣內各個功能模塊經過API Server將信息存入etcd,當須要獲取和操做這些數據時,經過API Server提供的REST接口(GET/LIST/WATCH方法)來實現,從而實現各模塊之間的信息交互。

4.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容器 -

4.2. kube-controller-manager與API Server交互

kube-controller-manager中的Node Controller模塊經過API Server提供的Watch接口,實時監控Node的信息,並作相應處理。

4.3. kube-scheduler與API Server交互

Scheduler經過API Server的Watch接口監聽到新建Pod副本的信息後,它會檢索全部符合該Pod要求的Node列表,開始執行Pod調度邏輯。調度成功後將Pod綁定到目標節點上。

4.4. 特別說明

爲了緩解各模塊對API Server的訪問壓力,各功能模塊都採用緩存機制來緩存數據,各功能模塊定時從API Server獲取指定的資源對象信息(LIST/WATCH方法),而後將信息保存到本地緩存,功能模塊在某些狀況下不直接訪問API Server,而是經過訪問緩存數據來間接訪問API Server。

參考《kubernetes權威指南》

https://www.huweihuang.com/article/kubernetes/core-principle/kubernetes-core-principle-api-server/

相關文章
相關標籤/搜索