半小时带你熟悉Docker镜像的构建方式
目录
2.5.3、Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#”号开头的注释
摘要
在构建容器化应用时,相当重要的步骤莫过于镜像制作,本文将介绍镜像制作方法以及镜像制作的建议。
采用docker commit生成的镜像实际上是容器内的文件系统进行修改在进行提交,而运行的容器实际上是在镜像的文件系统顶层添加了一层读写层,所都的修改都是基于这一层,当生成镜像时会将这一层数据保存,所以每次使用commit提交镜像时候都会比原来多一层,这样会使得镜像越来越大并且不易维护。同时,对于镜像使用者来说完全不透明,使用者不清楚该镜像怎么样构建的,是否安全等,这种方式及其不推荐。
而使用Dockerfile构建镜像,对于使用者来说完全透明,构建镜像的每一个步骤都在Dockerfile文件中描述的清清楚楚,同时当需要对镜像修改时候,只需修改Dockerfile文件中的指令,维护镜像只需要维护一个Dockerfile,这也是镜像构建的最佳方式。当然,要使用Dockerfile就必须明白Dockerfile的语法和各个指令,以下将作详细介绍
一、Docker镜像的分层
- Dockerfile中的每个指令都会创建一个新的镜像层
- 镜像层将被缓存和复用
- 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效
- 某一层的镜像缓存失效之后,它之后的镜像层都会失效
- 镜像层时不可变的,如果在某一层中添加一个文件,然后再下一层中删除它,则镜像中依然会包含该文件
二、Docker镜像的创建
2.1、Docker镜像
2.1.1、应用发布的标准格式
2.1.2、支撑一个Docker容器的运行
2.2、Docker镜像的创建方法
2.2.1、基于已有镜像创建
2.2.2、基于本地模板创建
2.2.3、基于Dockerfile创建
2.3、基于已有镜像创建
2.3.1、将容器里面运行的程序及运行环境打包生成新的镜像
docker create -it 镜像 /bin/bash
docker commit [选项] 容器ID/名称 仓库名称:[标签]
-m:说明信息
-a:作者信息
-p:生成过程中停止容器的运行
2.3.2、操作步骤
[aaa@qq.com ~]# docker commit -m "new" -a "yun" 356c7fa47764 centos:xu
sha256:1c0bd2acf2df664b2fa516e352bb6640568d1fc2ba9c5a64935a9cb45e92c158
[aaa@qq.com ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos xu 1c0bd2acf2df 35 seconds ago 204MB
centos 7 8652b9f0cb4c 12 days ago 204MB
2.4、基于本地模板创建
导入本地镜像debian-7.0-x86-minimal.tar.gz
[aaa@qq.com ~]# cat debian-7.0-x86-minimal.tar.gz | docker import - docker:yun
sha256:cb190951edfb4274dd4933d34ffe36f11fbe985629cd274fb297d092a314362e
[aaa@qq.com ~]# docker images #查看是否导入成功
REPOSITORY TAG IMAGE ID CREATED SIZE
docker yun cb190951edfb 10 seconds ago 215MB
2.5、基于Dockerfile创建
2.5.1、Dockerfile是由一组指令组成的文件
2.5.2、Dockerfile结构四部分
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
2.5.3、Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#”号开头的注释
2.5.4、Dockerfile操作指令
指令 |
含义 |
FROM 镜像 |
指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令 |
MAINTAINER 名字 |
说明新镜像的维护人信息 |
RUN 命令 |
在所基于的镜像上执行命令,并提交到新的镜像中 |
CMD [“要运行的程序”,“参数”] |
指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行 |
EXPOSE 端口号 |
指定新镜像加载到Docker时要开启的端口 |
ENV 环境变量 变量值 |
设置一个环境变量的值,会被后面的RUN使用 |
ADD 源文件/目录 目标文件/目录 |
将主机的文件拷贝到容器中,源文件要与Dockerfile位于相同目录中,或者是一个URL |
COPY 源文件/目录 目标文件/目录 |
将容器中的文件拷贝到容器的其他目录中 |
VOLUME [“目录”] |
再容器中创建一个挂载点 |
USER 用户名/UID |
指定运行容器时的用户 |
WORKDIR 路径 |
为后续的RUN、CMD、ENTRYPOINT指定工作目录 |
ONBUILD 命令 |
指定所生成的镜像作为一个基础镜像时所要运行的命令 |
HEALTHCHECK |
健康检查 |
2.5.5、Dockerfile创建
创建环境:
[aaa@qq.com ~]# mkdir Dockerfile
[aaa@qq.com ~]# cd Dockerfile/
准备环境:
[aaa@qq.com Dockerfile]# vim Dockerfile
FROM centos:7 ###基于的基础镜像
MAINTAINER this is porject ###维护镜像的用户信息
RUN yum -y update ###镜像操作指令:安装Apache软件
RUN yum -y install httpd
EXPOSE 80 ###开启80端口
ADD index.html /var/www/html/index.html ###复制网站首页文件
ADD run.sh /run.sh ###将执行脚本复制到镜像中
RUN chmod 755 /run.sh
CMD ["/run.sh"] ###启动容器时执行脚本
制作网页:
[aaa@qq.com Dockerfile]# vim index.html ###编辑网页用于测试
<h1>this is yun web</h1>
制作脚本:
#!/bin/bash
rm - rf /eun/httpd/* ###还原apache环境
exec /usr/sbin/apachectl -D FOREGROUND ###启动apache
[aaa@qq.com Dockerfile]# docker build -t httpd:centos . ###生成镜像(注意末尾有 .),如果没有改镜像文件则会自动下载。
Sending build context to Docker daemon 4.096kB
Step 1/9 : FROM centos:7
---> 8652b9f0cb4c
Step 2/9 : MAINTAINER this is porject
---> Running in 34bd82aa6673
Removing intermediate container 34bd82aa6673
---> 3755fedb11a0
Step 3/9 : RUN yum -y update
---> Running in 98ce317dc57b
Loaded plugins: fastestmirror, ovl
.......
[aaa@qq.com Dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd centos 156224687ee8 54 seconds ago 476MB
[aaa@qq.com Dockerfile]# docker run -d -p 1216:80 httpd:centos ###新景象运行容器,开放端口
2a12b1df8720537830234194f11643387bba44f7c3829f6e941828b8654c33b0
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2a12b1df8720 httpd:centos "/run.sh" About a minute ago Up About a minute 0.0.0.0:1216->80/tcp vigorous_thompson
测试apache网页是否能正常访问
三、私有仓库建立
3.1、下载私有仓库
[aaa@qq.com Dockerfile]# docker pull registty
3.2、添加私有仓库的IP和对应端口
[aaa@qq.com Dockerfile]# vim /etc/docker/daemon.json
{
"insecure-registries": ["192.168.206.10:5000"], ###添加,私有仓库的IP和对应端口(私有仓库端口号必须为5000)
"registry-mirrors": ["https://whqvkexq.mirror.aliyuncs.com"]
}
[aaa@qq.com Dockerfile]# systemctl restart docker ###重启容器
[aaa@qq.com Dockerfile]# docker create -it registry /bin/bash ###创建私有仓库容器
2689fc06b74aff5c369d0e752eed630543e566ec5b9342a0a8fcb4d477c3da95
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2689fc06b74a registry "/entrypoint.sh /bin…" About a minute ago Created eager_herschel
3.3、挂载
[aaa@qq.com Dockerfile]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
1878a65906829e1de7d3652219b0d80cc5854a5e13a98f7831b4a2363baddb89
宿主机的/data/registry自动创建挂载容器中的/tmp/registry
-v自动创建挂载目录
3.4、更改标记并上传
[aaa@qq.com Dockerfile]# docker tag httpd:centos 192.168.206.10:5000/httpd ###更改镜像名
[aaa@qq.com Dockerfile]# docker push 192.168.206.10:5000/httpd ###上传镜像至私有仓库
The push refers to repository [192.168.206.10:5000/httpd]
f02747fcff65: Pushed
d6c78c677b78: Pushed
f825568f2398: Pushed
21e2a5ab4395: Pushed
1fe4b51e1368: Pushed
174f56854903: Pushed
latest: digest: sha256:f21bce184cccec0a257efa32c89db7df9c67dd362b7af714c992047bdf6b1aad size: 1574
[aaa@qq.com Dockerfile]# curl -XGET http://192.168.206.10:5000/v2/_catalog ###查看私有仓库日志是否上传成功
{"repositories":["httpd"]}
3.5、从私有库下载
[aaa@qq.com Dockerfile]# docker pull 192.168.206.10:5000/httpd ###从私有库下载镜像
Using default tag: latest
latest: Pulling from httpd
2d473b07cdd5: Already exists
aeccfc090adc: Pull complete
d774628e1410: Pull complete
881f2f80d1a9: Pull complete
7d317a21df31: Pull complete
c5ecc453c9ea: Pull complete
Digest: sha256:f21bce184cccec0a257efa32c89db7df9c67dd362b7af714c992047bdf6b1aad
Status: Downloaded newer image for 192.168.206.10:5000/httpd:latest
192.168.206.10:5000/httpd:latest
[aaa@qq.com Dockerfile]# docker images ###查看是否下载成功
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.206.10:5000/httpd latest 156224687ee8 38 minutes ago 476MB
四、Docker数据卷
-v 会自动进行创建目录进行挂载(宿主机与容器之间挂载)
[aaa@qq.com Dockerfile]# docker pull centos ###基于centos镜像
Using default tag: latest
latest: Pulling from library/centos
3c72a8ed6814: Pull complete
Digest: sha256:76d24f3ba3317fa945743bb3746fbaf3a0b752f10b10376960de01da70685fbd
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
[aaa@qq.com Dockerfile]# docker run -v /var/www:/data1 --name web1 -it centos /bin/bash 将宿主机目录/var/www挂载到容器中的/data1
[aaa@qq.com /]# ls
bin dev home lib64 media opt root sbin sys usr
data1 etc lib lost+found mnt proc run srv tmp var
[aaa@qq.com /]# cd /data1
[aaa@qq.com data1]# echo "yun111" > yun.txt
[aaa@qq.com Dockerfile]# ls /var/www
yun.txt
在容器中创建文件,宿主机中查看
[aaa@qq.com Dockerfile]# docker run --name web100 -v /data1 -v /data2 -it centos:7 /bin/bas ###创建数据卷容器,容器中含两个数据卷提供使用
[aaa@qq.com /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
[aaa@qq.com /]# cd data1
[aaa@qq.com data1]# echo "yun111" > yun.txt
[aaa@qq.com data1]# cd ..
[aaa@qq.com /]# cd data2
[aaa@qq.com data2]# echo "yun222" > ming.txt
[aaa@qq.com Dockerfile]# docker run -it --volumes-from web100 --name db1 centos:7 /bin/bash ###创建另一台容器并关联web100,数据卷使用的为web100,名字为db1
[aaa@qq.com /]# ll
total 12
-rw-r--r--. 1 root root 12114 Nov 13 01:55 anaconda-post.log
lrwxrwxrwx. 1 root root 7 Nov 13 01:53 bin -> usr/bin
drwxr-xr-x. 2 root root 21 Nov 26 09:28 data1
drwxr-xr-x. 2 root root 22 Nov 26 09:29 data2
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f5be8a60fd2 centos:7 "/bin/bash" About a minute ago Exited (0) 7 seconds ago db1
5387638eee26 centos:7 "/bin/bash" 9 minutes ago Exited (0) 2 minutes ago web100
实现容器与容器之间数据共享
五、端口映射
[aaa@qq.com Dockerfile]# docker run -d -P 192.168.206.10:5000/httpd #P随机端口号,从32768开始
4f3fb7c10d610b68386c9e374e79671ea2e60a16eb5a2f0107d626ac153fe3bc
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f3fb7c10d61 192.168.206.10:5000/httpd "/run.sh" About a minute ago Up About a minute 0.0.0.0:32768->80/tcp pedantic_mayer
[aaa@qq.com Dockerfile]# docker run -d -p 42520:80 192.168.206.10:5000/httpd #p指定端口号
c50bf47c41ae6b062369360e76e7a7fd31875efbd6cde3901a0758d8b7a3925d
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c50bf47c41ae 192.168.206.10:5000/httpd "/run.sh" 47 seconds ago Up 46 seconds 0.0.0.0:42520->80/tcp clever_grothendieck
六、容器互联
创建并运行容器取名web3,端口号自动映射
[aaa@qq.com Dockerfile]# docker run -itd -P --name web3 centos:7 /bin/bash
c1bf9916cab7921ce1ddcd0306c3af57b8da44785d5821665762dff51d773540
--name 指定容器名称
创建并运行容器取名web4
[aaa@qq.com Dockerfile]# docker run -itd -P --name web4 --link web3:web3 centos:7 /bin/bash
1bc5e55147fa18756398cc77e54bd15098da0d57434115e9e785b05c952107d9
--link 关联
进web4容器ping web3
[aaa@qq.com Dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1bc5e55147fa centos:7 "/bin/bash" 2 minutes ago Up 2 minutes web4
c1bf9916cab7 centos:7 "/bin/bash" 4 minutes ago Up 4 minutes web3
[aaa@qq.com Dockerfile]# docker exec -it 1bc5e55147fa /bin/bash
[aaa@qq.com /]# ping web3
PING web3 (172.17.0.5) 56(84) bytes of data.
64 bytes from web3 (172.17.0.5): icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from web3 (172.17.0.5): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from web3 (172.17.0.5): icmp_seq=3 ttl=64 time=0.077 ms
64 bytes from web3 (172.17.0.5): icmp_seq=4 ttl=64 time=0.037 ms
64 bytes from web3 (172.17.0.5): icmp_seq=5 ttl=64 time=0.042 ms
64 bytes from web3 (172.17.0.5): icmp_seq=6 ttl=64 time=0.038 ms
64 bytes from web3 (172.17.0.5): icmp_seq=7 ttl=64 time=0.039 ms
64 bytes from web3 (172.17.0.5): icmp_seq=8 ttl=64 time=0.038 ms
^C
--- web3 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7002ms
rtt min/avg/max/mdev = 0.037/0.052/0.108/0.025 ms
安装net工具
[aaa@qq.com /]# yum -y install net-tools
[aaa@qq.com /]# ifconfig #查询网址信息
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.6 netmask 255.255.0.0 broadcast 172.17.255.255 #第一个创建的容器地址是172.17.0.2,以此类推
ether 02:42:ac:11:00:06 txqueuelen 0 (Ethernet)
RX packets 1625 bytes 11022891 (10.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1612 bytes 90769 (88.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上一篇: IOS键盘监听
下一篇: IOS自动登录Demo