kernel
;docker
主机支持运行多种 Linux 发行版;Copy-on-Write
可写容器层,相当于虚拟机的快照;缺点:
效率低、可重复性弱、容易出错;
使用者无法对镜像进行审计,存在安全隐患.
[root@server1 ~]# docker pull busybox ##拉取镜像
Using default tag: latest
latest: Pulling from library/busybox
92f8b3f0730f: Pull complete
Digest: sha256:b5fc1d7b2e4ea86a06b0cf88de915a2c43a99a00b6b3c0af731e5f4c07ae8eff
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@server1 ~]# docker images ##查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest d3cd072556c2 4 days ago 1.24MB
yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB
[root@server1 ~]# docker history busybox:latest
##查看镜像的构建历史,可以看到其分层结构;一层是官网信息,另外一层是得到一个shell
IMAGE CREATED CREATED BY SIZE COMMENT
d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
[root@server1 ~]# docker run -it --name demo busybox
##以交互模式来打开容器,获得一个 shell
/ # uname -r
3.10.0-957.el7.x86_64
/ # free -m
total used free shared buff/cache available
Mem: 3950 242 2977 0 730 3463
Swap: 2047 0 2047
/#
用ctrl +d
来退出,退出直接就关闭了docker
;用 ctrl+p+q
来将其打入后台运行;
[root@server1 ~]# docker run -it --name demo busybox
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch zxk1
/ # touch zxk2
/ # ls
bin dev etc home proc root sys tmp usr var zxk1 zxk2
/ # ##此处用 ctrl +d 来退出之后,容器就被关闭了
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28320d96c6 busybox "sh" 27 seconds ago Exited (0) 11 seconds ago demo
[root@server1 ~]# docker start demo ##可以用 start 来开启容器;
demo
[root@server1 ~]# docker attach demo ##然后用 attach 来进入容器
/ # ls
bin dev etc home proc root sys tmp usr var zxk1 zxk2
/ #
用参数ctrl +p +q
退出之后,是将容器打入后台继续在运行;
[root@server1 ~]# docker attach demo
/ # ls
bin dev etc home proc root sys tmp usr var zxk1 zxk2
/ # touch zxkfile1
/ # touch zckfile2
/ # ls
bin etc proc sys usr zckfile2 zxk2
dev home root tmp var zxk1 zxkfile1
/ # read escape sequence
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28320d96c6 busybox "sh" 3 minutes ago Up 2 minutes demo
运行的容器是能分配到 IP 的,可以用命令 docker inspect demo` 来查看运行容器的 IP ;此 IP 是桥接的方式和主机进行连接的;
[root@server1 ~]# docker inspect demo
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
[root@server1 ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.180 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.050 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.050/0.115/0.180/0.065 ms
对于桥接的查看可以下载一个工具包来进行查看;
[root@server1 ~]# yum install bridge-utils.x86_64 -y ##下载来查看桥接的状态
[root@server1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024226b06bff no veth8a55abb
[root@server1 ~]# docker stop demo
demo
[root@server1 ~]# brctl show
##当容器关闭后,此时资源就被释放,当别的容器再次运行时,便会依次获得IP
bridge name bridge id STP enabled interfaces
docker0 8000.024226b06bff no
对于容器的删除:
刚刚的只是停掉了容器,但容器还在;可以将其不需要的容器删除;
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28320d96c6 busybox "sh" 17 minutes ago Exited (137) 2 minutes ago demo
[root@server1 ~]# docker rm demo ##删除没有运行的容器
demo
[root@server1 ~]# docker ps ##查看运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker ps -a ##查看所有的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
当容器删除之后,此时之前新建的文件时在容器层,此时再次开启镜像,但是看不到之前的信息;
[root@server1 ~]# docker run -it --name demo busybox
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch 111 ##修改容器
/ # touch 222
/ # ls
111 222 bin dev etc home proc root sys tmp usr var
/ #
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f26670e58f0 busybox "sh" 43 seconds ago Exited (0) 17 seconds ago demo
[root@server1 ~]# docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith " )
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
[root@server1 ~]# docker commit -m "add file" demo busybox:v1 ##将容器保存为新的镜像
sha256:ec156da5008793b690ab6b9859daa4074e24d04bcc9302b27a2095f74e0e6182
[root@server1 ~]# docker images ##查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox v1 ec156da50087 11 seconds ago 1.24MB
busybox latest d3cd072556c2 6 days ago 1.24MB
yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB
[root@server1 ~]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
d3cd072556c2 6 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 6 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
[root@server1 ~]# docker history busybox:v1 ##查看构建历史
IMAGE CREATED CREATED BY SIZE COMMENT
ec156da50087 33 seconds ago sh ##此处别人不知道做了什么,存在安全隐患 26B add file
d3cd072556c2 6 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 6 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
[root@server1 ~]# docker rm demo ##删除之前的容器
demo
[root@server1 ~]# docker run -it --name demo busybox:v1 ##对新打包的镜像运行
/ # ls
111 222 bin dev etc home proc root sys tmp usr var
/ #
[root@server1 ~]# docker rm demo
demo
[root@server1 ~]# docker run -it --name demo busybox
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
上面的方式构建的镜像存在一定的安全隐患,因为别人无法从构建历史中知道做了那些事。
dockerfile常用指令
创建 Dockerfile 文件
创建一个空目录,然后在空目录中创建 Dockerfile
文件;
COPY:用于当前目录,不能指定为根目录。
[root@server1 ~]# mkdir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# ls
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox ##指定镜像,如果不存在会从远程仓库下载
COPY index.html / ##把文件从复制到镜像
[root@server1 docker]# echo www.westos.org > index.html
[root@server1 docker]# docker build -t busybox:v2 . ##构建镜像
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM busybox
---> d3cd072556c2
Step 2/2 : COPY index.html /
---> bac12c96f3cf
Successfully built bac12c96f3cf
Successfully tagged busybox:v2
[root@server1 docker]# docker history busybox:v2
##用 Dockerfile 文件构建镜像的过程会有详细的过程
IMAGE CREATED CREATED BY SIZE COMMENT
bac12c96f3cf About a minute ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
RUN
[root@server1 docker]# vim Docker
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY index.html /
RUN touch testfile ##在容器中运行命令并创建新的镜像层,常用于安装软件包
[root@server1 docker]# docker build -t busybox:v3 .
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM busybox
---> d3cd072556c2
Step 2/3 : COPY index.html /
---> Using cache
---> bac12c96f3cf
Step 3/3 : RUN touch testfile
---> Running in 1a97d38ee1dc
Removing intermediate container 1a97d38ee1dc
---> af6759a259ae
Successfully built af6759a259ae
Successfully tagged busybox:v3
[root@server1 docker]# docker history busybox:v3
IMAGE CREATED CREATED BY SIZE COMMENT
af6759a259ae 3 seconds ago /bin/sh -c touch testfile 0B
bac12c96f3cf 2 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
ADD
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY index.html /
RUN touch testfile
ADD nginx-1.18.0.tar.gz /
[root@server1 docker]# ls
Dockerfile index.html nginx-1.18.0.tar.gz
[root@server1 docker]# docker build -t busybox:v4 .
Sending build context to Docker daemon 1.043MB
Step 1/4 : FROM busybox
---> d3cd072556c2
Step 2/4 : COPY index.html /
---> Using cache
---> bac12c96f3cf
Step 3/4 : RUN touch testfile
---> Using cache
---> af6759a259ae
Step 4/4 : ADD nginx-1.18.0.tar.gz /
---> 4a5ec9658a0a
Successfully built 4a5ec9658a0a
Successfully tagged busybox:v4
[root@server1 docker]# docker history busybox:v4
IMAGE CREATED CREATED BY SIZE COMMENT
4a5ec9658a0a About a minute ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50… 6.25MB
af6759a259ae 8 minutes ago /bin/sh -c touch testfile 0B
bac12c96f3cf 10 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
[root@server1 docker]# docker run --rm busybox:v4 ls ##--rm 表示运行完后直接回收掉容器
bin
dev
etc
home
index.html
nginx-1.18.0 ##当前目录生成解压文件
proc
root
sys
testfile
tmp
usr
var
ENV、EXPOSE 、VOLUME
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY index.html /
RUN touch testfile
ADD nginx-1.18.0.tar.gz /mnt
ENV HOSTNAME server1
EXPOSE 22
VOLUME ["/data"] ##挂载
[root@server1 docker]# docker build -t busybox:v6 .
Sending build context to Docker daemon 1.043MB
Step 1/7 : FROM busybox
---> d3cd072556c2
Step 2/7 : COPY index.html /
---> Using cache
---> bac12c96f3cf
Step 3/7 : RUN touch testfile
---> Using cache
---> af6759a259ae
Step 4/7 : ADD nginx-1.18.0.tar.gz /mnt
---> Using cache
---> 2bd486599e5d
Step 5/7 : ENV HOSTNAME server1
---> Running in 585940a17fef
Removing intermediate container 585940a17fef
---> 815841bf0454
Step 6/7 : EXPOSE 22
---> Running in 020e1555035d
Removing intermediate container 020e1555035d
---> bf1c448c8e88
Step 7/7 : VOLUME ["/data"]
---> Running in e752fadafca6
Removing intermediate container e752fadafca6
---> 079d588ee2b0
Successfully built 079d588ee2b0
Successfully tagged busybox:v6
[root@server1 docker]# docker history busybox:v6
IMAGE CREATED CREATED BY SIZE COMMENT
079d588ee2b0 17 seconds ago /bin/sh -c #(nop) VOLUME [/data] 0B
bf1c448c8e88 17 seconds ago /bin/sh -c #(nop) EXPOSE 22 0B
815841bf0454 17 seconds ago /bin/sh -c #(nop) ENV HOSTNAME=server1 0B
2bd486599e5d 3 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50… 6.25MB
af6759a259ae 13 minutes ago /bin/sh -c touch testfile 0B
bac12c96f3cf 15 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3… 1.24MB
[root@server1 docker]# docker run -it --rm busybox:v6 env ##查询变量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=server1
TERM=xterm
HOME=/root
[root@server1 docker]# docker run -it --rm busybox:v6
/ # cd /data/
/data # ls
/data # touch file1
/data # ls
file1
/data # [root@server1 docker]# docker ps ##此时可以看到暴露的端口号
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89b679669449 busybox:v6 "sh" 46 seconds ago Up 45 seconds 22/tcp quirky_buck
[root@server1 docker]# docker inspect quirky_buck
##此名称为 ps 后看到的结果,用此命令可以看到挂载
[root@server1 docker]# cd /var/lib/docker/volumes/f3890ceefa0cf175ba9477be8dc027fcbac07e83237ac0183e5cac034eafca8d/_data
[root@server1 _data]# ls ##在挂载中可以看到其容器中新建的文件
file1
[root@server1 _data]# rm -fr file1
[root@server1 _data]# ls
[root@server1 _data]# touch file2 ##在该目录中修改文件
[root@server1 _data]# ls
file2
[root@server1 _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89b679669449 busybox:v6 "sh" 4 minutes ago Up 4 minutes 22/tcp quirky_buck
[root@server1 _data]# docker attach 89b679669449 ##也可以用ID加进取,可以看到其修改后的文件信息
/data # ls
file2
/data #
WORKDIR
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY index.html /
RUN touch testfile
ADD nginx-1.18.0.tar.gz /mnt
ENV HOSTNAME server1
EXPOSE 22
VOLUME ["/data"]
WORKDIR /nginx-1.18.0.tar.gz ##指定进入容器所在目录
[root@server1 docker]# docker build -t busybox:v7 .
Sending build context to Docker daemon 1.043MB
Step 1/8 : FROM busybox
---> d3cd072556c2
Step 2/8 : COPY index.html /
---> Using cache
---> bac12c96f3cf
Step 3/8 : RUN touch testfile
---> Using cache
---> af6759a259ae
Step 4/8 : ADD nginx-1.18.0.tar.gz /mnt
---> Using cache
---> 2bd486599e5d
Step 5/8 : ENV HOSTNAME server1
---> Using cache
---> 815841bf0454
Step 6/8 : EXPOSE 22
---> Using cache
---> bf1c448c8e88
Step 7/8 : VOLUME ["/data"]
---> Using cache
---> 079d588ee2b0
Step 8/8 : WORKDIR /nginx-1.18.0.tar.gz
---> Running in 99fe5b85b0df
Removing intermediate container 99fe5b85b0df
---> 469584a6752f
Successfully built 469584a6752f
Successfully tagged busybox:v7
[root@server1 docker]# docker run -it --rm busybox:v7
/nginx-1.18.0.tar.gz # ls
/nginx-1.18.0.tar.gz #
CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
Shell和exec格式的区别
#cat Dockerfile
FROM busybox
ENV name world
CMD echo “hello, $name”
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", “hello, $name”]
需要改写成以下形式:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", “-c”, “echo hello, $name”]
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
#cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", “hello”]
CMD [“world”]
看下在运行容器时的区别:
#docker run --rm busybox:v1
hello world
#docker run --rm busybox:v1 linux
hello linux
官方推荐使用exec格式书写
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
COPY index.html /
RUN touch testfile
ADD nginx-1.18.0.tar.gz /mnt
ENV HOSTNAME server1
EXPOSE 22
VOLUME ["/data"]
WORKDIR /nginx-1.18.0.tar.gz
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
[root@server1 docker]# docker build -t busybox:v8 .
Sending build context to Docker daemon 1.043MB
Step 1/10 : FROM busybox
---> d3cd072556c2
Step 2/10 : COPY index.html /
---> Using cache
---> bac12c96f3cf
Step 3/10 : RUN touch testfile
---> Using cache
---> af6759a259ae
Step 4/10 : ADD nginx-1.18.0.tar.gz /mnt
---> Using cache
---> 2bd486599e5d
Step 5/10 : ENV HOSTNAME server1
---> Using cache
---> 815841bf0454
Step 6/10 : EXPOSE 22
---> Using cache
---> bf1c448c8e88
Step 7/10 : VOLUME ["/data"]
---> Using cache
---> 079d588ee2b0
Step 8/10 : WORKDIR /nginx-1.18.0.tar.gz
---> Using cache
---> 469584a6752f
Step 9/10 : ENTRYPOINT ["/bin/echo","hello"]
---> Running in 9eb5b2461081
Removing intermediate container 9eb5b2461081
---> 3dd02e78d687
Step 10/10 : CMD ["world"]
---> Running in 4c2b4bf52610
Removing intermediate container 4c2b4bf52610
---> 9e88acbedae1
Successfully built 9e88acbedae1
Successfully tagged busybox:v8
[root@server1 docker]# docker run -it --rm busybox:v8
hello world
[root@server1 docker]# docker run -it --rm busybox:v8 zxk
hello zxk
[root@server1 docker]# docker run -it --rm busybox:v8 westos
hello westos
例子:
尝试创建一个 Nginx 的镜像,这里使用精简版的 RHEL7 作为 base 镜像;
[root@server1 ~]# ls
docker rhel7.tar
[root@server1 ~]# docker load -i rhel7.tar ##导入镜像
e1f5733f050b: Loading layer 147.1MB/147.1MB
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 1ae02957d153 About an hour ago 7.49MB
yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
[root@server1 docker]# ls
Dockerfile dvd.repo index.html nginx-1.18.0.tar.gz
[root@server1 docker]# cat dvd.repo
[dvd]
name=rhel7.6
baseurl=http://172.25.25.250/rhel7.6
gpgcheck=0
[root@server1 docker]# cat Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt/
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
COPY index.html /usr/local/nginx/html
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v1 .
##构建镜像
[root@server1 docker]# docker images rhel7
##可以看到新构建出来的镜像比较大
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v1 fffa388c2f85 45 seconds ago 296MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
[root@server1 docker]# docker run -d --name nginx rhel7:v1
##运行容器
c518fc1078acf7a8bca3b2c2dede4a17c42c80b5c6ff83edce323044294f5e18
[root@server1 docker]# docker ps
##能运行起来说明没有问题
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36b62af6ee1c rhel7:v1 "/usr/local/nginx/sb…" 11 seconds ago Up 10 seconds 80/tcp nginx
[root@server1 docker]# docker inspect nginx ##容器运行之后会获得一个IP
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
[root@server1 docker]# curl 172.17.0.2 ##测试
www.westos.org
优化一:减少镜像层数,清理镜像构建的中间产物
[root@server1 docker]# docker history rhel7:v1
##优化之前查看其镜像层
IMAGE CREATED CREATED BY SIZE COMMENT
fffa388c2f85 4 minutes ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb… 0B
bc7b1152962c 4 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
e4255b736ea2 4 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
f4372157f041 4 minutes ago /bin/sh -c make install 3.88MB
c82e12550cac 4 minutes ago /bin/sh -c make 12.4MB
6d042420eb1d 4 minutes ago /bin/sh -c ./configure --prefix=/usr/local/n… 71.7kB
0a26b8674cb6 6 minutes ago /bin/sh -c rpmdb --rebuilddb && yum install … 133MB
8c2017ec9956 7 minutes ago /bin/sh -c #(nop) WORKDIR /mnt/nginx-1.18.0 0B
4086ae26148a 7 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50… 6.25MB
18246b081767 7 minutes ago /bin/sh -c #(nop) COPY file:5ec2460d7fc0badb… 67B
0a3eb3fde7fd 6 years ago 140MB Imported from -
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt/
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 && yum clean all
COPY index.html /usr/local/nginx/html
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v2 .
[root@server1 docker]# docker images rhel7
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v2 45d788701ce8 35 seconds ago 255MB
rhel7 v1 fffa388c2f85 48 minutes ago 296MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
[root@server1 docker]# docker history rhel7:v2
##优化之后查看其镜像层
IMAGE CREATED CREATED BY SIZE COMMENT
45d788701ce8 About a minute ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb… 0B
46a3d583baa3 About a minute ago /bin/sh -c #(nop) EXPOSE 80 0B
571b111ea252 About a minute ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
a4605bef525d About a minute ago /bin/sh -c rpmdb --rebuilddb && yum install … 108MB
8c2017ec9956 52 minutes ago /bin/sh -c #(nop) WORKDIR /mnt/nginx-1.18.0 0B
4086ae26148a 52 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50… 6.25MB
18246b081767 52 minutes ago /bin/sh -c #(nop) COPY file:5ec2460d7fc0badb… 67B
0a3eb3fde7fd 6 years ago 140MB Imported from -
优化二:使用多阶段构建镜像
在构建NGINX时我们只需要的是Nginx的二进制文件, 中途为了编译而安装的依赖以及编译中产生的内容其实在服务中都没有用到;
采用多阶段构建的方法,创建一个临时镜像用于编译,将编译好的二进制文件拷贝到最终要创建的镜像。
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.18.0.tar.gz /mnt/
WORKDIR /mnt/nginx-1.18.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 && yum clean all
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
COPY index.html /usr/local/nginx/html
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t rhel7:v3 .
查看构建完成的大小为141M, 仅比base镜像大了1M而已。
[root@server1 docker]# docker images rhel7
##查看最新构建出来的大小
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 8c8a22458c17 25 seconds ago 141MB
rhel7 v2 45d788701ce8 4 minutes ago 255MB
rhel7 v1 fffa388c2f85 53 minutes ago 296MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
[root@server1 docker]# docker history rhel7:v3
IMAGE CREATED CREATED BY SIZE COMMENT
8c8a22458c17 50 seconds ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb… 0B
fa842e59a5ed 50 seconds ago /bin/sh -c #(nop) EXPOSE 80 0B
9ac15082bdda 50 seconds ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73… 15B
bd2144a4860b 50 seconds ago /bin/sh -c #(nop) COPY dir:e5b2163c7ba7dfad7… 851kB
0a3eb3fde7fd 6 years ago 140MB Imported from -
优化三:选择最精简的基础镜像
如果还需要进一步的优化,此处我们选择更加精简的基础镜像;
[root@server1 ~]# ls
base-debian10.tar docker rhel7.tar
[root@server1 ~]# docker load -i base-debian10.tar ##导入镜像
[root@server1 ~]# docker images
##可以看到其只有 19.2M
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 8c8a22458c17 7 minutes ago 141MB
rhel7 v2 45d788701ce8 12 minutes ago 255MB
rhel7 v1 fffa388c2f85 About an hour ago 296MB
<none> <none> 1ae02957d153 2 hours ago 7.49MB
yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
对于刚才构建的镜像,可以查看其大小以及运行过程调用的资源;
[root@server1 ~]# docker run -it --rm rhel7:v3 bash
bash-4.2# cd /usr/local/nginx/
bash-4.2# ls
conf html logs sbin
bash-4.2# du -sh
876K .
bash-4.2# cd sbin/
bash-4.2# ls
nginx
bash-4.2# ldd nginx ##调用系统的库函数
linux-vdso.so.1 => (0x00007ffdbe7c2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f9aabde3000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9aabbc7000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f9aab990000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f9aab72f000)
libz.so.1 => /lib64/libz.so.1 (0x00007f9aab519000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9aab158000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9aabfe7000)
libfreebl3.so => /lib64/libfreebl3.so (0x00007f9aaaed9000)
bash-4.2#
使用官方镜像的Dockfile 来构建新的镜像;
[root@server1 ~]# cd docker/
[root@server1 docker]# mkdir new
[root@server1 docker]# cd new/
[root@server1 new]# docker pull nginx
##拉取最新版的镜像
[root@server1 new]# vim Dockerfile
[root@server1 new]# cat Dockerfile
##内容为从官方复制而来
FROM nginx as base
#https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${
TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian10
COPY --from=base /opt /
VOLUME ["/usr/share/nginx/html"] ##来挂接发布目录;
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 new]# docker build -t rhel7:v4 .
##构建镜像
[root@server1 new]# docker run -d --name demo rhel7:v4
##运行容器
4a742f3593214fd518832e8a48928d8e94852df4823d4ddaf50f3c387c18d85c
[root@server1 new]# docker images rhel7
##可以看到其只有31.9M,包括其中的基础19.2M,相对于前面的来说经建立很多
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 e8c324efa2e0 About an hour ago 31.9MB
rhel7 v3 8c8a22458c17 2 hours ago 141MB
rhel7 v2 45d788701ce8 2 hours ago 255MB
rhel7 v1 fffa388c2f85 2 hours ago 296MB
rhel7 latest 0a3eb3fde7fd 6 years ago 140MB
[root@server1 new]# docker history rhel7:v4
IMAGE CREATED CREATED BY SIZE COMMENT
b3388a690329 5 minutes ago /bin/sh -c #(nop) ENTRYPOINT ["nginx" "-g" … 0B
52d6aca444a9 5 minutes ago /bin/sh -c #(nop) EXPOSE 443 80 0B
55d6bb5728eb 5 minutes ago /bin/sh -c #(nop) VOLUME [/usr/share/nginx/… 0B
36cd5ddf7ad3 5 minutes ago /bin/sh -c #(nop) COPY dir:4b299d402b46c2983… 12.7MB
d48fcdd54946 51 years ago bazel build ... 17.4MB
<missing> 51 years ago bazel build ... 1.8MB
除了 docker 引擎管理的卷之外还可以手动指定挂载;
[root@server1 new]# docker rm -f demo
[root@server1 new]# docker run -d --name demo -v /data:/usr/share/nginx/html rhel7:v4
##手动指定挂载,-v 所接的路径不管是宿主机还是容器中的,当不存在时会自动新建;宿主机目录下的数据一定会覆盖容器中的数据
a8c1fcb30efd26b551caaea35d9c9cda37db7d357795e25d71bee3a3aa9739d0
[root@server1 new]# docker inspect demo
##查看运行容器分配的IP
[root@server1 new]# curl 172.17.0.2
##此时访问时已经被覆盖
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.10</center>
</body>
</html>
[root@server1 new]# cd /data
[root@server1 data]# echo www.westos.org > index.html
[root@server1 data]# curl 172.17.0.2
www.westos.org
[root@server1 data]# echo www.westos.org >> index.html
[root@server1 data]# echo www.westos.org >> index.html
[root@server1 data]# echo www.westos.org >> index.html
[root@server1 data]# curl 172.17.0.2
www.westos.org
www.westos.org
www.westos.org
www.westos.org
[root@server1 data]# docker rm -f demo
[root@server1 new]# cd /data/
[root@server1 data]# ls
此时即使删除了容器,但是数据还在,当再启动一个容器时将数据挂接还可以看到数据
docker
镜像,掌握了镜像的分层结构,学习了如何通过dockerfile
构建镜像,最后实践了docker
镜像的多种优化方法。images
显示镜像列表history
显示镜像构建历史commi
t 从容器创建镜像build
从Dockerfile构建镜像tag
给镜像打标签search
搜索镜像pull
从仓库拉取镜像push
上传镜像到仓库rmi
删除镜像