一、手動制作鏡像
以yum版nginx鏡像為例,一般基于某基礎(chǔ)鏡像之上進行鏡像制作,本次使用centos基礎(chǔ)鏡像
1、下載基礎(chǔ)鏡像centos
~]#? docker pull centos:7.5.1804
2、基于centos啟動一個容器
~]#? docker run -it centos:7.5.1804 bash

3、安裝系統(tǒng)常見命令
[root@8e0df75fd0be /]#??yum -y install wget?vim pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop?
4、在容器之上更改yum源
[root@c0de5aa39852 /]#? mkdir /etc/yum.repos.d/bak
[root@c0de5aa39852 /]#?mv?/etc/yum.repos.d/*??/etc/yum.repos.d/bak/
[root@c0de5aa39852 /]#?wget -O?/etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo?
[root@c0de5aa39852 /]#?wget -O? /etc/yum.repos.d/epel.repo? http://mirrors.aliyun.com/repo/epel-7.repo?
5、yum安裝nginx
[root@c0de5aa39852 /]#? yum -y install nginx
6、自定義一個測試用的web頁面
[root@c0de5aa39852 /]#??rm -rf /usr/share/nginx/html/index.html
[root@c0de5aa39852 /]#??vim /usr/share/nginx/html/index.html
[root@c0de5aa39852 /]#??cat /usr/share/nginx/html/index.html
docker_test_commit 20201220

7、切換到宿主機終端,基于改容器ID構(gòu)建鏡像
~]#?docker commit -a "mamzi 18883552477@163.com" -m "centos-yum-nginx image" c0de5aa39852 centos-nginx:1.16
注:
-a? ? ?指定鏡像的作者信息
-m? ? 提交鏡像的文字說明

8、基于自己構(gòu)建的鏡像創(chuàng)建容器
~]#?docker run -d -p 81:80 centos-nginx:1.16 nginx -g "daemon off;"

9、測試訪問結(jié)果如下

二、基于Dockerfile構(gòu)建鏡像
Docker以從上到下的順序讀取Dockerfile中的指令,使用docker?build命令來完成鏡像的構(gòu)建,dcokerfile的第一行必須是FROM。以下先針對dockerfile的常用指令進行說明:
FROM? 指定基礎(chǔ)鏡像
格式:
? ? ? ?FROM [--platform=<platform>] <image> [AS <name>]
? ? ? ?FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
? ? ? ?FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]示例:
? ? ? ?FROM centos:7.5.1804注:
? ? ? ?tag和digest為可選的,如果不指定默認使用latest版本
RUN? 指定鏡像構(gòu)建需執(zhí)行的命令
格式:
? ? ? ?RUN <command>? ? ?#shell形式
? ? ? ?RUN ["executable", "param1", "param2"]? ? ?#exec形式示例:
? ? ? ?RUN echo 'hello,$name'
? ? ? ?RUN ["/bin/bash","-c","echo hello,$name"]注:
? ? ? ?shell語句會自主默認/bin/sh -c 來執(zhí)行,而exec格式不會,exec格式需要指定使用什么腳本來執(zhí)行
CMD? 指定容器啟動命令
格式:
? ? ? ?CMD?["executable","param1","param2"]? ? ?#exec形式
? ? ? ?CMD ["param1","param2"]? ? ?#作為ENTRYPOINT的默認參數(shù)
? ? ??CMD command param1 param2? ? ?#sehll形式示例:
? ? ? ?CMD ["nginx","-g","daemon off;"]
? ? ? ?CMD nginx -g "daemon off;"注:
? ? ? ?CMD是在基于該進行啟動容器的時候執(zhí)行的命令,RUN是在鏡像構(gòu)建時候執(zhí)行的命令
ENTRYPOINT? 指定容器啟動命令
格式:
? ? ??ENTRYPOINT ["executable", "param1", "param2"]? ? ?#exec形式
? ? ??ENTRYPOINT command param1 param2? ? ?#shell形式示例:
? ? ? ?FROM ubuntu
? ? ? ?ENTRYPOINT ["top", "-b"]
? ? ? ?CMD ["-c"]注:
? ? ? ?ENTRYPOINT和CMD非常相似,都是在容器啟動時候運行的命令,其區(qū)別在于CMD中的命令會被docker run傳遞的命令覆蓋掉,而ENTRYPOINT則不會,且將docker run指定的參數(shù)傳遞到ENTRYPOINT命令中當參數(shù);
? ? ? ?CMD可以為ENTRYPOINT傳遞默認參數(shù),且會被docker傳遞的覆蓋。
LABEL? 添加鏡像標簽
格式:
? ? ??LABEL <key>=<value> <key>=<value>示例:
? ? ? ?LABEL maintainer='鏡像的作者信息'? ? ?#說明鏡像的作者信息
ENV? 指定環(huán)境變量
格式:
? ? ? ?ENV <key>=<value>示例:
? ? ? ?ENV MY_NAME="John Doe"
? ? ? ?ENV MY_DOG=Rex\ The\ Dog
? ? ? ?ENV MY_CAT=fluffy注:
? ? ? ?允許一次設(shè)置多個變量ENV <key>=<value> ...
ADD? 將宿主機上的文件添加到鏡像中
格式:
? ? ? ?ADD [--chown=<user>:<group>] <src>... <dest>
? ? ? ?ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]示例:
? ? ? ?add --chown=bin test_add /? ? ?#將當前目錄的的test_add文件,添加到容器的/根目錄
COPY? 將宿主機文件復(fù)制到鏡像中
和ADD類似,其中不同點在于ADD可以將tar類型文件會自動解壓,可以訪問網(wǎng)絡(luò)資源,如wget
EXPOSE??指定開放端口
格式:
? ? ? ?EXPOSE <port> [<port>...]示例:
? ? ? ?EXPOSE 80 443
? ? ? ?EXPOSE 8080
? ? ? ?EXPOSE 11211/tcp 11211/udp
STOPSIGNAL? 指定容器退出的信號值
格式:
? ? ? ?STOPSIGNAL signal?示例:
? ? ? ?STOPSIGNAL 9注:
? ? ? ?主要的目的是為了實現(xiàn)容器的平滑退出,如果不做任何處理,容器將在一段時間之后強制退出,會造成業(yè)務(wù)的強制中斷,默認10s
USER? 指定運行容器時或者RUN指令執(zhí)行時的用戶
格式:
? ? ? ?USER <user>[:<group>]示例:
? ? ? ?USER www
? ? ? ?RUN mkdir /home/www/app注:
? ? ? ?使用USER指定用戶后,Dockerfile中后面的RUN、CMD、ENTRYPOINT等均使用該用戶執(zhí)行;docker run命令創(chuàng)建容器時可通過-u覆蓋該用戶
WORKDIR? 工作目錄
格式:
? ? ? WORKDIR path示例:
? ? ? ?WORKDIR /opt/nginx? ? ? #工作目錄為/opt/nginx
? ? ? ?WORKDIR /a
? ? ? ?WORKDIR b?
? ? ? ?WORKDIR c? ? ? #工作目錄為/a/b/c注:
? ? ? ?類似cd命令,設(shè)置WORKDIR工作目錄后,Dockerfile中其后面的RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會在該目錄執(zhí)行
VOLUME
? 創(chuàng)建掛載點,用于掛載外部存儲,將數(shù)據(jù)保存到宿主機,避免數(shù)據(jù)丟失
格式:
? ? ?? VOLUME? ["/data"]示例:
? ? ???
(1)Dockerfile文件示例:構(gòu)建基礎(chǔ)鏡像
#? cat Dockerfile
FROM centos:7.5.1804? ? ? #導(dǎo)入一個基礎(chǔ)鏡像
LABEL maintaine='san.zhang 18883552477@163.com'? ? ? #鏡像的作者信息,也可添加其他的標簽信息
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum -y install vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl-devel iproute net-tools iotop
RUN groupadd www -g 2020 && useradd www -u 2020 -g www?
執(zhí)行docker build構(gòu)建鏡像
#?docker build -t centos-base:v1.0 .? ? ? #-t指定鏡像名稱及tag號,如果dockerfile不在當前目錄需要指定指定所在路徑
#??docker images? ? ? #查看鏡像是否構(gòu)建成功
#? docker run -it --rm centos-base:v1.0 bash? ? ? #測試使用該鏡像運行容器

(1)Dockerfile文件示例:構(gòu)建JDK鏡像
[root@VM_0_16_centos jdk]#? ls
Dockerfile? jdk-8u151-linux-x64.tar.gz? ?profile[root@VM_0_16_centos jdk]#??cat Dockerfile
#JDK base images
FROM centos-base:v1.0
LABEL maintaine='san.zhang 18883552477@163.com' description='This text illustrates that label-values can span multiple lines.'
ADD jdk-8u151-linux-x64.tar.gz /opt/RUN ln -s /opt/jdk1.8.0_151 /opt/jdk1.8
#COPY profile /etc/profile
#RUN echo "source /etc/profile" >> ~/.bashrc
ENV JAVA_HOME /opt/jdk1.8
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
RUN rm /etc/localtime -f && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime?
執(zhí)行docker build構(gòu)建鏡像
#? docker?build -t jdk-base:v1.0 .? ? ? #構(gòu)建鏡像
#??docker run -it --rm jdk-base:v1.0 bash? ? ? #測試鏡像
