docker模式,为应用部署平台,打包应用。共享宿主机的操作系统。docker景象非常小。
安装
[root@server1 Desktop]# ls
containerd.io-1.2.5-3.1.el7.x86_64.rpm docker-ce-18.09.6-3.el7.x86_64.rpm
container-selinux-2.21-1.el7.noarch.rpm docker-ce-cli-18.09.6-3.el7.x86_64.rpm
[root@server1 Desktop]# yum install -y *rpm 安装
[root@server1 Desktop]# systemctl start docker 启动
[root@server1 Desktop]# systemctl enable docker 自启动
我们准备了一个游戏镜像现在开始倒入
[root@server1 Desktop]# docker load -i game2048.tar 倒入镜像到docker
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: game2048:latest
[root@server1 Desktop]# docker images 查看已经加载进去的
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 2 years ago 55.5MB
[root@server1 Desktop]# docker history game2048:latest 分层结构,镜像构造的结构
IMAGE CREATED CREATED BY SIZE COMMENT
19299002fdbe 2 years ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "sed … 0B
<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B
<missing> 2 years ago /bin/sh -c #(nop) COPY dir:cb74e9c037a3d501c… 600kB
我们建立并运行一个容器
[root@server1 Desktop]# docker run -d --name game1 -p 80:80 game2048 运行这个游戏80物理机对,contain的80端口游戏
00f1a8fc8e19b65d7b9567f2131d6ebaf7a3519232e199ac89053208ef5996fc
[root@server1 Desktop]# docker images 查看进去的镜像内容
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 2 years ago 55.5MB
[root@server1 Desktop]# docker ps 查看容器中运行的容器状态。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00f1a8fc8e19 game2048 "/bin/sh -c 'sed -i …" 18 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp, 443/tcp game1
[root@server1 Desktop]# docker info 容器的各种信息
Containers: 1
Running: 1
Paused: 0
Stopped: 0
[root@server1 Desktop]# docker inspect game1 查看已经创建的容器的详情。
我们访问本机80端口可以看到。容器中的软件运行
在容器中我们创建的文件是不会影响下一个容器的建立,也就是容器的所有操作不会影响镜像。这样有效的隔离了镜像与容器。
[root@server1 Desktop]# docker load -i ubuntu.tar 我们加载一个镜像
[root@server1 Desktop]# docker history ubuntu:latest 看下他的构造历史
[root@server1 Desktop]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00f1a8fc8e19 game2048 "/bin/sh -c 'sed -i …" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, 443/tcp game1
[root@server1 Desktop]# docker rm -f game1 删除以前存在的容器
game1
[root@server1 Desktop]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 Desktop]#
[root@server1 Desktop]# docker run -it --name vm1 ubuntu 我们运行新加载的镜像,用交互式的方法
root@1973ceb5d634:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@1973ceb5d634:/# touch file1 我们在里面建立一个文件
root@1973ceb5d634:/# ls
bin dev file1 lib media opt root sbin sys usr
boot etc home lib64 mnt proc run srv tmp var
root@1973ceb5d634:/# uname -r 他的内核是和物理机共享的,所以很小
3.10.0-862.el7.x86_64
root@1973ceb5d634:/# exit 然后退出
exit
[root@server1 Desktop]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 Desktop]# docker ps -a 已经存在的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1973ceb5d634 ubuntu "/bin/bash" About a minute ago Exited (0) 46 seconds ago vm1
[root@server1 Desktop]# docker rm vm1 将他删除
vm1
[root@server1 Desktop]# docker run -it --name vm1 ubuntu 我们重新建立一个容器,用原来的镜像
root@0ba0a765ccf3:/# ls 可以看到不会影响新建立的容器
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
[root@server1 network-scripts]# docker rm vm1 删除容器
vm1
[root@server1 network-scripts]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
我们重新加载一个镜像,用它来测试一个退出方法ctrl+p+q可以后台运行。
ctrl+p+q退出到后台
[root@server1 network-scripts]# docker run -it --name vm1 busybox
WARNING: IPv4 forwarding is disabled. Networking will not work.
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
[root@server1 network-scripts]# docker images 所有的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 19485c79a9bb 3 weeks ago 1.22MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 network-scripts]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90c2042ded8d busybox "sh" 2 minutes ago Up 2 minutes vm1
[root@server1 network-scripts]# docker attach vm1 连接到后台容器
/ # ls
bin dev etc home proc root sys tmp usr var
[root@server1 network-scripts]# docker rm -f vm1 删除容器
vm1
容器的构建历史,我们在构建一个镜像时,每作一次操作都会在镜像的历史中留下痕迹。我们来看commit构建镜像在,镜像中留下的痕迹。
[root@server1 network-scripts]# docker run -it --name vm1 busybox 我们来运行这个容器
/ # vi testfile
/ # ls
bin etc proc sys tmp var
dev home root testfile usr
[root@server1 network-scripts]# docker history busybox:latest 查看他的历史
IMAGE CREATED CREATED BY SIZE COMMENT
19485c79a9bb 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
[root@server1 network-scripts]# docker commit vm1 test:v1 我恩将它打包成test 版本v1
sha256:87bf30e7174baf8a9b57e46139116c5d871f6ef99f7f7731c3f297640103e368
[root@server1 network-scripts]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 87bf30e7174b 5 seconds ago 1.22MB
busybox latest 19485c79a9bb 3 weeks ago 1.22MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 network-scripts]# docker history test:v1 可以看出时在之前的上面加的一层
IMAGE CREATED CREATED BY SIZE COMMENT
87bf30e7174b About a minute ago sh 106B
19485c79a9bb 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
在上面我们在说明镜像的构造过程,时会留下一定的历史操作的。当时用的时commit来进行的,他的过程是,运行容器,修改容器,将容器保存为新的镜像。但是这种方式较为麻烦,因此我们使用dockerfile来创建镜像,这个样我们将所有的构造过程写入一个文件中,在用build指令就可以一次性的执行所有操作。非常的方便。
我们现在进行简单的尝试
mkdir docker 创建文件夹来方自动安装的目录
cd docker 进入文件夹
vim Dockerfile 创建自动安装文件
docker build -t test:v2 . 自动生成镜像v2
cat Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
RUN echo testfile > file1
RUN echo testfile > file2
在来生成一个镜像
vim Dockerfile 创建自动安装文件
docker build -t test:v3
[root@server1 docker]# cat Dockerfile
FROM busybox
RUN echo testfile > file1
RUN echo testfile > file2
RUN echo testfile > file3 多了以行
[root@server1 docker]# docker history test:v2 我们呢看构建的镜像历史中自动一次性的加入了file1 file2这两个过程
IMAGE CREATED CREATED BY SIZE COMMENT
d17d657294c9 16 hours ago /bin/sh -c echo testfile > file2 9B
3b1001f0cfca 16 hours ago /bin/sh -c echo testfile > file1 9B
19485c79a9bb 4 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
docker history test:v3 . docker3的dockerfile中加入多加了以层。我们可以看出
[root@server1 docker]# docker history test:v3
IMAGE CREATED CREATED BY SIZE COMMENT
304043aeddd7 16 hours ago /bin/sh -c echo testfile > file3 9B
d17d657294c9 16 hours ago /bin/sh -c echo testfile > file2 9B
3b1001f0cfca 16 hours ago /bin/sh -c echo testfile > file1 9B
19485c79a9bb 4 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
[root@server1 docker]# docker images 这是我们构建的所有镜像v1、v2
REPOSITORY TAG IMAGE ID CREATED SIZE
test v3 304043aeddd7 16 hours ago 1.22MB
test v2 d17d657294c9 16 hours ago 1.22MB
test v1 87bf30e7174b 17 hours ago 1.22MB
busybox latest 19485c79a9bb 4 weeks ago 1.22MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
我们将之前的版本全部删除,现在说名在dockerfile中我们中的一些构建层数的方式。
FROM:用于指定base镜像,本地不存在会从远程仓库进行下。MAINTAINER:设置镜像的作者,不是必须存在的。COPY:
把文件复制到镜像(容器层)
COPY这样我们可以将东西放入我们的容器镜像中去
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 19485c79a9bb 4 weeks ago 1.22MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 docker]# ls
Dockerfile testfile
[root@server1 docker]# cat Dockerfile 我们docker'file中写入的东西
FROM busybox
COPY testfile /tmp 经我们testfile中放入容器的路径中
[root@server1 docker]# cat testfile 在这里面是hello world
hello world
[root@server1 docker]# docker build -t test:v1 . 建立v1
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM busybox
---> 19485c79a9bb
Step 2/2 : COPY testfile /tmp 将东西放入其中
---> a3fd7aad8143
Successfully built a3fd7aad8143
Successfully tagged test:v1
[root@server1 docker]# docker history test:v1 可以看到构建历史
IMAGE CREATED CREATED BY SIZE COMMENT
a3fd7aad8143 19 seconds ago /bin/sh -c #(nop) COPY file:9144eb84ab54e5c9… 12B
19485c79a9bb 4 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
[root@server1 docker]# docker run -it --name vm1 test:v1 运行可以进入
/ # ls
bin dev etc home proc root sys tmp usr var
ADD也可以将外界的东西放入里面去,但是这个有个好处就是可以放压缩包,它会自动解压压缩包,放到镜像中去。我们以nginx压缩包为例。
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile 文件中写入,使用ADD
FROM busybox
COPY testfile /tmp
ADD nginx-1.17.0.tar.gz /tmp 将其与镜像一块放到/tmp下
[root@server1 docker]# pwd
/root/docker
找一个nginx,我们从主机拿一个我们要用的ngnix安装包
[root@server1 docker]# scp kiosk@172.25.38.250:/home/kiosk/Desktop/12/nginx-1.17.0.tar.gz .
[root@server1 docker]# ls 放到dockerfile统一目录下
Dockerfile nginx-1.17.0.tar.gz testfile
查看已经比那一到里面
[root@server1 docker]# docker build -t test:v2 . 构建v2
Sending build context to Docker daemon 1.037MB
Step 1/3 : FROM busybox
---> 19485c79a9bb
Step 2/3 : COPY testfile /tmp
---> Using cache 前面有缓存可以用
---> a3fd7aad8143
Step 3/3 : ADD nginx-1.17.0.tar.gz /tmp ADD
---> 431bbc504de0
Successfully built 431bbc504de0
Successfully tagged test:v2
[root@server1 docker]# docker rm -f vm1 将之前容器删除
vm1
[root@server1 docker]# docker run -it --name vm1 test:v2 运行容器v2
/ # ls
bin dev etc home proc root sys tmp usr var
/ # cd tmp/
/tmp # ls 可以看出我们用两种方法放入容器中的东西
nginx-1.17.0 testfile
/tmp # cd nginx-1.17.0/
/tmp/nginx-1.17.0 # ls
CHANGES CHANGES.ru LICENSE README auto conf configure contrib html man src
volume数据挂在地方,我们在放在运行容器时,所存的数据不会影向它的镜像,那么它的数据放在的地点就要由我们的volume来指定。
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile 我们加入数据挂载点
FROM busybox
COPY testfile /tmp
ADD nginx-1.17.0.tar.gz /tmp
VOLUME ["/data"]
[root@server1 docker]# docker build -t test:v3 . 创建v3版本
Sending build context to Docker daemon 1.037MB
Step 1/4 : FROM busybox
---> 19485c79a9bb
Step 2/4 : COPY testfile /tmp
---> Using cache
---> a3fd7aad8143
Step 3/4 : ADD nginx-1.17.0.tar.gz /tmp
---> Using cache
---> 431bbc504de0
Step 4/4 : VOLUME ["/data"]
---> Running in 9683b6fb9e0f
Removing intermediate container 9683b6fb9e0f
---> 79efc0986a72
Successfully built 79efc0986a72
Successfully tagged test:v3
[root@server1 docker]# docker run -it --name vm2 test:v3 创建容器并运行
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # [root@server1 docke 后台运行
[root@server1 docker]# docker inspect vm2 查看具体信息,存放地点
"Source": "/var/lib/docker/volumes /702f374797debe309bf6eb322e64ef3db21bde48a96253189006511fcb7b69ae/_data",
进入这里面我们可以看到到这里面健文件,可以在容器中看
[root@server1 docker]# cd /var/lib/docker/volumes/702f374797debe309bf6eb322e64ef3db21bde48a96253189006511fcb7b69ae/_data
[root@server1 _data]# ls
[root@server1 _data]# touch file1 我们在数据挂载点建立文件
[root@server1 _data]# touch westos
[root@server1 _data]# ls
file1 westos
[root@server1 _data]# docker attach vm2 我们运行容器,在容器中可以看到数据。
/ # cd data/
/data # ls
file1 westos
我们在里面删除,外界也会消失
还有在我们构建容器时,写下的数据挂载点这样也可以
/data # rm -fr * 删除他们在外界也会消失
/data # ls
/data # read escape sequence
还有一种联系外界的方法
[root@server1 _data]# ls
[root@server1 _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9a2ec8b686e test:v3 "sh" 10 minutes ago Exited (0) About a minute ago vm2
bf0537c76b7b test:v2 "sh" 17 minutes ago Exited (0) 15 minutes ago vm1
[root@server1 _data]# docker run -it --name vm3 -v /opt/data:/data test:v 直接在这里面运行容器
v1 v2 v3
[root@server1 _data]# docker run -it --name vm3 -v /opt/data:/data test:v3
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # cd data/
/data # touch file1 建立文件
/data # [root@server1 _data]#
[root@server1 _data]# ls
[root@server1 _data]# cd /opt/data/ 外界进去
[root@server1 data]# ls 可以看到数据
file1
CMD与ENTRYPOINT设置容器启动后执行的命令,但是CMD会被doker run后面的命令覆盖,但是ENTRYPOINT不会,dockerfile中只能指定一个ENTRYPOINT,指定多个最后一个起作用docker run后面的参数可以传递给ENTRYPOINT。
我们先来说明变量:
[root@server1 ~]# cd docker/
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile env来设置变量的值
FROM busybox
ENV name westos
ENTRYPOINT echo "hello, $name" 这个来调用变量
[root@server1 docker]# docker build -t test:v4 .
Sending build context to Docker daemon 1.037MB
Step 1/3 : FROM busybox
---> 19485c79a9bb
Step 2/3 : ENV name westos
---> Running in 749a68774b8c
Removing intermediate container 749a68774b8c
---> 9672cd2ffd0d
Step 3/3 : ENTRYPOINT echo "hello, $name"
---> Running in 515e69ecd0af
Removing intermediate container 515e69ecd0af
---> 53375c8ee5f1
Successfully built 53375c8ee5f1
Successfully tagged test:v4
[root@server1 docker]# docker run --rm test:v4 当我们运行后,他会执行这个命令。运行环境变量的东西
hello, westos
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v4 53375c8ee5f1 25 seconds ago 1.22MB
test v3 79efc0986a72 21 minutes ago 7.42MB
test v2 431bbc504de0 25 minutes ago 7.42MB
test v1 a3fd7aad8143 43 minutes ago 1.22MB
busybox latest 19485c79a9bb 4 weeks ago 1.22MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
ubuntu latest 07c86167cdc4 3 years ago 188MB
[root@server1 docker]# docker history test:v4 我们可以看到构建过程。其中在里面,输出了变量的过程。
IMAGE CREATED CREATED BY SIZE COMMENT
53375c8ee5f1 31 minutes ago /bin/sh -c #(nop) ENTRYPOINT 引用 的时这里面的 ["/bin/sh" "-c… 0B
9672cd2ffd0d 31 minutes ago /bin/sh -c #(nop) ENV name=westos 0B
19485c79a9bb 4 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:9151f4d22f19f41b7… 1.22MB
当然我们也可以在里面引用这种中/bin/sh来执行引用变量,执行程序:
[root@server1 docker]# cat Dockerfile 我们可以用这种方式来
FROM busybox
ENV name westos
ENTRYPOINT ["/bin/echo", "hello, $name"]
[root@server1 docker]# docker build -t test:v5 . 构建v5
Sending build context to Docker daemon 1.037MB
Step 1/3 : FROM busybox
---> 19485c79a9bb
Step 2/3 : ENV name westos
---> Using cache
---> 9672cd2ffd0d
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello, $name"]
---> Running in fc09f4663c99
Removing intermediate container fc09f4663c99
---> 1d5de35ae995
Successfully built 1d5de35ae995
Successfully tagged test:v5
[root@server1 docker]# docker run --rm test:v5 ,我们发现没有引用,那是因为东西没有写完
hello, $name
现在更改后我们再看:
[root@server1 docker]#
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# docker build -t test:v6 .
Sending build context to Docker daemon 1.037MB
Step 1/3 : FROM busybox
---> 19485c79a9bb
Step 2/3 : ENV name westos
---> Using cache
---> 9672cd2ffd0d
Step 3/3 : ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
---> Running in 0ff422197f10
Removing intermediate container 0ff422197f10
---> 2ba304436877
Successfully built 2ba304436877
Successfully tagged test:v6
[root@server1 docker]# docker run --rm test:v6
hello, westos
[root@server1 docker]# cat Dockerfile
FROM busybox
ENV name westos
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
当然我们也可以用cmd的放式来追加值
我们也可以线执行hello,然后在里面执行输出world。
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
[root@server1 docker]# docker build -t test:v7 .
Sending build context to Docker daemon 1.037MB
Step 1/3 : FROM busybox
---> 19485c79a9bb
Step 2/3 : ENTRYPOINT ["/bin/echo", "hello"]
---> Running in 210017e24186
Removing intermediate container 210017e24186
---> 90d2ac4c2c9c
Step 3/3 : CMD ["world"]
---> Running in e4dd49ae8a52
Removing intermediate container e4dd49ae8a52
---> d511f51066b2
Successfully built d511f51066b2
Successfully tagged test:v7
[root@server1 docker]# docker run --rm test:v7
hello world
docker的优化。
我们首先放一个系统为7的操作系统,然后在里面在进行安装一个nginx。
[root@server1 docker]# scp kiosk@172.25.38.250:/home/kiosk/Desktop/12/images/rhel7.tar .
kiosk@172.25.38.250's password:
rhel7.tar 100% 140MB 19.0MB/s 00:07
[root@server1 docker]# ls
Dockerfile nginx-1.17.0.tar.gz rhel7.tar testfile
[root@server1 docker]# docker load -i rhel7.tar 加载镜像
e1f5733f050b: Loading layer [==================================================>] 147.1MB/147.1MB
[root@server1 docker]# docker ps | grep rhel7
[root@server1 docker]# docker ps | grep rhe
[root@server1 docker]# docker images | grep rhel7
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
以dockerfile来在镜像中安装一个我们的nginx
[root@server1 docker]# ls 下面有如下文件
Dockerfile nginx-1.17.0.tar.gz rhel7.5.repo rhel7.tar testfile 其中有一个yum源,一个nginx的安装包
[root@server1 docker]# cat Dockerfile 我们看一下其中内容
FROM rhel7
EXPOSE 80
COPY rhel7.5.repo /etc/yum.repos.d 依赖性时通过yum源进行的
RUN rpmdb --rebuilddb
RUN yum install -y gcc make pcre-devel zlib-devel
ADD nginx-1.17.0.tar.gz /mnt 用add来经nginx安装解压到/mnt中
WORKDIR /mnt/nginx-1.17.0 指定工作的目录
RUN ./configure --prefix=/usr/local/nginx 下来我们开始编译
RUN make 下载
RUN make install
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]在启动后我们运行nginx
[root@server1 docker]# docker images | grep rhel7.
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
[root@server1 docker]# docker build -t nginx:v1 . 这样将镜像编译到里面
[root@server1 docker]# docker images nginx:v1 它有301MB
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 7fe009b3111b 2 minutes ago 301MB
优化一共有三种放式,在上面的基础上开始优化。
1、清理镜像的中间产物。(安装包等)
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
COPY rhel7.5.repo /etc/yum.repos.d
RUN rpmdb --rebuilddb
RUN yum install -y gcc make pcre-devel zlib-devel && yum clean all 加入消除缓存
ADD nginx-1.17.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.17.0
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t nginx:v2 .
2、减少镜像的层数。
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
COPY rhel7.5.repo /etc/yum.repos.d
ADD nginx-1.17.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.17.0
将我们后面安装nginx的过程,层数尽量一次性安装完毕
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.17.0
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t nginx:v3 .
3、多阶段构建构建过程在临时容器中完成,我们只需要最后的二进制文件,其他的过程文件全部删除
在nginx中我们其实只要我们最终二进制程序,其他的东西都不要,所以我们可以,将安装过程放入一个临时容器,而我们的最终结果放入另外一个好的容器中。这样也可以简化。
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
EXPOSE 80
COPY rhel7.5.repo /etc/yum.repos.d
ADD nginx-1.17.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.17.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.17.0
这是第二个阶段
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY --from=build /usr/local/nginx /usr/local/nginx
ENTRYPOINT ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t nginx:v4 . 编译v4
4、使用更加精简的基础镜像。
我们在nginx时可使用最简单的安装包来实现。通过使用distroless来实现。
[root@server1 docker]# docker load -i nginx.tar
014cf8bfcb2d: Loading layer [==================================================>] 58.46MB/58.46MB
832a3ae4ac84: Loading layer [==================================================>] 53.91MB/53.91MB
e89b70d28795: Loading layer [==================================================>] 3.584kB/3.584kB
Loaded image: nginx:latest
[root@server1 docker]# docker history nginx:latest
IMAGE CREATED CREATED BY SIZE COMMENT
e548f1a579cf 19 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 19 months ago /bin/sh -c #(nop) STOPSIGNAL [SIGTERM] 0B
<missing> 19 months ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B
<missing> 19 months ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B
<missing> 19 months ago /bin/sh -c set -x && apt-get update && apt… 53.4MB
<missing> 19 months ago /bin/sh -c #(nop) ENV NJS_VERSION=1.13.9.0.… 0B
<missing> 19 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.13.9-… 0B
<missing> 19 months ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 19 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 19 months ago /bin/sh -c #(nop) ADD file:27ffb1ef53bfa3b9f… 55.3MB
[root@server1 docker]# mkdir distroless 建立一个文件夹
[root@server1 docker]# cd distroless/
[root@server1 distroless]# vim Dockerfile 在这里面建立一个dockerfile
[root@server1 distroless]# cd /root/docker/
[root@server1 docker]# scp kiosk@172.25.38.250:/home/kiosk/Desktop/distroless.tar .
[root@server1 docker]# docker load -i distroless.tar 加载惊醒
668afdbd4462: Loading layer [==================================================>] 18.39MB/18.39MB
Loaded image: gcr.io/distroless/base:latest
[root@server1 distroless]# cat Dockerfile 在里面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/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt.so.* /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
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 distroless]# docker build -t nginx:v5 . 构建v5
我们从v1-v2一步步优化现在看下结果
我们可以看一下他们的对比
[root@server1 distroless]# docker images | grep nginx
nginx v5 22f1fe2820d5 13 seconds ago 24.6MB
nginx v4 dc0579920189 22 minutes ago 144MB
nginx v3 c75b81177b65 About an hour ago 257MB
nginx v2 61cbbebaa1df About an hour ago 276MB
nginx v1 7fe009b3111b 2 hours ago 301MB
nginx latest e548f1a579cf 19 months ago 109MB
运行结果
[root@server1 distroless]# docker run -d --name nginx nginx:v5
3e121b37c6f674c7c81f2412e81ff82c4d32b83305b1062ed0004074df539f8d
[root@server1 distroless]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e121b37c6f6 nginx:v5 "nginx -g 'daemon of…" 8 seconds ago Up 6 seconds 80/tcp, 443/tcp nginx
[root@server1 distroless]#
可以去访问运行的nginx
我们把他映射到80端口上,用浏览器来访问