2. Docker容器相关操作
Docker容器相关操作
一、简单的hello world实例
1.1 将image文件从仓库抓取到本地
[root@docker ~]# docker image pull hello-world
1.2 查看抓取到本地的image文件
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 4 weeks ago 13.3kB
1.3 运行此image文件
[root@docker ~]# docker container run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
... ...
# 注释
docker container run 命令会从image文件,生成一个正在运行的容器实例
'注意,docker container run 命令具有自动抓取image文件的功能。如果发现本地没有执行的Image文件,就会从仓库自动抓取'
# 上述镜像运行成功后,会输出一段提示,输出提示之后,hello world就会停止运行,容器自动终止
# 有些容器不会自动终止,因为提供的是服务。比如,安装运行Ubuntu 的image ,就可以在命令行体验Ubuntu系统
[root@docker ~]# docker image pull ubuntu
[root@docker ~]# docker container run -it ubuntu bash
'对于那些不会自动终止的容器,必须使用 docker container kill命令手动终止'
[root@docker ~]# docker container kill ebe17146ca4d
二、容器文件
2.1 什么是容器
# 容器是一种轻量级、可移植并将应用程序进行打包的技术,使应用程序可以在几乎任何地方以相同的方式运行,Docker将镜像文件运行起来后,产生的对象就是容器。容器就相当于是镜像运行起来的一个实例且容器具备一定的生命周期
2.2 容器的生命周期
# 容器之内必须至少有一个进程运行在前台。如果一个进程都没有的话,那么此容器就相当于完成了它的生命周期
2.3 什么是容器文件
# image文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已
三、容器相关命令
3.1 查看本机容器列表
# 列出本机正在运行的容器
[root@docker ~]# docker container ls
# 列出本机所有容器,包括终止运行的容器
[root@docker ~]# docker container ls --all
'or以下两个命令'
[root@docker ~]# docker ps
[root@docker ~]# docker ps --all
'每列内容解释'
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 容器的ID 镜像 容器的启动命令 容器的创建时间 容器的状态 容器的端口 容器的名称
其中STATUS里面可能含有以下内容
UP: 容器处于启动状态
Exited: 容器处于停止状态
Created: 容器已经创建,但是还没有启动
'上面命令的输出结果中,包括容器的ID。很多地方都需要提供这个ID,比如上一个内容的终止容器运行的'
docker container kill命令
# 关于docker ps常用的参数主要有以下两种
-a: 查看系统上所有的容器(包含未启动)
-q: 只显示容器ID
3.2 容器的创建和启动
所需要的命令主要为 docker run
1) 新建并启动
# 格式如下,其中参数和启动命令可以省略
docker run [参数] 镜像 [启动命令]
# 参数如下
-d: 以守护进程方式运行容器
--name: 自定义容器的名称
-p: 指定一个端口映射
-P: 随机一个端口映射
-i: 打开标准输出
-t: 创建一个终端(让Docker分配一个伪终端并绑定到容器的标准输入上)
-e: 在容器内部增加一个环境变量
-h: 指定一个主机名(默认的主机名是容器的缩写版ID)
-v: 指定一个挂载卷(将宿主主机的目录挂载到容器内,从而实现文件互通)
--network: 连接一个网桥
--Line: 连接一个容器
# 案例如下
1. 使用下面命令输出一个"hello world",之后终止容器
[root@docker ~]# docker run ubuntu:v1 /bin/echo 'hello world'
hello world
2. 使用ubuntu镜像允许用户进行交互
[root@docker ~]# docker run -t -i ubuntu:v1 /bin/bash
root@a197ee3924c8:/#
3. 启动nginx容器并自定义容器的名称
# 下面命令的第一个nginx为自定义容器的名称,第二个nginx为镜像的名称
[root@docker ~]# docker run -d --name nginx nginx
7ef3eaf29a7923545ccaef81b84eb1c0a9b289aed381ba7323fae61e12cf317c
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ef3eaf29a79 nginx "/docker-entrypoint.…" 30 seconds ago Up 29 seconds 80/tcp nginx
'当利用Docker run来创建容器时,Docker在后台运行的标准操作如下'
1. 检查本地是否存在指定的镜像,不存在就从官方仓库下载
2. 利用镜像创建并启动一个容器
3. 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
4. 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
5. 从地址池配置一个ip地址给容器
6. 执行用户指定的应用程序
7. 执行完毕后容器被终止
2) 启动已终止容器
# 可以利用 docker container start命令,直接将一个已经终止(exited)的容器启动运行
'容器的核心为所执行的应用程序,所需要的资源都是应用程序锁必须的,除此之外,并没有其他的资源'
[root@docker ~]# docker container start 0b4ead31509d
3) 守护态运行
# 更多时候,需要让Docker在后台运行而不是直接把执行命令的结果输出在当前宿主机下,此时就可以通过添加 -d 参数来实现
'如果不使用-d参数运行容器'
# 此时容器会把输出的结果打印到宿主机上面
[root@docker ~]# docker run ubuntu:v1 /bin/sh -c "while true;do echo hello world;sleep 1;done"
hello world
hello world
hello world
hello world
'如果使用-d参数运行容器'
# 此时容器会在后台运行并不会把输出的结果打印到宿主机上面(结果输出可以用docker logs查看)
[root@docker ~]# docker run -d ubuntu:v1 /bin/sh -c "while true;do echo hello world;sleep 1;done"
7349a2276df9087df3071fe7a2918864951b5fba305a34ccafef8aa78c78005b
'注意: 容器是否会长久运行,是和docker run指定的命令有关,和-d参数无关'
# 使用-d参数启动后会返回一个唯一的id,也可以通过以下命令来查看容器信息
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7349a2276df9 ubuntu:v1 "/bin/sh -c 'while t…" 3 minutes ago Up 3 minutes gracious_vaughan
# 要获取容器的输出信息,通过以下命令查看日志
[root@docker ~]# docker logs 7349a2276df9
hello world
hello world
hello world
hello world
... ...
3.3 查看容器的详细状态
'可使用docker inspect 命令查看某个容器的 详细状态'
# 语法如下
docker inspect [容器的ID或名称]
1. 要求判断指定容器是否正在运行
[root@docker ~]# docker inspect -f '{{ .State.Running }}' 64a54a154922
true
'如果显示为true则表示该容器正在运行,显示false则显示该容器没有在运行'
'其中 -f 选项为指定返回值的模板文件。'
3.4 容器的终止
'可使用 docker container stop 来终止一个运行中的容器'
# 此外,当docker容器中指定的应用终结时,容器也将自动终止,例如,之前我们只启动了一个带终端的容器,当我们通过exit命令或者ctrl+d来退出终端时,所创建的容器立刻终止
'案例如下'
1. 查看当前正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3efa49b7280 ubuntu:v1 "/bin/sh -c 'while t…" 12 seconds ago Up 10 seconds nervous_leavitt
2. 停止正在运行的容器
[root@docker ~]# docker stop nervous_leavitt
# 终止状态的容器可以用以下命令看到
[root@docker ~]# docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3efa49b7280 ubuntu:v1 "/bin/sh -c 'while t…" 2 minutes ago Exited (137) About a minute ago nervous_leavitt
'或者如下命令'
[root@docker ~]# docker ps -all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3efa49b7280 ubuntu:v1 "/bin/sh -c 'while t…" 3 minutes ago Exited (137) About a minute ago nervous_leavitt
'处于终止状态的容器,可以通过docker container start 命令来重新启动'
3.5 容器的暂停与重新运行
# 使用下面命令 容器将暂定服务
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1761c7fa113 ubuntu:v1 "/bin/bash" 2 hours ago Up 2 hours funny_driscoll
[root@docker ~]# docker container pause funny_driscoll
funny_driscoll
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1761c7fa113 ubuntu:v1 "/bin/bash" 2 hours ago Up 2 hours (Paused) funny_driscoll
# 使用下面命令,容器将重新运行,恢复和提供服务
[root@docker ~]# docker container unpause funny_driscoll
funny_driscoll
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1761c7fa113 ubuntu:v1 "/bin/bash" 2 hours ago Up 2 hours funny_driscoll
3.6 进入容器
'在使用 -d 参数时,容器启动会进入后台'
# 某些时候需要进入容器进行操作,包括使用 docker attach 命令或docker exec 命令,推荐使用exec命令
1) attach命令
attach是进入容器,原理是将容器内PID为1的进程开辟一个管道,连接到宿主主机,当在宿主主机上退出时,容器也随即退出(结束了生命周期)
# 1. 后台运行ubuntu
[root@docker ~]# docker run -dit ubuntu
0d82f14af08533328de7af056677b2a0b797550846bd882a9fdaefecd447e680
# 2. 查看当前运行的容器信息
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d82f14af085 ubuntu "bash" About a minute ago Up 59 seconds great_leavitt
# 3. 进入容器
[root@docker ~]# docker attach 0d82
root@0d82f14af085:/#
'注意: 如果输入exit的话,会导致容器的停止'
2) exec命令
exec其本质是在宿主机上执行一个容器内的命令,但是加上-it参数,可以达到进入容器的效果,其原理是在容器内部新创建一个bash的进程,所以当exec退出时不影响容器的正常运行
# docker exec 后面可以跟多个参数,这里主要说明 -i -t参数
1. 只用 -i 参数时,由于没有分配伪终端,页面没有我们熟悉的linux命令提示符,但命令执行结果仍然可以返回
2. 当 -i -t参数一起使用时,则可以看到我们熟悉的linux命令提示符
[root@docker ~]# docker run -dit ubuntu
ac383b660f079ccea6a3e9c74fcf7e39aadb6a7e0739a08508a9571e701bab5d
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac383b660f07 ubuntu "bash" 33 seconds ago Up 32 seconds intelligent_wu
[root@docker ~]# docker exec -it ac38 bash
root@ac383b660f07:/#
'如果从这个容器中使用exit,不会导致容器的停止。这就是推荐使用docker exec的原因'
3) nsenter命令
nsenter的原理是建立一个管道进程,连接到容器的内部
[root@docker ~]# nsenter --target $( docker inspect -f '{{.State.Pid }}' centos ) --mount --uts --ipc --net --pid
3.7 复制容器中的内容
1) 将宿主主机上的内容复制到容器
[root@docker ~]# docker cp init.sh f1761c7fa113:/root/
[root@docker ~]# docker exec -it f1761c7fa113 /bin/bash -c 'ls /root'
init.sh
2) 将容器内的文件复制到宿主主机
[root@docker ~]# docker cp f1761c7fa113:/root/init.sh /tmp/
[root@docker ~]# ll /tmp/
total 8
-rwxr-xr-x. 1 root root 4544 Jun 29 03:42 init.sh
3.8 容器的导出与导入
1) 导出容器
'如果要导出本地某个容器,可以使用docker export 命令'
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac383b660f07 ubuntu "bash" 4 minutes ago Up 4 minutes intelligent_wu
0d82f14af085 ubuntu "bash" 16 hours ago Exited (127) 4 minutes ago great_leavitt
[root@docker ~]# docker export 0d82f14af085 > ubuntu.tar
[root@docker ~]# ll
total 131044
-rw-------. 1 root root 75158528 Oct 23 02:31 ubuntu.tar
'这样将多出容器快照到本地文件'
2) 导入容器
'可以使用 docker import 从容器快照文件再导入为镜像'
[root@docker ~]# cat ubuntu.tar | docker import - test/ubuntu:v1.0
sha256:8a5d582b033d25906fcb975568124956ee935c8e2d7ca0c6678007b607acb61b
[root@docker ~]#
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/ubuntu v1.0 8a5d582b033d 3 seconds ago 72.8MB
# 此外也可以通过指定URL或者某个目录来导入,如下所示
$ docker import http://example.com/exampleimage.tgz example/imagerepo
'注意,用户既可以使用docker load 来导入镜像存储文件到本地镜像库,也可以使用docker import来导入一个容器快照到本地镜像库'
'这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息'
3.9 将容器保存成本地镜像
[root@docker ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1761c7fa113 ubuntu:v1 "/bin/bash" 2 hours ago Up 2 hours funny_driscoll
[root@docker ~]# docker commit -a "yuyuyu" -m 'this is v2 version' -p funny_driscoll ubuntu:v2
sha256:c5b12f7981dde73e63463ee7c3e74631919b50d4e416634448f897bbd2723448
[root@docker ~]#
[root@docker ~]#
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu v2 c5b12f7981dd 5 seconds ago 72.8MB
# docker commit 参数详解
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
3.10 容器的删除
1) 删除容器
'可以使用 docker container rm来删除一个处于终止状态的容器'
[root@docker ~]# docker container rm 0d82f14af085
0d82f14af085
# 如果要删除一个运行中的容器 ,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器
2) 清理所有处于终止状态的容器
'用 docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦'
# 可使用下面的命令清理掉所有处于终止状态的容器
[root@docker ~]# docker container prune
3) 清理所有容器
[root@docker ~]# docker rm -f $(docker ps -a -q)
7ef3eaf29a79
ac383b660f07
1. 首先docker ps -a先查询出来所有的容器(包括未运行的)
2. -q参数为静默模式,只显示出容器编号
3. 即 docker rm -f [所有的容器编号]
3.11 查看容器的运行日志
[root@docker ~]# docker run -d nginx
ea201d5f886fded7aa33f0c890e1375f340c0bf590acfda2a21b71fc30a998f5
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea201d5f886f nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp hungry_maxwell
f1761c7fa113 ubuntu:v1 "/bin/bash" 2 hours ago Up 2 hours funny_driscoll
[root@docker ~]# docker container logs hungry_maxwell
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
... ...
'可使用 -f 参数 进行持续监控'
四、使用容器搭建小游戏
[root@docker ~]# docker run -d --name mario -v /opt/html5-mario:/usr/share/nginx/html -p 8080:80 nginx
'其中参数详解'
docker run: 启动并新建容器
--name mario: 将此容器重命名为mario
-v: 为需要挂载的目录(将本地的opt/html5-mario目录挂载到容器内的/usr/share/nginx/html目录)
-p: 映射端口(将容器的80端口映射为本地的8080端口)
nginx: 启动容器的镜像

浙公网安备 33010602011771号