一.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,可以爲一組具有相同功能的容器應用提供一個統一的入口地址,並且將請求負載分發到後端的各個容器應用上。