1. 程式人生 > >Kubernetes基本概念以及術語

Kubernetes基本概念以及術語

kubernetes 是什麼?

  • kubernetes又稱k8s,他是一個基於容器技術的分散式架構方案。他是谷歌Borg的一個開源版本,基於容器技術用於大規模叢集管理。

它能做那些事?

  • 資源管理自動化
  • 跨多個數據中心的資源利用率的最大化
  • 降低開發成本(負載均衡器、服務治理、服務監控、故障處理模組等都不用開發了)
  • 降低運維難度和運維成本(基於配置檔案的UI運維)
  • 開放的開發平臺,可使用任意語言通過TCP協議進行互動
  • 分散式系統支撐平臺,具有完備的叢集管理能力,包括多層次的安全防火和准入機制、多租戶應用支撐能力、透明的服務註冊和服務發現機制、內建智慧負載均衡器、強大的故障發現和自我修復能力、服務滾動升級和線上擴容能力、可擴充套件的資源排程機制、多粒度的資源配額管理功能

為什麼要使用它?

  • 降低複雜系統的開發難度
  • 全面擁抱微服務架構
  • 具備搬遷至公有云的能力
  • 超強的橫向擴容能力

kubernetes的基本概念和術語

kubernetes叢集管理角色有兩種:Master和Node,包含“資源物件”如Node Pod Replication Controller Services

管理角色

  • Master 叢集控制節點,每個叢集中都需要有一個Master節點負責整個叢集的管理和控制(高可用部署建議部署3臺),Master節點上有以下程序:

    • kube-apiserver:提供了http rest介面的關鍵服務程序,是叢集控制的入口程序
    • kube-controller-manager:所有資源物件的自動化控制中心
    • kube-scheduler:Pod排程的程序
    • etcd:用於儲存資源物件的資料
  • Node 除了Master之外的機器為Node節點,主要是叢集工作中的負載節點,當一個node宕機時,其上的工作會被master轉移到其他節點上去,Node之上執行著以下程序:

    • kubelet:負責Pod對應容器的建立、啟停等任務,同時與master節點密切協作,實現叢集管理的基本功能
    • kube-proxy:實現kubernetes services 的通訊與負載均衡機制的重要元件
    • Docker Engine

資源物件

kubernetes裡的資源物件都可以使用yaml或者json檔案進行描述定義

Pod

  • Pod:由一個根容器(Pause)和一組使用者容器組成。Pause容器的狀態代表了整個容器組的狀態,多個業務容器共享Pause容器的IP,共享Pause容器掛接的Volume。 K8s為每個Pod都分配了唯一的IP地址,稱為Pod IP,所以在叢集中一個Pod裡的容器與另外主機的Pod容器能夠直接通訊;Pod有兩種型別:普通的Pod以及靜態的Pod,後者不存在於Etcd裡,而是在具體Node上的一個具體檔案中

  • 舉例

$ cat > k8s-tomcat-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: k8s-tomcat
  labels:
    name: demo
spec:
  containers:
  - name: k8s-tomcat
    image: alleyz.com:5000/k8s-tomcat-demo:1211
    ports:
    - containerPort: 8080
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "512Mi"
        cpu: "500m"
EOF

$ kubectl apply -f k8s-tomcat-pod.yaml

$ kubectl get pods
NAME         READY     STATUS    RESTARTS   AGE
k8s-tomcat   1/1       Running   0          20s

Label

  • Label:一個label就是一個key=value的鍵值對,key和value均可自己指定。Label可以附加到各種資源物件上,一個資源物件可以定義任意數量的Label。 通途 通過給指定的資源物件捆綁一個或者多個不同的Label來實現多維度的資源分組管理功能,以便於靈活、方便地進行資源分配、排程、配置、部署等管理工作,例如:部署不同的版本到不同的環境中

  • Label Selector:當給資源物件打上標籤以後,就可以通過label selector查詢和篩選這些資源物件。一般有兩種label selector表示式,如

    • 基於等式:

      • name=demo 匹配所有具有標籤name=demo的資源物件
      • name!=demo 匹配所有不具有name=demo的物件
    • 基於集合:
      • name in (dev, test) 匹配所有具有name=dev或者name=test的資源物件
      • name not in (dev, test) 匹配所有不具備name=dev或者name=test的資源物件
  • Label Selector的使用場景:

    • kube-controller程序通過資源物件RC上定義的Label Selector來篩選要監控的Pod副本數量,從而實現Pod副本數量始終符合預期設定的全自動控制流程
    • kube-proxy 程序通過service的label selector來選擇對應的pod,自動建立起每個service到pod的請求轉發路由表,從而實現service的智慧均衡負載機制
    • 通過對某些Node定義特定的label,並且在pod定義檔案中使用NodeSelector進行定向排程

Replication Controller

  • 簡稱RC,用於宣告某個Pod的副本數量在任意時刻的預期值,它主要包括下邊幾個部分:

    • pod期待的副本數
    • 用於篩選目標pod的label selector
    • 當pod數量小於預期數量時,用於建立新pod的模板(template)
  • Replica Set: 新版本的RC,與Replication Controller的唯一區別是:ReplicaSet支援集合labelselector,而RC只支援等式的labelSelector,當然在後續的版本里,deployment已經取代了RC(後文詳述)

  • 特性:

    • 通過定義RC實現Pod的建立過程以及副本數量的自動控制
    • RC裡包括完整的Pod定義模板
    • RC通過Label Selector機制實現對Pod副本的自動控制
    • 通過改變RC裡的Pod副本數量,可以實現Pod的擴容或者縮容功能
    • 通過改變RC裡Pod模板中的映象版本可以實現Pod的滾動升級功能
  • 舉例:

$ cat > k8s-tomcat-demo-rc.yaml <<EOF
apiVersion: v1
kind: ReplicationController
metadata:
  name: k8s-tomcat-rc
spec:
  replicas: 3
  selector:
    demo: k8s-tomcat
  template:
    metadata:
      labels:
        demo: k8s-tomcat
        name: demo
    spec:
      containers:
      - name: tomcat-demo
        image: alleyz.com:5000/k8s-tomcat-demo:1211
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
EOF

$ kubectl apply -f k8s-tomcat-demo-rc.yaml 

$ kubectl get rc 
NAME            DESIRED   CURRENT   READY     AGE
k8s-tomcat-rc   3         3         3         12m

$ kubectl get pods
NAME                  READY     STATUS    RESTARTS   AGE
k8s-tomcat            1/1       Running   0          15m
k8s-tomcat-rc-klnvv   1/1       Running   0          12m
k8s-tomcat-rc-zb1r0   1/1       Running   0          12m

Deployment

  • Deployment可以認為是RC的升級版,最大的區別是我們可以隨時知道POD容器的部署進度,典型的使用場景有:

    • 建立一個Deployment物件來生成RC並完成Pod副本的建立過程
    • 檢查Deployment的狀態看部署動作是否完成
    • 更新deployment以建立新的Pod(升級)
    • 如果當前Deployment不穩定則回滾到早先版本
    • 暫停Deployment以便於一次修改多個PodTemplateSpec的配置項,之後再進行釋出
    • 擴充套件Deployment以應對高負載
    • 檢視Deployment的狀態,以此作為釋出是否成功的指標
    • 清理不在需要的舊版本RC
  • 例子

$ cat > k8s-tomcat-demo-deploy.yaml  <<EOF
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: k8s-tomcat-dep
spec:
  replicas: 4
  selector:
    matchLabels:
      demo: k8s-tomcat
  template:
    metadata:
      labels:
        demo: k8s-tomcat
        name: demo
    spec:
      containers:
      - name: tomcat-demo
        image: alleyz.com:5000/k8s-tomcat-demo:1211
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
EOF

$ kubectl apply -f k8s-tomcat-demo-deploy.yaml 

$ kubectl get deploy
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
k8s-tomcat-dep   4         4         4            4           21s

HPA(橫向自動擴容)

  • Horizontal Pod Autoscaler 即HPA也是一種資源物件,通過追蹤分析RC控制的pod的負載變化情況來確定是否需要針對性地調整目標pod的副本數(增加或者減少),當前主要有以下兩種方式作為Pod負載的度量指標:

    • CpuUtilizationPercentage(CPU利用率),取所有副本自身CPU利用率的平均值(需要定義Pod Request值)
    • 應用程式自定義的度量指標,比如TPS或者QPS

StatefulSet

  • 用於實現有狀態的叢集管理,可以將它看做Deployment/RC的一個變種,它有以下特性

    • StatefulSet裡的每個Pod都有穩定、唯一的網路標識,可以用來發現叢集的其他成員
    • StatefulSet控制的Pod副本的啟停順序是受控的,如StatefulSet名叫zk,則第一個叫做zk-0,第二個叫做zk-2,依次類推
    • Stateful裡的Pod採用穩定的持久化儲存卷,通過PV/PVC實現
  • 詳細使用待了解過PV/PVC之後進行zookeeper叢集部署時進行說明

Service

  • service定義了一個服務的訪問入庫地址,前端應用(Pod)通過這個入口地址訪問其背後的一組由Pod副本組成的叢集例項,Service與其後端Pod副本叢集之間則是通過Label Selector來實現無縫對接的。RC的作用實際上是保證service服務能力和服務質量始終處於預期的標準。

  • 一組Pod組成的服,客戶端如何訪問?每個Node上的kube-proxy程序負責把對service的請求轉發的後端某個Pod的例項上,並在內部實現了服務的負載均衡與會話保持機制。但需要注意的是:service不是共用一個IP,而是每個Service分配了一個全域性唯一的虛擬IP地址(ClusterIP),服務呼叫就變成一個TCP網路通訊。

  • kubernetes的服務發現機制,Service物件都有一個唯一的ClusterIP以及唯一的名字,在老版本中通過自動注入環境變數將service的name與ClusterIP繫結,新版本中採用外掛的方式引入了DNS系統,把service的name作為DNS域名,然後程式就可以通過service的name來建立通訊連線了

  • 外部系統訪問service的關鍵在於3種IP,即:

    • Node IP node節點的IP地址,叢集之外的節點訪問叢集內的服務時,必須要通過NodeIP進行訪問
    • Pod IP pod的IP地址,Docker Engine根據dicker0網橋的IP地址段進行分類的一個虛擬的二層網路的IP地址
    • Cluster IP service的IP地址,虛擬的IP,它的特點:

      • 僅作用域service物件,由k8s管理和分配IP地址
      • 無法被ping
      • 只能結合service port組成一個具體的通訊埠,單獨的Cluster IP不具備通訊基礎
      • 叢集之內 Node/pod/cluster之間的通訊與通常的IP路由與很大的不同
  • service的cluster IP無法供外部直接使用,但通過指定服務的port繫結在節點的port上,即可進行訪問;當pod位於多個node時,通過nodeip:port訪問到的是nodeip所在node上的pod,如需負載可以考慮使用硬體負載均衡器或者Nginx

  • 例子:只在叢集內進行訪問的service

$ cat > k8s-tomcat-demo-svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: k8s-tomcat-svc
spec:
  ports:
  - port: 8080
  selector:
    demo: k8s-tomcat
EOF

$ kubectl apply -f k8s-tomcat-demo-svc.yaml

$ kubectl get svc 
NAME             CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
k8s-tomcat-svc   10.108.64.29   <none>        8080/TCP   14h

$ kubectl get endpoints
NAME             ENDPOINTS                                                  AGE
k8s-tomcat-svc   10.36.0.3:8080,10.36.0.4:8080,10.36.0.5:8080 + 4 more...   14h
  • 例子:叢集之外可以進行訪問的service
$ cat > k8s-tomcat-demo-svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: k8s-tomcat-svc
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30001
  selector:
    demo: k8s-tomcat
EOF

$ kubectl apply -f  k8s-tomcat-demo-svc.yaml

$ kubectl get svc 
NAME             CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
k8s-tomcat-svc   10.108.64.29   <nodes>       8080:30001/TCP   15h

Volume

  • volume是pod中能夠別多個容器訪問的共享目錄;k8s中volume定義在pod上,然後被pod中的多個容器掛載到具體的目錄下;volume與pod的生命週期相同

  • volume具有豐富的型別:

    • emptyDir:Pod分配到node時建立的,它的初始內容為空,並且無需指定宿主機上對應的目錄檔案,pod從node上移除時,則emptyDir中的資料永久刪除;emptyDir的用途有:

      • 臨時空間
      • 長時間任務的checkpoint點
      • 一個容器需要從另一個容器獲取資料的目錄
    • hostPath,在pod上掛載宿主機的檔案或目錄,

      • 主要用途:

        • 容器應用生成的檔案(如日誌)需要永久儲存時
        • 需要訪問宿主機的檔案時
      • 注意事項:

        • 不同的node上具有相同配置的pod可能因為宿主機上的目錄和檔案不同而導致對Volume上目錄和檔案的訪問結果不一致
        • hostPath無法納入資源配額管理
    • NFS,使用NFS網路檔案系統共享儲存資料

    • 其他型別:cephglusterfs

PV (Persistent Volume,持久卷)

  • PV是k8s叢集中某個網路儲存中對應的一塊儲存,它和Volume的區別:

    • PV只能是網路儲存,不屬於任何Node,但可以在每個Node上訪問
    • PV獨立於Pod定義
    • PV目前支援的型別涵蓋了很多公有云平臺儲存(gce、aws)以及一些網路檔案系統(NFS)
  • Pod想申請PV時,需要先定義一個PVC(Persistent Volume Claim),然後在Pod的Volume中引用定義好的PVC

Namespace 名稱空間

  • Namespace通過將叢集中的資源物件分配(邏輯上的)到不同的Namespace中,形成邏輯上的分組不同的專案、使用者組等,便於實現多租戶資源管理。 預設的namespace是default

  • 宣告資源物件時,在metadata一項中可以指定,如namespace: dev

Annotation

  • 註解與Label類似,但具有嚴格的命名規則

參考資料:《kubernetes權威指南》