本文爲做者原創,轉載請註明出處(http://www.cnblogs.com/mar-q/)by 負贔屓docker
好久沒寫博客了,集中寫幾個比較有意思的小問題。centos
1、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也不是沒有解決方案:socket
yum install -y initscripts.x86_64
把它裝上就能夠用了,只是讓你用着舒服,其實它仍是經過systemctl來執行。ide
2、CentOS容器沒有pidof命令學習
這是由於官方的鏡像是精簡版的,沒有提供pidof所在的指令集,若是須要使用,也是須要安裝的:centos7
yum install -y redhat-lsb
3、 Failed to get D-Bus connection: Operation not permittedspa
當咱們在CentOS7上執行systemctl命令就會產生這個錯誤,上面兩個問題其實和這個問題緣由產生的是一致的,尤爲是關於這個問題,網上給出諸多說法,我來給你們一個官方的說法。首先不要急,我先給性子急的同窗幾個解決方案:.net
方案一:
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/,老頭也是挺不容易,夾在中間多難受啊。
4、恩,我只是一個搞深度學習的圍觀吃瓜羣衆。。。