截止目前k8s1.18,k8s已經支持標準容器,sidecar容器,init 容器,ephemeral 容器 4種類型的containers。本文咱們詳細介紹一下這4種容器的特性已經使用場景。nginx
臨時容器與其餘容器的不一樣之處在於,它們缺乏對資源或執行的保證,而且永遠不會自動重啓,所以不適用於構建應用程序。臨時容器使用與常規容器相同的 ContainerSpec
段進行描述,但許多字段是不相容且不容許的。git
ports
,livenessProbe
,readinessProbe
這樣的字段是不容許的。resources
配置是不容許的。臨時容器是使用 API 中的一種特殊的 ephemeralcontainers
處理器進行建立的,而不是直接添加到 pod.spec
段,所以沒法使用 kubectl edit
來添加一個臨時容器。docker
與常規容器同樣,將臨時容器添加到 Pod 後,將不能更改或刪除臨時容器。shell
爲何咱們須要Ephemeral 容器?數據庫
咱們知道容器的優勢是它們經過使用不變方法提供全部必需的依賴項來運行隔離的進程。經過僅將所需的依賴項添加到鏡像中,容器能夠下降攻擊面並提供更快的啓動和部署。使用「distroless」方法構建容器鏡像(基於scratch),經過僅包含已編譯的應用程序二進制文件,將容器鏡像提高到了一個新的水平。與普通的容器鏡像不一樣,它們不基於任何種類的Linux發行版,所以不包含任何其餘可經過kubectl exec執行以進行故障排除的二進制文件和工具。這就決定了該容器有助於提供安全可靠的運行時環境,但也很難在問題發生時進行調試。json
在這種狀況下,臨時容器發揮做用。它們實現了調試容器附加到主進程的功能,而後你能夠用於調試任何類型的問題。調試容器能夠基於任何鏡像,所以能夠根據您的需求進行定製。您能夠構建本身的調試鏡像,其中包含特殊的調試二進制文件或僅包含curl,OpenSSL和MongoDB客戶端之類的工具。可是,您也能夠選擇Linux發行版(如Ubuntu)或僅運行Busybox鏡像,這兩個鏡像都已經包含了許多有用的工具。api
如何使用臨時容器?安全
臨時容器是alpha功能,所以默認狀況下處於禁用狀態。您將須要激活如下功能門才能使用它們:服務器
本節中的示例演示了臨時容器如何出如今 API 中。 一般,您可使用 kubectl
插件進行故障排查,從而自動化執行這些步驟。網絡
臨時容器是使用 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 } ] }
可使用如下命令查看新建立的臨時容器的狀態:
kubectl describe pod example-pod ... Ephemeral Containers: debugger: Container ID: docker://cf81908f149e7e9213d3c3644eda55c72efaff67652a2685c1146f0ce151e80f Image: busybox Image ID: docker-pullable://busybox@sha256:9f1003c480699be56815db0f8146ad2e22efea85129b5b5983d0e0fb52d9ab70 Port: <none> Host Port: <none> Command: sh State: Running Started: Thu, 29 Aug 2019 06:42:21 +0000 Ready: False Restart Count: 0 Environment: <none> Mounts: <none> ...
可使用如下命令鏈接到新的臨時容器:
kubectl attach -it example-pod -c debugger
若是啓用了進程命名空間共享,則能夠查看該 Pod 全部容器中的進程。 例如,運行上述 attach
操做後,在調試器容器中運行 ps
操做:
# 在 "debugger" 臨時容器內中運行此 shell 命令 ps auxww
運行命令後,輸出相似於:
PID USER TIME COMMAND 1 root 0:00 /pause 6 root 0:00 nginx: master process nginx -g daemon off; 11 101 0:00 nginx: worker process 12 101 0:00 nginx: worker process 13 101 0:00 nginx: worker process 14 101 0:00 nginx: worker process 15 101 0:00 nginx: worker process 16 101 0:00 nginx: worker process 17 101 0:00 nginx: worker process 18 101 0:00 nginx: worker process 19 root 0:00 /pause 24 root 0:00 sh 29 root 0:00 ps auxww
在Kubernetes中,init容器是在同一Pod中的其餘容器以前開始並執行的容器。它旨在爲Pod上託管的主應用程序執行初始化邏輯。例如,建立必要的用戶賬戶,執行數據庫遷移,建立數據庫結構等。
建立initcontainer時應考慮一些注意事項:
正如咱們剛剛討論的那樣,init容器老是比同一個Pod上的其餘應用程序容器先啓動。結果,調度程序對init容器的資源和限制賦予了更高的優先級。必須仔細考慮這種行爲,由於這可能會致使不良後果。例如,若是您有一個初始化容器和一個應用程序容器,而且將初始化容器的資源和限制設置爲高於應用程序容器的資源和限制,那麼只有在有一個可用節點知足初始化的狀況下,才調度整個Pod容器要求。換句話說,即便有一個未使用的節點能夠在其中運行應用程序容器,但若是初始化容器具備該節點能夠處理的更高資源先決條件,則Pod也不會部署到該節點。所以,在定義初始化容器的請求和限制時,您應儘量嚴格。最佳作法是,除非絕對必要,不然請勿將這些參數設置爲高於應用程序容器的值。
在k8s1.18 以前,這兩種容器從k8s管理的角度來看,並無什麼區別。只不過人爲從功能上作了區分。
使用sidecar容器(模塊化)具備的優勢
對於Sidecar容器通常來講主要體如今如下4種角色:
代理
。例如如今Istio中的Envoy。
經過這種Sidercar 模式,代理能夠攔截進出主容器的流量從而Istio能夠提取有關流量行爲的大量信號做爲屬性。 Istio可使用這些屬性來執行策略決策,並將其發送到監視系統以提供有關整個網格行爲的信息。
Sidecar代理模型還容許您將Istio功能添加到現有部署中,而無需從新構造或重寫代碼。
適配器
。適配器容器對輸出進行標準化。考慮監視N個不一樣應用程序的任務。可使用不一樣的導出監視數據的方式來構建每一個應用程序。 (例如JMX,StatsD,特定於應用程序的統計信息),但每一個監控系統都但願其收集的監控數據具備一致且統一的數據模型。經過使用複合容器的適配器模式,您能夠經過建立Pod來未來自不一樣系統的異構監視數據轉換爲一個統一的表示形式,該Pod將應用程序容器與知道如何進行轉換的適配器分組在一塊兒。一樣,因爲這些Pod共享名稱空間和文件系統,所以這兩個容器的協調很是簡單明瞭。
加強主容器功能
。Sidecar容器擴展並加強了「主」容器,它們可使用現有的容器並使它們變得更好。例如,考慮一個運行Nginx Web服務器的容器。添加另外一個將文件系統與git存儲庫同步的容器,在這些容器之間共享文件系統,而且您已經構建了Git Push-to-deploy。可是您已經以模塊化的方式完成了此工做,其中git同步器能夠由不一樣的團隊構建,而且能夠在許多不一樣的Web服務器(Apache,Python,Tomcat等)上重複使用。因爲這種模塊化,您只需編寫和測試git同步器一次,便可在衆多應用程序中重複使用它。並且,若是有人編寫它,您甚至不須要這樣作。實現輔助功能
。這種場景通常出如今DevOps中。好比將收集日誌的組件以Sidecar的方式部署,實現收集日誌的用途,或是部署一個Sidecar組件從配置中心監聽配置變化,實時更新本地配置。生命週期
Sidecar容器的全部問題都與容器生命週期相關性有關。因爲Pod中的常規容器之間沒有區別,所以沒法控制哪一個容器首先啓動或最後終止,可是先正確運行Sidecar容器一般是應用程序容器正確運行的要求。
從1.18版本開始,K8S內置的Sidecar功能將確保Sidecar容器在正常業務流程開始以前就啓動並運行,即經過更改pod的啓動生命週期,在init容器完成後啓動sidecar容器,在sidecar容器就緒後啓動業務容器,從啓動流程上保證順序性。
經過更改Pod規範中的container.lifecycle.type
將容器標記爲Sidecar類型:Sidecar
,默認爲Standard
,以下:
apiVersion: v1 kind: Pod metadata: name: bookings-v1-b54bc7c9c-v42f6 labels: app: demoapp spec: containers: - name: bookings image: banzaicloud/allspark:0.1.1 ... - name: istio-proxy image: docker.io/istio/proxyv2:1.4.3 lifecycle: type: Sidecar ...
本文簡單介紹了標準容器,sidecar容器,init 容器,ephemeral 容器 4種類型的containers。隨着kubernetes日益普及,咱們須要充分掌握着幾種類型容器原理和使用方法,才能更好地服務業務。
此外Sidecar容器將會成爲將來軟件交付的一種新的方式,參照Dapr等,不一樣的團隊提供本身的功能容器,而後選擇性注入Sidecar到主業務容器,實現解耦。