CLOUD SERVING 三月 17, 2021

Docker

文章字数 32k 阅读约需 57 mins. 阅读次数 0

引言

本篇整理了我学习Docker时的一些笔记。
部署环境:Windows 10 Professional Workstation

Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。

Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持, 就连 Google 的 Compute Engine 也支持 docker 在其之上运行。

  • 环境管理复杂 - 从各种OS到各种中间件到各种app, 一款产品能够成功作为开发者需要关心的东西太多,且难于管理,这个问题几乎在所有现代IT相关行业都需要面对。
  • 云计算时代的到来 - AWS的成功, 引导开发者将应用转移到 cloud 上, 解决了硬件管理的问题,然而中间件相关的问题依然存在 (所以openstack HEAT和 AWS cloudformation 都着力解决这个问题)。开发者思路变化提供了可能性。
  • 虚拟化手段的变化 - cloud 时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需使用的需求以及保证可用性和隔离性。然而无论是KVM还是Xen在 docker 看来,都在浪费资源,因为用户需要的是高效运行环境而非OS, GuestOS既浪费资源又难于管理, 更加轻量级的LXC更加灵活和快速。
  • LXC的移动性 - LXC在 linux 2.6 的 kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可迁移性,决定其构建出的环境难于迁移和标准化管理(相对于KVM之类image和snapshot的概念)。docker 就在这个问题上做出实质性的革新。这是docker最独特的地方。

面对上述几个问题,docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段自由组装运行环境,同时集装箱的内容可以由用户自定义,也可以由专业人员制造。这样,交付一个软件,就是一系列标准化组件的集合的交付,如同乐高积木,用户只需要选择合适的积木组合,并且在最顶端署上自己的名字( 最后一个标准化组件是用户的app )。这也就是基于docker的PaaS产品的原型。


Hello World

官方文档


Docker vs VM

优点

  • 配置快 - 提供独立的开发环境,便于开发, 由于 Docker 可以在各种各样的环境中使用,而基础架构不要求与应用程序的环境相关联,因此不存在兼容性问题。

  • 提高工作效率 - 这是一种类似于集装箱的概念,在开发之初就将项目放到一个类似于集装箱的独立环境进行开发,到部署的时候只是部署集装箱环境,而集装箱环境已经被所有的系统指定了统一标准,不存在兼容问题,所以可以提高工作效率。

  • 应用隔离 - Docker 提供用于在隔离环境中运行应用程序的容器。每个容器都是独立,并允许执行任何类型的应用程序,并且不存在入侵和病毒感染的问题,甚至可以使用沙箱进行病毒隔离。

  • 云集 - 它是 Docker 容器的集群和调度工具。 Swarm 使用 Docker API作为其前端,这有助于我们使用各种工具来控制它。 它还可以将 Docker 主机集群控制为一个虚拟主机。 这是一个用于启用可插拔后端的自组织引擎组。

  • 路由网 - 它能够将可用节点上已发布端口的传入请求路由到活动容器,实现连接。

  • 服务 - 服务是允许指定集群内的容器状态的任务列表。 每个任务表示一个应该运行的容器的一个实例,并且 Swarm 在节点之间调度它们。

  • 安全管理 - 安全性和管理应当是一个高优先级的考虑因素;企业用户不应再把它们当作应用程序迁移至容器的最后一步。反之,企业必须从一开始就做好安全性和管理的规划,把它们的功能纳入应用程序的开发过程中,并在应用程序运行过程中积极主动地关注这些方面。

局限

  • Docker 是基于 Linux64 bit的,无法在 32bit 的 Linux/Windows/unix环境下使用。

  • LXC 是基于 cgroup等 linux kernel 功能的,因此container的 guest 系统只能是 linux base 的。

  • 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有 container 公用一部分的运行库。

  • 网络管理相对简单,主要是基于 namespace 隔离,cgroup 的 cpu 和 cpuset 提供的cpu功能相比 KVM 的等虚拟化方案相比难以度量(所以 Dotcloud 主要是按内存收费)。

  • Docker 对 disk 的管理比较有限,container 随着用户进程的停止而销毁,container 中的 log 等用户数据不便收集


Welcome To Docker

PS C:\Users\P7XXTM1-G> docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Docker 帮助命令

docker version

查看 Docker 版本信息。

PS C:\Users\P7XXTM1-G> docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.9
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        55c4c88
 Built:             Tue Mar  2 20:14:53 2021
 OS/Arch:           windows/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       363e9a8
  Built:            Tue Mar  2 20:15:47 2021
  OS/Arch:          linux/amd64
  Experimental:     false
......

docker info

查看 Docker 信息。

PS C:\Users\P7XXTM1-G> docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
  scan: Docker Scan (Docker Inc., v0.5.0)

Server:
 Containers: 2
  Running: 0
  Paused: 0
  Stopped: 2
 Images: 2
 Server Version: 20.10.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 5.4.72-microsoft-standard-WSL2
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 6
 Total Memory: 12.44GiB
 Name: docker-desktop
 ID: LJH4:2VZK:AH4N:WRBD:A27I:KKRD:IWQP:C4ML:D753:TVQD:53ES:YECZ
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://w3z80w3y.mirror.aliyuncs.com/
  https://hub-mirror.c.163.com/
 Live Restore Enabled: false

WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support

docker xx –help

查看 Docker 命令的帮助文档。

例如:docker images --help

PS C:\Users\P7XXTM1-G> docker images --help

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show image IDs

Docker 镜像命令

docker images

查看本机所有 Docker 镜像。

  • -a, –all 列出所有镜像
  • -q, –quite 只显示镜像id

-aq可在后续 删除镜像命令 时配合使用

PS C:\Users\P7XXTM1-G> docker images
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
docker/getting-started   latest    021a1b85e641   3 months ago    27.6MB
hello-world              latest    bf756fb1ae65   14 months ago   13.3kB

docker search 镜像关键词

搜索 Docker 镜像。

PS C:\Users\P7XXTM1-G> docker search ubuntu
NAME                                                      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                                                    Ubuntu is a Debian-based Linux operating sys…   11944     [OK]
dorowu/ubuntu-desktop-lxde-vnc                            Docker image to provide HTML5 VNC interface …   504                  [OK]
......

docker pull 镜像名[:tag]

Docker 镜像库

拉取 Docker 镜像。

PS C:\Users\P7XXTM1-G> docker pull mysql:latest
latest: Pulling from library/mysql # 如果不指定 tag,则默认 latest
a076a628af6f: Pull complete # 分层下载,联合文件系统
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1a8c919e89bf: Pull complete
9f3cf4bd1a07: Pull complete
80539cea118d: Pull complete
201b3cad54ce: Pull complete
944ba37e1c06: Pull complete
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址

docker rmi 镜像

删除 Docker 镜像。

docker rmi -f 容器id # 删除指定镜像
docker rmi -f 容器id 容器id ... # 删除多个镜像
docker rmi -f $(docker images -aq) # 删除所有镜像

Docker 容器命令

docker run [可选参数] image

通过指定镜像,生成指定容器。

搭配 -it 与终端路径可对应进入指定 Linux 容器。

常用可选参数 说明
–name=”Name” 容器名
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p ip:主机端口:容器端口 指定容器端口
-p 主机端口:容器端口(常用) 指定容器端口
-p 容器端口 指定容器端口
-P 指定随机端口
PS C:\Users\P7XXTM1-G> docker run -it ubuntu /bin/bash
root@33339890e94c:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@33339890e94c:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
root@33339890e94c:/#

exit

退出且停止容器

root@33339890e94c:/# exit
exit
PS C:\Users\P7XXTM1-G>

若要退出容器,但不想停止容器,则通过快捷键 Ctrl + P + Q 即可。

root@cd9e271f0792:/#
PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
cd9e271f0792   ubuntu    "/bin/bash"   7 seconds ago   Up 6 seconds             serene_hopper
PS C:\Users\P7XXTM1-G>

docker ps

查看运行的容器。

常用可选参数 说明
-a 列出当前正在运行的容器与历史运行容器
-n=? 显示最近运行的容器,”?” 可指定输出条目,如:-n=1,则输出最近一条记录
-q 只显示容器编号
PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS C:\Users\P7XXTM1-G> docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                          PORTS     NAMES
33339890e94c   ubuntu    "/bin/bash"   5 minutes ago   Exited (0) About a minute ago             inspiring_zhukovsky
PS C:\Users\P7XXTM1-G>

docker rm 容器id

删除容器

docker rm 容器id # 删除指定容器,不能删除正在运行的容器,如果要强制删除则需要通过 rm -f 执行
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -aq|xargs docker rm # 删除所有容器(管道锁)

容器的 启动/重启/停止/强制停止 命令

docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前正在运行的容器

Docker 其他常用命令

docker run -d 镜像名

以后台启动方式启动容器。

此时若后台启动的容器中没有前台应用,则 Docker 会停止该后台容器,则使用 docker ps 命令将不会后台运行容器。

若需要容器在后台保持运行,则必须有一个前台进程。

PS C:\Users\P7XXTM1-G> docker run -d ubuntu
e0f36dc3a166a6dd9c612d26b17e845a8a3a0a2c071f47b8fd9f8cf9ee78082a

docker logs

查看容器日志。

常用可选参数 说明
-f 打印日志
-t 以时间戳字符串输出
–tail 输出日志条数
PS C:\Users\P7XXTM1-G> docker run -d ubuntu /bin/sh -c "while true;do echo hello-from-ubunut;sleep 1;done"
2f090441e6e80fcf526e664973e968fbf8b33d1228ea4a91d38a02d4661edc3a
PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
2f090441e6e8   ubuntu    "/bin/sh -c 'while t…"   4 seconds ago   Up 2 seconds             gallant_elgamal
PS C:\Users\P7XXTM1-G> docker logs -f -t --tail 10 2f090441e6e8
2021-03-18T05:13:02.218287300Z hello-from-ubunut
2021-03-18T05:13:03.219282500Z hello-from-ubunut
2021-03-18T05:13:04.220377900Z hello-from-ubunut
2021-03-18T05:13:05.221435600Z hello-from-ubunut
2021-03-18T05:13:06.223104800Z hello-from-ubunut
2021-03-18T05:13:07.223687300Z hello-from-ubunut
2021-03-18T05:13:08.224903600Z hello-from-ubunut
2021-03-18T05:13:09.225778500Z hello-from-ubunut
2021-03-18T05:13:10.226692700Z hello-from-ubunut
2021-03-18T05:13:11.227667300Z hello-from-ubunut
2021-03-18T05:13:12.228729200Z hello-from-ubunut
2021-03-18T05:13:13.229784400Z hello-from-ubunut
2021-03-18T05:13:14.230961900Z hello-from-ubunut
2021-03-18T05:13:15.232517700Z hello-from-ubunut
2021-03-18T05:13:16.233134900Z hello-from-ubunut
2021-03-18T05:13:17.234228900Z hello-from-ubunut
2021-03-18T05:13:18.235945200Z hello-from-ubunut
2021-03-18T05:13:19.236571400Z hello-from-ubunut
2021-03-18T05:13:20.238078900Z hello-from-ubunut
PS C:\Users\P7XXTM1-G>

docker stats

查看 Docker 资源占用情况。

ubuntu@DESKTOP-5IG459O:~$ docker stats
CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT     MEM %     NET I/O        BLOCK I/O   PIDS
f3a8f8e37903   dreamy_tesla      0.00%     6.809MiB / 12.44GiB   0.05%     516B / 0B      0B / 0B     1
c08739536043   quirky_roentgen   0.00%     2.285MiB / 12.44GiB   0.02%     656B / 0B      0B / 0B     1
9e8cb66f4144   Elasticsearch     0.21%     2.224GiB / 12.44GiB   17.87%    1.8kB / 867B   0B / 0B     48

docker top 容器id

查看容器中的的进程信息。

PS C:\Users\P7XXTM1-G> docker run -d ubuntu /bin/sh -c "while true;do echo hello-from-ubunut;sleep 1;done"
a7e9449469b287e1cfc7c2768fa66c19113135421659568ca4da14b9ac9bcdd3
PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
a7e9449469b2   ubuntu    "/bin/sh -c 'while t…"   8 seconds ago   Up 7 seconds             great_chaum
PS C:\Users\P7XXTM1-G> docker top a7e9449469b2
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                1720                1699                0                   05:59               ?                   00:00:00            /bin/sh -c while true;do echo hello-from-ubunut;sleep 1;done
root                1777                1720                0                   06:00               ?                   00:00:00            sleep 1
PS C:\Users\P7XXTM1-G>

docker inspect 容器id

查看容器信息。

PS C:\Users\P7XXTM1-G> docker run -d ubuntu
1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80
PS C:\Users\P7XXTM1-G> docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                      PORTS     NAMES
1147368a1740   ubuntu    "/bin/bash"   18 seconds ago   Exited (0) 17 seconds ago             naughty_engelbart
PS C:\Users\P7XXTM1-G> docker inspect 1147368a1740
[
    {
        "Id": "1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80",
        "Created": "2021-03-18T06:04:28.0414634Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-03-18T06:04:28.2739845Z",
            "FinishedAt": "2021-03-18T06:04:28.2748083Z"
        },
        "Image": "sha256:4dd97cefde62cf2d6bcfd8f2c0300a24fbcddbe0ebcd577cc8b420c29106869a",
        "ResolvConfPath": "/var/lib/docker/containers/1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80/hostname",
        "HostsPath": "/var/lib/docker/containers/1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80/hosts",
        "LogPath": "/var/lib/docker/containers/1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80/1147368a1740a8a9367f550447faa808bbf8fe3eb43a3fb5d890f88153ee2e80-json.log",
        "Name": "/naughty_engelbart",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,

        ......
    }
]

docker exec -it 容器id 终端地址

进入当前正在运行的容器,开启新终端

常用的终端地址:

  • /bin/bash(常用)
  • /bin/sh
PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
4172c4f6f390   ubuntu    "/bin/bash"   7 seconds ago   Up 5 seconds             eloquent_bohr
PS C:\Users\P7XXTM1-G> docker exec -it 4172c4f6f390 /bin/bash
root@4172c4f6f390:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 06:11 pts/0    00:00:00 /bin/bash
root        10     0  0 06:12 pts/1    00:00:00 /bin/bash
root        19    10  0 06:12 pts/1    00:00:00 ps -ef
root@4172c4f6f390:/#

docker attach 容器id

进入当前正在运行的容器,但不会开启新终端,会继续以前终端的操作

PS C:\Users\P7XXTM1-G> docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS              PORTS     NAMES
4172c4f6f390   ubuntu    "/bin/bash"   About a minute ago   Up About a minute             eloquent_bohr
PS C:\Users\P7XXTM1-G> docker attach 4172c4f6f390
正在运行的终端指令......

docker cp 容器id:/容器目录 本地目录

从容器(无论容器是否运行)中将文件拷贝到外部。

ubuntu@DESKTOP-5IG459O:~$ docker run -it ubuntu /bin/bash
root@0619c363583e:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@0619c363583e:/# cd home/
root@0619c363583e:/home# ls

# 在容器中新建一个测试用的 test.file
root@0619c363583e:/home# touch test.file
root@0619c363583e:/home# ls
test.file
root@0619c363583e:/home# exit
exit

# 查看容器id
ubuntu@DESKTOP-5IG459O:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND           CREATED          STATUS                     PORTS     NAMES
0619c363583e   ubuntu    "/bin/bash"       25 seconds ago   Exited (0) 3 seconds ago             optimistic_cartwright

# 将容器中的文件拷贝到本地(由于我未将 Docker 加入用户组,故在使用 Docker 的部分命令时需使用 sudo 权限)
ubuntu@DESKTOP-5IG459O:~$ sudo docker cp 0619c363583e:/home/test.file /home

# 查看 Docker 容器中的文件是否已拷贝到本地目录下
ubuntu@DESKTOP-5IG459O:~$ ls
ubuntu@DESKTOP-5IG459O:~$ cd /home/
ubuntu@DESKTOP-5IG459O:/home$ ls
test.file  ubuntu
ubuntu@DESKTOP-5IG459O:/home$

docker commit

生成本地 Docker 自定义镜像。

常用可选参数 说明
-a 提交镜像作者
-m 提交镜像信息

这里我们制作一个带有 Vim 编辑器的 Ubuntu 镜像(ubuntu-vim),并通过 docker commit 命令制作一个本地镜像。

当我们尝试对 Ubuntu 镜像添加软件或对一些系统配置进行修改时,我们就生成了一个属于自己的自定义镜像,通过使用自定义镜像,我们可以对日常工作时的项目进行客制化修改,并可以省去大部分需要因为配置开发环境与部署环境的高度重合的工作,只需要对自定义镜像进行二次修改,即可满足需求再次上线。

docker commit -a "Peter Chen" -m "Add Vim" c79bc37440d2 ubuntu-vim
sha256:8e9d1c74cd2404d7c006c5f7074b1f00b61f8c10a22044ab5b24da68c34a67ae
ubuntu@DESKTOP-5IG459O:~$ docker images
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
ubuntu-vim               latest    8e9d1c74cd24   4 seconds ago   168MB
ubuntu                   latest    4dd97cefde62   2 weeks ago     72.9MB
mysql                    latest    c8562eaf9d81   2 months ago    546MB
redis                    latest    621ceef7494a   2 months ago    104MB
tomcat                   latest    040bdb29ab37   2 months ago    649MB
nginx                    latest    f6d0b4767a6c   2 months ago    133MB
portainer/portainer-ce   latest    980323c8eb3f   2 months ago    196MB
centos                   latest    300e315adb2f   3 months ago    209MB
kibana                   latest    a674d23325b0   2 years ago     388MB
elasticsearch            latest    5acf0e8da90b   2 years ago     486MB
ubuntu@DESKTOP-5IG459O:~$

Docker 命令简单应用

部署 Nginx

WSL2 下通过 Docker 命令部署 Nginx,通过端口映射到主机上的 80 端口,并通过 curl 命令对该端口内容进行查看。
Nginx 默认端口:80

ubuntu@DESKTOP-5IG459O:~$ docker run -d --name Nginx -p 80:80 nginx
ae4f49240c2af6e20faa786a8fc144b78aacb6c7625ff11cf7ea39e67193ac22
ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
ae4f49240c2a   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 3 seconds   0.0.0.0:80->80/tcp   Nginx
ubuntu@DESKTOP-5IG459O:~$ curl localhost:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

部署 Tomcat

WSL2 下通过 Docker 命令部署 Tomcat,通过端口映射到主机上的 8080 端口,并通过 curl 命令对该端口内容进行查看。
Tomcat 默认端口:8080

ubuntu@DESKTOP-5IG459O:~$ docker run -d --name Tomcat -p 8080:8080 tomcat
1d5186fd99fae677916b5ddb7012a3277881bfefd8ee7da762b264b3aca05ddd
ubuntu@DESKTOP-5IG459O:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                    NAMES
1d5186fd99fa   tomcat    "catalina.sh run"   4 seconds ago   Up 4 seconds   0.0.0.0:8080->8080/tcp   Tomcat
ubuntu@DESKTOP-5IG459O:~$ curl localhost:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.41</h3></body></html>
ubuntu@DESKTOP-5IG459O:~$

在这里我们会感受到 Docker 镜像的最小化体验,即我们通过 curl 命令直接访问是会报 404的,这是因为 Docker 的镜像通常只包含最小运行环境,会省去大量无用的资源。

在进入容器后,我们会发现 Tomcat 中的 webapps 文件夹目录下并无任何东西。

ubuntu@DESKTOP-5IG459O:~$ docker exec -it Tomcat /bin/bash
root@1d5186fd99fa:/usr/local/tomcat# whereis tomcat
tomcat: /usr/local/tomcat
root@1d5186fd99fa:/usr/local/tomcat# cd /usr/local/tomcat/
root@1d5186fd99fa:/usr/local/tomcat# ls
BUILDING.txt     LICENSE  README.md      RUNNING.txt  conf  logs            temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   native-jni-lib  webapps  work
root@1d5186fd99fa:/usr/local/tomcat# cd webapps
root@1d5186fd99fa:/usr/local/tomcat/webapps# ls
root@1d5186fd99fa:/usr/local/tomcat/webapps#

通过翻阅资料,我们可以知道:Tomcat 镜像会将原有 webapps 文件夹下的文件删除,如需要恢复则可通过将 webapps.dist 文件夹下的文件拷贝到 webapps 文件夹解决。

root@1d5186fd99fa:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@1d5186fd99fa:/usr/local/tomcat# cd webapps
root@1d5186fd99fa:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
root@1d5186fd99fa:/usr/local/tomcat/webapps#
ubuntu@DESKTOP-5IG459O:~$ curl localhost:8080



<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/9.0.41</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="https://tomcat.apache.org/">Home</a></span>
                <span id="nav-hosts"><a href="/docs/">Documentation</a></span>
                <span id="nav-config"><a href="/docs/config/">Configuration</a></span>
                <span id="nav-examples"><a href="/examples/">Examples</a></span>
                <span id="nav-wiki"><a href="https://wiki.apache.org/tomcat/FrontPage">Wiki</a></span>
                <span id="nav-lists"><a href="https://tomcat.apache.org/lists.html">Mailing Lists</a></span>
                <span id="nav-help"><a href="https://tomcat.apache.org/findhelp.html">Find Help</a></span>
                <br class="separator" />
            </div>
            <div id="asf-box">
                <h1>Apache Tomcat/9.0.41</h1>
            </div>

            ......
    </body>

</html>

部署 Elasticsearch

WSL2 下通过 Docker 命令部署 Elasticsearch,通过端口映射到主机上的 9200 端口,并通过 curl 命令对该端口内容进行查看。
Elasticsearch 默认端口:9200

ubuntu@DESKTOP-5IG459O:~$ docker run -d --name Elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:latest
9e8cb66f41446d40ec2ce3dd8bd1aab7189e9c37daf5233795e25926bece5587
ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                            NAMES
9e8cb66f4144   elasticsearch:latest   "/docker-entrypoint.…"   4 seconds ago   Up 2 seconds   0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   Elasticsearch
ubuntu@DESKTOP-5IG459O:~$ curl localhost:9200
{
  "name" : "03-Xaze",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "afbJDcPlTJuv2-FI0n7rIA",
  "version" : {
    "number" : "5.6.12",
    "build_hash" : "cfe3d9f",
    "build_date" : "2018-09-10T20:12:43.732Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.1"
  },
  "tagline" : "You Know, for Search"
}
ubuntu@DESKTOP-5IG459O:~$ docker status
docker: 'status' is not a docker command.
See 'docker --help'

ES 默认会占用大量内存,若想通过修改配置的方式对 ES 进行配置,可追加 -e [参数],对其进行环境配置。
此处我们将 ES 的内存限制为最小内存 64m,最大内存 1024m。

ubuntu@DESKTOP-5IG459O:~$ docker run -d --name Elasticsearch -p 9200:9200 -p 9300:9300 -e "-Xms=64m -Xmx=1024m" elasticsearch:latest
021abaaf2148248188c8add919576895dc9d61bca8834601d4947058616ce1ec
ubuntu@DESKTOP-5IG459O:~$ docker stats
CONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT    MEM %     NET I/O     BLOCK I/O   PIDS
021abaaf2148   Elasticsearch   0.17%     2.22GiB / 12.44GiB   17.84%    696B / 0B   0B / 0B     43

可视化管理工具

Portiner

官方地址:Portiner
Portiner 默认端口:9000

ubuntu@DESKTOP-5IG459O:~$ docker run -d -p 9000:9000 --name=Portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
a60bf182bf76b2ce5971cb47da02c6be15d4132b37364bf63987e98079195d30
ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE                    COMMAND        CREATED         STATUS         PORTS                              NAMES
a60bf182bf76   portainer/portainer-ce   "/portainer"   2 seconds ago   Up 2 seconds   8000/tcp, 0.0.0.0:9000->9000/tcp   Portainer
ubuntu@DESKTOP-5IG459O:~$

Portainer 显示效果

Portainer 登录页

Portainer 管理配置页

Portainer 主页


容器数据卷

原理

当我们想要通过 Docker 进行数据持久化存储的时候,若我们将数据全部存放于 Docker 容器中,则当我们删除容器时,容器中的数据也就被我们一并删除,也就是通俗意义上讲的“删库跑路”。
现实中为了防止此类事情发生,通常可以通过容器数据卷技术,将容器中的目录挂载到外部目录(这个外部目录通常是当前计算机上的物理地址)。

即:双向绑定,容器的持久化和同步操作,即使 Docker 中各个容器间互相隔离,但容器间也是可以数据共享的。


docker run -it -v 主机目录:容器内目录

在这里我们尝试将本地 Ubuntu WSL2 虚拟机上的目录挂载到 Docker 中新建的 Ubuntu 容器上。

本地挂载目录:/home/test,若本地无此目录,则 Docker 会帮助创建。
容器挂载目录:/home

ubuntu@DESKTOP-5IG459O:~$ docker run -it -v /home/test:/home ubuntu /bin/bash

挂载后容器与外部的数据共享

通过 docker inspect,我们可以检查容器挂载信息。

ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
562e4b3c9d92   ubuntu    "/bin/bash"   6 minutes ago   Up 6 minutes             nervous_darwin
ubuntu@DESKTOP-5IG459O:~$ docker inspect 562e4b3c9d92
[
    {
        "Id": "562e4b3c9d92cc41642ccaf6e4883ec328a9df205b0ea2d6c00e54fab253e42e",
        "Created": "2021-03-23T01:33:55.8844317Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1277,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-03-23T01:33:56.1845627Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },

        ......
        
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/test", # 容器内的挂载目录
                "Destination": "/home", # 容器外的挂载目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

        ......
    }
]
ubuntu@DESKTOP-5IG459O:~$

测试 MySQL 数据

这里我们测试将容器中的 MySQL 配置文件挂载到外部,并将数据目录也挂载到外部,防止因为误删容器而导致的数据丢失。

建立一个通过 3306 端口映射到本地,配置文件与数据文件目录挂载到本地,MySQL root 账户密码为 root,容器名为 testMySQL 的 MySQL 容器。

本地挂载配置文件目录:/home/mysql/conf
容器配置文件目录:/etc/mysql/conf.d

本地挂载数据目录:/home/mysql/data
容器数据目录:/var/lib/mysql

ubuntu@DESKTOP-5IG459O:~$ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name testMySQL mysql:latest

ubuntu@DESKTOP-5IG459O:~$ cd /home/
ubuntu@DESKTOP-5IG459O:/home$ ls
mysql  ubuntu
ubuntu@DESKTOP-5IG459O:/home$ cd mysql/
ubuntu@DESKTOP-5IG459O:/home/mysql$ ls
conf  data
ubuntu@DESKTOP-5IG459O:/home/mysql$ cd data/
ubuntu@DESKTOP-5IG459O:/home/mysql/data$ ls
'#ib_16384_0.dblwr'   auto.cnf        binlog.index   client-cert.pem   ib_logfile0   ibtmp1      performance_schema   server-cert.pem   undo_001
'#ib_16384_1.dblwr'   binlog.000001   ca-key.pem     client-key.pem    ib_logfile1   mysql       private_key.pem      server-key.pem    undo_002
'#innodb_temp'        binlog.000002   ca.pem         ib_buffer_pool    ibdata1       mysql.ibd   public_key.pem       sys

# 这里我们通过 DataGrip,对映射出来的本地 3306 进行控制,并添加一个 test 表。
ubuntu@DESKTOP-5IG459O:/home/mysql/data$ ls
'#ib_16384_0.dblwr'   auto.cnf        binlog.index   client-cert.pem   ib_logfile0   ibtmp1      performance_schema   server-cert.pem   test
'#ib_16384_1.dblwr'   binlog.000001   ca-key.pem     client-key.pem    ib_logfile1   mysql       private_key.pem      server-key.pem    undo_001
'#innodb_temp'        binlog.000002   ca.pem         ib_buffer_pool    ibdata1       mysql.ibd   public_key.pem       sys               undo_002
ubuntu@DESKTOP-5IG459O:/home/mysql/data$ docker run -d -it /bin/bash mysql

假设我们删除容器,挂载目录中的数据文件也不会丢失。

ubuntu@DESKTOP-5IG459O:/home/mysql$ docker stop testMySQL
ubuntu@DESKTOP-5IG459O:/home/mysql$ docker rm testMySQL
testMySQL
ubuntu@DESKTOP-5IG459O:/home/mysql$ cd data/
ubuntu@DESKTOP-5IG459O:/home/mysql/data$ ls
'#ib_16384_0.dblwr'   auto.cnf        binlog.index   client-cert.pem   ib_logfile0   mysql                private_key.pem   server-key.pem   undo_002
'#ib_16384_1.dblwr'   binlog.000001   ca-key.pem     client-key.pem    ib_logfile1   mysql.ibd            public_key.pem    sys
'#innodb_temp'        binlog.000002   ca.pem         ib_buffer_pool    ibdata1       performance_schema   server-cert.pem   undo_001
ubuntu@DESKTOP-5IG459O:/home/mysql/data$

PS:这里有一个暂时未解决的问题,即 Docker 的容器数据卷挂载会将本地目录覆盖容器内目录,即会隐藏容器内的文件。

ubuntu@DESKTOP-5IG459O:~$ docker exec -it testMySQL /bin/bash
root@a0a84f3635e0:/# whereis mysql
mysql: /usr/bin/mysql /usr/lib/mysql /etc/mysql
root@a0a84f3635e0:/# cd /etc/mysql/
root@a0a84f3635e0:/etc/mysql# ls
conf.d  my.cnf  my.cnf.fallback
root@a0a84f3635e0:/etc/mysql# cd conf.d/
root@a0a84f3635e0:/etc/mysql/conf.d# ls
root@a0a84f3635e0:/etc/mysql/conf.d#

匿名挂载

当我们尝试创建 Docker 容器卷时,若不指定容器卷的卷名直接挂载外部目录,就是匿名挂载。

这里我们生成一个测试用的 Nginx 容器,并通过匿名挂载方式,挂载 Nginx 的配置文件目录。

 docker run -d -P --name AnonymousMountNginx -v /etc/nginx nginx
1cbff8ab5b4c295384d1d0a508a6d828997cca6e992c5416fbc9c9668367c957
ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                   NAMES
1cbff8ab5b4c   nginx     "/docker-entrypoint.…"   2 seconds ago   Up 2 seconds   0.0.0.0:49153->80/tcp   AnonymousMountNginx

docker volume … 命令是 Docker 的容器卷管理命令。

# 通过 docker volume ls 命令可查看当前 Docker 中的容器卷
# 未指定名字的就是匿名挂载卷(这里是43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b)
ubuntu@DESKTOP-5IG459O:~$ docker volume ls
DRIVER    VOLUME NAME
local     43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b

# 通过 docker volume inspect [容器卷名]
docker volume inspect 43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b
[
    {
        "CreatedAt": "2021-03-23T06:39:05Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b/_data",
        "Name": "43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b",
        "Options": null,
        "Scope": "local"
    }
]
ubuntu@DESKTOP-5IG459O:~$

Windows10 WSL2 Ubuntu20.04中的镜像位置:
\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes

Windows 中的 Docker 容器数据卷位置

通过 docker volume inspect 命令提供的目录,如果你的操作系统是 Linux,则可以直接访问挂载的命令目录,由于我的机器是 Windows,挂载目录较其他系统不一样


具名挂载

这里我们生成一个测试用的 Nginx 容器,并通过具名挂载方式,挂载 Nginx 的配置文件目录。

ubuntu@DESKTOP-5IG459O:/mnt/c/Users/P7XXTM1-G$ docker run -d -P --name NamedMountNginx -v named-nginx-volume:/etc/nginx nginx
fa91bb3dd49f476874d99a1e1199ecf24dd309d4240535611156b6dc5f5ab10a
ubuntu@DESKTOP-5IG459O:/mnt/c/Users/P7XXTM1-G$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                   NAMES
fa91bb3dd49f   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:49153->80/tcp   NamedMountNginx
ubuntu@DESKTOP-5IG459O:/mnt/c/Users/P7XXTM1-G$ docker volume ls
DRIVER    VOLUME NAME
local     43145ccdd2df15993af6a2077e044a8089e003b5a4e564be8dad03162aa8816b
local     named-nginx-volume
ubuntu@DESKTOP-5IG459O:/mnt/c/Users/P7XXTM1-G$ docker volume inspect named-nginx-volume
[
    {
        "CreatedAt": "2021-03-25T02:31:48Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/named-nginx-volume/_data",
        "Name": "named-nginx-volume",
        "Options": null,
        "Scope": "local"
    }
]
ubuntu@DESKTOP-5IG459O:/mnt/c/Users/P7XXTM1-G$

区分

匿名挂载
-v 容器内路径

具名挂载
-v 卷名:容器内路径

指定路径挂载(普通挂载,也是匿名挂载)
-v /宿主机路径:容器内路径


读写权限

通过 -v 容器内路径:ro 或 rw 改变读写权限

  • ro read-only # 只读
  • rw read-and-write # 可读写
# ro
docker run -d -P --name NamedMountNginx -v named-nginx-volume:/etc/nginx:ro nginx

# rw
docker run -d -P --name NamedMountNginx -v named-nginx-volume:/etc/nginx:rw nginx

Docker File

即用来构建 Docker 镜像的构建文件。

编写脚本

创建 Docker File。

ubuntu@DESKTOP-5IG459O:~$ mkdir Test-Docker-File
ubuntu@DESKTOP-5IG459O:~$ ls
Test-Docker-File
ubuntu@DESKTOP-5IG459O:~$ cd Test-Docker-File/
ubuntu@DESKTOP-5IG459O:~/Test-Docker-File$ vim docker-file

docker-file 文件中的内容
通过编辑该文件,对 Docker 镜像进行客制化。

FROM ubuntu

VOLUME ["volume1", "volume2"]

CMD echo "---BUILD END---"

CMD /bin/bash

docker build

ubuntu@DESKTOP-5IG459O:~/Test-Docker-File$ docker build -f /home/ubuntu/Test-Docker-File/docker-file -t custom/ubuntu .
[+] Building 0.2s (5/5) FINISHED
 => [internal] load build definition from docker-file                                                                                              0.0s
 => => transferring dockerfile: 123B                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                    0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                                                                   0.0s
 => [1/1] FROM docker.io/library/ubuntu                                                                                                            0.1s
 => exporting to image                                                                                                                             0.0s
 => => exporting layers                                                                                                                            0.0s
 => => writing image sha256:5212c89e92e63e84857aa6cb946d18b0e161adfb9a606ff1762e174d299aac57                                                       0.0s
 => => naming to docker.io/custom/ubuntu                                                                                                           0.0s
ubuntu@DESKTOP-5IG459O:~/Test-Docker-File$

查看构建完成后的镜像

ubuntu@DESKTOP-5IG459O:~/Test-Docker-File$ docker image ls
REPOSITORY               TAG       IMAGE ID       CREATED        SIZE
ubuntu                   latest    4dd97cefde62   3 weeks ago    72.9MB
custom/ubuntu            latest    5212c89e92e6   3 weeks ago    72.9MB

检查生成的镜像

ubuntu@DESKTOP-5IG459O:~/Test-Docker-File$ docker run -it custom/ubuntu /bin/bash
root@3e8bb3cc0c7a:/# ls -l
total 56
lrwxrwxrwx   1 root root    7 Feb 17 01:04 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15  2020 boot

...

# 这里是我们在之前脚本中挂载的容器数据卷
drwxr-xr-x   2 root root 4096 Mar 29 13:55 volume1
drwxr-xr-x   2 root root 4096 Mar 29 13:55 volume2
root@3e8bb3cc0c7a:/#

我们在 volume1 文件夹中创建一个测试文件 testFile。
通过 docker inspect 命令,检查用客制化镜像所生成的容器
通过检查 Windows 中的 Docker Volume文件夹,验证我们创建的容器的正确性。

检查挂载容器数据卷中的文件


数据卷容器(待完善)

当容器与容器之间需要同步数据的时候,一般使用数据卷容器进行挂载。

使用场景示例:多个 MySQL 同步数据。

类似 Windows 中的共享文件夹

步骤:

  1. 创建父容器
  2. 通过 –volumes-from 命令,将子容器挂载到父容器

创建父容器

ubuntu@DESKTOP-5IG459O:~$ docker image ls
REPOSITORY               TAG       IMAGE ID       CREATED        SIZE
custom/ubuntu            latest    715329a7458b   5 weeks ago    72.9MB
ubuntu                   latest    4dd97cefde62   5 weeks ago    72.9MB

# 运行我们刚才创建的自定义容器,并运行,可以看到 VOLUME01 与 VOLUME02 为自定义容器中默认挂载的两个容器。
ubuntu@DESKTOP-5IG459O:~$ docker run -it --name Docker-Host custom/ubuntu
root@0d03cf71815e:/# ls -l
total 56
drwxr-xr-x   2 root root 4096 Apr 12 08:41 VOLUME01
drwxr-xr-x   2 root root 4096 Apr 12 08:41 VOLUME02
lrwxrwxrwx   1 root root    7 Feb 17 01:04 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15  2020 boot
...
root@0d03cf71815e:/#

创建子容器

–volumes-from

# 查看正在运行中的父容器。
ubuntu@DESKTOP-5IG459O:~$ docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS     NAMES
0d03cf71815e   custom/ubuntu   "/bin/sh -c /bin/bash"   2 minutes ago   Up 2 minutes             Docker-Host

# 通过 --volumes-from 命令,指定子容器所要继承的父容器。
ubuntu@DESKTOP-5IG459O:~$ docker run -it --name Docker-Child01 --volumes-from Docker-Host custom/ubuntu

# 运行子容器,可以看到挂载到父容器的 VOLUME01 与 VOLUME02 卷。
root@2864c4f3b8ba:/# ls -l
total 56
drwxr-xr-x   2 root root 4096 Apr 12 08:41 VOLUME01
drwxr-xr-x   2 root root 4096 Apr 12 08:41 VOLUME02
lrwxrwxrwx   1 root root    7 Feb 17 01:04 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15  2020 boot
...
root@2864c4f3b8ba:/#

当我们在父容器 Docker-Host 中创建文件时,子容器 Docker-Child01 会同步文件


创建多个子容器,当我们在子容器中进行文件的修改,父容器也会同步。

子容器 Docker-Child02 创建文件,父容器 Docker-Host 同步文件


PS:

只要有一个容器尚在,容器中的文件都不会被删除。

容器创建时使用的镜像已挂载了两个卷(VOLUME01 与 VOLUME02),所以是肯定有两个目录的,跟数据卷容器没关系。

–volumes-from 不是同步所有目录,而是同步挂载点,这就是同步 Docker-Child01 与 Docker-Child02,但在其他目录是不会同步的。


参考资料


0%