Docker|Docker 实战教程之从入门到提高(三)

本系列的前两篇文章,我们已经学习了 Docker 的安装步骤,通过实际的例子,学习了Docker 和宿主机操作系统文件目录互相隔离的实现原理,以及 Docker Volume 的工作原理:

  • Docker 实战教程之从入门到提高 (一)
  • Docker 实战教程之从入门到提高 (二)
本文继续通过实战来学习如何编辑 Docker 镜像以及如何使用 Dockerfile 自制镜像。
  • 练习1:Docker 镜像提交命令 commit 的工作原理和使用方法
在本地创建一个容器后,可以依据这个容器创建本地镜像,并可把这个镜像推送到 Docker hub 中,以便在网络上下载使用。
下面我们来动手实践。
docker pull nginx:1.15.3
Docker|Docker 实战教程之从入门到提高(三)
文章图片

用命令行启动一个容器:
docker run -d -p 1080:80 --name jerry-nginx nginx:1.15.3
Docker|Docker 实战教程之从入门到提高(三)
文章图片

访问 url localhost:1080,能看到 Nginx 的默认首页:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

进入容器的 shell:
docker exec -it jerry-nginx /bin/bash
查看这个 nginx 镜像默认的首页:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

我想在容器里使用 wget,所以先安装:
apt-get update && apt-get -y install wget
Docker|Docker 实战教程之从入门到提高(三)
文章图片

【Docker|Docker 实战教程之从入门到提高(三)】使用 wget 命令下载一个图片文件和一个 html 文件到 Nginx 服务器存放网页的位置:
wget --no-check-certificate -O /usr/share/nginx/html/evil.jpg https://github.com/raw/slvi/docker-k8s-training/master/docker/res/evil.jpg wget --no-check-certificate -O /usr/share/nginx/html/index.html https://github.com/raw/slvi/docker-k8s-training/master/docker/res/evil.html

重新刷新页面,我们现在看到的页面已经变成了 wget 下载下来的页面:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

我们现在希望把这个容器里发现的修改固化下来,以便其他人可以使用。
docker commit jerry-nginx jerry-modify-nginx:1.0
Docker|Docker 实战教程之从入门到提高(三)
文章图片

sha256:7e243a7b4c0796e3a787fe963224fdf1fe81d9fe9b283f6f3e4f17e1defa0c96
使用命令将 1.0 设置成 latest tag:
docker tag jerry-modify-nginx:1.0 jerry-modify-nginx:latest
docker stop jerry-nginx 把旧的容器停掉,再启动修改后的容器 jerry-modify-nginx:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

docker history 命名查看这个新镜像的历史:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

执行命令给这个新的镜像打上标签:
docker tag jerry-modify-nginx:latest registry.ingress.shcw46.k8s-train.k8s-hana.ondemand.com/jerry-modify-nginx:760d7ca6
把打上标签的镜像 push 到远端:
docker push registry.ingress.shcw46.k8s-train.k8s-hana.ondemand.com/jerry-modify-nginx:760d7ca6
Docker|Docker 实战教程之从入门到提高(三)
文章图片

这样网络上的其他开发人员就可以使用这个修改了 Nginx 首页的 Docker 镜像了。
  • 练习2:创建一个支持 SSL 的 Nginx 镜像
什么是 dockerfile?简单的说就是一个文本格式的脚本文件,其内包含了一条条的指令(Instruction),每一条指令负责描述镜像的当前层(Layer)如何构建。
下面通过一个具体的例子来学习 dockerfile 的写法。
新建一个 dbuild 文件夹,创建一个自定义的 Nginx 首页,逻辑很简单,显示一个自定义的图片文件 train.jpg.
Docker|Docker 实战教程之从入门到提高(三)
文章图片

我想基于标准的 Nginx 镜像做一些修改,让 Nginx 支持 SSL。SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS) 是为网络通信提供安全及数据完整性的一种安全协议。
TLS 与 SSL 在传输层对网络连接进行加密。
为此我首先需要创建一个针对 SSL 的配置文件。
Docker|Docker 实战教程之从入门到提高(三)
文章图片

cat << '__EOF' > ssl.conf server { listen443 ssl; server_namelocalhost; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; location / { root/usr/share/nginx/html; indexindex.html index.htm; } } __EOF

使用如下命令创建 nginx.keynginx.crt 文件:
openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj "/CN=$(hostname)"
Docker|Docker 实战教程之从入门到提高(三)
文章图片

一切就绪之后,下面就应该创建 dockerfile 了:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

FROM nginx:stable# copy the custom website into the image COPY train.jpg /usr/share/nginx/html/ COPY index.html /usr/share/nginx/html/# copy the SSL configuration file into the image COPY ssl.conf /etc/nginx/conf.d/ssl.conf# download the SSL key and certificate into the image COPY nginx.key /etc/nginx/ssl/nginx.key COPY nginx.crt /etc/nginx/ssl/nginx.crt# expose the https port EXPOSE 443

所有 dockerfile 的文件,第一行指令必定是 FROM XXXX.
FROM 的作用是指定基准镜像。该 dockerfile 以 FROM 后面指定的镜像为基础,在其上进行定制。
Docker Store 上有很多高质量的官方镜像,主要分为以下三大类:
  1. 开箱即用的服务类的镜像,比如网络服务器 nginx ,也有数据库服务器诸如 redis 、 mongo 、mysql 等;
  2. 方便开发、构建、运行各种语言应用的镜像,如 node 、openjdk 、python 等。
  3. 相对前两大类更为基础的操作系统镜像,如 ubuntu 、 debian 、 centos 等。
当然您如果不愿意基于这些官方已有镜像开始镜像构建,而是想从头开始,这也是可以的。
Docker 存在一个特殊的镜像,名为 scratch. 它是一个虚拟的概念,表示一个空白的镜像。
直接使用 FROM scratch 会让镜像体积更加小巧。
接下来的一系列 ·copy· 指令都很好理解。
dockerfile 开发完毕之后,执行命令:
docker build -t jerry-nginx:1.0 .
意思是基于当前目录开始构建镜像,注意末尾的 . 必不可少,代表“当前目录”。
通过 docker build 执行输出的日志可以观察到里面每一行的指令被逐行执行:
Docker|Docker 实战教程之从入门到提高(三)
文章图片

最后一行日志提示标签为 jerry-nginx:1.0 的镜像被成功构建。
用下面的命令基于刚刚制作好的镜像运行一个容器:
docker run -d -p 443:443 -p 1082:80 jerry-nginx:1.0
基于 http 协议访问没有问题:
http://localhost:1082
Docker|Docker 实战教程之从入门到提高(三)
文章图片

基于https访问也能正常工作:
https://localhost:443
Docker|Docker 实战教程之从入门到提高(三)
文章图片

至此,这个支持 SSL 的 Nginx 镜像制作成功。
总结 本文通过两个实战练习,分别介绍了如何基于标准的 Nginx 镜像,修改其默认首页,以及制作一个支持 SSL 的 Nginx 镜像的步骤,从实际例子解释了 Dockerfile 的工作原理。
本系列前两篇文章的链接:
  • Docker 实战教程之从入门到提高 (一)
  • Docker 实战教程之从入门到提高 (二)

    推荐阅读