Kubernetes pod裡一個特殊的容器:pause-amd64
大家在使用Docker容器或者Kubernetes時,遇到過這個容器麼?gcr.io/google_containers/pause-amd64
docker ps的命令返回的結果:
[root@k8s-minion1 kubernetes]# docker ps |grep pause c3026adee957 gcr.io/google_containers/pause-amd64:3.0 "/pause" 22 minutes ago Up 22 minutes k8s_POD.d8dbe16c_redis-master-343230949-04glm_default_ce3f60a9-095d-11e7-914b-0a77ecd65f3e_66c108d5 202df18d636e gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-proxy-js0z0_kube-system_2866cfc2-0891-11e7-914b-0a77ecd65f3e_c8e1a667 072d3414d33a gcr.io/google_containers/pause-amd64:3.0 "/pause" 24 hours ago Up 24 hours k8s_POD.d8dbe16c_kube-flannel-ds-tsps5_default_2866e3fb-0891-11e7-914b-0a77ecd65f3e_be4b719e [root@k8s-minion1 kubernetes]#
Kubernetes的官網解釋:
it's part of the infrastructure. This container is started first in all Pods to setup the network for the Pod.
意思是:pause-amd64是Kubernetes基礎設施的一部分,Kubernetes管理的所有pod裡,pause-amd64容器是第一個啟動的,用於實現Kubernetes叢集裡pod之間的網路通訊。
我們檢視這個pause-amd64映象的dockerfile,發現實現很簡單,基於一個空白映象開始:
FROM scratch ARG ARCH ADD bin/pause-${ARCH} /pause ENTRYPOINT ["/pause"]
ARG指令用於指定在執行docker build命令時傳遞進去的引數。
這個pause container是用C語言寫的:
在執行的Kubernetes node上執行docker ps,能發現這些pause container:
pause container作為pod裡其他所有container的parent container,主要有兩個職責:
-
是pod裡其他容器共享Linux namespace的基礎
-
扮演PID 1的角色,負責處理殭屍程式
這兩點我會逐一細說。在Linux裡,當父程式fork一個新程式時,子程式會從父程式繼承namespace。目前Linux實現了六種型別的namespace,每一個namespace是包裝了一些全域性系統資源的抽象集合,這一抽象集合使得在程式的名稱空間中可以看到全域性系統資源。名稱空間的一個總體目標是支援輕量級虛擬化工具container的實現,container機制本身對外提供一組程式,這組程式自己會認為它們就是系統唯一存在的程式。
在Linux裡,父程式fork的子程式會繼承父程式的名稱空間。與這種行為相反的一個系統命令就是unshare:
再來聊聊pause容器如何處理殭屍程式的。
Pause容器內其實就執行了一個非常簡單的程式,其邏輯可以從前面提到的Pause github倉庫上找到:
static void sigdown(int signo) { psignal(signo, "Shutting down, got signal"); exit(0); }static void sigreap(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0); }int main() { if (getpid() != 1) /* Not an error because pause sees use outside of infra containers. */ fprintf(stderr, "Warning: pause should be the first process\n"); if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 1; if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0) return 2; if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap, .sa_flags = SA_NOCLDSTOP}, NULL) < 0) return 3; for (;;) pause(); fprintf(stderr, "Error: infinite loop terminated\n"); return 42; }
這個c語言實現的程式,核心程式碼就28行:
其中第24行裡一個無限迴圈for(;;), 至此大家能看出來pause容器名稱的由來了吧?
這個無限迴圈裡執行的是一個系統呼叫pause,
因此pause容器大部分時間都在沉睡,等待有訊號將其喚醒。
接收什麼訊號呢?
一旦收到SIGCHLD訊號,pause程式就執行註冊的sigreap函式。
看下SIGCHLD訊號的幫助:
SIGCHLD,在一個程式正常終止或者停止時,將SIGCHLD訊號傳送給其父程式,按系統預設將忽略此訊號,如果父程式希望被告知其子系統的這種狀態,則應捕捉此訊號。
pause程式註冊的訊號處理函式sigreap裡,呼叫另一個系統呼叫waitpid來獲得子程式終止的原因。
希望這篇文章對大家理解Kubernetes裡的pause容器有所幫助。感謝閱讀。
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2286053/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Kubernetes筆記(五):瞭解Pod(容器組)筆記
- 檢視pod下面某一個容器的日誌
- 通過一個實際例子理解Kubernetes裡pod的自動scale - 水平自動伸縮
- 傲視Kubernetes(三):Kubernetes中的Pod
- 【一】kubernetes學習筆記-Pod概念筆記
- Kubernetes的Pod進階(十一)
- kubernetes實踐之三十九:Pod初始化容器之Init ContainerAI
- 在kubernetes裡使用seccomp限制容器的系統呼叫
- 如何使用Kubernetes的configmap通過環境變數注入到pod裡變數
- 如何在Kubernetes裡建立一個Nginx serviceNginx
- Kubernetes-POD的健康檢查
- 當一個 Pod 被排程時,Kubernetes 內部發生了什麼?
- Kubernetes部署單元-Pod
- Kubernetes Pod 全面知識
- Kubernetes:Pod總結(二)
- Kubernetes Pod驅逐策略
- kubernetes之pod中斷
- Kubernetes之Pod排程
- 通過一個例子學習Kubernetes裡的PersistentVolumeClaim的用法AI
- kubernetes實踐之三十六:在容器內獲取Pod資訊 Downward APIAPI
- MySQL:一個特殊的問題MySql
- 在kubernetes裡使用AppArmor限制容器對資源的訪問APP
- Kubernetes之Pod工作負載負載
- Kubernetes Pod OOM 排查日記OOM
- Kubernetes:Pod 升級、回滾
- Kubernetes:28---pod託管(Job:任務型pod)
- K8s 裡多容器 Pod 的健康檢查探針工作機制分析K8S
- Kubernetes資源編排系列之一: Pod YAML篇YAML
- 重定向Kubernetes pod中的tcpdump輸出TCP
- python kubernetes 獲取 pod 的 cpu 佔用率Python
- Kubernetes原始碼分析之Pod的刪除原始碼
- 容器、Docker與Kubernetes——Kubernetes的配置入門Docker
- 詳解Kubernetes Pod優雅退出
- 技術分享 | kubernetes pod 簡介
- kubernetes-pod驅逐機制
- kubernetes如何訪問pod服務
- Kubernetes裡的Operator
- kubernetes雜談之(二)Pod初談