一、基于現(xiàn)有鏡像創(chuàng)建
1、創(chuàng)建啟動(dòng)鏡像
(1)首先啟動(dòng)一個(gè)鏡像,在容器里做修改
docker run -itd centos:7 /bin/bash
2、生成新鏡像
(2)將修改后的容器提交為新的鏡像,需要使用該容器的 ID 號(hào)創(chuàng)建新鏡像
docker commit -m "new-images" -a "test" dda50e36fd55 centos:test
#常用選項(xiàng):
-m 說明信息;
-a 作者信息;
-p 生成過程中停止容器的運(yùn)行;
docker images
#查看新生成的鏡像
三、基于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)分層:
鏡像不是一個(gè)單一的文件,而是有多層構(gòu)成。容器其實(shí)是在鏡像的最上面加了一層讀寫層,在運(yùn)行容器里做的任何文件改動(dòng),都會(huì)寫到這個(gè)讀寫層。如果刪除了容器,也就刪除了其最上面的讀寫層,文件改動(dòng)也就丟失了。Docker使用存儲(chǔ)驅(qū)動(dòng)管理鏡像每層內(nèi)容及可讀寫層的容器層。
(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è)文件在容器中不可見了不會(huì)影響在鏡像中的數(shù)據(jù)。
2、聯(lián)合文件系統(tǒng)
聯(lián)合文件系統(tǒng)(unionFS):分層、輕量級(jí)并且高性能的文件系統(tǒng),即一層一層疊加然后制作成的鏡像,底層為內(nèi)核加載,然后是rootfs系統(tǒng),再上層是只可讀的基礎(chǔ)鏡像,鏡像啟動(dòng)后成為容器即為可讀可寫層此層保存數(shù)據(jù)等,然后可以再打包成一個(gè)新的鏡像保存數(shù)據(jù)
特性:一次同時(shí)加載多個(gè)文件系統(tǒng),但從外面看起來,只能看到一個(gè)文件系統(tǒng),聯(lián)合加載會(huì)把各層文件系統(tǒng)疊加起來,這樣最終的文件系統(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
④我們可以理解成一開始內(nèi)核里什么都沒有,操作一個(gè)命令下載debian,這時(shí)就會(huì)在內(nèi)核上面加了一層基礎(chǔ)鏡像;再安裝一個(gè)emacs,會(huì)在基礎(chǔ)鏡像上疊加一層image;接著再安裝一個(gè)apache,又會(huì)在images上面再疊加一層image。最后它們看起來就像一個(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ì)于精簡的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序庫就可以了,因?yàn)榈讓又苯佑盟拗鳈C(jī)的kernel,自己只需要提供rootfs就可以了。由此可見對(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 指令
說明新鏡像的維護(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ù)。
可以通過使用命令docker run --entrypoint 來覆蓋鏡像中的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í)要開啟的端口
(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下載和解壓特性不能一起使用。任何壓縮文件通過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拉取目錄來復(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)編寫一個(gè)新的Dockerfile文件來基于A鏡像構(gòu)建一個(gè)鏡像(比如為B鏡像)時(shí),這時(shí)構(gòu)造A鏡像的Dockerfile文件中的ONBUILD指令就生效了,在構(gòu)建B鏡像的過程中,首先會(huì)執(zhí)行ONBUILD指令指定的指令,然后才會(huì)執(zhí)行其它指令。
(14)HEALTHCHECK
健康檢查
四、Dockerfile 案例
1、dockerfile構(gòu)建httpd實(shí)例
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
#建立工作目錄
mkdir /opt/apache
cd /opt/apache
echo '<h1>this is my Dockerfile</h1>' > index.html
vim Dockerfile
#基于的基礎(chǔ)鏡像
#指定基礎(chǔ)鏡像
FROM centos:7
#描述維護(hù)者信息
MAINTAINER this is apache image from centos7 <ll 2023-6-8>
#鏡像操作指令安裝apache軟件
RUN yum install -y httpd
#復(fù)制網(wǎng)站首頁文件
ADD index.html /var/www/html
#開啟 80 端口
#開啟 443 端口
EXPOSE 80
EXPOSE 443
#啟動(dòng)容器時(shí)執(zhí)行腳本
CMD ["/usr/sbin/apachectl","-D","FOREGROUND"]
docker build -t apache:centos7 .
docker run -itd --name c1 -p 1314:80 apache:centos7
2、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
MAINTAINER this is nginx image from centos7 <wl 2023-6-8>
ADD nginx-1.22.0.tar.gz /opt/
RUN yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make &&\
useradd -M -s /sbin/nologin nginx &&\
cd /opt/nginx-1.22.0 &&\
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH $PATH:/usr/local/nginx/sbin
EXPOSE 80
#EXPOSE 443
ENTRYPOINT ["/usr/local/nginx/sbin/nginx"]
CMD ["-g","daemon off;"]
更換網(wǎng)頁頁面
cd /opt/nginx
mkdir html
echo '<h1>this is my test web</h1>' > html/index.html
docker rm -f e7888865896b #刪除之前創(chuàng)建的nginx容器
docker run -itd --name c2 -P -v /opt/nginx/html:/usr/local/nginx/html nginx:centos7
3、Dockerfile構(gòu)建tomcat實(shí)例
mkdir /opt/tomcat
cd /opt/tomcat/
#將apache-tomcat-9.0.16.tar.gz包和jdk-8u91-linux-x64.tar.gz包拷貝到tomcat目錄下
tar xf apache-tomcat-9.0.16.tar.gz
tar xf jdk-8u91-linux-x64.tar.gz
vim Dockerfile
FROM centos:7
MAINTAINER this is tomcat image from centos7 <ll 2023-6-8>
#安裝jdk
ADD jdk-8u91-linux-x64.tar.gz /usr/local/
ENV JAVA_HOME=/usr/local/jdk1.8.0_91
ENV JRE_HOME=${JAVA_HOME}/jre
ENV CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH
#安裝tomcat
ADD apache-tomcat-9.0.16.tar.gz /usr/local/
EXPOSE 8080
#前臺(tái)運(yùn)行tomcat
ENTRYPOINT ["/usr/local/apache-tomcat-9.0.16/bin/catalina.sh","run"]
docker pull centos:7
docker build -t tomcat:centos7 .
docker run -itd --name c3 -p 8080:8080 tomcat:centos7
4、使用Dockerfile搭建lnmp服務(wù)
#部署php(容器IP 為 172.18.0.30)
mkdir /opt/php
cd /opt/php
上傳 php-7.1.10.tar.bz2 到 /opt/php 目錄中
vim Dockerfile
FROM centos:7
MAINTAINER this is php image <wl 2023-6-8>
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel gcc gcc-c++ make
ADD php-7.1.10.tar.bz2 /opt/
RUN cd /opt/php-7.1.10 && \
./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make -j2 && make install && \
cp /opt/php-7.1.10/php.ini-production /usr/local/php/lib/php.ini && \
sed -i '939c date.timezone = Asia/Shanghai' /usr/local/php/lib/php.ini && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i '17c pid = run/php-fpm.pid' /usr/local/php/etc/php-fpm.conf && \
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf && \
useradd -M -s /sbin/nologin nginx && \
sed -i -e '23c user = nginx' -e '24c group = nginx' -e '36c listen = 172.18.0.30:9000' -e '62c listen.allowed_clients = 172.18.0.10' /usr/local/php/etc/php-fpm.d/www.conf
EXPOSE 9000
ENTRYPOINT ["/usr/local/php/sbin/php-fpm","-F"]
docker build -t php:centos7 .
cd /opt/nginx
docker cp 158f23b25a66:/usr/local/nginx/conf/nginx.conf ./
vim nginx.conf
docker network create --subnet 172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
docker network ls
docker run -itd --name nginx -p 80:80 -v /opt/nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf -v /opt/nginx/html:/usr/local/nginx/html --network mynetwork --ip 172.18.0.10 nginx:centos7
瀏覽器訪問 http://192.168.154.10:80
vim /opt/nginx/html/index.php
<?php
phpinfo();
?>
#把之前創(chuàng)建的php容器刪除,重新創(chuàng)建
docker run -itd --name php -p 9000:9000 --volumes-from nginx --network mynetwork --ip 172.18.0.30 php01:centos7
五、縮小鏡像體積大小
如何縮小鏡像的體積大小
1)盡可能的使用小體積的基礎(chǔ)鏡像
2)盡可能減少Dockerfile文件中的指令數(shù)量
3)構(gòu)建鏡像步驟最后添加清空系統(tǒng)和應(yīng)用程序的緩存的命令
4)使用多級(jí)(多階段)構(gòu)建FROM AS 別名
COPY --from 別名
#體積比較小的jdk的鏡像
docker pull openjdk:8-jdk-alpine
基于這個(gè)jdk鏡像去創(chuàng)建tomcat
docker build -t tomcat2:jdk .
docker run -itd -P tomcat2:jdk
改變前面php鏡像的體積大小文章來源:http://www.zghlxwxcb.cn/news/detail-702000.html
vim /opt/php/Dockerfile
FROM centos:7 AS installphp
MAINTAINER this is php image <wl 2023-6-8>
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel gcc gcc-c++ make
ADD php-7.1.10.tar.bz2 /opt/
RUN cd /opt/php-7.1.10 && \
./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make -j2 && make install && \
cp /opt/php-7.1.10/php.ini-production /usr/local/php/lib/php.ini && \
sed -i '939c date.timezone = Asia/Shanghai' /usr/local/php/lib/php.ini && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i '17c pid = run/php-fpm.pid' /usr/local/php/etc/php-fpm.conf && \
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf && \
sed -i -e '23c user = nginx' -e '24c group = nginx' -e '36c listen = 172.18.0.30:9000' -e '62c listen.allowed_clients = 172.18.0.10' /usr/local/php/etc/php-fpm.d/www.conf
FROM centos:7
COPY --from=installphp /usr/local/php/ /usr/local/php/
RUN useradd -M -s /sbin/nologin nginx
EXPOSE 9000
ENTRYPOINT ["/usr/local/php/sbin/php-fpm","-F"]
docker build -t php3:centos7 .
docker images
文章來源地址http://www.zghlxwxcb.cn/news/detail-702000.html
到了這里,關(guān)于Docker鏡像的創(chuàng)建方法及Dockerfile案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!