Docker 是流行的开源应用容器引擎,本文介绍 docker 的概念以及何如使用。
Docker 镜像
Docker 镜像类似于虚拟机的镜像,可以将它理解为一个只读的模板。
镜像管理
镜像由【镜像名+Tag】指定,Tag 通常用版本来表示,例如 ubuntu:14.04。 如果 Tag 不指定,就默认使用 latest 标签,表示最新版本的镜像。
获取镜像
1 | # 这个命令将从 Docker Hub 下载指定的镜像 |
查看镜像信息
1 | # 列出本地主机上已有镜像的基本信息,其中的 IMAGE ID 唯一标识了镜像 |
给镜像添加标签
1 | # 创建一个镜像 ${NEW_IMAGE_NAME}[:${NEW_TAG}],新镜像实际上指向旧的镜像 |
查看镜像/容器的详细信息
1 | docker inspect ${IMAGE_NAME}[:${TAG}] |
查看镜像的历史
1 | docker history ${IMAGE_NAME}[:${TAG}] |
搜索镜像
1 | # 在远端仓库搜索指定的镜像 |
删除镜像
1 | docker rmi ${IMAGE_NAME}[:${TAG}] |
注:如果有该镜像创建的容器时,镜像文件默认无法删除,除非用 -f 强制删除
导入 & 导出镜像
1 | # 将镜像导出到文件 |
上传镜像
1 | docker push ${USER_NAME}/${IMAGE_NAME}[:${TAG}] |
镜像制作
镜像制作有 3 种方式:基于已有镜像的容器创建;基于本地模板导入;基于 Dockerfile 创建
基于已有镜像的容器创建
1 | # 根据容器 CONTAINER_ID 创建一个镜像 |
基于本地模板导入
1 | # 从文件、URL 或标准输入读取信息并创建一个镜像 |
1 | # 将容器导出到文件 |
使用 Dockerfile 创建
Docker 容器
Docker 容器类似于一个轻量级的沙箱,用来运行和隔离应用。容器是从镜像创建的应用运行实例,可以将其启动,开始,停止,删除,而容器彼此间是相互隔离的。
容器管理
容器的创建与启动
1 | # 根据指定的镜像创建一个容器,容器处于停止状态 |
1 | # 启动一个容器 |
1 | # 等价于 start 与 run 的组合,创建并启动一个容器 |
用 run 创建容器时, docker 在后台运行这些操作
- 检查宿主是否有指定的镜像,没有就从仓库下载
- 利用镜像创建容器,并启动
- 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中
- 从网桥的地址池配置一个 IP 地址给容器
- 执行用户指定的应用程序(run 命令指定的应用程序)
与容器交互
run 命令中
-i 选项可以保持标准输入打开
-t 选项可以分配一个伪终端(-it 一般一起使用)
-d 选项使容器在后台运行
–name=”” 指定容器别名,方便引用
1 | # 查看容器中标准输出所输出的信息 |
1 | # 进入容器 |
1 | # 在容器中执行命令,可以执行 /bin/bash 来进入容器并进行操作 |
容器网络设定
通过 p 参数可以设定网卡和端口映射,可以用 -P 随机映射端口
1 | docker run -d -p 8080:8080 ${IMAGE} |
通过 name 参数可以设定容器的名字,之后可以通过 link 参数让容器连接
1 |
|
使用 link 后,Docker 相当于在两个互联的容器之间创建了一个虚拟通道,这样 db 就不用映射它的端口到宿主。在 web 容器中,会有环境变量带入 db 中相关的变量,例如端口,协议。同时 web 容器的 /etc/host 会有 db 的 IP。
存储
docker 中数据有两种方式管理
- 数据卷: 容器内数据映射到宿主环境
- 数据卷容器: 使用特定的容器维护数据卷
数据卷
数据卷是一个可以供容器使用的特殊目录,将宿主的目录直接映射进容器,类似于 linux 中的 mount。数据卷和镜像是
解耦的,数据的更新不会影响到镜像(例如 commit 不包含数据)
使用 run 命令的 -v 选项可以创建一个或多个数据卷,也可以映射到宿主的目录
1 | # 创建一个数据卷并挂载到容器的 CONTAINER_DIR 目录 |
1 | # 加载宿主的目录到容器的指定目录 |
数据卷容器
数据卷容器也是容器,它的作用就是专门用来存放数据(注:数据卷容器的使用时,并不需要在运行状态)
首先,创建一个带有数据卷的容器
1 | docker run -it -v ${CONTAINER_DIR} --name dbdata ${IMAGE} |
然后可以在其他容器中挂载 dbdata 容器中的数据卷
1 | # 容器 db1, db2 都使用了同一个数据卷, 3 个容器任何一方在该目录写入的数据 |