本文章从广度上讲解 Docker 使用的基本流程。
容器化时代的由来

Docker Engine
Docker Engine 位于物理机与APP之间,为上层 APP 提供下层物理机的可用资源(内存、CPU等等)

Docker Engine 是 C/S 架构,用 REST API 进行通讯,可以将客户端和服务端方便地分离在不同的主机上。

容器和镜像
镜像是提供了运行程序完整的软硬件资源的集装箱。(可类比于一个系统镜像)
容器是由镜像生成的可运行的实例。容器之间彼此隔离。(可类比于由系统镜像安装好的一个系统)
Docker 的执行流程

常用命令
-
docker pull <image><:tags>
从过程仓库拉取镜像(hub.docker.com) -
docker images
查看本地下载的镜像 -
docker run <image><:tags>
由镜像创建容器 -
docker ps
查看正在运行的容器 -
docker rm <-f> <container_id>
删除容器 -
docker rmi <-f> <image_id
删除镜像 docker exec -it <image_id> <command>
docker run
必用参数:
-
-p <local_port>:<image_port>
端口映射 -
-d
,即--detach
,Run container in background and print container ID -
--name <container_name>
,指定容器名
默认 docker 的文件目录在 /var/lib/docker
中,有存储镜像、容器等等。
docker 的生命周期
生命状态有: created (==stopped), running(/Up), stopped(/Exited), deleted, paused
控制命令(docker <command>)有: create, run, start, rm, kill, stop, restart, pause, unpause
Dockerfile 镜像的描述文件
Dockerfile 是一个命令文本,Docker 通过读取 Dockerfile 的指令按步自动创建镜像。
创建镜像命令:
docker build -t 机构/镜像名<:tag> <dockerfile>
Dockerfile 命令
- FROM:使用的基础镜像。(FROM scratch 不使用任何镜像);
- MAINTAINER:说明性信息,拥有者;
- LABEL:说明信息,如 version=1.0;
- WORKDIR:切换 工作目录;
- COPY:复制本地文件到镜像;src 是本目录的相对路径,dst 是 workdir 的相对路径或绝对路径;(这里说在“文件”包含目录)
- ADD:复制本地文件或网络文件到镜像,对压缩包还可自动解压;
- ENV <ENV_NAME> <ENV_VAL>:设置环境常量;
- RUN:在 build 时 执行命令;
- ENTRYPOINT:在容器 启动时 执行命令。(多个时只最后一个有效);
- CMD:在容器 启动时(/后) 执行的 默认 命令 或参数。(当启动时加了命令后默认命令会被覆盖);
RUN、ENTRYPOINT、CMD 详解:
- 注意区分三种命令的不同点:
-
RUN
构建时执行,每一条都会执行; -
ENTRYPOINT
启动时执行,多条时仅最后一个有效,且一定会执行; -
CMD
启动时(/后)执行,同样多条时仅最后一条会执行,可以只传入参数,作为 ENTRYPOINT 的参数
-
- 只传入参数时,是与 ENTRYPOINT 合并 起来的命令。如
ENTRYPOINT
传ps
,CMD
传-ef
,相当于ps -ef
命令,此特性给 run 容器时提供了一些灵活性 -
docker run
命令提供的运行命令参数 会覆盖CMD,但不会覆盖ENTRYPOINT; - 它们都有两种书写格式(推荐 Exec 格式):
- Shell 命令格式:
RUN yum install -y vim
。会创建一个子 shell 执行,结束后退出。 - Exec 命令格式:
RUN ["yum", "install", "-y", "vim"]
。会替换当前进程,且保持 PID 不变。
- Shell 命令格式:
镜像分层
在 build Dockerfile 时,是每一行生成一个镜像。这就是镜像分层。可以修改 Dockerfile 的后几个命令查看 build 执行时的输出会有 Using cache
提示,即使用了缓存的镜像。
实例:自制 redis docker 镜像
- 下载一个 redis 包(当前下载文件名为 redis-5.0.5.tar.gz 下载链接),放到某工程目录下
- 在此目录下创建一个
redis-7000.conf
文件,用于启动 redis 的配置文件(可以只写一句port 7000
指定端口号)
- 在此目录下创建一个
- 在此目录下创建 Dockerfile 文件,内容如下。(redis 包是源代码,gcc 是编译工具,net-tools 是网络工具包,make 是安装程序的必备组件)
FROM ubuntu
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "gcc", "net-tools", "make"]
WORKDIR /usr/local
ADD redis-5.0.5.tar.gz .
WORKDIR /usr/local/redis-5.0.5/src
RUN make && make install
WORKDIR /usr/local/redis-5.0.5
ADD redis-7000.conf .
EXPOSE 7000
CMD ["redis-server", "redis-7000.conf"]
- 成功执行构建之后,可以用
docker images
查看结果。
- 成功执行构建之后,可以用
- 还可以运行出容器,并进入进行操作
docker run -p 8003:7000 -d <image_id>
,docker exec -it <container_id> bash
- 还可以运行出容器,并进入进行操作
容器间的单向访问:Link 参数
容器启动会自动创建 IP 地址,同一个机器上不同的容器可以用 IP 进行互联。但 IP 是容器创建时自动生成的,不能用于实际业务。
容器间创建时用 link 参数指定到关联的容器名上,即可进行单向的访问。
docker run -d --name <name> --link <other_container_name> <image_name>
容器的双向通信:Bridge 网桥
网桥是 docker 环境与物理网卡通信的桥梁(是在什么时候创建的,是不是第一个 docker 启动的时候?),各容器内部访问外网也需要通过它。

docker 可以将容器从网络层面上进行分组:docker network
-
docker network ls
:查看当前宿主机上的 docker 网络列表 -
docker network create -d bridge <new_bridge_name>
:创建一个网桥 -
docker network connect <bridge_name> <container_name>
:连接网桥和容器。
网桥的实现原理
当创建一个网桥时, docker 会在宿主机上创建一个 虚拟网卡,充当网关的作用实现内部的互联外部的隔离。

容器间数据共享
原理:容器与宿主机共享一块文件空间(Volume,或者说文件夹),这样可以多个容器同时共享一块空间。

方法一:运行容器时挂载共享目录
docker run --name <container_name> -v <host/shared/dir>:</container/dir <image_name>
方法二:先创建一个共享宿主机目录的容器,运行其他容器时引用这个容器上的共享目录。(/bin/true
只是一个占位符)
docker create --name <new_shared_container_name> -v <host_dir>:<container_dir> <image> /bin/true
docker run --volumes-from <shared_container_name> --name <container_name> -d <image>
方法二让我们修改容器目录更加得简单,可以统一管理共享目录一致的容器,只需要改 <shared_container_name>
的共享目录就可以应用到其他容器上
容器编排工具 Docker Composer
容器编排:一次性部署多个容器,且保持容器间的依赖关系与部署流程的依赖关系。
特点:单机内多容器部署;通过 .yml
或 .yaml
定义如何部署。
多机容器编排时,可以用 docker-swarm 或 kubenetes。
实例:用 Docker Compose 部署 WordExpress
Docker Compose 实战
去 hub.docker.com/ 中找可用的镜像资源。
略
-
docker-compose up -d
: 后台启动,先编译镜像,再创建容器; -
docker-compose logs
: 查看启动日志,后面再加上服务名可只看对应容器的日志; -
docker-compose down
:将容器停止并移除。
网友评论