Kubernetes核心技術--Pod,Label,Volume,Service,Deployment詳解

一.kubernetes簡介

kubernetes,簡稱K8s,是用8代替8個字符“ubernete”而成的縮寫。是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。

傳統的應用部署方式是通過插件或腳本來安裝應用。這樣做的缺點是應用的運行、配置、管理、所有生存週期將與當前操作系統綁定,這樣做並不利於應用的升級更新/回滾等操作,當然也可以通過創建虛擬機的方式來實現某些功能,但是虛擬機非常重,並不利於可移植性。

新的方式是通過部署容器方式實現,每個容器之間互相隔離,每個容器有自己的文件系統 ,容器之間進程不會相互影響,能區分計算資源。相對於虛擬機,容器能快速部署,由於容器與底層設施、機器文件系統解耦的,所以它能在不同雲、不同版本操作系統間進行遷移。

容器佔用資源少、部署快,每個應用可以被打包成一個容器鏡像,每個應用與容器間成一對一關係也使容器有更大優勢,使用容器可以在build或release 的階段,爲應用創建容器鏡像,因爲每個應用不需要與其餘的應用堆棧組合,也不依賴於生產環境基礎結構,這使得從研發到測試、生產能提供一致環境。類似地,容器比虛擬機輕量、更“透明”,這更便於監控和管理

Pod,Label,Volume,Service,Deployment是kubernetes工作過程中重要的幾個概念

二.Pod

Pod是Kubernetes的最重要概念,每一個Pod都有一個特殊的被稱爲”根容器“的Pause容器。Pause容器對應的鏡像屬於Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或多個緊密相關的用戶業務容器。

2.1 創建Pod

在kubernetes中,使用下面的yaml文件定義的Pod的完整內容

apiVersion: v1 //版本
kind: Pod //類型,pod
metadata: //元數據
name: string //元數據,pod的名字
namespace: string //元數據,pod的命名空間
labels: //元數據,標籤列表
- name: string //元數據,標籤的名字
annotations: //元數據,自定義註解列表
- name: string //元數據,自定義註解名字
spec: //pod中容器的詳細定義
containers: //pod中的容器列表,可以有多個容器
- name: string //容器的名稱
image: string //容器中的鏡像
imagesPullPolicy: [Always|Never|IfNotPresent]//獲取鏡像的策略,默認值爲Always,每次都嘗試重新下
載鏡像
command: [string] //容器的啓動命令列表(不配置的話使用鏡像內部的命令)
args: [string] //啓動參數列表
workingDir: string //容器的工作目錄
volumeMounts: //掛載到到容器內部的存儲卷設置
- name: string
mountPath: string //存儲卷在容器內部Mount的絕對路徑
readOnly: boolean //默認值爲讀寫
ports: //容器需要暴露的端口號列表
- name: string
containerPort: int //容器要暴露的端口
hostPort: int //容器所在主機監聽的端口(容器暴露端口映射到宿主機的端口,設置hostPort時同一
臺宿主機將不能再啓動該容器的第2份副本)
protocol: string //TCP和UDP,默認值爲TCP
env: //容器運行前要設置的環境列表
- name: string
value: string
resources:
limits: //資源限制,容器的最大可用資源數量
cpu: Srting
memory: string
requeste: //資源限制,容器啓動的初始可用資源數量
cpu: string
memory: string
livenessProbe: //pod內容器健康檢查的設置
exec:
command: [string] //exec方式需要指定的命令或腳本
httpGet: //通過httpget檢查健康
path: string
port: number
host: string
scheme: Srtring
httpHeaders:
- name: Stirng
value: string
tcpSocket: //通過tcpSocket檢查健康
port: number
initialDelaySeconds: 0//首次檢查時間
timeoutSeconds: 0 //檢查超時時間
periodSeconds: 0 //檢查間隔時間
successThreshold: 0
failureThreshold: 0
securityContext: //安全配置
privileged: falae
restartPolicy: [Always|Never|OnFailure]//重啓策略,默認值爲Always
nodeSelector: object //節點選擇,表示將該Pod調度到包含這些label的Node上,以key:value格式指定
imagePullSecrets:
- name: string
hostNetwork: false //是否使用主機網絡模式,棄用Docker網橋,默認否
volumes: //在該pod上定義共享存儲卷列表
- name: string
emptyDir: {} //是一種與Pod同生命週期的存儲卷,是一個臨時目錄,內容爲空
hostPath: //Pod所在主機上的目錄,將被用於容器中mount的目錄
path: string
secret: //類型爲secret的存儲卷
secretName: string
item:
- key: string
path: string
configMap: //類型爲configMap的存儲卷
name: string
items:
- key: string
path: string

2.2 Pod使用方法

在kubernetes中對運行容器的要求爲:容器的主程序需要一直在前臺運行,而不是後臺運行。應用需要改造成前臺運行的方式。如果我們創建的Docker鏡像的啓動命令是後臺執行程序,則在kubelet創建包含這個容器的pod之後運行完該命令,即認爲Pod已經結束,將立刻銷燬該Pod。如果爲該Pod定義了RC,則創建、銷燬會陷入一個無限循環的過程中。

Pod可以由1個或多個容器組合而成

由一個容器組成的Pod,其yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: mytomcat
  labels:
    name: mytomcat
spec:
  containers:
  - name: mytomcat
    image: tomcat
    ports:
    - containerPort: 8000

由兩個爲緊耦合的容器組成的Pod的yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  labels:
    name: tomcat-redis
spec:
  containers:
  - name: tomcat
    image: tomcat
    ports:
    - containerPort: 8080
  - name: redis
    image: redis
    ports:
    - containerPort: 6379

使用yaml文件創建Pod

kubectl create -f xxx.yaml

查看Pod詳細信息命令

kubectl get pod/po <Pod_name>
kubectl get pod/po <Pod_name> -o wide
kubectl describe pod/po <Pod_name>

刪除Pod命令

kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]

2.3 靜態Pod和普通Pod

Pod有兩種類型,一種是靜態Pod,另一種是普通Pod

普通Pod

普通Pod一旦被創建,就會被放入到etcd中存儲,隨後會被Kubernetes Master調度到某個具體的Node上並進行綁定,隨後該Pod對應的Node上的kubelet進程實例化成一組相關的Docker容器並啓動起來。在默認情況下,當Pod裏某個容器停止時,Kubernetes會自動檢測到這個問題並且重新啓動這個Pod裏某所有容器,如果Pod所在的Node宕機,則會將這個Node上的所有Pod重新調度到其它節點上

靜態Pod

靜態Pod是由kubelet進行管理的僅存在於特定Node上的Pod,它們不能通過 API Server進行管理,無法與ReplicationController、Deployment或DaemonSet進行關聯,並且kubelet也無法對它們進行健康檢查

靜態Pod由於管理非常不方便所以很少使用,日常運維和開發中常用的Pod都是普通Pod

2.4 Pod的生命週期和重啓策略

Pod的狀態

狀態值 說明
Pending API Server已經創建了該Pod,但Pod中的一個或多個容器的鏡像還沒有創建,包括鏡像下載過程
Running Pod內所有容器已創建,且至少一個容器處於運行狀態、正在啓動狀態或正在重啓狀態
Completed Pod內所有容器均成功執行退出,且不會再重啓
Failed Pod內所有容器均已退出,但至少一個容器退出失敗
Unknown 由於某種原因無法獲取Pod狀態,例如網絡通信不暢

Pod重啓策略

Pod的重啓策略包括Always、OnFailure和Never,默認值是Always

重啓策略 說明
Always 當容器失效時,由kubelet自動重啓該容器
OnFailure 當容器終止運行且退出碼不爲0時,由kubelet自動重啓該容器
Never 不論容器運行狀態如何,kubelet都不會重啓該容器

Pod常見狀態轉換

Pod包含的容器數 Pod當前的狀態 發生事件 Pod的結果狀態
RestartPolicy=Always RestartPolicy=OnFailure RestartPolicy=Never
包含一個容器 Running 容器成功退出 Running Succeeded Succeeded
包含一個容器 Running 容器失敗退出 Running Running Failure
包含兩個容器 Running 1個容器失敗退出 Running Running Running
包含兩個容器 Running 容器被OOM殺掉 Running Running Failure

2.5 Pod資源配置

每個Pod都可以對其能使用的服務器上的計算資源設置限額,Kubernetes中可以設置限額的計算資源有CPU與
Memory兩種,其中CPU的資源單位爲CPU數量,是一個絕對值而非相對值。Memory配額也是一個絕對值,它的單
位是內存字節數。
Kubernetes裏,一個計算資源進行配額限定需要設定以下兩個參數:

  • Requests 該資源最小申請數量,系統必須滿足要求

  • Limits 該資源最大允許使用的量,不能突破,當容器試圖使用超過這個量的資源時,可能會被KubernetesKill並重啓

sepc
  containers:
  - name: db
    image: mysql
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

上述代碼表明MySQL容器申請最少0.25個CPU以及64MiB內存,在運行過程中容器所能使用的資源配額爲0.5個CPU以及128MiB內存。

三.Label

Label是Kubernetes系統中另一個核心概念。一個Label是一個key=value的鍵值對,其中key與value由用戶自己指定。Label可以附加到各種資源對象上,如Node、Pod、Service、RC,一個資源對象可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源對象上,Label通常在資源對象定義時確定,也可以在對象創建後動態添加或刪除。
Label的最常見的用法是使用metadata.labels字段,來爲對象添加Label,通過spec.selector來引用對象

apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
-------------------------------------
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 3333
selector:
app: nginx

Label附加到Kubernetes集羣中的各種資源對象上,目的就是對這些資源對象進行分組管理,而分組管理的核心就是Label Selector。Label與Label Selector都是不能單獨定義,必須附加在一些資源對象的定義文件上,一般附加在RC和Service的資源定義文件中。

四.Replication Controller

Replication Controller(RC)是Kubernetes系統中核心概念之一,當我們定義了一個RC並提交到Kubernetes集羣中以後,Master節點上的Controller Manager組件就得到通知,定期檢查系統中存活的Pod,並確保目標Pod實例的數量剛好等於RC的預期值,如果有過多或過少的Pod運行,系統就會停掉或創建一些Pod.此外我們也可以通過修改RC的副本數量,來實現Pod的動態縮放功能

kubectl scale rc nginx --replicas=5

由於Replication Controller與Kubernetes代碼中的模塊Replication Controller同名,所以在Kubernetes v1.2時,它就升級成了另外一個新的概念Replica Sets,官方解釋爲下一代的RC,它與RC區別是:Replica Sets支援基於集合的Label selector,而RC只支持基於等式的Label Selector。我們很少單獨使用Replica Set,它主要被Deployment這個更高層面的資源對象所使用,從而形成一整套Pod創建、刪除、更新的編排機制。最好不要越過RC直接創建Pod,因爲Replication Controller會通過RC管理Pod副本,實現自動創建、補足、替換、刪除Pod副本,這樣就能提高應用的容災能力,減少由於節點崩潰等意外狀況造成的損失。即使應用程序只有一個Pod副本,也強烈建議使用RC來定義Pod

五.Replica Set

ReplicaSet 跟 ReplicationController 沒有本質的不同,只是名字不一樣,並且 ReplicaSet 支持集合式的selector(ReplicationController 僅支持等式)。Kubernetes官方強烈建議避免直接使用ReplicaSet,而應該通過Deployment來創建RS和Pod。由於ReplicaSet是ReplicationController的代替物,因此用法基本相同,唯一的區別在於ReplicatSet支持集合式的selector。

六.Deployment

Deployment是Kubenetes v1.2引入的新概念,引入的目的是爲了更好的解決Pod的編排問題,Deployment內部使用了Replica Set來實現。Deployment的定義與Replica Set的定義很類似,除了API聲明與Kind類型有所區別:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
    tier: frontend
  matchExpressions:
    - {key: tier, operator: In, values: [frontend]}
template:
  metadata:
    labels:
      app: app-demo
      tier: frontend
  spec:
    containers:
    - name: tomcat-demo
      image: tomcat
      ports:
      - containerPort: 8080

七.Horizontal Pod Autoscaler

Horizontal Pod Autoscal(Pod橫向擴容 簡稱HPA)與RC、Deployment一樣,也屬於一種Kubernetes資源對象。通過追蹤分析RC控制的所有目標Pod的負載變化情況,來確定是否需要針對性地調整目標Pod的副本數,這是HPA的實現原理。
Kubernetes對Pod擴容與縮容提供了手動和自動兩種模式,手動模式通過kubectl scale命令對一個
Deployment/RC進行Pod副本數量的設置。自動模式則需要用戶根據某個性能指標或者自定義業務指標,並指定Pod副本數量的範圍,系統將自動在這個範圍內根據性能指標的變化進行調整。

八.Volume

Volume是Pod中能夠被多個容器訪問的共享目錄。Kubernetes的Volume定義在Pod上,它被一個Pod中的多個容器掛載到具體的文件目錄下。Volume與Pod的生命週期相同,但與容器的生命週期不相關,當容器終止或重啓時,Volume中的數據也不會丟失。要使用volume,pod需要指定volume的類型和內容( spec.volumes 字段),和映射到容器的位置( spec.containers.volumeMounts 字段)。 Kubernetes支持多種類型的Volume,包括:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、flocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PoteworxVolume、ScaleIO

九.Namespace

Namespace在很多情況下用於實現多用戶的資源隔離,通過將集羣內部的資源對象分配到不同的Namespace中,形成邏輯上的分組,便於不同的分組在共享使用整個集羣的資源同時還能被分別管理。Kubernetes集羣在啓動後,會創建一個名爲"default"的Namespace,如果不特別指明Namespace,則用戶創建的Pod,RC,Service都將被系統 創建到這個默認的名爲default的Namespace中。

十.Service

Service是Kubernetes最核心概念,通過創建Service,可以爲一組具有相同功能的容器應用提供一個統一的入口地址,並且將請求負載分發到後端的各個容器應用上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章