第04章 操作 Docker 容器
容器是镜像的一个运行实例.
4.1 创建容器
主要介绍 create
, start
, run
, logs
子命令.
1. 新建容器
可以使用 docker [container] create
命令新建一个容器.
jk@jk-System-Product-Name:~$ docker create -it ubuntu:latest
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
1eddb92809ff2aae01d8e3857db2ea823719a62358de156ea17dce76e57d680e
jk@jk-System-Product-Name:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1eddb92809ff ubuntu:latest "bash" 14 seconds ago Created strange_kapitsa
上述命令在本地未发现
ubuntu:latest
, 然后自动下载了镜像, 然后创建容器.
创建的容器为停止状态. 使用命令 docker [container] start
来启动它.
create
命令与run
命令可用选项非常多. 可以使用--help
来查看.书 P40
2. 启动容器
命令 docker [container] start
来启动一个已经创建的容器.
可以在 docker ps
中查看正在运行的容器.
3. 新建并启动容器
可以直接使用 run
子命令. 其背后逻辑为:
- 检查本地是否存在镜像, 若不存在从仓库下载
- 利用镜像创建一个容器, 并启动该容器
- 分配一个文件系统给容器, 并在只读镜像层外面挂载一层可读可写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中
- 从网桥地址池配置一个 IP 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被自动终止
$ docker run -it ubuntu:18.04 /bin/bash
其中
-t
是让 Docker 为其分配一个伪终端 (pseudo-tty), 并绑定到容器上.
-i
则是让容器的标准输入保持打开.在交互模式下, 执行
exit
退出 bash 后, 容器中没有运行程序也会自动退出.
可以使用 docker containert wait 容器 [容器 ...]
子命令来等待容器退出, 并打印返回结果.
执行 docker run
无法正常启动, 可查看退出的错误代码, 可能的代码错误
- 125: Docker Daemon 执行出错, 例如参数不正确
- 126: 命令无法执行, 例如无权限
- 127: 容器内命令无法找到
4. 守护态运行
利用参数 -d
进入守护态.
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
容器会返回一个唯一的 ID, 或使用 docker ps
或 docker container ls
来查看.
5. 查看容器输出
命令 docker logs 容器ID
jk@jk-System-Product-Name:~$ docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m
for 42 minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g.
42m for 42 minutes)
4.2 停止容器
涉及命令有: pause
/ unpause
, stop
和 prune
1. 暂停容器
可以使用 docker [container] pause 容器 [容器 ...]
来暂停容器.
使用 docker [container] unpause 容器 [容器 ...]
来将暂停的容器恢复到运行状态.
2. 终止容器
使用命令
docker [container] stop [-t|--time[=10]] [容器 ...]
来终一个运行中的容器.
该命令首先向容器发送 SIGTERM 信号, 等一段超时时间后 (默认 10 秒), 在发送 SIGKILL 信号来终止容器.
容器中无程序运行或程序退出后也会处于终止状态.
可以使用 docker ps -qa
查看所有容器 ID. 可以再使用 start
对容器启动.
重启命令 docker [container] restart 容器
可以将容器先停止, 再启动.
4.3 进入容器[重点]
使用参数 -d
进入后台, 需要进入容器, 可以使用 attach
或 exec
命令
1. attach
命令
命令格式为:
docker [container] attach [--detach-keys[=[]]] [--no-stdin] [--sig-proxy[=true]] 容器
其中三个主要选项表示
--detach-keys[=[]]
指定退出attach
模式的快捷键序列. 默认为 CTRL-p CTRL-q.--no-stdin=true|false
是否关闭标准输入. 默认是保持打开.--sig-proxy=true|false
是否代理收到的系统信号给应用程序进程, 默认为true
.
当多个窗口同时 attach 到同一个容器时, 所有窗口会同步显示, 当某个窗口被命令阻塞时, 其他窗口也无法使用.
2. exec
命令 [推荐使用]
从 Docker 1.3.0 开始支持, 其命令格式为
docker [container] exec
[-d|--detach]
[--detach-keys[=[]]]
[-i|--interactive]
[--privileged]
[-t|--tty]
[-u|--user[=USER]]
容器 [ARG ...]
比较重要的参数有:
-d
,--detach
: 在容器中后台执行命令--detach-keys
: 指定将容器切回后台的按键-e
,--env=[]
: 指定环境变量列表-i
,--interactive=true|false
: 打开标准输入接收用户输入命令, 默认为false
--privileged=true|false
: 是否给执行命令最高权限, 默认为false
-t
,--tty=true|false
: 分配伪终端. 默认false
-u
,--user=
: 执行命令的用户名
例如:
$ docker exec -it 容器ID /bin/bash
这样就会开启一个新的终端, 可在其与容器交互, 并不影响其他连接.
完整语法为:
jk@jk-System-Product-Name:~$ docker exec --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in
the background
--detach-keys string Override the key sequence for
detaching a container
-e, --env list Set environment variables
--env-file list Read in a file of environment
variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the
command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format:
<name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the
container
4.4 删除容器
使用 docker [container] rm
来删除处于终止或退出状态的容器. 命令格式为:
jk@jk-System-Product-Name:~$ docker rm --help
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
-f, --force Force the removal of a running container
(uses SIGKILL)
-l, --link Remove the specified link
-v, --volumes Remove anonymous volumes associated with
the container
默认无法删除正在运行的, 但是加上参数
-f
则先发送信号SIGKILL
, 待容器终止后删除.
4.5 导入和导出容器
将一个容器从一个系统中迁移到另一个系统中使用 [是不是可以看成备份???]
1. 导出容器
将容器导出到文件中, 无论是否处于运行状态.
jk@jk-System-Product-Name:~$ docker export --help
Usage: docker export [OPTIONS] CONTAINER
Export a container's filesystem as a tar archive
Options:
-o, --output string Write to a file, instead of STDOUT
导出的文件, 可以拷贝到其他机器中再导入运行.
2. 导入容器
使用命令 docker import
来导入容器, 使其称为镜像.
jk@jk-System-Product-Name:~$ docker import --help
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
Options:
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Set commit message for imported image
--platform string Set platform if server is multi-platform capable
4.6 查看容器
主要介绍 inspect
, top
和 stats
子命令.
1. 查看容器详情
使用 docker inspect 容器
来查看容器内容
jk@jk-System-Product-Name:~$ docker inspect --help
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
Return low-level information on Docker objects
Options:
-f, --format string Format the output using the given Go template
-s, --size Display total file sizes if the type is container
--type string Return JSON for specified type
2. 查看容器内进程
使用 docker top 容器
来查看
jk@jk-System-Product-Name:~$ docker top --help
Usage: docker top CONTAINER [ps OPTIONS]
Display the running processes of a container
3. 查看统计信息
使用命令 docker stats 容器
来显示统计信息.
jk@jk-System-Product-Name:~$ docker stats --help
Usage: docker stats [OPTIONS] [CONTAINER...]
Display a live stream of container(s) resource usage statistics
Options:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output
4.7 其他容器命令 [暂略]
4.8 本章小结 [略]
第05章 访问 Docker 仓库 [暂略]
第06章 Docker 数据管理
生产环境中会对数据进行持久化. 并且需要在不同容器之间共享数据. 那么就需要在容器外部管理数据.
容器中的数据管理有两种方式:
- 数据卷 (Data Volumes): 容器中的数据直接映射到本地主机环境.
- 数据卷容器 (Data Volume Containers): 使用特定容器维护数据卷.
本章首先介绍数据卷, 然后介绍数据卷容器, 并在主机, 容器之间共享数据, 并实现数据的备份与恢复.
6.1 数据卷 [重要]
数据卷是供容器使用的特殊目录. 将主机操作系统目录直接映射进容器. 类似于 Linux 中的 mount
行为.
数据卷让数据与容器解耦
1. 创建数据卷
docker 提供了 volume 子命令来管理数据卷.
jk@jk-System-Product-Name:~$ docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
使用下面命令可以快速的在本地创建一个数据卷:
$ docker volume create -d local test
test
可以在 /var/lib/docker/volumes/
目录下查看所创建的数据卷.
可以使用
docker volume rm
删除数据卷.使用
docker volume prune
清除未用的数据卷使用
docker volume inspect
来查看数据卷信息使用
docker volume ls
列出所有数据卷
2. 绑定数据卷
除了使用 volume
来管理数据卷外, 还可以在创建容器的时将主机本地的任意路径挂载到容器内作为数据卷. 即为 绑定数据卷.
在使用 docker run
命令时, 可以使用 -mount
选项来使用数据卷. 该选项支持三种数据卷:
volume
普通数据卷. 映射到主机/var/lib/docker/columes
路径下.bind
绑定到数据卷. 映射到制定路径下.tmpfs
临时数据卷. 只存在于内存中.
案例 该案例为作者提供:
使用
training/webapp
镜像创建一个 web 容器, 并创建一个数据卷挂载到容器的 /opt/webapp 目录$ docker run -d -P --name web --mount type=bind,source=/webapp,destination=/opt/webapp training/webapp python app.py
上述命令等同于早期的
-v
选项, 在容器内创建一个数据卷$ docker run -d -P --name web -v /webapp:/opt/webapp training/webapp python app.py
这个功能在测试的时候十分方便.
需要注意: 本地目录路径必须使用绝对路径, 容器内可以使用相对路径. 若目录不存在, docker 会创建目录.
Docker 挂载的数据卷默认为读写 (
rw
), 可以使用ro
设置为只读.$ docker run -d -P --name web -v /webapp:/opt/webapp:ro training/webapp python app.py
如此, 容器内对所挂数据卷内的数据就无法修改了.
推荐挂载目录, 而不是文件.
在 docker
中运行一个 ubuntu:latest
, 然后将 /home/webapp
目录与本地 /webapp
绑定在一起.
$ docker run -dit --name ubuntu-web-server --mount type=bind,source=/webapp,destination=/home/webapp ubuntu:latest /bin/bash
进入 docker 中 /home
目录下可以看到 webapp
已被创建. 现在, 在该目录下做的所有操作, 都会映射到主机的 /webapp
目录中.
6.2 数据卷容器
一般用在多个容器间数据共享. 数据卷也是一个容器, 其作用是专门提供数据卷给其他容器挂载.
例子, 创建一个数据卷容器
dbdata
, 并在其中创建一个数据卷挂载到/dbdata
:jk@jk-System-Product-Name:~$ docker run -it -v /dbdata --name dbdata ubuntu root@2454ba698668:/# ls bin dbdata etc lib lib64 media opt root sbin sys usr boot dev home lib32 libx32 mnt proc run srv tmp var root@2454ba698668:/#
进入容器后, 可以查看本地目录.
疑惑
-v
带有形如path1:path2
的参数,path1
为本地目录,path2
为容器中的目录[正解]-v
仅带有形如path
的参数, 表示容器中的目录???在其他容器中要使用数据卷容器 dbdata, 则使用
--volumes-from
来引用数据卷容器.下面创建
db1
和db2
两个容器, 并从dbdata
容器挂载数据卷$ docker run -it --volumes-from dbdata --name db1 ubuntu $ docker run -it --volumes-from dbdata --name db2 ubuntu
此时有三个容器在运行:
dbdata
,db1
,db2
. 并且任何一个容器在/dbdata
中写下数据, 其他两个容器都可以看到变化.
可以多次使用 --volumes-from
从多个容器挂载数据卷. 还可以从其他已经挂载了数据卷的容器来挂载数据卷.
注意:
- 提供数据卷的容器不必保持运行状态.
- 删除挂载容器, 数据卷容器不会自动删除. 若要关联删除, 需要在删除最后一个容器时, 使用
-v
参数. [怎么用?]
6.3 利用数据卷来迁移数据
可以利用数据卷容器对其中的数据卷进行备份, 恢复, 来实现数据的迁移.
数据卷是存数据的地方.
数据卷容器, 为数据卷提供了一个容器空间. 可以将其想象成一个文件服务器.
1. 备份
使用下面的命令来备份 dbdata
数据卷容器内的数据卷:
$ docker run --volumns-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata
解释
- 首先利用
ubuntu
镜像创建了一个docker
容器worker
- 使用
--volumes-from dbdata
表示挂载容器卷 -v $(pwd):/backup
表示将本地的当前目录与容器的/backup
目录绑定- 启动容器后, 执行
tar cvf /backup/backup.tar /dbdata
将/dbdata
目录打包到/backup/back.tar
中
备份实际上就是利用数据卷共享这一特征, 将数据卷容器中的数据卷打包成一个压缩文件.
不过直接将本地目录作为共享目录, 压缩本地目录似乎一样.
或许在大面积集群等特殊逻辑中有用吧.
2. 恢复
恢复数据到换一个容器, 可以按照下面步骤.
- 首先创建一个带有数据卷的容器
dbdata2
. - 然后创建一个新容器挂载这个带有数据卷的容器.
- 同时在这个新容器中使用
untar
解压备份文件到所挂载容器卷中
$ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
$ docker run --volumns-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
创建数据卷容器, 并用本地
/dbdata
目录作为数据卷然后运行一个新容器, 挂载该数据卷容器, 即可在本地操作
/dbdata
然后解压文件, 使得数据卷容器可用