1. 程式人生 > >Kubernetes核心概念介紹

Kubernetes核心概念介紹


Kubernetes是一個可輕便的,可拓展的開源平臺,為管理容器與服務提供便利的配置以及自動化.現已有著很龐大以及快速增長的生態系統.
Kubernetes還有一個重要的思想就是一切皆容器.
k8s是kubernetes的簡稱,8代指是ubernete.

關鍵概念

node

一個節點可以是VM虛擬機器或者物理機,部署service執行pod.由Master元件管理.

pod

在K8s當中能夠被建立以及排程的最小單元,並不是單個容器,一個Pod是由若干個容器組成.Pod容器內共享Network space.

  • IP等網路資源分配的單位的基本單位.
  • 共享Volume
  • 同一個pod內的容器可以功能性IPC(訊息佇列等),共享主機名.

service

service其實就是一組pods的集合抽象定義.
service可以由Label Selector選出pods.

pod的IP地址會隨著pod生命週期消亡而變更,但service的IP不會產生變更,這樣可以很好的標識一個服務.

其實通過概念可以看出Service其實不是真正提供服務的因此,他需要將TCP/UDP的流量轉發到實際的Endpoints(實際是由Service的selector選擇出的Pod).
還有一點是Service可以直接通過設定ExternalIP(公網IP)訪問到內部應用服務.

網路

Docker Mode

Docker中同一主機內容器通過虛擬橋接進行通訊,預設情況下這個網路是host-private(私有網路).因此Docker容器在各個節點互不相同.
如果需要進行跨節點進行通訊,需要在每臺主機上開啟埠,Docker代理並轉發這個埠的流量到容器中,從而實現跨節點通訊.

Kubernetes實現

Kubernetes網路實現概念:

1.所有的容器可以不基於NAT互相通訊
2.所有的節點可以和容器進行不基於NAT通訊
3.IP地址對容器內外都是一致

NAT:網路地址轉換.

pod當中的容器位於同一個NetworkNamespace,因此它們是共享IP的,同一個pod可以通過localhost進行訪問.這個是通過Docker的--net=--net=container:<id>

實現.

KubeProxy

用於流量轉發每個節點都會存在KubeProxy.為每個服務生成一個虛擬的IP,並由三種(IPVS,iptables,usersapce)方式轉發到Pods中.

IPVS還是beta版,這裡先只介紹一下兩種方式:

  • iptables:預設模式,kubeproxy不參與真正的流量轉發,實時監聽endpoints與service的變化控制iptables的轉發規則.實際流量的轉發是由iptables進行.因此相比與userspace模式速度更快,流量的轉發只是在核心.
  • userspace:將實際service中cluster的IP通過iptables轉發到kube-proxy代理的埠中然後kube-proxy在轉到對應的pod當中.

MASTER元件

MASTER元件可以執行到任叢集的何節點,也可以實現高可用.執行這些元件的節點成為主節點.
這些元件為叢集提供控制層.這些主要元件做一些主要的決策例如排程,發現和響應叢集事件.

  • kube-apiserver
    位於MASTER節點,暴露K8s的介面
  • etcd
    提供一致性和高可用的持久化的鍵值儲存服務.
  • kube-scheduler
    觀察是否有新的pod建立,如果有新的pod建立並且沒有分配節點,為pod分配節點並執行.
  • kube-controller-manager
    • Node Controller:當節點停止時傳送通知和進行響應.
    • Replication Controller:維護pod在節點設定的正確執行的副本數量.可以用於灰度釋出,滾動更新,多版本追蹤等
    • Endpoints Controller:用於維護Services與endpoint的關係.
    • Service Account & Token Controllers:為新的名稱空間建立下預設的賬戶與API的access token.

Node Component

Node Component執行在每一個節點之上,維護執行的pods,以及k8s的環境.

  • Kubelet
    叢集當中每個節點的代理,確保在一個pod中的容器處於執行狀態.
  • kube-proxy
    能夠讓k8s通過維護在主機的網路規則以及連線代理進行服務抽象.
  • Container Runtime
    是承擔容器執行的軟體

Addons

附加元件都屬於kube-system名稱空間,不是必須元件,但是這裡只介紹一個DNS元件.

DNS

Cluster DNS是一個叢集的DNS服務.容器啟動時在DNS查詢之時會使用DNS服務.

Namespaces

使用不同的名稱空間是為了分割資源,使用標籤來區分資源在同一名稱空間下.
可以在多個名稱空間存在相同的名字,但是在單個名稱空間下只能存在一個.

Label 與 Selector

Label使用鍵值儲存,關鍵做用是用於區分不同的物件.可以用來選擇區分不同的物件.

命名規則

Label的key分為字首以及名字.

Key 規則如下:

1.名字必須不超過63個字元,且以字母開頭,可由[\.-_a-zA-Z0-9]構成.
2.字首必須是域名加/,不超過253個字元.
3.如果字首不存在那麼k8s會假設這個Key是這個使用者私有.

Value規則:

不超過63個字元且以字母開頭可由[\.-_a-zA-Z0-9]構成.

進行選擇

目前只支援基於集合和基於相等,並列條件可以在每個選擇條件之間加入,表示邏輯&&.

基於集合

支援的字元:in not in exists not exists

exists的語法是直接寫Key的名稱,下述例子是查詢env為qa,dev,prod,且包含partition的key,且不包含notincluded的key.

env in (qa, dev, prod),partition,!notincluded

基於相等

支援的字元:= != == .
===是等價的都表示相等條件.

使用示例:
選出pods當中label中的key為env,value為prod

kubectl get pods -l 'env=prod,partition in (1)'

deployment

主要為了操作部署replicaset與pod.
功能:可以進行橫向擴充套件,藍綠髮布,金絲雀釋出,灰度釋出,多版本釋出等.
除此之外可已根據對應的釋出版本的歷史記錄進行回滾.

當然我們也可以設定自己的策略,當我們部署的pods或者需要更新pods沒有正常執行而異常退出,deployment controller會根據設定的策略對部署的pods進行重新部署.

配置示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  #指定副本數量
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  #pod的模板資訊   
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

replicaset

主要作用:確保當前執行數量的pods.

官方不推薦直接使用replicaset進行操作,而推薦使用deployment.
其與replication controller最主要的區別是replicaset中selector支援集合操作.

Jobs

一個Job建立一個或者多個pods確保明確的執行數量成功執行.

主要存在下述三種類型:

1.非平行工作:通常啟動一個pod,當pod成功退出,任務就被完成.
2.固定執行任務數的平行工作:指定了.spec.completions非0正數值,當執行成功的pod滿足了.spec.completions的值時,那麼任務就會被完成
3.平行工作:每個pod都在執行job,只要有任一一個job中的工作完成,那麼其他的pod也會終止job.

CronJob

CronJob是類似於Crond服務的計劃工作模式.

配置要求:
1.Kubernetes版本大於1.8
2.對於小於1.8版本的需要在啟動時增加--runtime-config=batch/v2alpha1=true配置項

簡單的配置要求

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

Volume

k8s支援很多種型別的Volume.這裡簡單介紹幾種Volume.
Volume宣告是在pod當中,因此pod的內的容器共享Volume.

pod中程序看到容器的內的檔案系統由兩部分組成:
1.Docker映象檔案系統
2.若干個Volume

ConfigMap

ConfigMap可以用於儲存一些配置資料,變數等.不適合儲存大型檔案.

示例:

apiVersion: v1
data:
  allowed: '"true"'
  enemies: aliens
  lives: "3"
kind: ConfigMap
metadata:
  creationTimestamp: 2017-12-27T18:36:28Z
  name: game-config-env-file
  namespace: default
  resourceVersion: "809965"
  selfLink: /api/v1/namespaces/default/configmaps/game-config-env-file
  uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8

secret

secret 可用於儲存一些加密的資訊以檔案的形式傳給pod.

persistentVolume

持久化volume,獨立於pod的生命週期.指定資源型別,大小,儲存型別等等.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

persistentVolumeClaim

對於PersistentVolume的資源請求(分配),被用於掛載persistentVolume到pod上,不需要關心底層的儲存環境無論是GCE或者是ISCSI.
通過多個pod使用供用的PVC我們可以實現,不同的之間共享資料.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

pod使用emptDir型別Volume使用示例

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}