1. 程式人生 > 其它 >Kubernetes之Pod初始化容器

Kubernetes之Pod初始化容器

Kubernetes之Pod初始化容器

概述

​ 初始化是很多程式語言普遍關注的問題,甚至有些程式語言直接支援模式構造來生成初始化程式,這些用於進行初始化的程式結構稱為初始化器或初始化列表。初始化程式碼要首先執行,且只能執行一次,它們常用於驗證前提條件、基於預設值或傳入的引數初始化物件例項的欄位等。Pod中的初始化容器(Init Container)功能與此類似,它們為那些有先決條件的應用容器完成必要的初始設定,例如設定特殊許可權、生成必要的iptables規則、設定資料庫模式,以及獲取最新的必要資料等。

​ 有很多場景都需要在應用容器啟動之前進行部分初始化操作,例如等待其他關聯元件服務可用、基於環境變數或配置模板為應用程式生成配置檔案、從配置中心獲取配置等。初始化容器的典型應用需求有如下幾種。

  • 用於執行需要管理許可權的工具程式,例如iptables命令等,出於安全等方面的原因,應用容器不適合擁有執行這類程式的許可權。
  • 提供主容器映象中不具備的工具程式或自定義程式碼。
  • 為容器映象的構建和部署人員提供了分離、獨立工作的途徑,部署人員使用專用的初始化容器完成特殊的部署邏輯,從而使得他們不必協同起來製作單個映象檔案。
  • 初始化容器和應用容器處於不同的檔案系統檢視中,因此可分別安全地使用敏感資料,例如Secrets資源等。
  • 初始化容器要先於應用容器序列啟動並執行完成,因此可用於延後應用容器的啟動直至其依賴的條件得以滿足。

​ Pod物件中的所有初始化容器必須按定義的順序序列執行,直到它們全部成功結束才能啟動應用容器,因而初始化容器通常很小,以便它們能夠以輕量的方式快速執行。某初始化容器執行失敗將會導致整個Pod重新啟動(重啟策略為Never時例外),初始化容器也必將再次執行,因此需要確保所有初始化容器的操作具有冪等性,以避免無法預知的副作用。

​ Init 容器與普通的容器非常像,除了如下兩點:

  • 它們總是執行到完成,即它的本身是有周期的,並不是像nginx,tomcat那樣一直堵塞在那裡。
  • 每個都必須在下一個啟動之前成功完成,即在真正容器啟動之前,初始化容器都要成功跑完。

應用

下面這個pod,會先在初始化容器中往掛載的路徑的index.html寫入12222222,然後nginx的掛載靜態檔案下,讀取index.html

apiVersion: v1
kind: Pod
metadata:
  name: "pod-life"
  labels:
    app: "pod-life"
spec:
  volumes:
  - name: content-vol
    emptyDir: {}
  initContainers:  ## Pod在啟動containers之前,先要【執行完】initContainers的所有容器,所以這些容器必須有終結,不能一直執行
  - name: init-c-01
    image: alpine  ### 必須有終結的那個時刻,一般不要用一直啟動的映象
    command: ["/bin/sh","-c","echo 12222222 > /app/index.html;sleep 30;echo success;"]
    volumeMounts: 
     - name: content-vol
       mountPath: /app
  containers:
  ### docker run alpine 沒有在後臺一直啟動的程式
  - name: pod-life-01
    image: "nginx" #預設的啟動命令是啟動nginx。nginx啟動在後臺一直有了
    volumeMounts: 
     - name: content-vol
       mountPath: /usr/share/nginx/html
  - name: pod-life-02
    image: "alpine"  #pod裡面的containers都必須能啟動起來,Pod會不斷的重啟這個容器
    command: ["/bin/sh","-c","sleep 30"]

應用後,檢視日誌

[root@k8s-01 ~]# kubectl logs -f --tail 200 pod-life -c init-c-01
success
[root@k8s-01 ~]#

檢視pod,發現請求nginx的首頁已經變成12222222

[root@k8s-01 ~]# kubectl get pods -o wide
NAME                                      READY   STATUS    RESTARTS        AGE    IP               NODE     NOMINATED NODE   READINESS GATES
counter                                   1/1     Running   0               35h    10.244.165.198   k8s-03   <none>           <none>
nfs-client-provisioner-69b76b8dc6-ms4xg   1/1     Running   1 (6d18h ago)   18d    10.244.179.21    k8s-02   <none>           <none>
nginx-5759cb8dcc-t4sdn                    1/1     Running   0               32m    10.244.179.50    k8s-02   <none>           <none>
pod-life                                  2/2     Running   0               117s   10.244.179.52    k8s-02   <none>           <none>
[root@k8s-01 ~]# curl 10.244.179.52
12222222
[root@k8s-01 ~]#

如果這個時候將yaml的命令改錯

那麼初始化容器就會一直報錯,重試,真正的容器也不會執行

Every 1.0s: kubectl get pods                                                                                                  Mon Jun 20 11:34:12 2022

NAME                                      READY   STATUS                  RESTARTS        AGE
counter                                   1/1     Running                 0               36h
nfs-client-provisioner-69b76b8dc6-ms4xg   1/1     Running                 1 (6d19h ago)   18d
nginx-5759cb8dcc-t4sdn                    1/1     Running                 0               47m
pod-life                                  0/2     Init:CrashLoopBackOff   3 (18s ago)     104s

實際應用

下面為kong的官方提供的yaml,就有一段初始化容器

      initContainers:
      - command:
        - /bin/sh
        - -c
        - while true; do kong migrations list; if [[ 0 -eq $? ]]; then exit 0; fi;
          sleep 2;  done;
        env:
        - name: KONG_PG_HOST
          value: postgres
        - name: KONG_PG_PASSWORD
          value: kong
        image: kong:2.8
        name: wait-for-migrations

主要是檢視是否對資料庫進行初始化資料,外面巢狀一層迴圈,一直等待初始化完成,則退出迴圈,再啟動kong,把命令拿出來到原始碼安裝環境下執行:

[root@localhost ~]#  kong migrations list
2022/06/20 11:48:08 [warn] ulimit is currently set to "1024". For better performance set it to at least "4096" using "ulimit -n"
Executed migrations:
                                    core: 000_base, 003_100_to_110, 004_110_to_120, 005_120_to_130, 006_130_to_140, 007_140_to_150, 008_150_to_200, 009_200_to_210, 010_210_to_211, 011_212_to_213, 012_213_to_220, 013_220_to_230, 014_230_to_260, 015_260_to_270, 016_270_to_280
                                     acl: 000_base_acl, 002_130_to_140, 003_200_to_210, 004_212_to_213
                                    acme: 000_base_acme
                              basic-auth: 000_base_basic_auth, 002_130_to_140, 003_200_to_210
                           bot-detection: 001_200_to_210
                                  canary: 001_200_to_210
                               degraphql: 000_base
          graphql-rate-limiting-advanced: 000_base_gql_rate_limiting
                               hmac-auth: 000_base_hmac_auth, 002_130_to_140, 003_200_to_210
                          ip-restriction: 001_200_to_210
                                     jwt: 000_base_jwt, 002_130_to_140, 003_200_to_210
                              jwt-signer: 000_base_jwt_signer, 001_200_to_210
                                key-auth: 000_base_key_auth, 002_130_to_140, 003_200_to_210
                            key-auth-enc: 000_base_key_auth_enc, 001_200_to_210
                               mtls-auth: 000_base_mtls_auth, 001_200_to_210, 002_2200_to_2300
                                  oauth2: 000_base_oauth2, 003_130_to_140, 004_200_to_210, 005_210_to_211
                          openid-connect: 000_base_openid_connect, 001_14_to_15, 002_200_to_210
                    proxy-cache-advanced: 001_035_to_050
                           rate-limiting: 000_base_rate_limiting, 003_10_to_112, 004_200_to_210
                   response-ratelimiting: 000_base_response_rate_limiting
                                 session: 000_base_session, 001_add_ttl_index
                              vault-auth: 000_base_vault_auth
                              enterprise: 000_base, 006_1301_to_1500, 006_1301_to_1302, 010_1500_to_2100, 007_1500_to_1504, 008_1504_to_1505, 007_1500_to_2100, 009_1506_to_1507, 009_2100_to_2200, 010_2200_to_2211, 010_2200_to_2300, 010_2200_to_2300_1, 011_2300_to_2600, 012_2600_to_2700, 012_2600_to_2700_1, 013_2700_to_2800
                          enterprise.acl: 001_1500_to_2100
                   enterprise.basic-auth: 001_1500_to_2100
                    enterprise.hmac-auth: 001_1500_to_2100
                          enterprise.jwt: 001_1500_to_2100
                     enterprise.key-auth: 001_1500_to_2100
                 enterprise.key-auth-enc: 001_1500_to_2100
                    enterprise.mtls-auth: 001_1500_to_2100, 002_2200_to_2300
                       enterprise.oauth2: 001_1500_to_2100, 002_2200_to_2211
 enterprise.request-transformer-advanced: 001_1500_to_2100
enterprise.response-transformer-advanced: 001_1500_to_2100
[root@localhost ~]# echo  $?
0
[root@localhost ~]#