目錄
一、基于現(xiàn)有鏡像創(chuàng)建
1、創(chuàng)建啟動(dòng)鏡像
2、生成新鏡像
二、基于本地模板創(chuàng)建?
1、OPENVZ 下載模板
2、導(dǎo)入容器生成鏡像
三、基于dockerfile創(chuàng)建?
1、dockerfile結(jié)構(gòu)及分層
2、聯(lián)合文件系統(tǒng)
3、docker鏡像加載原理
4、dockerfile操作常用的指令
(1)FROM指令
(2)MAINTAINER 指令
(3)RUN指令
(4)ENTRYPOINT指令
(5)CMD指令
(6)EXPOSE指令
(7)ENV指令
(8)ADD指令
(9)COPY指令
(10)VOLUME指令
(11)USER指令
(12)WORKDIR指令
(13)ONBUILD指令
(14)HEALTHCHECK
四、dockerfile構(gòu)建鏡像實(shí)例
1、dockerfile構(gòu)建httpd實(shí)例
2、dockerfile構(gòu)建sshd實(shí)例
3、dockerfile構(gòu)建systemd實(shí)例
4、dockerfile構(gòu)建nginx實(shí)例
一、基于現(xiàn)有鏡像創(chuàng)建
1、創(chuàng)建啟動(dòng)鏡像
(1)首先啟動(dòng)一個(gè)鏡像,在容器里做修改
docker run -itd centos:7 /bin/bash
#創(chuàng)建并啟動(dòng)鏡像
docker ps
#查看啟動(dòng)的鏡像信息
2、生成新鏡像
(2)將修改后的容器提交為新的鏡像,需要使用該容器的 ID 號(hào)創(chuàng)建新鏡像
docker commit -m "new-images" -a "test" dda50e36fd55 centos:test
#常用選項(xiàng):
-m 說(shuō)明信息;
-a 作者信息;
-p 生成過(guò)程中停止容器的運(yùn)行;
docker images
#查看新生成的鏡像
二、基于本地模板創(chuàng)建?
1、OPENVZ 下載模板
通過(guò)導(dǎo)入操作系統(tǒng)模板文件可以生成鏡像,模板可以從 OPENVZ 開(kāi)源項(xiàng)目下載,下載地址為http://openvz.org/Download/template/precreated
wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
2、導(dǎo)入容器生成鏡像
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test
#查看這個(gè)模板導(dǎo)入到docker的debian:test鏡像
三、基于dockerfile創(chuàng)建?
1、dockerfile結(jié)構(gòu)及分層
①dockerfile結(jié)構(gòu)大致分為四個(gè)部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令和容器啟動(dòng)時(shí)執(zhí)行指令
Dockerfile是一個(gè)文本文件,其內(nèi)包含了一條條的指令(Instruction),每一條指令構(gòu)建一層,因此每一條指令的內(nèi)容,就是描述該層應(yīng)當(dāng)如何構(gòu)建。有了Dockerfile,當(dāng)我們需要定制自己額外的需求時(shí),只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻煩。
除了手動(dòng)生成Docker鏡像之外,可以使用Dockerfile自動(dòng)生成鏡像。Dockerfile是由多條的指令組成的文件,其中每條指令對(duì)應(yīng) Linux 中的一條命令,Docker 程序?qū)⒆x取Dockerfile 中的指令生成指定鏡像
②docker鏡像的結(jié)構(gòu)分層:
(1)Dockerfile 中的每個(gè)指令都會(huì)創(chuàng)建一個(gè)新的鏡像層;
(2)鏡像層將被緩存和復(fù)用;
(3)當(dāng)Dockerfile 的指令修改了,復(fù)制的文件變化了,或者構(gòu)建鏡像時(shí)指定的變量不同了,對(duì)應(yīng)的鏡像層緩存就會(huì)失效;
(4)某一層的鏡像緩存失效,它之后的鏡像層緩存都會(huì)失效;
(5)鏡像層是不可變的,如果在某一層中添加一個(gè)文件,然后在下一層中刪除它,則鏡像中依然會(huì)包含該文件,只是這個(gè)文件在容器中不可見(jiàn)了不會(huì)影響在鏡像中的數(shù)據(jù)。
2、聯(lián)合文件系統(tǒng)
聯(lián)合文件系統(tǒng)(unionFS):分層、輕量級(jí)并且高性能的文件系統(tǒng),即一層一層疊加然后制作成的鏡像,底層為內(nèi)核加載,然后是rootfs系統(tǒng),再上層是只可讀的基礎(chǔ)鏡像,鏡像啟動(dòng)后成為容器即為可讀可寫(xiě)層此層保存數(shù)據(jù)等,然后可以再打包成一個(gè)新的鏡像保存數(shù)據(jù)
特性:一次同時(shí)加載多個(gè)文件系統(tǒng),但從外面看起來(lái),只能看到一個(gè)文件系統(tǒng),聯(lián)合加載會(huì)把各層文件系統(tǒng)疊加起來(lái),這樣最終的文件系統(tǒng)會(huì)包含所有底層的文件和目錄。
我們下載的時(shí)候看到的一層層的就是聯(lián)合文件系統(tǒng)。
3、docker鏡像加載原理
①Docker的鏡像實(shí)際上由一層一層的文件系統(tǒng)組成,這種層級(jí)的文件系統(tǒng)就是UnionFS
②bootfs主要包含bootloader和kernel,bootloader主要是引導(dǎo)加載kernel,Linux剛啟動(dòng)時(shí)會(huì)加載bootfs文件系統(tǒng)。
③在Docker鏡像的最底層是bootfs,這一層與我們典型的Linux/Unix系統(tǒng)是一樣的,包含boot加載器和內(nèi)核。當(dāng)boot加載完成之后整個(gè)內(nèi)核就都在內(nèi)存中了,此時(shí)內(nèi)存的使用權(quán)已由bootfs轉(zhuǎn)交給內(nèi)核,此時(shí)系統(tǒng)也會(huì)卸載bootfs
④我們可以理解成一開(kāi)始內(nèi)核里什么都沒(méi)有,操作一個(gè)命令下載debian,這時(shí)就會(huì)在內(nèi)核上面加了一層基礎(chǔ)鏡像;再安裝一個(gè)emacs,會(huì)在基礎(chǔ)鏡像上疊加一層image;接著再安裝一個(gè)apache,又會(huì)在images上面再疊加一層image。最后它們看起來(lái)就像一個(gè)文件系統(tǒng)即容器的rootfs。在Docker的體系里把這些rootfs叫做Docker的鏡像。但是,此時(shí)的每一層rootfs都是read-only的,我們此時(shí)還不能對(duì)其進(jìn)行操作。當(dāng)我們創(chuàng)建一個(gè)容器,也就是將Docker鏡像進(jìn)行實(shí)例化,系統(tǒng)會(huì)在一層或是多層read-only的rootfs之上分配一層空的read-write的rootfs。
⑤為什么容器中的centos大小只有200M
因?yàn)閷?duì)于精簡(jiǎn)的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序庫(kù)就可以了,因?yàn)榈讓又苯佑盟拗鳈C(jī)的kernel,自己只需要提供rootfs就可以了。由此可見(jiàn)對(duì)于不同的linux發(fā)行版,bootfs基本是一致的,rootfs會(huì)有差別,因此不同的發(fā)行版可以公用bootfs。
4、dockerfile操作常用的指令
(1)FROM指令
用于指定生成新的鏡像所基于的基礎(chǔ)進(jìn)項(xiàng),dockerfile的第一條命令必須是FROM指定本次生成鏡像是基于那個(gè)基礎(chǔ)鏡像進(jìn)程的,每創(chuàng)建一個(gè)鏡像需要一個(gè)FROM。
(2)MAINTAINER 指令
說(shuō)明新鏡像的維護(hù)人信息
(3)RUN指令
在所基于的鏡像上執(zhí)行命令,并提交到新的鏡像中,例如執(zhí)行yum安裝等
(4)ENTRYPOINT指令
ENTRYPOINT? ??["要運(yùn)行的程序", "參數(shù) 1", "參數(shù) 2"]
設(shè)定容器啟動(dòng)時(shí)第一個(gè)運(yùn)行的命令及其參數(shù),此指令為在使用docker exec 進(jìn)入容器時(shí)就添加的命令參數(shù)。
可以通過(guò)使用命令docker run --entrypoint 來(lái)覆蓋鏡像中的ENTRYPOINT指令的內(nèi)容
(5)CMD指令
CMD ["要運(yùn)行的程序", "參數(shù)1", "參數(shù)2"]
此指令為指定進(jìn)入容器之后的第一個(gè)命令或腳步,進(jìn)入容器后在容器中的shell中執(zhí)行的第一個(gè)命令,dockerfile中只能有一條CMD命令若有多條CMD則只執(zhí)行最后一條命令。
如果在docker run時(shí)指定了命令或者鏡像中有ENTRYPOINT指令則CMD程序不會(huì)執(zhí)行。
docker RUN優(yōu)先級(jí)>ENTRYPOINT指令>CMD指令
(6)EXPOSE指令
EXPOSE "端口號(hào)"
指定dockerfile生成的新鏡像加載到 Docker 時(shí)要開(kāi)啟的端口
(7)ENV指令
ENV 環(huán)境變量 變量值
(8)ADD指令
ADD 源路徑 目標(biāo)路徑
ADD指令用于將源文件復(fù)制到dockerfile產(chǎn)生的新鏡像中,要求源文件必須與dockerfile在同一文件夾下,或者同一個(gè)url下。有以下注意事項(xiàng):
①源路徑為文件時(shí),目標(biāo)路徑以/結(jié)尾則dockerfile將目標(biāo)文件視為目錄將源路徑的文件存到模板路徑的目錄下,且若模板路徑不存在則自動(dòng)創(chuàng)建模板路徑
②源路徑為文件時(shí),目標(biāo)路徑不以/結(jié)尾則dockerfile將目標(biāo)路徑視為文件,則直接將目標(biāo)路徑文件內(nèi)容覆蓋但名稱不會(huì)改變,如果模板路徑不存在則會(huì)創(chuàng)建一個(gè)以目標(biāo)路徑為名的文件,內(nèi)容為源路徑的文件內(nèi)容
③源路徑為文件夾時(shí),若目標(biāo)路徑存在則直接將原路徑的文件夾拷貝到模板路徑的目錄下。
若目標(biāo)路徑不存在,則自動(dòng)創(chuàng)建一個(gè)以目標(biāo)路徑為名的文件夾將源文件夾拷貝到目錄下。
④若源文件是個(gè)歸檔文件或壓縮文件,docker會(huì)自動(dòng)幫忙解壓。URL下載和解壓特性不能一起使用。任何壓縮文件通過(guò)URL拷貝,都不會(huì)自動(dòng)解壓。
(9)COPY指令
copy 源文件/目錄 目標(biāo)文件/目錄
只復(fù)制本地主機(jī)上的文件/目錄? 復(fù)制目標(biāo)點(diǎn)為鏡像中。要求本機(jī)文件必須與dockerfile在同一路徑下。
ADD與copy對(duì)比:
①都有本地復(fù)制文件和目錄到鏡像的功能
②ADD復(fù)制歸檔文件和壓縮文件會(huì)自動(dòng)解壓
③都要求與dockerfile在同一文件夾
④URL拉取目錄來(lái)復(fù)制
⑤COPY只能復(fù)制本地主機(jī)文件到鏡像中,ADD可以復(fù)制到url中
(10)VOLUME指令
volume ["目錄"]
在容器中創(chuàng)建一個(gè)掛載點(diǎn)
(11)USER指令
USER 用戶名/uid
指定運(yùn)行容器時(shí)的用戶
(12)WORKDIR指令
為后續(xù)的RUN/CMD/ENTRYPOINT指定工作目錄,可以理解為切換到指定的目錄執(zhí)行RUN等其他指令。
(13)ONBUILD指令
指定所生成的鏡像作為一個(gè)基礎(chǔ)鏡像時(shí)所要允許的命令,調(diào)用有ONBUILD命令時(shí)的鏡像會(huì)先執(zhí)行ONBUILD命令。在使用其他鏡像時(shí),仔細(xì)檢查ONBUILD命令的內(nèi)容。
當(dāng)在一個(gè)Dockerfile文件中加上ONBUILD指令,該指令對(duì)利用該Dockerfile構(gòu)建鏡像(比如為A鏡像)不會(huì)產(chǎn)生任何實(shí)質(zhì)性影響。 但是當(dāng)編寫(xiě)一個(gè)新的Dockerfile文件來(lái)基于A鏡像構(gòu)建一個(gè)鏡像(比如為B鏡像)時(shí),這時(shí)構(gòu)造A鏡像的Dockerfile文件中的ONBUILD指令就生效了,在構(gòu)建B鏡像的過(guò)程中,首先會(huì)執(zhí)行ONBUILD指令指定的指令,然后才會(huì)執(zhí)行其它指令。
(14)HEALTHCHECK
健康檢查
四、dockerfile構(gòu)建鏡像實(shí)例
1、dockerfile構(gòu)建httpd實(shí)例
mkdir /opt/apache
cd /opt/apache
#創(chuàng)建并進(jìn)入文件夾,每個(gè)服務(wù)一個(gè)文件夾
vim Dockerfile
#創(chuàng)建Dockerfile文件,文件內(nèi)容如下
FROM centos:7
#基于的基礎(chǔ)鏡像指定為centos:7,注意本機(jī)要有此基礎(chǔ)鏡像
MAINTAINER this is apache image <test>
#說(shuō)明鏡像維護(hù)人信息為,指定用戶為test
RUN yum -y update
RUN yum -y install httpd
#鏡像RUN指令指定啟動(dòng)容器后的運(yùn)行命令,yum安裝update和httpd服務(wù)
EXPOSE 80
#開(kāi)啟80端口
ADD index.html /var/www/html/index.html
#復(fù)制宿主機(jī)index.html文件到容器的 /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/apachectl"]
CMD ["-D","FOREGROUND"]
#使用前臺(tái)啟動(dòng)apache注意使用絕對(duì)路徑,如果后臺(tái)啟動(dòng),啟動(dòng)完shell就結(jié)束了容器就結(jié)束了,保存退出。
echo "this is test web">index.thml
#準(zhǔn)備網(wǎng)站的網(wǎng)頁(yè),注意必須在和Dockerfile文件相同的目錄
docker build -t httpd:centos .
#將dockerfile 文件生成鏡像注意最后有個(gè)點(diǎn)。
docker run -d -p 40330:80 httpd:centos
#新鏡像運(yùn)行容器,映射宿主機(jī)的40330端口為容器的80端口
訪問(wèn)192.168.30.11:40330 進(jìn)行測(cè)試是否可以訪問(wèn)容器的httpd主業(yè)
2、dockerfile構(gòu)建sshd實(shí)例
FROM centos:7
#指定sshd基于centos:7的鏡像
MAINTAINER this is ssh image <ssh>
#說(shuō)明鏡像信息,鏡像用戶為ssh
RUN yum -y update
#此內(nèi)容若保存可注釋掉
#運(yùn)行RUN指令執(zhí)行update更新
RUN yum -y install openssh* net-tools lsof telnet passwd
#RUN指令執(zhí)行安裝openssh相關(guān)工具,net工具,lsof、telnet、passwd程序
RUN echo "abc123" |passwd --stdin root
#免交互設(shè)置root密碼為abc123
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#關(guān)閉sshd服務(wù)的pam認(rèn)證
RUN sed -i '12d' /etc/pam.d/sshd
#刪除/etc/pam.d/sshd的12行,刪除12行為取消pam的限制
RUN ssh-keygen -t rsa -A
#生成秘鑰認(rèn)證文件
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
#遞歸創(chuàng)建/root/.ssh文件夾并修改屬主屬租為root,添加權(quán)限為700只允許屬組屬組用戶操作
EXPOSE 22
#規(guī)定端口為22
ENTRYPOINT [ "/usr/sbin/sshd" ]
CMD ["-D", "FOREGROUND"]
#/usr/sbin/sshd -D用于前臺(tái)啟動(dòng)sshd服務(wù)
docker build -t sshd:centos .
#創(chuàng)建sshd;centos鏡像
docker run -d -p 40022:22 sshd:centos
#運(yùn)行sshd:centos容器并映射容器中的22端口為40022端口
docker ps
#查看容器信息
ssh localhost -p 40022
ifconfig
#宿主機(jī)執(zhí)行驗(yàn)證sshd容器
?
3、dockerfile構(gòu)建systemd實(shí)例
mkdir /opt/systemctl
cd /opt/systemctl
#創(chuàng)建systemd目錄
vim Dockerfile
#編輯Dockerfile文件內(nèi)容如下
FROM sshd:centos
#以sshd:centos為基礎(chǔ)鏡像,注意要做上面的sshd實(shí)例,不然無(wú)此進(jìn)項(xiàng)不能制作systemd鏡像
MAINTAINER this is systemctl image <systemd>
ENV container docker
#除了systemd-tmpfiles-setup.service,刪除其它所有文件
RUN (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"]
docker build -t systemd:centos .
#生成systemd鏡像
docker run --privileged -d -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:centos /sbin/init
#啟動(dòng)容器,并掛載宿主機(jī)目錄掛載到容器中,和進(jìn)行初始化
#--privileged:使container內(nèi)的root擁有真正的root權(quán)限。否則,container內(nèi)的root只是外部的一個(gè)普通用戶權(quán)限。
docker ps -a
docker exec -it 56b06afcef9a /bin/bash
#進(jìn)入容器
systemctl start sshd
systemctl status sshd
?
4、dockerfile構(gòu)建nginx實(shí)例
mkdir /opt/nginx
cd /opt/nginx/
cp /opt/nginx-1.12.0.tar.gz /opt/nginx
#創(chuàng)建nginx目錄,將nginx安裝包放到創(chuàng)建的nginx目錄下,必須與Dockerfile文件在同一目錄下
vim Dockerfile
#編輯nginx的dockerfile文件內(nèi)容如下
FROM centos:7
#基于基礎(chǔ)鏡像,centos
MAINTAINER this is nginx image <nginx>
#用戶信息,鏡像維護(hù)用戶為nginx
RUN yum -y update
#此內(nèi)容若保存可注釋掉
RUN yum -y install pcre-devel zlib-devel gcc gcc-C++ make
RUN useradd -M -s /sbin/ nologin nginx
#安裝編譯安裝工具
ADD nginx-1.12.0.tar.gz /opt/
#上傳nginx軟件壓縮包,docker自動(dòng)解壓
WORKDIR /opt/nginx-1.12.0
RUN ./ configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
#指定工作目錄
EXPOSE 80
EXPOSE 443
#指定http和https端口
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf
#關(guān)閉nginx 在后臺(tái)運(yùn)行
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
#添加宿主機(jī)中run.sh到容器中
vim run.sh
#創(chuàng)建run.sh腳本,注意必須和dockerfile在同一路徑下,內(nèi)容如下
#!/bin/bash
/usr/local/nginx/sbin/nginx
docker build -t nginx:centos .
docker run -itd -P nginx:centos /bin/bash
docker ps -a
#查看nginx容器,訪問(wèn)80對(duì)應(yīng)的隨機(jī)端口驗(yàn)證,443的端口驗(yàn)證不了,ngingx中每家ssl模塊
http://192.168.30.11:32769
5、創(chuàng)建實(shí)例時(shí)網(wǎng)絡(luò)報(bào)錯(cuò)解決
報(bào)錯(cuò):[Warning] IPv4 forwarding is disabled. Networking will not work.?
解決方法:
vim /etc/sysctl.conf
net.ipv4.ip_forward=1文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-419626.html
sysctl -p
systemctl restart network
systemctl restart docker文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-419626.html
到了這里,關(guān)于docker容器:docker鏡像的三種創(chuàng)建方法及dockerfile案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!