Kubernetes K8S之Pod 生命週期與init container初始化容器詳解

 

K8S中Pod的生命週期與init container初始化容器詳解node

 

主機配置規劃

服務器名稱(hostname) 系統版本 配置 內網IP 外網IP(模擬)
k8s-master CentOS7.7 2C/4G/20G 172.16.1.110 10.0.0.110
k8s-node01 CentOS7.7 2C/4G/20G 172.16.1.111 10.0.0.111
k8s-node02 CentOS7.7 2C/4G/20G 172.16.1.112 10.0.0.112

 

Pod容器生命週期

 

Pause容器說明

每一個Pod裏運行着一個特殊的被稱之爲Pause的容器,其餘容器則爲業務容器,這些業務容器共享Pause容器的網絡棧和Volume掛載卷,所以他們之間通訊和數據交換更爲高效。在設計時能夠充分利用這一特性,將一組密切相關的服務進程放入同一個Pod中;同一個Pod裏的容器之間僅需經過localhost就能互相通訊。python

 

kubernetes中的pause容器主要爲每一個業務容器提供如下功能:

PID命名空間:Pod中的不一樣應用程序能夠看到其餘應用程序的進程ID。api

網絡命名空間:Pod中的多個容器可以訪問同一個IP和端口範圍。安全

IPC命名空間:Pod中的多個容器可以使用System V IPC或POSIX消息隊列進行通訊。服務器

UTS命名空間:Pod中的多個容器共享一個主機名;Volumes(共享存儲卷)。網絡

Pod中的各個容器能夠訪問在Pod級別定義的Volumes。app

 

Init Container容器

Pod能夠包含多個容器,應用運行在這些容器裏面,同時 Pod 也能夠有一個或多個先於應用容器啓動的 Init 容器。ide

若是爲一個 Pod 指定了多個 Init 容器,這些Init容器會按順序逐個運行。每一個 Init 容器都必須運行成功,下一個纔可以運行。當全部的 Init 容器運行完成時,Kubernetes 纔會爲 Pod 初始化應用容器並像日常同樣運行。工具

 

Init容器與普通的容器很是像,除了如下兩點:google

一、Init容器老是運行到成功完成且正常退出爲止

二、只有前一個Init容器成功完成並正常退出,才能運行下一個Init容器。

若是Pod的Init容器失敗,Kubernetes會不斷地重啓Pod,直到Init容器成功爲止。但若是Pod對應的restartPolicy爲Never,則不會從新啓動。

在全部的 Init 容器沒有成功以前,Pod 將不會變成 Ready 狀態。 Init 容器的端口將不會在 Service 中進行彙集。 正在初始化中的 Pod 處於 Pending 狀態,但會將條件 Initializing 設置爲 true。

若是 Pod 重啓,全部 Init 容器必須從新執行。

在 Pod 中的每一個應用容器和 Init 容器的名稱必須惟一;與任何其它容器共享同一個名稱,會在校驗時拋出錯誤。

 

Init 容器能作什麼?

由於 Init 容器是與應用容器分離的單獨鏡像,其啓動相關代碼具備以下優點:

一、Init 容器能夠包含一些安裝過程當中應用容器不存在的實用工具或個性化代碼。例如,在安裝過程當中要使用相似 sed、 awk、 python 或 dig 這樣的工具,那麼放到Init容器去安裝這些工具;再例如,應用容器須要一些必要的目錄或者配置文件甚至涉及敏感信息,那麼放到Init容器去執行。而不是在主容器執行。

二、Init 容器能夠安全地運行這些工具,避免這些工具致使應用鏡像的安全性下降。

三、應用鏡像的建立者和部署者能夠各自獨立工做,而沒有必要聯合構建一個單獨的應用鏡像。

四、Init 容器能以不一樣於Pod內應用容器的文件系統視圖運行。所以,Init容器可具備訪問 Secrets 的權限,而應用容器不可以訪問。

五、因爲 Init 容器必須在應用容器啓動以前運行完成,所以 Init 容器提供了一種機制來阻塞或延遲應用容器的啓動,直到知足了一組先決條件。一旦前置條件知足,Pod內的全部的應用容器會並行啓動。

 

Init 容器示例

下面的例子定義了一個具備 2 個 Init 容器的簡單 Pod。 第一個等待 myservice 啓動,第二個等待 mydb 啓動。 一旦這兩個 Init容器都啓動完成,Pod 將啓動spec區域中的應用容器。

 

Pod yaml文件

 1 [root@k8s-master lifecycle]# pwd
 2 /root/k8s_practice/lifecycle
 3 [root@k8s-master lifecycle]# cat init_C_pod.yaml
 4 apiVersion: v1
 5 kind: Pod
 6 metadata:
 7   name: myapp-busybox-pod
 8   labels:
 9     app: myapp
10 spec:
11   containers:
12   - name: myapp-container
13     image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
14     command: ['sh', '-c', 'echo The app is running! && sleep 3600']
15   initContainers:
16   - name: init-myservice
17     image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
18     command: ['sh', '-c', "until nslookup myservice; do echo waiting for myservice; sleep 60; done"]
19   - name: init-mydb
20     image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
21     command: ['sh', '-c', "until nslookup mydb; do echo waiting for mydb; sleep 60; done"]

 

啓動這個 Pod,並檢查其狀態,能夠執行以下命令:

1 [root@k8s-master lifecycle]# kubectl apply -f init_C_pod.yaml 
2 pod/myapp-busybox-pod created 
3 [root@k8s-master lifecycle]# kubectl get -f init_C_pod.yaml -o wide  # 或者kubectl get pod myapp-busybox-pod -o wide
4 NAME                READY   STATUS     RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
5 myapp-busybox-pod   0/1     Init:0/2   0          55s   10.244.4.16   k8s-node01   <none>           <none>

 

如需更詳細的信息:

 1 [root@k8s-master lifecycle]# kubectl describe pod myapp-busybox-pod 
 2 Name:         myapp-busybox-pod
 3 Namespace:    default
 4 Priority:     0
 5 …………
 6 Node-Selectors:  <none>
 7 Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
 8                  node.kubernetes.io/unreachable:NoExecute for 300s
 9 Events:
10   Type    Reason     Age    From                 Message
11   ----    ------     ----   ----                 -------
12   Normal  Scheduled  2m18s  default-scheduler    Successfully assigned default/myapp-busybox-pod to k8s-node01
13   Normal  Pulled     2m17s  kubelet, k8s-node01  Container image "registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24" already present on machine
14   Normal  Created    2m17s  kubelet, k8s-node01  Created container init-myservice
15   Normal  Started    2m17s  kubelet, k8s-node01  Started container init-myservice

 

如需查看Pod內 Init 容器的日誌,請執行:

 1 [root@k8s-master lifecycle]# kubectl logs -f --tail 500 myapp-busybox-pod -c init-myservice   # 第一個 init container 詳情
 2 Server:    10.96.0.10
 3 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 4 
 5 waiting for myservice
 6 nslookup: can't resolve 'myservice'
 7 Server:    10.96.0.10
 8 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 9 ………………
10 [root@k8s-master lifecycle]# kubectl logs myapp-busybox-pod -c init-mydb   # 第二個 init container 詳情
11 Error from server (BadRequest): container "init-mydb" in pod "myapp-busybox-pod" is waiting to start: PodInitializing

此時Init 容器將會等待直至發現名稱爲mydb和myservice的 Service。

 

Service yaml文件

 1 [root@k8s-master lifecycle]# pwd
 2 /root/k8s_practice/lifecycle
 3 [root@k8s-master lifecycle]# cat init_C_service.yaml 
 4 ---
 5 kind: Service
 6 apiVersion: v1
 7 metadata:
 8   name: myservice
 9 spec:
10   ports:
11     - protocol: TCP
12       port: 80
13       targetPort: 9376
14 ---
15 kind: Service
16 apiVersion: v1
17 metadata:
18   name: mydb
19 spec:
20   ports:
21     - protocol: TCP
22       port: 80
23       targetPort: 9377

 

建立mydb和myservice的 service 命令:

1 [root@k8s-master lifecycle]# kubectl create -f init_C_service.yaml 
2 service/myservice created
3 service/mydb created

 

以後查看pod狀態和service狀態,能看到這些 Init容器執行完畢後,隨後myapp-busybox-pod的Pod轉移進入 Running 狀態:

1 [root@k8s-master lifecycle]# kubectl get svc -o wide mydb myservice
2 NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE   SELECTOR
3 mydb        ClusterIP   10.108.24.84     <none>        80/TCP    72s   <none>
4 myservice   ClusterIP   10.105.252.196   <none>        80/TCP    72s   <none>
5 [root@k8s-master lifecycle]# 
6 [root@k8s-master lifecycle]# kubectl get pod myapp-busybox-pod -o wide 
7 NAME                READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
8 myapp-busybox-pod   1/1     Running   0          7m33s   10.244.4.17   k8s-node01   <none>           <none>

由上可知:一旦咱們啓動了 mydb 和 myservice 這兩個 Service,咱們就可以看到 Init 容器完成,而且 myapp-busybox-pod 被建立。

進入myapp-busybox-pod容器,並經過nslookup查看這兩個Service的DNS記錄。

 1 [root@k8s-master lifecycle]# kubectl exec -it myapp-busybox-pod sh
 2 / # nslookup mydb 
 3 Server:    10.96.0.10
 4 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 5 
 6 Name:      mydb
 7 Address 1: 10.108.24.84 mydb.default.svc.cluster.local
 8 / # 
 9 / # 
10 / # 
11 / # nslookup myservice
12 Server:    10.96.0.10
13 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
14 
15 Name:      myservice
16 Address 1: 10.105.252.196 myservice.default.svc.cluster.local

 

完畢!

 


———END———
若是以爲不錯就關注下唄 (-^O^-) !

相關文章
相關標籤/搜索