一般的Docker鏡像為了節(jié)省空間,通常是沒有安裝systemd或者sysvint這類初始化系統(tǒng)的進程。一旦容器的起始進程不穩(wěn)定將會產(chǎn)生大量的僵尸進程,影響宿主系統(tǒng)的運行。
缺少init的容器
init系統(tǒng)有以下幾個特點:
- 它是系統(tǒng)的第一個進程,負責產(chǎn)生其他所有用戶進程。
- init 以守護進程方式存在,是所有其他進程的祖先。
- 它主要負責:
1.啟動守護進程
2.回收孤兒進程
3.將操作系統(tǒng)信號轉(zhuǎn)發(fā)給子進程
以下dockerfile為例:
FROM Nginx
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
當docker容器啟動時,PID 1即容器啟動程序?qū)莕ginx, 只要這個程序停止,容器就會跟住停止。由于nginx 不具備init 上述的功能,PID 1是無法回收異常退出進程,異常退出的進程變成僵尸進程,繼續(xù)占用系統(tǒng)資源。
當多個容器運行在一個宿主機上的時候,為了避免一個容器消耗完我們整個宿主機進程號資源,docker會配置PID CGROUP來限制每個容器的最大進程數(shù)目。也就是說,進程數(shù)目在每個容器中也是有限的,是一種很寶貴的資源。(例如:linux 機器上的進程總數(shù)目是有限制,如果進程數(shù)據(jù)過多,比如你想ssh登錄到機器上就不行 )
如何使用 tini 初始化系統(tǒng)
tini 是一套更簡單的 init 系統(tǒng),專門用來執(zhí)行一個子程序(spawn a single child),并等待子程序結(jié)束,即便子程序已經(jīng)變成僵尸程序也能捕捉到,同時也能轉(zhuǎn)送 Signal 給子程序。如果你使用docker來跑容器,可以非常簡便的在docker run的時候用--init參數(shù),就會自動注入tini程式 (/sbin/docker-init) 到容器中,并且自動取代ENTRYPOINT設定,讓原本的程式直接跑在 tini程序底下。
dockerfile如下:
FROM nginx
RUN export TINI_VERSION=0.9.0 &&
export TINI_SHA=fa23d1e20732501c3bb8eeeca423c89ac80ed452 &&
curl -fsSL https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-static -o /bin/tini &&
echo 'Calculated checksum: '$(sha1sum /bin/tini) &&
chmod +x /bin/tini && echo "$TINI_SHA /bin/tini" | sha1sum -c
ENTRYPOINT ["/bin/tini","--","/opt/nginx/docker-entrypoint.sh"]
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
建議為了提高容器運行的可靠性,可以選擇在打包鏡像時加入tini的安裝,并以tini作為啟動入口。
以上就是關(guān)于今天的全部內(nèi)容,下期將給大家?guī)怼禟8S之調(diào)度器-精細控制Pod分布》,敬請期待~