k8s-ephemeral和init容器


  截止到目前k8s1.18版本,k8s已經支持四種類型的container:標准容器,sidecar容器,init容器,ephemeral容器。

    

 

一:ephemeral容器

1.1.什么是ephemeral容器

      臨時容器與其他容器的不同之處在於,它們缺少對資源或執行的保證,並且永遠不會自動重啟,因此不適用於構建應用程序。臨時容器使用與常規容器相同的 ContainerSpec 段進行描述,但許多字段是不相容且不允許的。

  • 臨時容器沒有端口配置,因此像 portslivenessProbereadinessProbe 這樣的字段是不允許的。
  • Pod 資源分配是不可變的,因此 resources 配置是不允許的。
  • 有關允許字段的完整列表,

1.2.ephemeral容器的用途

  當由於容器崩潰或容器鏡像不包含調試實用程序而導致 kubectl exec 無用時,臨時容器對於交互式故障排查很有用

  尤其是,distroless 鏡像能夠使得部署最小的容器鏡像,從而減少攻擊面並減少故障和漏洞的暴露。由於 distroless 鏡像不包含 shell 或任何的調試工具,因此很難單獨使用 kubectl exec 命令進行故障排查。

使用臨時容器時,啟用進程命名空間共享很有幫助,可以查看其他容器中的進程。

1.3.使用ephemeral容器

  臨時容器是使用 Pod 的 ephemeralcontainers 子資源創建的,可以使用 kubectl --raw 命令進行顯示。首先描述臨時容器被添加為一個 EphemeralContainers 列表:

{
    "apiVersion": "v1",
    "kind": "EphemeralContainers",
    "metadata": {
            "name": "example-pod"
    },
    "ephemeralContainers": [{
        "command": [
            "sh"
        ],
        "image": "busybox",
        "imagePullPolicy": "IfNotPresent",
        "name": "debugger",
        "stdin": true,
        "tty": true,
        "terminationMessagePolicy": "File"
    }]
}

  使用如下命令更新已運行的臨時容器 example-pod

kubectl replace --raw /api/v1/namespaces/default/pods/example-pod/ephemeralcontainers  -f ec.json

  這將返回臨時容器的新列表:

{
   "kind":"EphemeralContainers",
   "apiVersion":"v1",
   "metadata":{
      "name":"example-pod",
      "namespace":"default",
      "selfLink":"/api/v1/namespaces/default/pods/example-pod/ephemeralcontainers",
      "uid":"a14a6d9b-62f2-4119-9d8e-e2ed6bc3a47c",
      "resourceVersion":"15886",
      "creationTimestamp":"2019-08-29T06:41:42Z"
   },
   "ephemeralContainers":[
      {
         "name":"debugger",
         "image":"busybox",
         "command":[
            "sh"
         ],
         "resources":{

         },
         "terminationMessagePolicy":"File",
         "imagePullPolicy":"IfNotPresent",
         "stdin":true,
         "tty":true
      }
   ]
}

 

二.Init容器

 2.1.什么是Init容器

  一個pod中可以運行多個容器,也可以運行多個init 容器,init容器先於應用容器運行。

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

  • 它們總是運行到完成。
  • 每個都必須在下一個啟動之前成功完成。

 2.2.與普通容器的不同之處

  Init 容器支持應用容器的全部字段和特性,包括資源限制、數據卷和安全設置。 然而,Init 容器對資源請求和限制的處理稍有不同,在下面 資源 處有說明。

  同時 Init 容器不支持 Readiness Probe,因為它們必須在 Pod 就緒之前運行完成。

  如果為一個 Pod 指定了多個 Init 容器,這些容器會按順序逐個運行。每個 Init 容器必須運行成功,下一個才能夠運行。當所有的 Init 容器運行完成時,Kubernetes 才會為 Pod 初始化應用容器並像平常一樣運行。

 2.3.Init 容器作用

  因為 Init 容器具有與應用容器分離的單獨鏡像,其啟動相關代碼具有如下優勢:

  • Init 容器可以包含一些安裝過程中應用容器中不存在的實用工具或個性化代碼。例如,沒有必要僅為了在安裝過程中使用類似 sed、 awk、 python 或 dig 這樣的工具而去FROM 一個鏡像來生成一個新的鏡像。
  • Init 容器可以安全地運行這些工具,避免這些工具導致應用鏡像的安全性降低。
  • 應用鏡像的創建者和部署者可以各自獨立工作,而沒有必要聯合構建一個單獨的應用鏡像。
  • Init 容器能以不同於Pod內應用容器的文件系統視圖運行。因此,Init容器可具有訪問 Secrets 的權限,而應用容器不能夠訪問。
  • 由於 Init 容器必須在應用容器啟動之前運行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,直到滿足了一組先決條件。一旦前置條件滿足,Pod內的所有的應用容器會並行啟動。

2.4使用Init容器

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

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"]

  這是 Kubernetes 1.6 版本的新語法,盡管老的 annotation 語法仍然可以使用。我們已經把 Init 容器的聲明移到 spec 中:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

  1.5 版本的語法在 1.6 版本仍然可以使用,但是我們推薦使用 1.6 版本的新語法。 在 Kubernetes 1.6 版本中,Init 容器在 API 中新建了一個字段。 雖然期望使用 beta 版本的 annotation,但在未來發行版將會被廢棄掉。

  在所有的 Init 容器沒有成功之前,Pod 將不會變成 Ready 狀態。 Init 容器的端口將不會在 Service 中進行聚集。 正在初始化中的 Pod 處於 Pending 狀態,但應該會將條件 Initializing 設置為 true。

  如果 Pod 重啟,所有 Init 容器必須重新執行。

  對 Init 容器 spec 的修改,被限制在容器 image 字段中。 更改 Init 容器的 image 字段,等價於重啟該 Pod。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM