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