Docker 实践

使用 Dockerfile 构建镜像

在本地创建一个 hello-app 目录,作为项目文件夹:

在该目录下创建 Python 脚本 hello.py

为了构建一个 Docker 镜像,可在该目录下创建 Dockerfile 文件:

FROM python:3
COPY . /app
CMD python /app/hello.py
  • FROM python:3 表示基于 python:3 镜像创建新的镜像。

  • COPY . /app 表示将 build context(当前目录)中的文件添加到镜像的 /app 目录中。

  • CMD python3 /app/hello.py 表示在镜像中运行 python /app/hello.py(运行 Python 脚本)。

有了 Dockerfile,就可以通过 docker build 命令构建镜像了。在默认情况下,当前目录将作为构建上下文(build context),发往 Docker daemon,用于镜像的构建。

不妨将镜像命名为 hello-python,并打上 v1 标签:

使用 docker images 命令就能找到 hello-python 镜像:

通过 docker history 命令即可查看 hello-python:v1 镜像的构建历史,也就是 Dockerfile (包括 python:3 镜像的 Dockerfile)的执行过程:

运行容器的命令是 docker run

由于之前在 Dockerfile 中添加了 CMD 指令,所以 python /app/hello.py 命令会在容器后自动执行,输出 Hello World。另一种指定容器启动时所执行的命令的方法是直接在 docker run 命令中编写(这种方法会覆盖 Dockerfile 中的 CMD 指令):

容器之间的网络连接

Docker 支持用户自定义桥接网络,与 Docker 默认的桥接网络相比,自定义的网络自带 DNS:使用自定义桥接网络,容器间可通过容器名访问;而如果使用默认的桥接网络,则容器间只能通过 IP 访问。

为了对网络连接进行测试,首先构造一个支持 ifconfigping 命令的 Ubuntu 容器:

$ docker run --name unet -it --rm ubuntu bash
root@d79ef0a1715a:/# apt-get update
root@d79ef0a1715a:/# apt-get install -y net-tools
root@d79ef0a1715a:/# apt-get install -y iputils-ping

(省略了输出信息)

启动另一个窗口,在 unet 的基础上使用 docker commit 指令创建新的镜像 ubuntu:net

创建一个新的桥接网络 mynet

分别在两个窗口中基于 ubuntu:net 镜像创建容器 u1u2,并指定连接的网络为 mynet

docker run --name u1 -it --net mynet --rm ubuntu:net bash
docker run --name u2 -it --net mynet --rm ubuntu:net bash

在容器 u1 中 ping 容器 u2,能够 ping 通:

在容器 u2 中 ping 容器 u1,同样能够 ping 通:

让容器 u1u2 与默认桥接网络相连,并断开与 mynet 的连接:

再次尝试在容器 u1 中通过容器名 ping 容器 u2,发现无法连接:

在容器 u2 中也无法通过容器名 ping 容器 u1

说明默认桥接网络中无法通过容器名进行网络访问。

Updated: