文章索引
容器也是docker的一种核心概念。简单来讲,容器是镜像的运行实例,不同的是它带有额外的可写入层。如果认为虚拟机是模拟运行的一套操作系统(提供运行环境和其他系统环境)和泡在上面的应用。那么docker容器就是独立运行的一个或者一组应用,以及他们所需要的运行环境。
docker是一种十分轻量级的容器,用户可以随时创建或者删除容器。
新建容器
新建容器可以使用docker create命令新建一个容器,例如:
$ sudo docker create -it ubuntu:latest eb6cbaf7b3e0d2352b99e6a87ae86c72d44e6ac46c26a92559b3f455c78ce322 $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eb6cbaf7b3e0 ubuntu:latest "/bin/bash" 46 seconds ago Created berserk_banach
使用docker create创建的容器处于停止状态,可以使用docker start启动它。
新建并启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动另一种是将会在终止状态(stopped)的容器重新启动,所需的命令主要为docker run,相当于先执行了docker create 然后再执行docker star命令。
例如,创建先忙=下面容器先输出一个“Hello world!”然后停止容器:
$ sudo docker run ubuntu /bin/echo 'Hello World' Hello World
当利用docker run来创建并启动容器时,docker在后台运行的标准操作,包括:
1、检查本地是否存在本地镜像,不存在就从共有仓库创建。
2、利用镜像创建并启动一个容器。
3、分配一个文件系统,并在只读的镜像层外面挂载一个=层可读写层。
4、从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去。
5、从地址池配置一个IP给容器。
6、执行用户执行的应用程序。
7、执行完毕后容器被终止。
例如,创建一个bash终端,允许用户进行交互:
$ sudo docker run -t -i ubuntu:14.04 /bin/bash root@2bb7323a58bc:/#
其中-t选项让docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。
在交互式下,用户可以通过所创建的终端来输入命令,例如:
root@2bb7323a58bc:/# root@2bb7323a58bc:/# pwd / root@2bb7323a58bc:/# whoami root root@2bb7323a58bc:/# ps PID TTY TIME CMD 1 ? 00:00:00 bash 19 ? 00:00:00 ps
在容器内使用ps命令查看进程,可以看到只运行了bash应用,并没有运行其他不需要的进程。用户可以按Ctrl+d或者exit退出容器:
root@2bb7323a58bc:/# exit exit
对于创建的bash容器,当使用exit退出后,该容器会自动处于终止状态,当运行的应用退出后,容器也没有继续运行的必要了。
守护态运行
很多时候需要docker容器在后台以守护进态(daemonized)形式运行。用户可以用-d参数。
例如,下面在后台运行一个容器:
$ sudo docker run -d ubuntu /bin/bash -c "while true;do echo hello world;sleep 1;done" 8647fab02d93b55d0b2da511544ac833b33d5f4ab8ae1a0847c85aaa62a3b26d
容器启动后会返回一个唯一的ID,可以通过docker ps命令来查看容器信息:
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8647fab02d93 ubuntu "/bin/bash -c 'while " 59 seconds ago Up 58 seconds angry_ride
要获取容器的输出信息,我们可以通过docker logs命令查看:
$ sudo docker logs 8647fab02d93 hello world hello world hello world ........
二、终止容器
终止容器可以使用docker stop来终止运行容器,命令格式为:docker stop [-t] --time[=10],它会首先向容器发送SIGTERM信息,等待一段时间后(默认为10秒),再发送SIGKILL信号终止容器。
此外,当docker容器中指定的应用终止时,容器也自动终止。例如我们终止刚才启动的容器:
$ sudo docker stop 8647fab02d93 8647fab02d93 $ sudo docker ps -a -q 8647fab02d93 2bb7323a58bc 7fbb467939e9 eb6cbaf7b3e0 c14c52a30a6c 2513e3394ffb e29a9a911ae7 ccc0659fbf64
处于终止状态的容器,可以使用docker start命令来重新启动:
$ sudo docker start 8647fab02d93 8647fab02d93 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8647fab02d93 ubuntu "/bin/bash -c 'while " 10 minutes ago Up 3 seconds angry_ride
此外,还有个将容器运行状态终止,然后再重启的命令:docker restart
三、进入容器
在使用-d参数时,容器启动后会进入后台,用户无法看到容器中的信息。有时候会进入容器进行操作,例如: docker attach 、docker exec命令以及 nsenter工具。
attach命令
docker attach命令是docker自带命令。
$ sudo docker run -idt ubuntu 17c7e0c4d3217d4a791e745c7e72c849536e9edf14a2da316b7e9836dd205925 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 17c7e0c4d321 ubuntu "/bin/bash" 7 seconds ago Up 6 seconds drunk_bartik 8647fab02d93 ubuntu "/bin/bash -c 'while "16 minutes ago Up 6 minutes angry_ride $ sudo docker attach drunk_bartik root@17c7e0c4d321:/#
但是使用这个命令不是特别方便,当多个窗口同时attach到同一个容器的时候,所有窗口都会同步显示,当某个窗口命令阻塞时,其他创建也无法执行操作
exec命令
docker从1.3版本起,提供一个更加方便的工具exec,可以直接在容器内运行命令,例如,进入刚创建的容器并启动一个bash:
$ sudo docker exec -ti cbddc9a91d96 /bin/bash root@cbddc9a91d96:/#
nsenter工具
nsenter工具在util-linux包2.2版本后包含。如果系统中没有util-linux命令,那么可以通过下面的方式安装:
$ sudo yum install util-linux -y
为了使用nsenter连接到容器,还需要找到容器的进程pid,可以通过下面命令获取:
$ PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
通过这个PID可以连接到容器:
$ nsenter --target $PID --mount --uts --ipc --net --pid
下面是个完整的示例:
$ sudo docker run -idt ubuntu 8647fab02d93adc2100a7f49b399316120b633f7f96cb03236e6c37cff764c9f71 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8647fab02d93 ubuntu "/bin/bash" 7 seconds ago Up 5 seconds jolly_volhard $ echo $(sudo docker inspect --format {{.State.Pid}} 8647fab02d93) 863 $ sudo nsenter --target 863 --mount --uts --ipc --net --pid root@8647fab02d93:/# w 07:29:57 up 12 days, 3:42, 0 users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root@8647fab02d93:/# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 03:14 ? 00:00:05 /bin/bash -c while true;do echo hello worldl;sleep 1;done root 15316 0 0 07:29 ? 00:00:00 -bash root 15326 1 0 07:29 ? 00:00:00 sleep 1 root 15327 15316 0 07:29 ? 00:00:00 ps -ef
进入容器的脚本:传参
[root@linux-node1 ~]# cat ns.sh #!/bin/sh PID=$(docker inspect --format "{{.State.Pid}}" $1) nsenter -t $PID -u -i -n -p
四、删除容器
可以使用docker rm命令删除处于终止状态的容器,命令格式为:docker rm [OPTIONS] CONTAINER [CONTAINER...]。支持选项包括:
1、-f,--force=false #强制终止并删除容器
2、-l,link=false #删除容器的连接,但保留容器
3、-v,--volumes=false #删除容器挂载的数据卷
例如,查看处于终止状态的容器并删除如下所示
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ccc0659fbf64 c54a2cc56cbb "/hello" 4 months ago Exited (0) 4 months ago thirsty_swanson $ sudo docker rm ccc0659fbf64 ccc0659fbf64
如果要删除一个运行的容器,可以添加-f参数,docker会发送SIGKILL信号给容器终止其应用:
$ sudo docker run -d ubuntu /bin/bash -c "while true;do echo hello worldl;sleep 1;done" c1a30892b8ffb61edeced752a3031a7bc2a9d4633cafcf6533bd6a42f93fd00a $ sudo docker rm c1a3 Error response from daemon: You cannot remove a running container c1a30892b8ffb61edeced752a3031a7bc2a9d4633cafcf6533bd6a42f93fd00a. Stop the container before attempting removal or use -f $ sudo docker rm -f c1a3 c1a3
五、导入和导出容器
导出容器
导出容器是指导出一个已经创建的容器到一个文件,不管此时容器是否处于运行状态,可以使用docker export命令,该命令格式为docker export CONTAINER.
查看所有容器如下所示:
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a22bc3a703fa ubuntu "/bin/bash -c 'while " 3 seconds ago Up 2 seconds amazing_wright
导出a22bc3a703fa到test_for_a22.tar
$ sudo docker export a22 > test_for_a22.tar $ ls test_for_a22.tar
可以将传到其他机器上,通过导入命令实现容器迁移
导入容器
导出文件可以用docker import命令导入成为镜像,例如:
$ cat test_for_a22.tar |sudo docker import - test/ubuntu:v1.0 sha256:59f205052cd1f413f1086e9370f43c5be23a570bb02c5b7dd7308cf8b15ee9d4 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE test/ubuntu v1.0 59f205052cd1 8 seconds ago 97.5 MB
之前我们用docker load命令来导入过镜像,那么他们两个有什么区别呢?实际上,docker load命令来导入镜像存储文件到本地镜像库,又可以使用docker import命令来导入一个容器快照到本地镜像库。这两个的区别是处于容器快照文件将丢失所有历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积要大。此外,从容器快照文件导入时可以重新制定标签等元数据信息。
!评论内容需包含中文