關於docker使用的幾個小問題(二)


本文為作者原創,轉載請注明出處(http://www.cnblogs.com/mar-q/)by 負贔屓

 

  很久沒寫博客了,集中寫幾個比較有意思的小問題。

一、CentOS容器沒有service命令

  這是因為我們從docker官方鏡像倉庫中pull的最新CentOS鏡像都是centos7.4 Redhat-release,Redhat已經通過systemclt命令取代了service命令,所以如果需要運行service命令,可以通過systemctl來替換。如以下這兩條關於Apache的命令是等效的。

service httpd status
systemctl status httpd

  有的同學會說,為什么我本地裝的centos可以使用service?ok,如果一定要用service也不是沒有解決方案:

yum install -y initscripts.x86_64

  把它裝上就可以用了,只是讓你用着舒服,其實它還是通過systemctl來執行。

二、CentOS容器沒有pidof命令

  這是因為官方的鏡像是精簡版的,沒有提供pidof所在的指令集,如果需要使用,也是需要安裝的:

yum install -y redhat-lsb

三、 Failed to get D-Bus connection: Operation not permitted

  當我們在CentOS7上執行systemctl命令就會產生這個錯誤,上面兩個問題其實和這個問題原因產生的是一致的,尤其是關於這個問題,網上給出諸多說法,我來給大家一個官方的說法。首先不要急,我先給性子急的同學幾個解決方案:

  方案一:

docker run -d -e "container=docker" --privileged=true -v /sys/fs/cgroup:/sys/fs/cgroup --name centos7 centos /usr/sbin/init ###對安全問題比較關心的同學,建議將--privileged=true替換為--cap-add=SYS_ADMIN

  方案二:

docker run -ti --privileged centos init #或者 docker run -ti --privileged centos /usr/lib/systemd/systemd #或者 docker run -ti --cap-add=SYS_ADMIN cents init

  大家會說,方案二怎么卡住了,沒關系,不用管它,重啟一個連接exec到容器中即可,原來的窗口關掉就行。

  方案三:

FROM fedora:rawhide MAINTAINER “Dan Walsh” <dwalsh@redhat.com> ENV container docker RUN yum -y update; yum clean all RUN yum -y install systemd; yum clean all; (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); rm -f /lib/systemd/system/multi-user.target.wants/*; rm -f /etc/systemd/system/*.wants/*; rm -f /lib/systemd/system/local-fs.target.wants/*; rm -f /lib/systemd/system/sockets.target.wants/*udev*; rm -f /lib/systemd/system/sockets.target.wants/*initctl*; rm -f /lib/systemd/system/basic.target.wants/*; rm -f /lib/systemd/system/anaconda.target.wants/*; VOLUME [ “/sys/fs/cgroup” ] CMD [“/usr/sbin/init”]

  寫一個dockerfile,這段dockerfile是有來歷的,它的作用就是生成一個可以調用systemctl的CentOS容器,同時刪除了一些不必要的系統進程。在上面的指令中,我們經常看到/sbin/init,它是什么東東呢:

  之所以報這個d-bus的錯誤就是因為在容器中,CentOS的鏡像是默認不啟動systemd的,而且啟動需要privileged權限或者--cap-add=SYS_ADMIN權限。 Docker依賴Linux內核的功能:容器和宿主機建立相互隔離的環境(應用程序在里面運行)。而官方的容器很精簡,容器之所以和宿主機共享同一內核,卻在不同的運行時環境中執行,這歸功於控制組(cgroup)和命名空間,它們定義了容器可以使用哪些資源,與此同時,容器本身只能看到某些進程和網絡功能。所以我們可以看到前面第一個命令,在privileged的同時還進行了cgroup目錄的掛載,這就是定義了該容器獲取了系統的完整內核。

  下面我就給大家講講Redhat和Docker的那點故事,不喜歡八卦的同學可以不用看了啊:

  八卦的主人是一個叫Daniel Walsh的老頭,Daniel在Redhat專門從事容器安全工作,https://developers.redhat.com/blog/2014/05/05/running-systemd-within-docker-container/這篇文章是他在2014年所寫,前面的那個dockerfile就是他在解決這個問題時的成果之一,文章寫作時這個“bug”是以更嚴重的segment呈現的,而https://lwn.net/Articles/676831/https://developers.redhat.com/blog/author/rhatdan/,Daniel道出了關於systems和docker的沖突(因為這個老頭是直接受害人。。。畢竟他的主要工作就是磨合systemd和docker,哈哈)。反正我是看着頭大,簡單 來說大概就是Docker守護進程旨在接管系統還為Linux執行的很多功能,而Redhat擔心docker的安全性,所以在內核作出了諸多限制,最直觀的一個體現就是在systemd的使用上。

  這個圖是我在Daniel博客上的截圖, 從中我們可以看到Redhat和docker的開發者在扯皮,挺有意思,更多扯皮歡迎大家圍觀https://lwn.net/Articles/676831/,老頭也是挺不容易,夾在中間多難受啊。

  回到一開始,我們知道centos是基於Redhat內核的,所以才會造成這個問題。解決方案我剛開始已經給出了,這里還是一個使用機制的問題,不管是docker開發者還是Redhat的開發者,其實他們都期望用戶在一個docker里只運行一個服務,所以最好的解決辦法其實還是通過dockerfile,每個服務通過dockerfile來安裝並在dockerfile中啟動(CMD )。
但是安全問題始終是繞不過去的,docker和Redhat給出了一些建議:http://cloud.51cto.com/art/201501/464287.htm,希望對有深入了解需求的同學有所幫助。 

 四、恩,我只是一個搞深度學習的圍觀吃瓜群眾。。。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM