Contents
操作Docker容器¶
容器 是Docker的另一个核心概念。简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层,同时,容器中的应用进程处于运行状态。
如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行态环境和其他系统环境)和跑在上面的应用。那么Docker容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。
1. 容器的常见操作¶
下面是容器的常用操作命令:
create 创建容器
run 运行容器
pause 暂停容器
unpause 取消暂停继续运行容器
stop 发送 SIGTERM 停止容器
kill 发送 SIGKILL 快速停止容器
start 启动容器
restart 重启容器
attach attach 到容器启动进程的终端
exec 在容器中启动新进程,通常使用 "-it" 参数
logs 显示容器启动进程的控制台输出,用 "-f" 持续打印
rm 从磁盘中删除容器
1.新建一个停止状态的容器
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker create -it ubuntu:latest
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f13492a1cba7 ubuntu:latest "/bin/bash" 26 seconds ago Created infallible_lamarr
2.创建一个交互型容器
docker run -it --name=hu_ubuntu ubuntu /bin/bash
3.创建一个后台型容器,使用-d参数。
sudo docker run --name hu_demo_ubuntu -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done"
3. 查看容器¶
1.docker ps 命令,可以查看当前运行的容器
[root@hujianli-docker01 centos]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7fd009ee1f86 ubuntu "/bin/bash -c 'while…" 11 minutes ago Up 11 minutes hu_demo_ubuntu
e1e8c619585a quay.io/coreos/etcd "/usr/local/bin/etcd…" 20 hours ago Up 20 hours etcd
2.Docker列出所有容器,包括运行的和停止的容器
docker ps -a
3.Docker只列出最后创建的容器
docker ps -l
4.使用 -n=x 选项,此时会列出最后创建的x个容器
docker ps -n=2
4. 查看容器日志¶
[root@hujianli-docker01 centos]# docker logs -f hu_demo_ubuntu
hello world
hello world
# --tail 标志可以精确控制 logs 输出的日志行数。例如,查看最后5行日志
[root@hujianli-docker01 centos]# docker logs -f --tail=5 hu_demo_ubuntu
hello world
hello world
hello world
hello world
hello world
hello world
#可以通过 -t 标志查看日志产生的时刻
[root@hujianli-docker01 centos]# docker logs -f --tail=5 -t hu_demo_ubuntu
2019-07-05T02:48:53.092986363Z hello world
2019-07-05T02:48:54.095842349Z hello world
2019-07-05T02:48:55.098757187Z hello world
2019-07-05T02:48:56.100865840Z hello world
2019-07-05T02:48:57.104798046Z hello world
5. 启动容器¶
1.通过容器id启动
docker start 3d5e4ad6455f
2.通过容器名称启动
sudo docker start inspect_shell
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d5e4ad6455f ubuntu:14.04 "/bin/bash" 18 hours ago Up 3 seconds wonderful_wozniak
6. 新建并启动容器¶
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker run ubuntu /bin/echo "hello world"
hello world
# 当利用docker run来创建并启动容器时,Docker在后台运行的标准操作包括: ·检查本地是否存在指定的镜像,不存在就从公有仓库下载;
# 启动一个bash终端,允许用户进行交互:
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker run -it ubuntu:14.04 /bin/bash
root@22c6b5a012b0:/#
#,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。
守护态运行
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker run -d ubuntu:14.04 /bin/sh -c "while true;do echo hello world;sleep 1;done"
ca08bd323aecdc48e76918dd66d5e37362add12e81d43e185debc65ca4083f7b
#获取容器的输出信息,可以使用docker logs命令
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker logs ca08
hello world
hello world
hello world
hello world
hello world
7. 查看容器进程¶
[root@hujianli-docker01 centos]# docker top hu_demo_ubuntu
UID PID PPID C STIME TTY TIME CMD
root 23951 23935 0 02:31 ? 00:00:00 /bin
/bash -c while true; do echo hello world; sleep 1; doneroot 25679 23951 0 02:49 ? 00:00:00 slee
p 1
8. 查看容器信息¶
# 查看容器的配置信息,(容器名称、环境变量、运行命令、主机配置、数据卷......配置)
docker inspect hu_demo_ubuntu
# --format 格式化标志,可以查看指定部分的信息
#查看容器的运行状态
[root@hujianli-docker01 centos]# docker inspect --format='{{ .State.Running }}' hu_demo_ubuntu
true
#查看状态值
[root@hujianli-docker01 centos]# docker inspect --format='{{ .State.Status }}' hu_demo_ubuntu
running
# 查看容器的IP地址
[root@hujianli-docker01 centos]# docker inspect --format='{{ .NetworkSettings.IPAddress }}' hu_demo_ubuntu
172.17.0.2
#查看容器的镜像类型
[root@hujianli-docker01 centos]# docker inspect --format='{{ .Config.Image }}' hu_demo_ubuntu
ubuntu
9. 终止容器¶
#首先向容器发送SIGTERM信号,等待一段超时时间(默认为10秒)后,再发送SIGKILL信号来终止容器:
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca08bd323aec ubuntu:14.04 "/bin/sh -c 'while..." 2 minutes ago Up 2 minutes festive_nobel
3d5e4ad6455f ubuntu:14.04 "/bin/bash" 18 hours ago Up 7 minutes wonderful_wozniak
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker stop ca08
ca08
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3d5e4ad6455f ubuntu:14.04 "/bin/bash" 18 hours ago Up 7 minutes wonderful_wozniak
# docker kill命令会直接发送SIGKILL信号来强行终止容器。
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker kill 3d5e
3d5e
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#可以用docker ps-qa命令看到所有容器的ID
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps -qa
22c6b5a012b0
bdbdb0d56db9
9339393ce470
f13492a1cba7
3d5e4ad6455f
#可以使用docker start命令来重新启动
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker start 2c53
# docker restart命令会将一个运行态的容器先终止,然后再重新启动它:
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker restart 22c6b5a012b0
22c6b5a012b0
10. 进入容器¶
1.
# 用attach命令有时候并不方便。当多个窗口同时用attach命令连到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22c6b5a012b0 ubuntu:14.04 "/bin/bash" 10 minutes ago Up 57 seconds dazzling_dijkstra
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker attach 22c6
root@22c6b5a012b0:/#
2.
# Docker从1.3.0版本起提供了一个更加方便的exec命令,可以在容器内直接执行任意命令。
#进入到刚创建的容器中,并启动一个bash:
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker exec -it 22c6b5a012b0 /bin/bash
root@22c6b5a012b0:/#
# 执行以下命令,启动一个busybox镜像容器
docker run -itd busybox /bin/bash #下载镜像
docker exec -it b47 /bin/bash # 进入镜像容器
busybox:是一个mini版本的linux,有linux的所有命令行工具
3.nsenter工具(不常用)
cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf -; cd util-linux-2.24;
./configure --without-ncurses
make nsenter && cp nsenter /usr/local/bin
# 使用nsenter连接到容器,先找到容器进程的PID,通过下面的命令获取
[root@iZ2ze38chylj63vuj6fqiaZ util-linux-2.24]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22c6b5a012b0 ubuntu:14.04 "/bin/bash" 31 minutes ago Up 18 minutes dazzling_dijkstra
[root@iZ2ze38chylj63vuj6fqiaZ util-linux-2.24]# docker inspect -f {{.State.Pid}} 22c6b5a012b0
6450
# PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
[root@iZ2ze38chylj63vuj6fqiaZ util-linux-2.24]# nsenter --target 6450 --mount --uts --ipc --net --pid
root@22c6b5a012b0:/#
#如果只是为了查看启动命令的输出,可以使用 docker logs 命令:
attach VS exec
attach 与 exec 主要区别如下:
attach 直接进入容器 启动命令 的终端,不会启动新的进程。
exec 则是在容器中打开新的终端,并且可以启动新的进程。
如果想直接在终端中查看启动命令的输出,用 attach;其他情况使用 exec。
退出容器,保持容器继续运行:
ctrl-p和ctrl-q。 如果使用exit。退出容器时,容器会自动关闭。
#运行远程机器上的容器
docker run -it -h test.up.com daocloud.io/centos:7
11. 容器内执行命令¶
# 交互型任务的例子
[root@hujianli-docker01 centos]# docker exec -it 7fd009ee1f86 ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18364 1584 ? Ss 02:31 0:01 /bin/bash -c wh
root 1617 0.0 0.0 4520 384 ? S 02:58 0:00 sleep 1
root 1618 0.0 0.0 34388 1472 pts/0 Rs+ 02:58 0:00 ps aux
# 后台型任务的例子:
$ sudo docker exec -d daemon_dave touch /etc/new_config_file
12. (暂停/恢复)容器¶
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
350a409c2eb2 nginx "nginx -g 'daemon ..." 4 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp epic_meninsk
#暂停工作,比如对文件系统打快照
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker pause 350a4
350a4
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
350a409c2eb2 nginx "nginx -g 'daemon ..." 26 seconds ago Up 25 seconds(Paused) 0.0.0.0:8080->80/tcp epic_menins
# 恢复容器运行
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker unpause 350a4
350a4
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
350a409c2eb2 nginx "nginx -g 'daemon ..." 2 minutes ago Up About a minute 0.0.0.0:8080->80/tcp epic_menins
13. 删除容器¶
#默认情况下,docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22c6b5a012b0 ubuntu:14.04 "/bin/bash" 35 minutes ago Up 22 minutes dazzling_dijkstra
bdbdb0d56db9 ubuntu "/bin/echo 'hello ..." 36 minutes ago Exited (0) 36 minutes ago eloquent_swartz
9339393ce470 ubuntu "/bin/bash echo 'h..." 36 minutes ago Exited (126) 36 minutes ago objective_blackwell
f13492a1cba7 ubuntu:latest "/bin/bash" 40 minutes ago Created infallible_lamarr
3d5e4ad6455f ubuntu:14.04 "/bin/bash" 19 hours ago Exited (137) 29 minutes ago wonderful_wozniak
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker rm 3d5e4ad6455f
3d5e4ad6455f
# 如果要直接删除一个运行中的容器,可以添加-f参数
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker run -d ubuntu:14.04 /bin/sh -c "while true;do echo hello world;sleep 1;done"
d8f004f4573f9703d3734d3f0096ff5ba209f0b16e9c7b5d6b528b166acd9b66
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker rm d8f00
Error response from daemon: You cannot remove a running container d8f004f4573f9703d3734d3f0096ff5ba209f0b16e9c7b5d6b528b166acd9b66. Stop the container before attempting removal
or use -f[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker rm -f d8f00
d8f00
# 同时删除后台多个容器
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker rm $(docker ps -qa)
bdbdb0d56db9
9339393ce470
或者:
#docker rm 一次可以指定多个容器,如果希望批量删除所有已经退出的容器,可以执行如下命令:
## 根据格式删除所有容器,容器的状态为停止的
docker rm -v $(docker ps -aq -f status=exited)
docker rm $(docker ps -a -q)
## 强制批量删除
docker rm $(docker ps -a -q) --force
# 使用awk实现
docker rm $(docker ps -a|awk '/Exited/{print $1}')
#或者批量清理临时镜像文件
docker rmi $(docker images -q -f dangling=true)
#批量删除运行中的容器
docker rm -f $(docker ps|grep -v "CONTAINER"|awk '{print $1}')
# 执行无法删除运行中的容器,我们需要先停止然后在删除
docker stop d8f00
docker rm d8f00
14. 其他容器操作¶
14.1 复制文件¶
# 容器数据向外复制
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
# 外部数据复制到容器内
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
$ docker cp 9eac3a /var/jenkins_home/gitee_workspace_parallel/ /home/
"docker cp" requires exactly 2 arguments.
See 'docker cp --help'.
14.2 查看变更¶
查看jenkins_jenkins_1容器内的数据修改:
$ docker container diff jenkins_jenkins_1
C /tmp
A /tmp/hsperfdata_jenkins
A /tmp/hsperfdata_jenkins/6
A /tmp/jetty-0_0_0_0-8080-war-_-any-6407271552317565788.dir
A /tmp/jetty-0_0_0_0-8080-war-_-any-6753302642276023631.dir
A /tmp/jetty-0_0_0_0-8080-war-_-any-6829047221675530177.dir
A /tmp/winstone3743544242970475678.jar
A /tmp/winstone4225465649559590246.jar
A /tmp/winstone7204593242092902219.jar
14.3 查看端口映射¶
$ docker container port jenkins_jenkins_1
8080/tcp -> 0.0.0.0:8080
15.导入和导出容器¶
15.1 导出容器¶
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22c6b5a012b0 ubuntu:14.04 "/bin/bash" 40 minutes ago Up 26 minutes dazzling_dijkstra
bdbdb0d56db9 ubuntu "/bin/echo 'hello ..." 41 minutes ago Exited (0) 41 minutes ago eloquent_swartz
9339393ce470 ubuntu "/bin/bash echo 'h..." 41 minutes ago Exited (126) 41 minutes ago objective_blackwell
f13492a1cba7 ubuntu:latest "/bin/bash" 45 minutes ago Created infallible_lamarr
#分别导出容器f13492a1cba7和容器22c6b5a012b0 到文件test_for_ubuntu:latest和文件test_for_run_ubuntu.tar
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker export -o test_for_ubuntu:latest f13492
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker export 22c6b > test_for_run_ubuntu.tar
之后,可将导出的tar文件传输到其他机器上,然后再通过导入命令导入到系统中,从而实现容器的迁移。
15.2 导入容器¶
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bdbdb0d56db9 ubuntu "/bin/echo 'hello ..." 48 minutes ago Exited (0) 48 minutes ago eloquent_swartz
9339393ce470 ubuntu "/bin/bash echo 'h..." 49 minutes ago Exited (126) 49 minutes ago objective_blackwell
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker import test_for_ubuntu\:latest test_hu/ubuntu:14.04
sha256:d8a336bc07fd1b05266710a5d93f05d6a08dae99d0ae5afa1498ad9a78325191
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker import test_for_run_ubuntu.tar run_hu/ubuntu:14.04
sha256:a7c21f91b4afe37b48a1abc1b15ce2cd7b5c759367579b0837a4c6f64332a65f
[root@iZ2ze38chylj63vuj6fqiaZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
run_hu/ubuntu 14.04 a7c21f91b4af 4 seconds ago 175 MB
test_hu/ubuntu 14.04 d8a336bc07fd 11 seconds ago 69.9 MB
16. docker资源限制¶
-m --memory #限制容器使用的内存
--memory-swap #允许交换分区到磁盘的内存
--memory-swappiness=<0-100> #容器使用swap的百分比,默认关闭-1
--oom-kill-disable #禁用oom
--cpus #可以使用cpu的数量[常用]
--cpuset-cpus #限制容器使用特定的cpu 如: 0-3 0,1
--cpu-shares #cpu共享(相对的权重)
资源限制示例:
#限制内存500MB 开启swap600MB 禁止被oom
$ docker run -d --name nginx01 --memory="500m" --memory-swap="600m" --oom-kill-disable nginx
#限制CPU示例,最多可以使用1.5个cpu
$ docker run -d --name nginx02 --cpus="1.5" nginx
#限制最多使用50%cpu
$ docker run -d --name nginx05 --cpus=".5" nginx
#内存
$ docker run -m 200M --memory-swap=300M ubuntu
#其含义是允许该容器最多使用 200M 的内存和 100M 的 swap。默认情况下,上面两组参数为 -1,即对容器内存和 swap 的使用没有限制
$ docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
# --vm 1:启动 1 个内存工作线程。
# --vm-bytes 280M:每个线程分配 280M 内存。
#####如果在启动容器时只指定 -m 而不指定 --memory-swap,那么 --memory-swap 默认为 -m 的两倍,比如:
$ docker run -it -m 200M ubuntu
容器最多使用 200M 物理内存和 200M swap。
#CPU
# 比如在 host 中启动了两个容器:
$ docker run --name "container_A" -c 1024 ubuntu
$ docker run --name "container_B" -c 512 ubuntu
#container_A 的 cpu share 1024,是 container_B 的两倍。当两个容器都需要 CPU 资源时,container_A 可以得到的 CPU 是 container_B 的两倍
# Block IO
$ docker run -it --name container_A --blkio-weight 600 ubuntu
$ docker run -it --name container_B --blkio-weight 300 ubuntu
# 限制 bps 和 iops
#bps 是 byte per second,每秒读写的数据量。
#iops 是 io per second,每秒 IO 的次数。
可通过以下参数控制容器的 bps 和 iops:
--device-read-bps,限制读某个设备的 bps。
--device-write-bps,限制写某个设备的 bps。
--device-read-iops,限制读某个设备的 iops。
--device-write-iops,限制写某个设备的 iops。
17. 容器和镜像转化、迁移方式¶
一、容器转化为镜像(docker export、docker import)
1)docker export:表示将容器导出文件包
两种命令方式(finhub-cms为容器名):
docker export finhub-cms > finhub-cms.tar
docker export -o finhub-cms.tar finhub-cms
2)docker import:表示根据docker export 导出的文件包新建一个镜像。可以基于这个新镜像创建容器,实现容器迁移。
另种命令方式:
docker import finhub-cms.tar finhub-cms:v1
cat finhub-cms.tar | docker import - finhub-cms:v1
3)docker commit:也可以实现将容器转化为镜像。
docker commit finhub-cms finhub-cms:v1
二、镜像迁移(镜像导出、镜像导入)
1)docker save:表示将镜像打包,方便迁移
两种命令方式(finhub-cms:v1为镜像名):
docker save finhub-cms:v1 > finhub-cms_v1.tar.gz
docer save -o finhub-cms_v1.tar.gz finhub-cms:v1
2)docker load: 表示将docker save导出的镜像包导入到本地仓库
两种命令方式:
docker load < finhub-cms_v1.tar.gz
docker load --input finhub-cms_v1.tar.gz
三、注意细节
一般情况下:
docker save 导出的镜像包 要比docker export打成的容器文件包大一点。
这是因为docker export导出的容器包 丢失了历史和元数据metadata。
18.使用Kitematic来管理Docker容器¶
Kitematic是一个开源项目,旨在简化在Mac或Windows PC上使用Docker的过程。Kitematic自动化Docker安装和设置过程,并提供直观的图形用户界面(GUI)来运行Docker容器。
因此,我们推荐使用Kitematic工具来查看和管理自己的容器服务。如果尚未安装此工具,可以通过以下方式进行安装:
● 从Docker for Mac或Docker for Windows菜单中选择“Kitematic”选项,开始使用Kitematic安装。
● 直接从Kitematic版本页面下载Kitematic,下载地址为https://github.com/docker/kitematic/releases/。
另外,Kitematic集成了Docker Hub,允许通过搜索、拉取任何需要的镜像,并在上面部署应用,同时也能很好地切换到命令行模式。目前包括自动映射端口、可视化更改环境变量、配置卷、流式日志等功能。
如果安装完成后无法打开,可以将Kitematic安装后的文件迁移到Docker指定目录“C:\Program Files\Docker\Kitematic”。
Kitematic是开源的,如果大家有兴趣,可以访问其开源库下载全部源代码进行研究,下载地址为https://github.com/docker/kitematic。