共計 2981 個字符,預計需要花費 8 分鐘才能閱讀完成。
這篇文章主要介紹“Kubernetes pod 里的 pause-amd64 容器有什么用”,在日常操作中,相信很多人在 Kubernetes pod 里的 pause-amd64 容器有什么用問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Kubernetes pod 里的 pause-amd64 容器有什么用”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!
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 之間的網絡通訊。
對這個特殊容器感興趣的朋友,可以閱讀其源代碼:
https://github.com/kubernetes/kubernetes/tree/master/build/pause
我們查看這個 pause-amd64 鏡像的 dockerfile,發現實現很簡單,基于一個空白鏡像開始:
FROM scratch
ARG ARCH
ADD bin/pause-${ARCH} /pause
ENTRYPOINT [/pause]
ARG 指令用于指定在執行 docker build 命令時傳遞進去的參數。
這個 pause container 是用 C 語言寫的:
https://www.ianlewis.org/en/almighty-pause-container
在運行的 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 pod 里的 pause-amd64 容器有什么用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!