2、pod詳解

一、pod基本介紹

pod是一組容器,一組容器可以是多個容器也可以是單個容器(不包括系統內置的容器),當一個pod包含多個容器時,多個容器運行在同一個工作節點上,一個pod中的多個容器絕不會跨多個節點。

1、pod的名稱空間

pod中可以包含多個容器或單個容器,pod中包含多個容器時,多個容器是共享命名空間的,pod中多個容器可以進行進程通信,可以共享網絡空間。但pod中每個容器的文件系統是相互隔離的,不過可以通過Volume進行文件系統共享。

2、pod的網絡空間

pod中的容器共享網絡命名空間,因此pod中容器共享相同的IP和端口,這就要求pod中的容器不能綁定到相同的端口,否則會導致端口衝突,對於不同的pod不會導致端口衝突。共享網絡命名空間允許pod中的容器可以通過localhost進行通信。
k8s集羣中pod共享網絡地址地址空間,允許一個pod通過另一個pod的IP地址進行訪問。

3、pod優點

  1. 有利於進程隔離
    每個pod中運行一個容器,每個容器中只運行一個進程,當一個進程崩潰後不會影響到其它進程的執行。如果是以前的胖系統中,所有的應用都部署在一起,當其中的一個應用進程崩潰後導致整個系統崩潰,現在每個應用部署在一個pod的容器中,當一個應用崩潰後不會導致其它的pod中的應用崩潰。

  2. 有利於橫向擴縮pod
    像以前胖系統中,所有應用部署在一起,當修改其中的一個應用後就要對整個系統進行變更,有個pod後,每個應用部署在不同的pod中,當一個應用變更時,只需要修改相應pod的應用就可以,減小了整個系統的風險。另外對於胖系統,如果某個應用訪問量大,如果要擴容就要對整個系統就行擴容,導致資源浪費,有了pod後,只需要對訪問量大的pod進行橫向擴展pod就可以了,減少了資源的浪費。

二、pod基本操作

1、創建pod

以nginx爲例,通過yaml創建運行nginx的pod,下面建立niginx的yaml文件
pod_nginx.yaml

apiVersion: v1				#k8s的版本
kind: Pod 					#資源類型
metadata:  					#描述信息
  name: nginxpod  			#pod的名稱
spec:   					#pod的說明信息
  containers: 				#定義pod中運行的容器
 - image: nginx 			#運行容器的鏡像
    name: nginxcontainer	#pod中運行的容器的名字	
    ports: 					#定義容器暴露的端口
    - containerPort: 80 	#容器端口
      protocol: TCP  		#端口協議

創建完pod的yaml描述信息後,下面通過yaml描述的pod

 kubectl create -f pod_nginx.yaml

在這裏插入圖片描述
表示創建pod成功。

2、查詢pod

  • 查看創建的pod
kubectl get pod

在這裏插入圖片描述

  • 查看pod的節點等詳細信息
 kubectl get pod -o wide

在這裏插入圖片描述

  • 獲取pod的yaml完整描述
 kubectl get pod -o yaml
  • 查看pod日誌
    如果pod中只有一個容器,可以直接獲取pod的日誌
 kubectl logs nginxpod

如果pod中有多個容器,可以用-c指定查看哪個容器中日誌

kubectl logs nginxpod -c nginxcontainer

3、pod標籤

k8s集羣中有大規模的pod,通過pod的標籤可以有效的獲取、篩選、組織pod,pod標籤在pod創建時進行添加。

  • 創建帶標籤的pod
 apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  labels:
    app: nginx 		#pod的標籤爲app和sit,可以添加一個或多個標籤
    env: sit
spec:
  containers:
 - image: nginx
    name: nginxcontainer
    ports:
    - containerPort: 80
      protocol: TCP
  • 查詢帶標籤的pod
    –show-labels表示查詢顯示pod時,帶上標籤信息
 kubectl get pod --show-labels

查詢pod時,按指定的app,env標籤顯示pod信息。

kubectl get pod -L app,env
  • 修改標籤
    創建pod時未添加標籤的,可以手動添加標籤
kubectl label pod nginxpod2 app=nginxpod2

創建pod時帶標籤,後期想修改覆蓋原標籤

kubectl label pod nginxpod env=debug --overwrite

4、標籤選擇器

  • 篩選出app=nginx的標籤的pod
 kubectl get pod -l app=nginx
  • 篩選出所有含有app標籤的pod
kubectl get pod -l app
  • 篩選出不含有app標籤的pod
 kubectl get pod -l '!app'  #注意添加引號
  • 篩選出標籤爲app,但值不爲nginx的pod
kubectl get pod -l app!=nginx
  • 篩選出標籤app等於nginx或者js的pod
kubectl get pod -l 'app in (nginx,js)'
  • 篩選出標籤app不等於nginx和js的pod
kubectl get pod -l 'app notin (nginx,js)'
  • pod調度到指定標籤的節點上
 apiVersion: v1
kind: Pod
metadata:
  name: nginxpod
  labels:
    app: nginx
    env: sit
spec:
  nodeSelector: #pod調度到含有標籤nas=true的節點上
    nas: "true"
  containers:
 - image: nginx
    name: nginxcontainer
    ports:
    - containerPort: 80
      protocol: TCP

5、對pod添加註解

pod中註解起到註釋信息的作用,就想java程序中的註釋信息一樣。
下面爲創建的pod添加註解信息

kubectl annotate pod nginxpod pod/author="lzj default"

爲nginxpod添加了註解信息pod/author=“lzj default”,添加註解信息後,可以通過kubectl describe pod nginxpod 查看添加的註解信息。添加註解信息時也可以在yaml中配置。

6、刪除pod

  • 按名稱刪除pod
kubectl delete pod mypod  #按pod名稱刪除pod
  • 按標籤選擇器刪除pod
 kubectl delete pod -l app=nginx #刪除標籤爲nginx的pod
  • 刪除名稱空間中所有pod
kubectl delete namespace myspace  #刪除myspace名稱空間中所有的pod	
kubectl delete pod --all #刪除默認名稱空間中所有的pod
  • 刪除所有資源
kubectl delete all --all

三、pod生命週期

在這裏插入圖片描述
一般pod中運行一個應用容器,但除了主應用容器外還有其他容器,當一個pod被創建後,首先啓動的是pause容器,也是每個pod都會默認創建的容器,用於初始pod中網絡;其次pod也可以有一個或多個init初始化容器,也可沒有,主要負責應用啓動前的初始化工作,注意一點,不管有幾個init容器,一定是一個init容器停止後,另一個init容器纔會創建;等init容器創建並停止後,主應用容器被創建,主應用容器也可以由start和stop操作;最後主應用容器被創建後,也可以爲應用容器添加探針容器,主要用於pod中主應用容器的健康檢查。

四、Init容器

pod中可以有一個或多個先於主應用容器的Init容器,每一個Init容器都必須成功結束後纔會啓動下一個Init容器或者主應用容器。如果Init容器啓動失敗,k8s會不斷的重啓pod,如果restartPolicy爲Never,則k8s不會重新啓動pod。
Init應用場景:

  • 爲應用安裝的工具;
  • 應用之前的初始化工作;
  • 可以訪問系統的Secret權限;
  • 提供了一種簡單的阻塞或延遲應用容器啓動的方法。

下面通過一個示例演示Init容器的用法,以pod_init.yaml爲例:

metadata:
  name: mypod
  labels:
    app: pod
    env: sit
spec:
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent
    name: main-container
    command: ['sh', '-c', 'echo main-container is successfully > /root/test.txt && sleep 3600']
  initContainers:
  - name: init-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'sleep 30']

首先在創建main-container主應用服務器之前創建了init-container初始化容器,鏡像都爲busybox,Init服務器創建後休眠30s,然後退出,Init容器成功退出後,main-container主應用容器纔開始創建,主應用容器創建後,把日誌寫入/root/test.txt文件中,並休眠1小時。下面通過kubectl create -f pod_init.yaml創建pod,然後查看init容器和主容器運行情況

在這裏插入圖片描述
注意

  1. Pod啓動過程中,Init容器必須在pause容器啓動後啓動;
  2. Init容器如果啓動失敗,會根據pod的restartPolicy策略進行重啓;
  3. Init容器沒有成功之前,Pod不會變成ready狀態,Init的端口也不會在service進行聚集;
  4. 如果pod重啓,所有的Init容器都必須重啓;
  5. 修改Init容器的鏡像就會導致pod重啓。

五、探針

有時候pod中容器進程沒有崩潰,但容器中運行的程序崩潰,不會導致k8s重啓pod,因此就不方便知道應用是否正常。通過探針對容器定期進行診斷,可實時瞭解容器內部運行情況,探針是由kubelet對容器進行的定期診斷。kubelet可以通過如下三種方式對對容器進行診斷:

  • ExecAction: 在容器內執行命令,如果命令退出時返回碼爲0則認爲診斷成功;
  • TCPSocketAction: 對指定端口上的容器IP進行TCP檢查,如果端口打開,則診斷成功;
  • HTTPGetAction: 對指定的端口和路徑上的IP執行http get請求,如果響應狀態碼大於等於200且小於400,則診斷成功。

每次探測結果都是如下情況:

  • 成功:容器診斷成功;
  • 失敗:容器診斷失敗,根據重啓策略決定pod重啓;
  • 未知:不會採取任何行動

探針分兩種形式:

  • livenessProbe: 指示容器是否正在運行。如果存活檢測失敗,則kubelet會殺死容器,並將pod根據重啓策略進行重啓,如果容器不提供存活探針,默認狀態爲success,pod不會重啓。
  • readinessProbe: 指示容器是否準備好服務請求。如果ReadinessProbe探針檢測到失敗,則Pod的狀態被修改。Endpoint Controller將從Service的Endpoint中刪除包含該容器所在Pod的Endpoint。

兩種探針用法相同,下面以livenessProbe探針爲例

1、通過ExecAction形式進行診斷

創建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-exec-pod
  namespace: default
spec:
  containers:
  - name: live-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh", "-c", "echo hello > /tmp/hello.txt; sleep 10; rm /tmp/hello.txt; sleep 3600"]
    livenessProbe:
      exec:
        command: ["test", "-e", "/tmp/hello.txt"]
      initialDelaySeconds: 1  #容器啓動後1s後開始探測
      periodSeconds: 3		  #每隔3秒鐘探測一次

上面yaml定義了,當live-exec-container啓動後,會有一個livenessProbe探測器,從容器啓動後1s後開始通過[“test”, “-e”, “/tmp/hello.txt”]命令探測容器,如果返回0,探測成功,如果返回非0,探測失敗,pod重啓

[root@k8s-master01 work]# kubectl create -f pod_live_exec.yaml 
pod/live-exec-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-exec-pod   1/1     Running   0          4s
live-exec-pod   1/1     Running   1          49s
live-exec-pod   1/1     Running   2          97s
live-exec-pod   1/1     Running   3          2m26s
..............

2、通過HTTPGetAction形式進行診斷

創建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-http-pod
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      httpGet:
        port: 80
        path: /hello.html
      initialDelaySeconds: 0   	#nginx容器啓動後開始執行探針
      periodSeconds: 5  		#探針每5秒鐘探測一次
      timeoutSeconds: 20 		#20s後探針退出

創建nginx容器後,livenessProbe探針會對/hello.html路徑和端口80進行http get請求,每5s進行探測一次,超時時間爲20s。

[root@k8s-master01 work]# kubectl create -f pod_live_http.yaml 
pod/live-http-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-http-pod   1/1     Running   0          11s
live-http-pod   1/1     Running   1          15s
live-http-pod   1/1     Running   2          30s
live-http-pod   1/1     Running   3          45s
live-http-pod   0/1     CrashLoopBackOff   3          59s

3、通過TCPSocketAction形式進行

創建yaml如下

apiVersion: v1
kind: Pod
metadata:
  name: live-sock-pod
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    livenessProbe:
      initialDelaySeconds: 2
      timeoutSeconds: 1
      tcpSocket:
        port: 90

創建nginx容器後,探針會2s後對90端口進行探測,單次探測超時時間爲1s,如果端口不通,會重啓pod。

[root@k8s-master01 work]# kubectl create -f pod_live_sock.yaml
pod/live-sock-pod created
[root@k8s-master01 work]# kubectl get pod -w
NAME            READY   STATUS    RESTARTS   AGE
live-sock-pod   1/1     Running   0          8s
live-sock-pod   1/1     Running   1          27s
live-sock-pod   1/1     Running   2          57s

以上是livenessProbe的三種用法,readinessProbe用法完全相同。

六、主容器start/stop操作

pod中主容器啓動啓動後可以執行初始化內容,比如構建一些應用的環境變量等,或初始化數據庫等;主容器結束前可以執行應用的清理工作、數據庫清理工作等。可以通過postStart指定容器的初始化步驟,通過preStop指定容器的清理步驟。
創建yaml示例如下:

apiVersion: v1
kind: Pod
metadata:
  name: start-stop-pod
spec:
  containers:
 1. name: start-stop-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh", "-c", "sleep 20"]
    lifecycle:
      postStart: 	#執行初始化工作
        exec:
          command: ["/bin/sh", "-c", "echo start pod > /tmp/pod.txt"]
      preStop: 		#執行清理工作
        exec:
          command: ["/bin/sh", "-c", "rm -rf /tmp/pod.txt"]

七、pod生命週期狀態

通過pod的狀態可以得知pod運行情況,pod從創建到死亡全部的聲明週期狀態如下所示
1. Pending(掛起)
pod已被k8s管理,但pod中容器尚未全部創建,pod調度花費時間以及網絡下載鏡像事前全部在該狀態下完成。
2. Running(運行中)
Pod中所有容器已被創建,Running狀態不表示所有容器已經創建成功,可以表示容器已經正常啓動成功,也可以表示容器正處於啓動或重啓過程中。

3. Succeeded(成功)
pod中所有容器被成功終止,並且不會再重新啓動。

4. Failed(失敗)
Pod中所有已被終止,並且至少有一個容器因失敗爲終止,容器以非0狀態退出。

5. Unknow(未知)
無法與pod取得聯繫,一般pod脫離了k8s管理,通常原因pod與主機通信失敗。

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