iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 19
0
DevOps

從題目中學習k8s系列 第 19

【從題目中學習k8s】-【Day19】第十一題 - initContainer


title: 【從題目中學習k8s】-【Day19】第十一題 - initContainer
description: 以無比的恆毅力堅持30天鍊成鐵人--連續30天,一天發表一篇IT技術文章

【從題目中學習k8s】-【Day19】第十一題 - initContainer

tags: DevOps CICD K8s Docker

Question

Create a pod as follow:

name:my-nginx
image: nginx

Add an Init Container within the Pod, the role of Init Container is to create an empty file under /cache/test.txt, Pod Containers determine whether the file exists, exiting if it does not exist.


概念

這題提到了一個新的名詞,即Init Container (初始化容器),這什麼呢?

Init Container是運行於Pod Container之前的專用容器。Init Conatiner可以應用於一些不包含setup environment 的image

Init ContainerPod Container定義在同一個Pod YAML中,通常是用於幫助Pod Container運行的前置作業。像是Pod Container需要將執行結果輸出到某一檔案,但該檔案初始並不存在,這時就可以利用Init ContainerPod Container運行前先將檔案創建,以供使用。

Pod中可以有多個Pod Container,也可以有一個或多個Init Container,它們在啟動Pod Container之前就已運行。它們的生命週期如下圖:

Init Container與一般Container基本上完全一樣,有一點點不同的地方是,Init ContainerPod Container不會同時存在於同一Pod中,Pod Container會等待Init Container運行到完成狀態後才創建。
每個初始化容器必須成功完成工作才能啟動下一個容器 (包含初始化容器)。如果Pod的初始化容器失敗,Kubernetes會反復重啟Pod,直到初始化容器成功。 但若Pod的參數--restart=Never,則Kubernetes不會重新啟動Pod

要為Pod指定初始化化容器,須將initContainers欄位添加到Pod YAML中,例如:

$ cat init-container.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

Init Container通常是為了完成某些特定的工作而存在的,例如:

  • 等待某個Service被創建
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 向遠端Server註冊此Pod
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
  • Pod Container等待一段時間後再創建
sleep 60
  • Clone一個Git repo到Volume
  • 設定config或環境參數

要讓Container做某些事,可以通過Command參數

當有CommandContainer執行完Command後,會進入CrashLoopBackOff狀態,代表Container工作完成。若想讓它維持在Running Status,可以加上sleep命令

回到題目,這題是要創建一個Pod Container檢查某檔案是否存在,該檔案由Init Container創建,若檔案不存在則退出。因此我們需要一個Pod,裡面包含:

  1. 一個Pod Container 和一個 Init Container
  2. 兩者mount到同一Vloume
  3. Init Container於該Volume創建檔案
  4. Pod Container檢查該Volume,若檔案存在則印出檔案內容,若不存在則退出

Answer

$  vim q11-pod.yaml

apiVersion: v1
kind: Pod 
metadata:
  name: my-nginx
spec:
  containers:
  - name: my-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh"]
    args: ["-c", "cat /cache/test.txt && sleep 3600000"]
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  initContainers:
  - name: init-nginx
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ['touch', '/cache/test.txt']
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
    
    
$ kubectl apply -f q11-pod.yaml

touch命令用於建立空檔案
Pod Containercat到該檔案,代表檔案存在,則會sleep 3600000 (讓它維持在Running Status)
若無法cat,代表 /cache/test.txt 不存在,則Pod會處於Error Status,算是達到題目的要求退出


結論

今天介紹了Init Container的考題,這類題目還算簡單,比較要注意的是Command的寫法,有時候之要如何使用Init Container,但卻不知道Command怎麼下就很頭痛了!好啦,今天就到這囉~ 謝謝大家~

參考資料

Init Containers

Thank you!

You can find me on

  • george4908090@gmail.com

上一篇
【從題目中學習k8s】-【Day18】第十題 - Pod Scheduling 2
下一篇
【從題目中學習k8s】-【Day20】第十二題 - RBAC
系列文
從題目中學習k8s31

尚未有邦友留言

立即登入留言