Docker 镜像构建
Docker 的镜像构建算是 Docker 的一个重点,因为应用的交付就是通过镜像方式。
构建 Docker 镜像有 2 种方式:
- 手动构建
- Dockerfile
前面进行测试,运行了很多容器,下面我们将这些容器全部删除(此命令生产环境上慎用)
[root@linux-node1 ~]# docker kill $(docker ps -a -q)
ed81da17ee16
868a9e6b7aa0
9e061b675f1a
30fd50542bb5
420066be5a1d
7236cf1a985a
Failed to kill container (fa89f37d06f0): Error response from daemon: Cannot kill container fa89f37d06f0: Container fa89f37d06f01039025db83acd5af67ff90dd8c474d78872b4bf10ab3f354311 is not running
# 这个容器并没有运行,所以 docker kill 会报错
[root@linux-node1 ~]# docker rm $(docker ps -a -q)
ed81da17ee16
868a9e6b7aa0
9e061b675f1a
30fd50542bb5
420066be5a1d
7236cf1a985a
fa89f37d06f0
[root@linux-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
手动构建镜像
实质是运行一个容器后,进行相关处理,然后使用docker commit
创建一个镜像。
下面演示手动构建一个基于 centos 镜像的 nginx 镜像。
# 运行一个 centos 容器
[root@linux-node1 ~]# docker run --name mynginx -it centos
# 安装阿里的 EPEL 源
[root@a8ce8388eb81 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
Retrieving http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
warning: /var/tmp/rpm-tmp.joxzhq: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
Preparing... ################################# [100%]
Updating / installing...
1:epel-release-7-8 ################################# [100%]
# 安装 nginx
[root@a8ce8388eb81 /]# yum install nginx -y
...省略...
# 清除 yum 安装的缓存
[root@a8ce8388eb81 /]# yum clean all
Loaded plugins: fastestmirror, ovl
Cleaning repos: base epel extras updates
Cleaning up everything
Cleaning up list of fastest mirrors
# 配置 nginx 前台运行
[root@a8ce8388eb81 /]# vi /etc/nginx/nginx.conf
deamon off; # 增加这一行配置
user nginx;
[root@a8ce8388eb81 /]# exit
# 使用 docker commit 创建镜像
[root@linux-node1 ~]# docker commit -m "My Nginx" mynginx jaminzhang/mynginx:v1
sha256:370e352e4ed5c7edb4b34f06c9f3713112381fb618046e9d19310bfb11ca4da4
# 此处是本地提交,类似 git commit
# 使用 docker images 查看刚创建的 nginx 镜像
[root@linux-node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jaminzhang/mynginx v1 370e352e4ed5 20 seconds ago 261.9 MB
docker.io/nginx latest 4a88d06e26f4 3 days ago 183.5 MB
docker.io/centos latest 980e0e4c79ec 12 days ago 196.7 MB
# 以刚才创建的 nginx 镜像运行一个容器
[root@linux-node1 ~]# docker run --name mynginxv1 -d -p 80:80 jaminzhang/mynginx:v1 nginx
90714195490bf750007eb2a583679f03b94762c382276973b06c60f3f3c49368
[root@linux-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90714195490b jaminzhang/mynginx:v1 "nginx" 22 seconds ago Up 20 seconds 0.0.0.0:80->80/tcp mynginxv1
# 然后通过浏览器测试访问
# 使用 docker logs mynginxv1 查看容器日志
[root@linux-node1 ~]# docker logs -f mynginxv1
# 访问时并没有在上面看到日志,因为默认 nginx 访问日志是配置在 /var/log/nginx/access.log 了,我们可以查看下
[root@linux-node1 ~]#./docker_in.sh mynginxv1
[root@90714195490b /]# tail -5 /var/log/nginx/access.log
192.168.56.1 - - [19/Sep/2016:11:53:48 +0000] "GET /nginx-logo.png HTTP/1.1" 304 0 "http://192.168.56.11/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" "-"
192.168.56.1 - - [19/Sep/2016:11:53:48 +0000] "GET /poweredby.png HTTP/1.1" 304 0 "http://192.168.56.11/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" "-"
192.168.56.1 - - [19/Sep/2016:11:53:54 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" "-"
192.168.56.1 - - [19/Sep/2016:11:53:54 +0000] "GET /nginx-logo.png HTTP/1.1" 304 0 "http://192.168.56.11/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" "-"
192.168.56.1 - - [19/Sep/2016:11:53:54 +0000] "GET /poweredby.png HTTP/1.1" 304 0 "http://192.168.56.11/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36" "-"
通过 Dockerfile 构建镜像
下面演示将上面手动构建镜像过程改写成基于 Dockerfile 构建。
# 创建镜像构建准备目录
[root@linux-node1 ~]# mkdir /opt/dockerfile
[root@linux-node1 ~]# cd /opt/dockerfile
[root@linux-node1 dockerfile]# mkdir nginx
[root@linux-node1 dockerfile]# cd nginx
# 编写 Dockerfile
[root@linux-node1 nginx]# vim Dockerfile
# This Dockfile is used for nginx based on centos
# Base image
FROM centos
# Maintainer
MAINTAINER Jamin Zhang zhangjamin@163.com
# Commands
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install nginx -y && yum clean all
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
ADD index1.html /usr/share/nginx/html/index1.html
EXPOSE 80
CMD ["nginx"]
# 以上还使用了 ADD 添加本地文件到镜像中,如果是压缩文件,ADD 还可以做解压缩操作。
# 准备一个 index1.html 测试文件
[root@linux-node1 nginx]# echo "nginx in Docker." >> index1.html
# 以上 Dockerfile 详细说明在之后 Ref 中的文章有详细介绍,我这里就不再解释了。
# 这里暂时使用几个简单指令,就将上面手动构建镜像过程改写成了 Dockerfile。
# 使用 docker build 从 Dockerfile 构建镜像
[root@linux-node1 nginx]# docker build -t jaminzhang/mynginx:v2 .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos
---> 980e0e4c79ec
Step 2 : MAINTAINER Jamin Zhang zhangjamin@163.com
---> Running in 6087f6aeff98
---> 6a7aa317f098
Removing intermediate container 6087f6aeff98
Step 3 : RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
---> Running in 31955f1e721d
warning: /var/tmp/rpm-tmp.7M1zBQ: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
Retrieving http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
Preparing... ########################################
Updating / installing...
epel-release-7-8 ########################################
---> f563b84895a3
Removing intermediate container 31955f1e721d
Step 4 : RUN yum install nginx -y && yum clean all
---> Running in f06a0bf09545
Loaded plugins: fastestmirror, ovl
... 省略 ...
Complete!
Loaded plugins: fastestmirror, ovl
Cleaning repos: base epel extras updates
Cleaning up everything
Cleaning up list of fastest mirrors
---> 23bfc72bd0c2
Removing intermediate container f06a0bf09545
Step 5 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
---> Running in 6cc9395e7c7d
---> dd32cc906587
Removing intermediate container 6cc9395e7c7d
Step 6 : ADD index1.html /usr/share/nginx/html/index1.html
---> c0b601df1ff1
Removing intermediate container 4545930b1402
Step 7 : EXPOSE 80
---> Running in bf5569b609b4
---> d180626f3b15
Removing intermediate container bf5569b609b4
Step 8 : CMD nginx
---> Running in 660a9016ec6f
---> 41ae8a732748
Removing intermediate container 660a9016ec6f
Successfully built 41ae8a732748
# 以上构建镜像完成,我们查看下
[root@linux-node1 nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jaminzhang/mynginx v2 41ae8a732748 2 minutes ago 278.9 MB
jaminzhang/mynginx v1 370e352e4ed5 20 hours ago 261.9 MB
docker.io/nginx latest 4a88d06e26f4 4 days ago 183.5 MB
docker.io/centos latest 980e0e4c79ec 13 days ago 196.7 MB
# 从刚才创建的镜像运行容器并访问测试
[root@linux-node1 nginx]# docker run --name mynginxv2 -d -p 81:80 mynginx:v2
93045710a0314528af9b01468c1dd9742bb20f0020d7fc1f82d10c3196e8292f
[root@linux-node1 nginx]# docker port mynginxv2
80/tcp -> 0.0.0.0:81
[root@linux-node1 nginx]# curl "http://192.168.56.11:81/index1.html"
nginx in Docker.