简单来讲,Docker容器是镜像运行的一个实例。不同的点是镜像文件是静态的,而容器带有运行时需要的可写文件层。本节围绕容器的重要操作,包括创建一个容器、启动容器、终止容器、进入容器操作以及如何删除一个容器。
可以使用docker create创建一个新容器,如下所示:
$ docker create -it docker.io/centos
b0593e4654848e7c0f87902180fdf04351c51d214cf32e7764449e7accad1375
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0593e465484 docker.io/centos "/bin/bash" 3 minutes ago Created awesome_brahmagupta
95a7802eb2a7 docker.io/centos "bash" 3 days ago Exited (127) 3 days ago wizardly_yalow
563a76e327f7 dockerfile/tomcat "bash" 3 days ago Exited (0) 3 days ago dockerfile-tomcat
b90ebe1db621 centos/tomcat "bash" 3 days ago Exited (0) 3 days ago tomcat
f0094c6d8b47 docker.io/mysql "docker-entrypoint..." 6 days ago Exited (255) 3 days ago 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
可以看到一个以ID为b0593e465484开头的容器已经被创建,但是用docker create创建的容器处于停止状态,可以使用docker start开启容器(其中docker create命令的选项较为复杂,可以使用docker create --help查看使用)。
使用docker start命令来启动一个已经创建的容器,以上述刚刚创建的容器为例:
$ docker start b0593e465484
b0593e465484
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0593e465484 docker.io/centos "/bin/bash" 8 minutes ago Up 17 seconds awesome_brahmagupta
此时通过docker ps就可以看到正在运行的docker容器包含了b0593e465484容器。
除了通过docker create与docker start命令创建与开启容器以外,也可以直接创建并启动容器。所需要的命令为docker run。等于先执行docker create命令,后执行docker start命令。例如,下面的命令输出“hello world”,之后容器停止:
$ docker run centos /bin/echo "hello world"
hello world
当利用docker run命令来创建并启动容器时,Docker在后台运行的标准操作包括:
下面的命令会启动容器的一个bash终端,允许用户进行交互:
$ docker run -it dockerfile/tomcat bash
[root@d8f6764fe504 /]#
其中-t选项是让Docker分配一个伪终端并绑定到容器的标准输入上,-i选项是让容器的标准输入保持打开。
用户可以使用exit命令或Ctrl + C的命令退出容器的伪终端:
[root@d8f6764fe504 /]# exit
exit
$ docker stop ce5
ce5
用户可以使用docker ps -qa命令查看所有的容器ID。例如:
docker ps -qa
d8f6764fe504
b0593e465484
95a7802eb2a7
563a76e327f7
b90ebe1db621
f0094c6d8b47
用户可以使用docker start命令或者docker restart启动已经停止的容器。其中使用restart命令,如果容器为终止,restart命令会先终止容器再启动容器。
$ docker start dockerfile-tomcat
dockerfile-tomcat
$ docker restart dockerfile-tomcat
dockerfile-tomcat
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
563a76e327f7 dockerfile/tomcat "bash" 13 days ago Up 35 seconds 0.0.0.0:8080->8080/tcp dockerfile-tomcat
在使用-d操作时容器会进入后台运行,用户无法看到容器中的信息且无法操作。此时进入容器中操作有多种方法,包括exec和attach命令。
docker attach [--detech-keys[=[ ] ] ] [--no-sdin] [--sig-proxy [=true] ] CONTAINER |
–datech-keys[=[ ] ]:指定退出attach模式的快捷键序列,默认时CTRL-p CTRL-q;
–no-sdin=true | false:是否关闭标准输入,默认时保持打开;
–sig-proxy=true | false:是否代理收到的系统信号给应用进程,默认为true。
但是使用attach命令有时候并不方便,当多个窗口同时使用attach命令连到同一个容器的时候,窗口会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
docker exec [-d | -deatch] [--detach-keys[= [ ] ] ] [-i | -interactive] [--privileged] [-t | --tty] [-u | --user[= USER] ] CONTAINER COMMAND [ARG...] |
-i,–interactive=true | false:打开标准输入接受用户的输入命令,默认为false;
–privileged=true | false:是否给执行命令以更高的权限,默认为false;
-t,–tty=true | false:分配给终端,默认为false;
-u,–user="":执行命令的用户ID。
例如进入到刚创建的容器中,并启动一个bash:
$ docker exec -it dockerfile-tomcat bash
[root@563a76e327f7 /]#
可以使用docker rm命令来删除处于终止或退出状态的容器,命令格式如下:
docker rm [-f | --force] [-l | --link] [-v | --volumes] CONTAINER |
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8f6764fe504 dockerfile/tomcat "bash" 47 minutes ago Exited (130) 44 minutes ago competent_albattani
b0593e465484 docker.io/centos "/bin/bash" 10 days ago Exited (0) 8 days ago awesome_brahmagupta
95a7802eb2a7 docker.io/centos "bash" 13 days ago Exited (127) 13 days ago wizardly_yalow
563a76e327f7 dockerfile/tomcat "bash" 13 days ago Up 38 minutes 0.0.0.0:8080->8080/tcp dockerfile-tomcat
b90ebe1db621 centos/tomcat "bash" 13 days ago Exited (0) 13 days ago tomcat
f0094c6d8b47 docker.io/mysql "docker-entrypoint..." 2 weeks ago Exited (255) 2 weeks ago 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
$ docker rm wizardly_yalow
wizardly_yalow
默认情况下,docker rm只能删除处于停止或退出状态的容器,并不能删除正在运行的容器。如果要删除一个正在运行的容器,可以添加-f参数。
在生成环境中,往往需要将容器中的数据持久化,或者实现多个容器间的数据共享,这必然涉及到容器的数据管理操作。
容器中管理数据的方式主要有两种:
本节将介绍融合在容器内创建数据卷,并且把本地的目录或文件挂载到容器内的数据卷。接下来介绍如何使用数据卷容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复。
数据卷是一个可供容器使用的特殊目录,它可以将操作系统的目录映射到容器。
$ docker run -d -p --name web -v /webapp training/webapp python app.py
$ docker run -d -p --name web -v /src/webapp:/opt/webapp training/webapp python app.py
上面的命令加载主机的/src/webapp目录到容器的/opt/webapp目录下。
$ docker run -rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样就可以记录在容器输入过的命令历史了。
如果用户需要在多个容器间共享一些持续更新的数据,最简单的方式时使用数据卷容器。数据卷容器也是一个容器,但是目的是专门提供数据卷供其他容器使用。
$ docker run -it -v /dbdata --name dbdata centos
root@fc6625e7d31 :/#
[root@0fc6625e7d31 /]# ls
bin dbdata dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
$ docker run -it --volumes-from dbdata --name db1 centos
[root@b9e73776c173 /]#
$ docker run -it --volumes-from dbdata --name db2 centos
[root@b63b76236e99 /]#
此时,容器db1和db2都挂载到了同一个数据卷到相同的/dbdata目录。三个容器任何一方写下内容,其他两方都可以看到写下的内容。使用–volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态。
如果删除了挂载的容器,数据卷并不会自动删除。如果删除一个数据卷,必须在删除最后一个还挂载它的容器时显示使用docker rm -v命令来指定同时删除关联的容器。
$ docker run --volumes-from dbdata -v $(pwd):/backup --name worker centos tar cvf /backup/backup.tar /dbdata
此命令首先用centos镜像创建了一个worker容器。使用–volumes-from dbdata参数来让worker容器挂载到dbdata容器的数据卷;使用-v $(pwd):/backup 命令将本地的目录挂载到容器的/backup目录下。
worker容器启动后,执行命令tar cvf /backup/backup.jar将dbdata下内容备份为/backup/backup.jar,即宿主机当前目录下的backup.jar。
$ docker run -it -v /dbdata --name dbdata2 centos bash
然后创建另一个新的容器将需要备份的数据挂载解压到容器卷中:
$ docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar