Docker 基础-镜像&容器&网络&存储

掘金小册 - 开发者必备的 Docker 指南

Docker 基础-镜像&容器&网络&存储

知识脉络

  1. 安装 Docker
  2. 镜像&容器
  3. 网络
  4. 存储
  5. Dockerfile
  6. docker compose
  7. docker hub

1. 安装 Docker

官网安装教程:https://docs.docker.com/install/

2. 镜像&容器

2.1 概念

镜像: 我们可以理解为 包含应用程序以及其相关依赖的一个基础文件系统. 从另一个角度看, Docker 镜像其实是由基于 UnionFS 文件系统的一组镜像层依次挂载而得,而每个镜像层包含的其实是对上一镜像层的修改,这些修改其实是发生在容器运行的过程中的.

容器: 容器是基于 镜像 创建出来的。 可以将镜像理解为 类, 将容器理解为 类的实例.

2.2 容器的生命周期

CreatedRunningPausedStoppedDeleted

  • Created: 容器已经被创建,容器所需的相关资源已经准备就绪, 但容器中的程序还未处于运行状态.
  • Running: 容器正在运行, 也就是容器中的应用正在运行.
  • Paused: 容器已暂停, 表示容器中的所有程序都处于暂停 ( 不是停止 ) 状态.
  • Stopped: 容器处于停止状态, 占用的资源和沙盒环境都依然存在, 只是容器中的应用程序均已停止.
  • Deleted: 容器已删除, 相关占用的资源及存储在 Docker 中的管理信息也都已释放和移除.

2.3 容器与容器的主进程

容器的启动, 本质上可以理解为这个进程的启动, 而容器的停止也就意味着这个进程的停止, 反过来理解亦然.

2.4 写时复制机制

通过镜像运行容器时, 并不是马上就把镜像里的所有内容拷贝到容器所运行的沙盒文件系统中, 而是利用 UnionFS 将镜像以只读的方式挂载到沙盒文件系统中. 只有在容器中发生对文件的修改时, 修改才会体现到沙盒环境上.

2.5 相关命令

命令 解释 参数解释
docker pull 拉取镜像 -
docker images 查看系统内的镜像 -
docker inspect IMAGE_NAME 查看镜像的详细信息 -
docker rmi IMAGE_NAME/IMAGE_ID ... 删除镜像 -
docker create --name CUSTOM_IMAGE_NAME IMAGE_NAME:TAG 创建容器 --name: 指定容器名称
docker start IMAGE_NAME/IMAGE_ID 启动容器 -
docker restart IMAGE_NAME/IMAGE_ID 重启容器 -
docker run --name CUSTOM_IMAGE_NAME -d / --detach IMAGE_NAME:TAG 创建并启动容器 -d / --detach: 容器后台运行
docker stop IMAGE_NAME/IMAGE_ID 停止容器 -
docker rm [-f / --force] [-v] IMAGE_NAME/IMAGE_ID 删除容器 -f / --force: 强制删除容器, -v: 删除数据卷
docker ps [-a / --all] 查看正在运行的容器 加上 -a / --all 是查看所有容器
docker exec -it IMAGE_NAME/IMAGE_ID bash 进入容器 -i (--interactive)表示保持我们的输入流, -t ( --tty ) 表示启用一个伪终端
参数 解释
--name 指定容器名称
--network 指定网络
-p \:\:\ 端口映射
-d / --detach -d / --detach: 容器后台运行
-it -i (--interactive)表示保持我们的输入流, -t ( --tty ) 表示启用一个伪终端
--rm 容器停止后就自动删除

例子:

docker run --name NGINX --network bridge -p 80:80 -d nginx:1.12
docker run -it --name NGINX --network bridge -p 80:80 nginx:1.12 bash
docker exec -it NGINX  bash

3. 网络

3.1 概念

在 Docker 网络中,有三个比较核心的概念:沙盒 ( Sandbox )网络 ( Network )端点 ( Endpoint )

  • 沙盒 提供了容器的虚拟网络栈, 也就是之前所提到的端口套接字、IP 路由表、防火墙等的内容. 其实现隔离了容器网络与宿主机网络,形成了完全独立的容器网络环境.
  • 网络 可以理解为 Docker 内部的虚拟子网, 网络内的参与者相互可见并能够进行通讯. Docker 的这种虚拟网络也是于宿主机网络存在隔离关系的, 其目的主要是形成容器间的安全通讯环境.
  • 端点 是位于容器或网络隔离墙之上的洞, 其主要目的是形成一个可以控制的突破封闭的网络环境的出入口. 当容器的端点与网络的端点形成配对后, 就如同在这两者之间搭建了桥梁, 便能够进行数据传输了.

目前 Docker 官方为我们提供了五种 Docker 网络驱动,分别是:Bridge DriverHost DriverOverlay DriverMacLan DriverNone Driver
其中, Bridge 网络是 Docker 容器的默认网络驱动, 简而言之其就是通过网桥来实现网络通讯 (网桥网络的实现可以基于硬件, 也可以基于软件 ). 而 Overlay 网络是借助 Docker 集群模块 Docker Swarm 来搭建的跨 Docker Daemon 网络, 我们可以通过它搭建跨物理主机的虚拟网络, 进而让不同物理机中运行的容器感知不到多个物理机的存在.

3.2 容器互联

要让一个容器连接到另外一个容器, 我们可以在容器通过 docker create 或 docker run 创建时通过 --link 选项进行配置.

$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
$ sudo docker run -d --name webapp --link mysql webapp:latest

这样在 webapp 中连接 mysql 时就可以: String url = "jdbc:mysql://mysql:3306/webapp";, 或者我们可以在 --link 时定义别名, 使用 --link <name>:<alias> 的形式:

$ sudo docker run -d --name webapp --link mysql:database webapp:latest

这样在 webapp 中连接 mysql 时就可以: String url = "jdbc:mysql://database:3306/webapp";

3.3 暴露端口

在容器创建时端口暴露的方法是借助 --expose 这个选项

$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7

3.4 管理网络

容器能够互相连接的前提是两者同处于一个网络中 ( 这里的网络是指容器网络模型中的网络 )

当我们启动 Docker 服务时,它会为我们创建一个默认的 bridge 网络,而我们创建的容器在不专门指定网络的情况下都会连接到这个网络上

命令 解释 参数解释
docker network create -d bridge NETWORK_NAME 创建网络 -d: 指定网络驱动
docker network ls / list 查看已存在的网络 -
docker network rm NETWORK_NAME 删除网络 -

4. 存储

我们直接在 容器 内做的修改(也就是对 沙盒文件系统 做出的修改)是无法持久化保存的, 如果 Docker 容器删除了, 你的修改也就没了. 所以我们不要在容器内做修改. 我们只需要将宿主操作系统中, 文件系统里的文件或目录挂载到容器中, 便能够让容器内外共享这个文件.

Docker 提供了三种适用于不同场景的文件系统挂载方式:Bind MountVolume和 Tmpfs Mount

  • Bind Mount 能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中, 通过指定容器外的路径和容器内的路径, 就可以形成挂载映射关系, 在容器内外对文件的读写, 都是相互可见的.

  • Volume 也是从宿主操作系统中挂载目录到容器内, 只不过这个挂载的目录由 Docker 进行管理, 我们只需要指定容器内的目录, 不需要关心具体挂载到了宿主操作系统中的哪里.

  • Tmpfs Mount 支持挂载系统内存中的一部分到容器的文件系统里, 不过由于内存和容器的特征, 它的存储并不是持久的, 其中的内容会随着容器的停止而消失.

4.1 挂载文件到容器

使用 -v 或 --volume 来挂载宿主操作系统目录的形式是 -v <host-path>:<container-path> 或 --volume <host-path>:<container-path>, 其中 host-path 和 container-path 分别代表宿主操作系统中的目录和容器中的目录. 为了避免混淆, Docker 这里强制定义目录时必须使用绝对路径, 不能使用相对路径.

sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12

4.2 只读挂载

:ro

sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12

4.3 挂载临时文件目录

Tmpfs Mount 是一种特殊的挂载方式, 它主要利用内存来存储数据. 由于内存不是持久性存储设备, 所以其带给 Tmpfs Mount 的特征就是临时性挂载. 挂载临时文件目录要通过 --tmpf 这个选项来完成.

sudo docker run -d --name webapp --tmpfs /webapp/cache webapp:latest

4.4 使用数据卷

使用 -v 或  --volume 选项来定义数据卷的挂载.

sudo docker run -d --name webapp -v /webapp/storage webapp:latest

使用 -v <name>:<container-path> 来命名数据卷

sudo docker run -d --name webapp -v appdata:/webapp/storage webapp:latest

由于 -v 选项既承载了 Bind Mount 的定义, 又参与了 Volume 的定义, 所以其传参方式需要特别留意. 前面提到了, -v 在定义绑定挂载时必须使用绝对路径, 其目的主要是为了避免与数据卷挂载中命名这种形式的冲突.

4.5 数据卷命令

命令 解释
docker volume ls 列出数据卷
docker volume create VOLUME_NAME 创建数据卷
docker volume rm VOLUME_NAME 删除数据卷

4.6 数据卷容器

sudo docker create --name appdata -v /webapp/storage ubuntu

# 引用数据卷容器 --volumes-from
sudo docker run -d --name webapp --volumes-from appdata webapp:latest

4.7 备份和迁移数据卷

# 提前在宿主机器上 新建 /backup 文件夹
sudo docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage

5. docker commit

修改容器, 保存修改为新的镜像

启动一个 nginx 容器, 修改, 比如 安装 vim, 退出.
docker commit -a 'o9' -m 'add vim' nginx:1.12 o9-nginx:1.12

6. docker hub

https://hub.docker.com/

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!