在学习了 docker 镜像的内容后,我们在来看 docker 的另一个核心点:容器。
注:环境为 CentOS7,docker 19.03
docker 的容器是镜像的一个运行实例。docker 镜像是只读文件,而容器则带有运行时的可读写层,而且容器中的应用进程处于运行状态。接下来我们就来学习 docker 容器的具体操作。
创建容器
创建容器相关的命令有 create、start、run、wait 和 logs。
新建容器
使用命令 docker [container] create
新建一个容器:
# docker create -it ubuntu:latest
63197c11dc16e893dc8bb032ebf92419032cc40d6dcb6f750a16e9e308d52584
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63197c11dc16 ubuntu:latest "/bin/bash" 5 seconds ago Created hardcore_raman
docker create
命令对应的参数有很多,下面列出对应的选项:
create 命令与容器运行模式相关的选项
create 命令与容器环境和配置相关的选项
create 命令与容器资源限制和安全保护相关的选项
以及:
- -l, --label=[]: 以键值对⽅式指定容器的标签信息;
- --label-file=[]: 从⽂件中读取标签信息。
启动容器
使用该命令新建的容器处于停止状态,使用命令 docker [container] start
启动容器,通过 docker [container] ps
查看运行中的容器:
# docker start 63197c11dc16e893dc8bb032ebf92419032cc40d6dcb6f750a16e9e308d52584
63197c11dc16e893dc8bb032ebf92419032cc40d6dcb6f750a16e9e308d52584
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63197c11dc16 ubuntu:latest "/bin/bash" About a minute ago Up 3 seconds hardcore_raman
我们还可以将新建和启动容器合起来,命令 docker [container] run
就是两个命令的组合:
# docker run ubuntu /bin/echo "Hello World"
Hello World
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5982bad8cf83 ubuntu "/bin/echo 'Hello Wo…" 7 seconds ago Exited (0) 6 seconds ago exciting_lalande
使用 run 命令实际上在后台包含了以下过程:
- 检查本地是否存在指定的镜像, 不存在就从公有仓库下载;
- 利⽤镜像创建⼀个容器, 并启动该容器;
- 分配⼀个⽂件系统给容器, 并在只读的镜像层外⾯挂载⼀层可读写层;
- 从宿主主机配置的⽹桥接⼜中桥接⼀个虚拟接⼜到容器中去;
- 从⽹桥的地址池配置⼀个IP地址给容器;
- 执⾏⽤户指定的应⽤程序;
- 执⾏完毕后容器被⾃动终⽌。
注:运行结束后容器就会停止。
还可以在创建时启动一个 bash 终端,这样就能和容器交互了:
# docker run -it ubuntu bash
root@264cf6ed894e:/#
- -t:选项让Docker分配⼀个伪终端(pseudo-tty) 并绑定到容器的标准输⼊上,
- -i:则让容器的标准输⼊保持打开。
退出容器
⽤户可以按 Ctrl+d
或输⼊ exit
命令来退出容器,也可以使用命令 docker container wait CONTAINER[CONTAINER...]
⼦命令来等待容器退出, 并打印退出返回结果。
root@264cf6ed894e:/# exit
exit
如果启动容器的出项错误,有以下错误代码:
- 125: Docker daemon执⾏出错, 例如指定了不⽀持的Docker命令参数;
- 126: 所指定命令⽆法执⾏, 例如权限出错;
- 127: 容器内命令⽆法找到。
后台运行
如果需要让容器在后台以守护态(Daemonized) 形式运⾏,可以通过 -d 参数实现:
# docker run -itd ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done"
5352f3e531b2f451ec6b484a6d35d1fd064438fa3d3404691b80b98bbc6e7801
它会返回一个唯一的id值,使用 docker ps
或 docker container ls
来查看容器信息:
# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5352f3e531b2 ubuntu "/bin/bash -c 'while…" 2 minutes ago Up 2 minutes lucid_albattani
查看容器输出
刚才通过 -d 让容器以后台方式运行,我们没有看到它的输出信息,可以使用命令docker [container] logs
命令查看,该命令包含以下选项:
- -details: 打印详细信息;
- -f, -follow: 持续保持输出;
- -since string: 输出从某个时间开始的⽇志;
- -tail string: 输出最近的若⼲⽇志;
- -t, -timestamps: 显⽰时间戳信息;·-until string: 输出某个时间之前的⽇志。
# docker logs 5352f3e531b2
hello world
注:创建容器后会返回一个唯一的id,但一般我们截取字符前面的一部分,保证能认到这个容器就可以了。
停止容器
停止容器使用的子命令为 pause/unpause、stop、prune。
暂停容器
使用命令docker [container] pause CONTAINER[CONTAINER...]
来暂停一个运行中的容器
# docker run --name test --rm -itd ubuntu bash
c1a52ffc5f662b2e60bcd98fe81157754cb251b22a624e8a6a32785905d5b93e
# docker pause c1a52ffc5
c1a52ffc5
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1a52ffc5f66 ubuntu "bash" 16 seconds ago Up 16 seconds (Paused) test
出于 paused 状态的容器就可以使用 docker [container] unpause CONTAINER[CONTAINER...]
命令来恢复了。
注:启动时添加 --rm 选项时,在容器退出后会删除容器。
停止容器
使用命令docker [container] stop [-t|--time[=10]] [CONTAINER...]
停止容器:
# docker stop 5352f3e531b2
5352f3e531b2
现在使用命令 docker container prune
会删除所有处于停止状态的容器。
除了 stop 外,使用命令docker [container] kill
或在交互模式下通过命令exit
或Ctrl+d
都可以停止容器。
属于停止状态的容器,可以使用命令 docker [container] start
来启动,或者是命令 docker [container] restart
来先停止再启动。
进入容器
当容器再后台运行是,使用 docker [container] exec
命令可以进入容器中,支持的参数有:
- -d, --detach: 在容器中后台执⾏命令;
- --detach-keys="": 指定将容器切回后台的按键;
- -e, --env=[]: 指定环境变量列表;
- -i, --interactive=true|false: 打开标准输⼊接受⽤户输⼊命令, 默认值为false;
- --privileged=true|false: 是否给执⾏命令以⾼权限, 默认值为false;
- -t, --tty=true|false: 分配伪终端, 默认值为false;
- -u, --user="": 执⾏命令的⽤户名或ID。
# docker exec -it 5352f3e531b2 /bin/bash
删除容器
删除容器则是使用命令 docker [container] rm
,命令的格式为 docker [container] rm [-f|--force] [-l|--link] [-v|--volumes] CONTAINER [CONTAINER...]
,支持以下选项:
- -f, --force=false: 是否强⾏终⽌并删除⼀个运⾏中的容器;
- -l, --link=false: 删除容器的连接, 但保留容器;
- -v, --volumes=false: 删除容器挂载的数据卷
# docker rm -f 5352f3e531b2
5352f3e531b2
使用 docker rm 命令只能删除处于停止状态或退出状态的容器,并不能删除还在运行状态中的容器。但是使用选项 -f 可以删除,Docker会先发送SIGKILL信号给容器, 终⽌其中的应⽤, 之后强⾏删除。
导入和导出容器
有时我们需要将运行中的容器在不同的机器上拷贝,docker 则实现了容器的导入和导出功能。
导出容器
导出使用命令为 docker [container] export,命令格式为 docker [container] export [-o|--output[=""]] CONTAINER
:
# docker export -o ubuntu.tar 6f71e82ba8b1
[root@CentOS1 ~]# ls
anaconda-ks.cfg dockerfile ubuntu.tar
导出后的容器就可以直接复制到其他机器上导入运行了。
导入容器
使用命令 docker [container] import
则可以导入容器,格式为 docker import [-c|--change[=[]]] [-m|--message[=MESSAGE]] file|URL|-[REPOSITORY[:TAG]]
:
# docker import ubuntu.tar test/ubuntu:v1.0
sha256:6ccd40df1a76c15233708df3446fb97621f05826b2f0e4780aac29f5afaf76a7
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/ubuntu v1.0 6ccd40df1a76 7 seconds ago 69.9MB
注:可以使⽤docker load命令来导⼊镜像存储⽂件到本地镜像库, 也可以使⽤docker[container]import命令来导⼊⼀个容器快照到本地镜像库。 这两者的区别在于: 容器快照⽂件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态) , ⽽镜像存储⽂件将保存完整记录, 体积更⼤。 此外, 从容器快照⽂件导⼊时可以重新指定标签等元数据信息。
查看容器
查看容器有 inspect、top 和 stats 子命令。
inspect
使用命令 docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
查看容器详情:
# docker inspect 6f71e82ba8b129e54dd315d79ef4
[
{
"Id": "6f71e82ba8b129e54dd315d79ef4ec49fc3b26cd60102adcebe8b8a39c05dd3f",
"Created": "2019-08-21T13:22:23.432469852Z",
"Path": "/bin/bash"
...
}
]
该命令会以json格式返回包括容器Id、 创建时间、 路径、 状态、 镜像、 配置等在内的各项信息。
top
使用命令 docker [container] top [OPTIONS] CONTAINER [CONTAINER...]
查看容器内进程:
# docker container top 6f71e82b
UID PID PPID C STIME TTY TIME CMD
root 16395 16376 0 08:12 pts/0 00:00:00 /bin/bash
这个⼦命令类似于Linux系统中的top命令, 会打印出容器内的进程信息, 包括PID、 ⽤户、 时间、 命令等。
stats
使用命令 docke r[container] stats [OPTIONS] [CONTAINER...]
查看容器统计信息:
⽀持选项包括:
- -a, -all: 输出所有容器统计信息, 默认仅在运⾏中;
- --format string: 格式化输出信息;
- --no-stream: 不持续输出, 默认会⾃动更新持续实时结果;
- --no-trunc: 不截断输出信息。
其他命令
除此之外,docker 容器还支持其他类型的命令,如 cp、diff、port 和 update 子命令。
cp
该命令支持在容器和主机之间复制文件。命令格式为 docker [container] cp [OPTIONS] CONTAINER: SRC_PATH DEST_PATH|-
,支持的选项:
- -a, -archive: 打包模式, 复制⽂件会带有原始的uid/gid信息;
- -L, -follow-link: 跟随软连接。 当原路径为软连接时, 默认只复制链接信息, 使⽤该选项会复制链接的⽬标内容。
# docker container cp /etc/passwd 6f71e82ba8b1:/tmp/
diff
diff 查看容器内文件系统的变更,格式为 docker[container]diff CONTAINER
:
# docker container diff 6f71e82ba8b1
C /tmp
A /tmp/passwd
因为上面将文件复制到容器中,所以看到容器的文件系统发生了变化,C 为 改变,A 为追加
port
port 用来查看容器的端口映射情况,命令格式为 docker container port CONTAINER [PRIVATE_PORT [/PROTO]]
# docker container port 07a4e1582bd1
3306/tcp -> 0.0.0.0:3306
update
update 可以更新容器运行时配置,命令格式为 docker [container] update [OPTIONS] CONTAINER [CONTAINER...]
,支持选项有:
- --blkio-weight uint16: 更新块IO限制, 10~1000, 默认值为0, 代表着⽆限制;
- --cpu-period int: 限制CPU调度器CFS(Completely Fair Scheduler) 使⽤时间, 单位为微秒, 最⼩1000;
- --cpu-quota int: 限制CPU调度器CFS配额, 单位为微秒, 最⼩1000;
- --cpu-rt-period int: 限制CPU调度器的实时周期, 单位为微秒;
- --cpu-rt-runtime int: 限制CPU调度器的实时运⾏时, 单位为微秒;
- -c, -cpu-shares int: 限制CPU使⽤份额;
- --cpus decimal: 限制CPU个数;
- --cpuset-cpus string: 允许使⽤的CPU核, 如0-3, 0, 1;
- --cpuset-mems string: 允许使⽤的内存块, 如0-3, 0, 1;
- --kernel-memory bytes: 限制使⽤的内核内存;
- -m, -memory bytes: 限制使⽤的内存;
- --memory-reservation bytes: 内存软限制;
- --memory-swap bytes: 内存加上缓存区的限制, -1表⽰为对缓冲区⽆限制;
- --restart string: 容器退出后的重启策略
比如限制 docker 容器的内存和cpu:
# docker container update -m 1g --memory-swap 1g --cpus 1 6f71e82ba8b1
6f71e82ba8b1