第四阶段
时 间:2023年8月1日
参加人:全班人员
内 容:
Docker容器引擎操作
目录
一、Docker 容器操作
容器是Docker 的另一个核心概念,简单说,容器是镜像的一个运行实例,是独立运行的一个或一组应用以及它们所必需的运行环境,包括文件系统、系统类库、shell 环境等。
镜像是只读模板,而容器会给这个只读模板一个额外的可写层。
下面将具体介绍围绕容器的具体操作。
1、创建容器与运行容器
Docker 的创建就是将镜像加载到容器的过程,Docker 的容器十分轻量级,用户可以随时创建或者删除。新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器,这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全停止。停止的容器可以重新启动并保留原来的修改。可以使用docker create 命令新建一个容器。
命令格式:docker create [选项]… 镜像运行的程序
常用选项:
-i 让容器的输入保持打开
-t 让Docker 分配一个伪终端
-d 守护进程形式运行
[root@huyang1 ~]# docker create -it centos /bin/bash
注意:如果创建容器命令报错“WARNING: IPv4 forwarding is disabled. Networking will not work.
”,就使用vi编辑器打开/etc/sysctl.conf文件,在其中添加net.ipv4.ip_forward=1,然后使用sysctl -p命令加载配置。
使用docker create 命令创建新容器后会返回一个唯一的ID。
可以使用docker ps 命令来查看所有容器的运行状态。添加-a 选项可以列出系统中所有容器状态。
[root@huyang1 ~]# docker ps -a
输出信息显示容器的ID 号、加载的镜像、运行的程序、创建时间、目前所处的状态、端口映射。其中状态一栏为空表示当前的容器处于停止状态。
2、容器的启动与停止
启动停止容器可以使用docker start 命令。
命令格式:docker start 容器的ID/名称
[root@huyang1 ~]# docker start f4
[root@huyang1 ~]# docker ps -a
容器启动后,可以看到容器状态一栏已经变为UP,表示容器已经处于启动状态。如果用户想创建并启动容器,可以直接执行docker run 命令,等同于先执行docker create 命令,再执行docker start 命令。需要注意只要后面的命令运行结束,容器就会停止。
当利用docker run 来创建容器时,Docker 在后台的标准运行过程是这样的:检查本地是否存在指定的镜像,当镜像不存在时,会从公有仓库下载;利用镜像创建并启动一个容器;分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;分配一个地址池中的IP 地址给容器;执行用户指定的应用程序;执行完毕后容器被终止运行。
例如,创建容器并启动执行一条shell 命令:
[root@huyang1 ~]# docker run centos /bin/bash -c ls /
这和在本地直接执行命令几乎没有区别。
[root@huyang1 ~]# docker ps -a
查看容器的运行状态,可以看出容器在执行完”/usr/bin/bash -c ls” 命令之后就停止了
有时候需要在后台持续的运行这个容器,就需要让docker 容器在守护态形式在后台进行运行。可以在docker run 命令之后添加-d 选项来实现。但是需要注意容器所运行的程序不能结束。
例如,下面的容器会持续在后台进行运行:
[root@huyang1 ~]# docker run -d nginx /bin/bash -c "while true;do echo hello;done"
docker ps查看容器,-a 查看所有容器,-q 只查看容器ID
[root@huyang1 ~]# docker ps -a
查看容器的运行状态,可以看出容器始终处于UP,运行状态。
查看容器内的输出
[root@huyang1 ~]# docker logs 737a3707b305
3、容器的运行与终止
如果需要终止运行的容器,可以使用docker stop 命令完成。
命令格式:docker stop 容器的ID/名称
[root@huyang1 ~]# docker stop 737a3707b305
[root@huyang1 ~]# docker ps -a
查看容器的运行状态,可以看出容器处于Exited,终止状态。
4、容器的进入
需要进入容器进行相应操作时,可以使用docker exec 命令或者docker attach命令进入运行着的容器。
命令格式:docker exec -it 容器ID/名称/bin/bash
其中,
-i 选项表示让容器的输入保持打开;
-t 选项表示让Docker 分配一个伪终端。
例如:进入正在运行着的容器12214903978f:
[root@huyang1 ~]# docker exec -it b9145ebaec4b /bin/bash
[root@b9145ebaec4b /]# exit
用户可以通过所创建的终端来输入命令,通过exit 命令退出容器。
通过Ctrl+pq命令退出容器并保证容器在后台继续运行。
[root@huyang1 ~]# docker attach 888
[root@888f5cfff2ab /]# exit
我们再启动一个容器测试!
[root@huyang1 ~]# docker run -itd centos /bin/bash
[root@huyang1 ~]# docker attach b7
[root@b7e664a53618 /]# read escape sequence
(ctrl p+q)
小结:
通过上述实验可以发现,使用docker exec进入容器内,不论是使用exit还是使用(ctrl p+q),退出后,容器仍在运行;但是使用docker attach进入容器之后,使用exit退出则会停止运行这个容器,而使用(ctrl p+q),容器状态则不会收到影响!
5、容器的导出与导入
用户可以将任何一个Docker 容器从一台机器迁移到另一台机器。在迁移过程中,首先需要将已经创建好的容器导出为文件,可以使用docker export 命令实现,无论这个容器是处于运行状态还是停止状态均可导出。导出之后可将导出文件传输到其他机器,通过相应的导入命令实现容器的迁移。
命令格式:docker export 容器ID/名称>文件名
例如,导出888f5cfff2ab容器到文件centos-test:
[root@huyang1 ~]# docker run -it centos /bin/bash
[root@888f5cfff2ab /]# touch 123.txt
[root@huyang1 ~]# docker export 21f5e00a42e7 > centos-exp
[root@huyang1 ~]# ls -l centos-test
导出的文件从A 机器拷贝到B 机器,之后使用docker import 命令导入,成为镜像。
命令格式:cat 文件名| docker import – 生成的镜像名称:标签
例如,导入文件centos7.tar成为本地镜像:
[root@huyang1 ~]# cat centos-exp | docker import - centos:test
[root@huyang1 ~]# docker images
备注:在导入容器和导入镜像的时候有些区别!例如,导入容器需要用到cat,而导入镜像的时候需要用到的是load,要注意甄别!
6、容器的删除
docker start|stop|restart|kill //运行已停止的容器|停止一个正在运行的容器|重启一个容器|杀死一个正在运行的容器,可以使用docker rm 命令将一个已经终止状态的容器进行删除。
命令格式:docker rm 容器ID/名称
例如,删除ID 号为21f5e00a42e7的容器:
[root@huyang1 ~]# docker rm -f 19
[root@huyang1 ~]# docker rm 5a
如果删除一个正在运行的容器,可以添加-f 选项强制删除,但是建议先将容器停止再做删除操作。
Docker 默认的存储目录为/var/lib/docker,Docker的镜像、容器、日志等内容全部都存储在此,可以单独使用大容量的分区来存储这些内容,并且一般选择建立LVM 逻辑卷。从而避免Docker 运行过程中存储目录容量不足。
[root@huyang1 ~]# docker rm -f $(docker ps -qa)
一键删除所有正在运行的容器
7、文件复制
将主机/root/abc.txt目录拷贝到容器79e689b541e的/tmp目录下。
[root@huyang1 ~]# docker cp /root/abc.txt
79e689b541e:/tmp
[root@huyang1 ~]# docker attach 79e689b541e
79e689b541e:/# ls /tmp
8、查看容器资源使用率
[root@huyang1 ~]# docker stats
9、查看容器进程状态
[root@huyang1 ~]# docker top ba
更新容器配置
--restart=always #在docker服务重启时自动启动容器
[root@huyang1 ~]# docker update --restart=always d7
[root@huyang1 ~]# docker run --restart=always -itd nginx /bin/bash 设置开机自启
二、创建私有仓库
仓库(Repository)是集中存放镜像的地方。
仓库注册服务器才是存放仓库具体的服务器(Registry),每个服务器上都可以放置多个仓库,而每个仓库下可以放置多个镜像,每个镜像上可以运行多个容器,每个容器上可以跑一个应用或应用组。
仓库自身可以分为:公共仓库和私有仓库
官方仓库: http://hub.docker.com
国内仓库: http://dl.dockerpool.com
安装docker后,可以通过官方提供的registry镜像部署一套本地的私有仓库环境
[root@huyang1 ~]# mkdir -p /opt/data/registry
[root@huyang1 ~]# docker run -d --restart=always -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
[root@huyang1 ~]# docker ps -l
准备测试镜像
[root@huyang1 ~]# docker run -d -p 8000:80 nginx
//将宿主机8000端口映射给容器的业务端口
[root@huyang1 ~]# docker ps -l
宿主机(192.168.100.131)访问8000端口测试:
[root@huyang1 ~]# docker logs dfdf455c8790
将修改过的nginx镜像做标记封装,准备上传到私有仓库
[root@huyang1 ~]# docker tag nginx
192.168.100.131:5000/nginx-test
[root@huyang1 ~]# docker push
192.168.200.117:5000/nginx-test
可以发现此时发生错误,需要以下配置:
[root@huyang1 ~]# cat /etc/docker/daemon.json
重启dock服务:
[root@huyang1 ~]# systemctl daemon-reload
[root@huyang1 ~]# systemctl restart docker
将镜像上传到私有仓库:
[root@huyang1 ~]# docker push
192.168.100.131:5000/nginx-test
从私有仓库中下载镜像到本地
[root@huyang1 ~]# docker rmi 删除现有的文件
192.168.100.131:5000/nginx-test
[root@huyang1 ~]# docker images
[root@huyang1 ~]# docker pull 下载镜像192.168.100.131:5000/nginx-test
[root@huyang1 ~]# docker images
可以发现速度很快,因为是从私有仓库导入的镜像!
docker整体流程:
三、Docker资源限制
Docker容器技术底层是通过Cgroup(Control Group 控制组)实现容器对物理资源使用的限制,限制的资源包括CPU、内存、磁盘三个方面。基本覆盖了常见的资源配额和使用量控制。
Cgroup 是Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源的机制,被LXC及Docker等很多项目用于实现进程的资源控制。
Cgroup 是提供将进程进行分组化管理的功能和接口的基础结构,Docker中I/O 或内存的分配控制等具体的资源管理功能都是通过Cgroup功能来实现的。
这些具体的资源管理功能称为Cgroup子系统,以下是对几大子系统的介绍:
blkio:限制块设备的输入输出控制。如:磁盘、光盘、USB等。
cpu:限制CPU资源的访问
cpuacct:产生Cgroup 任务的CPU资源报告。
cpuset:限制分配单独的cpu 和内存资源。
devices:允许或拒绝对设备的访问。
freezer:暂停和恢复Cgroup 任务。
memory:设置每个Cgroup 的内存限制以及产生内存资源报告。
net_cls:用于标记每个网络包。
ns:命名空间子系统。
perf_event:增加了对每group 的监测跟踪的能力,可以监测属于某个特定的group 的所有线程以及运行在特定CPU 上的线程。
使用下面的Dockerfile 来创建一个基于CentOS的stress工具镜像:
[root@huyang1 ~]# cat centos-7-x86_64.tar.gz | docker import - centos:7
[root@huyang1 ~]# mkdir stress
[root@huyang1 ~]# cd stress
[root@huyang1 stress]# vim Dockerfile
[root@huyang1 ~]# cd stress/
[root@huyang1 stress]# docker build -t centos:stress .
(一)CPU使用率
在CentOS7中可以通过修改对应的Cgroup配置文件cpu.cfs_quota_us的值来实现,直接执行echo命令将设定值导入到文件中就会立即生效。
例如,将容器face0aee201c的CPU使用设置为20000,设置CPU的使用率限定为20%。
[root@huyang1 ~]# docker run -itd centos:stress /bin/bash
[root@huyang1 ~]# docker ps -a
[root@huyang1 ~]# echo "20000" >
/sys/fs/cgroup/cpu,cpuacct/docker/558fa9a052eb7488534577683f0ef3c29ba8e65cfb217ab0c70f8a61442e301c/cpu.cfs_quota_us
在cpu.cfs_quota_us这个文件内修改-1,是不可以用vim进入进行修改的,如果使用vim进入修改,会发现无论怎么修改都不能改变-1,这里只能用echo重定向!
(二)CPU共享比例
当多个容器任务运行时,很难计算CPU的使用率,为了使容器合理使用CPU资源,可以通过--cpu-shares选项设置容器按比例共享CPU资源,
这种方式还可以实现CPU使用率的动态调整。
命令中的--cpu-shares 选项值不能保证可以获得1 个vcpu 或者多少GHz 的CPU 资源,仅仅只是一个弹性的加权值。
例如,运行3个新建容器A、B、C。占用CPU资源的比例为1:1:2:4
docker run --name A -itd --cpu-shares 1024 centos:stress /bin/bash
docker run --name B -itd --cpu-shares 1024 centos:stress /bin/bash
docker run --name C -itd --cpu-shares 2048 centos:stress /bin/bash
docker run --name D -itd --cpu-shares 4096 centos:stress /bin/bash
如果又一个容器D需要更多CPU资源,则可以将其--cpu-shares的值设置为4096,那么ABCD的CPU资源比例变为1:1:2:4。
默认情况下,每个docker容器的cpu份额都是1024。单独一个容器的份额是没有意义的。
只有在同时运行多个容器时,容器的CPU加权的效果才能体现出来。
例如,两个容器A、B的CPU份额分别为1000和500,在CPU进行时间片分配的时候,容器A比容器B多一倍的机会获得CPU的时间片。但分配的结果取决于当时主机和其他容器的运行状态,实际上也无法保证容器A一定能获得CPU时间片。比如容器A的进程一直是空闲的,那么容器B 是可以获取比容器A更多的CPU时间片的。极端情况下,比如说主机上只运行了一个容器,即使它的CPU份额只有50,它也可以独占整个主机的CPU资源。
Cgroups 只在容器分配的资源紧缺时,也就是说在需要对容器使用的资源进行限制时才会生效。因此无法单纯根据某个容器的CPU份额来确定有多少CPU 资源分配给它,资源分配结果取决于同时运行的其他容器的CPU分配和容器中进程运行情况。
换句话说,可以通过cpu shares可以设置容器使用CPU的优先级,比如启动了两个容器及运行查看CPU使用百分比。
[root@huyang1 ~]# docker run -tid --name cpu512 --cpu-shares 512 centos:stress stress -c 10
[root@huyang1 ~]# docker run -tid --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10
[root@huyang1 ~]# docker ps -a
[root@huyang1 ~]# docker exec -it 8c0d2ee56229 /bin/bash
[root@8c0d2ee56229 /]# top
[root@huyang1 ~]# docker exec -it 4d1368e3537f /bin/bash
[root@4d1368e3537f /]# top
开启了10 个stress 进程,目的是充分让系统资源变得紧张。只有这样竞争资源,设定的资源比例才可以显现出来。如果只运行一个进行,会自动分配到空闲的CPU,这样比例就无法看出来。由于案例的环境不一样,可能导致上面两张图中占用CPU 百分比会不同,但是从cpu share 来看两个容器总比例一定会是1:2。
(三)CPU周期限制
docker 提供了--cpu-period、--cpu-quota 两个参数控制容器可以分配到的CPU 时钟周期。
--cpu-period 是用来指定容器对CPU的使用要在多长时间内做一次重新分配。
--cpu-quota 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。与--cpu-shares 不同的是:这种配置是指定一个绝对值,而且没有弹性在里面,容器对CPU 资源的使用绝对不会超过配置的值。
cpu-period 和cpu-quota 的单位为微秒(μs)。cpu-period 的最小值为1000 微秒,
最大值为1 秒(10^6 μs),默认值为0.1 秒(100000 μs)。cpu-quota 的值默认为-1,
表示不做控制。cpu-period、cpu-quota 这两个参数一般联合使用。
举个例子,如果容器进程需要每1 秒使用单个CPU 的0.2 秒时间,可以将cpu-period 设置为1000000(即1 秒),cpu-quota 设置为200000(0.2 秒)。
当然,在多核情况下,如果允许容器进程需要完全占用两个CPU,则可以将cpu-period 设置为100000(即0.1 秒),cpu-quota 设置为200000(0.2 秒)。
[root@huyang1 ~]# docker run -it --cpu-period 100000 --cpu-quota 200000 centos:stress /bin/bash
[root@2474ee0f7e62 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
[root@2474ee0f7e62 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
(四)CPU核心限制
多核CPU的服务器Docker还可以控制容器运行限定使用哪些CPU内核,可以使用--cpuset-cpus选项来使某些程序独享CPU核心,以便提高其处理速度,对应的Cgroup文件为/sys/fs/cgroup/cpuset/docker/容器ID号/cpuset.cpus。
选项后直接跟参数0、1、2……表示第1个内核,第2个内核,第3个内核,与/proc/cpuinfo中的标号相同。
如果服务器有16个核心,那么CPU编号为0~15,使新建容器绑定第1~4的核心使用:
docker run -itd --cpuset-cpus 0,1,2,3 centos:stress /bin/bash
或者
docker run --itd --cpuset-cpus 0-3 centos:stress /bin/bash
那么该容器内的进程只会在0,1,2,3的CPU上运行。
通过下面指令也可以看到容器中进程与CPU 内核的绑定关系,可以认为达到了绑定CPU 内核的目的。
[root@huyang1 ~]# docker exec 2474ee0f7e62 taskset -c -p 1
pid 1's current affinity list: 0-3 //容器内部第一个进程编号一般为1
尽量使用绑定内核的方式分配CPU资源给容器进程使用,然后在配合--cpu-shares选项动态调整CPU使用资源的比例。
(五)CPU 配额控制参数的混合案例
通过--cpuset-cpus 指定容器A 使用CPU 内核0,容器B 只是用CPU 内核1。在主机上只有这两个容器使用对应CPU 内核的情况,它们各自占用全部的内核资源,--cpu-shares 没有明显效果。
--cpuset-cpus、--cpuset-mems 参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
在系统具有多个CPU 内核的情况下,需要通过cpuset-cpus 为容器CPU 内核才能比较方便地进行测试。
用下列命令创建测试用的容器:
[root@huyang1 ~]# docker run -itd --name cpu1 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
[root@huyang1 ~]# docker exec -it容器ID /bin/bash
输入top 命令查看
[root@huyang1 ~]# docker run -itd --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
[root@huyang1 ~]# docker exec -it容器ID /bin/bash
输入top 命令查看
上面的centos:stress 镜像安装了stress 工具,用来测试CPU 和内存的负载。通过在两个容器上分别执行stress -c 1 命令,将会给系统一个随机负载,产生1 个进程。这个进程都反复不停的计算由rand() 产生随机数的平方根,直到资源耗尽。
观察到宿主机上的CPU 试用率,第三个内核的使用率接近100%,并且一批进程的CPU 使用率明显存在2:1 的使用比例的对比。
(六)内存限制
与操作系统类似,容器可使用的内存包括两部分:物理内存和swap。Docker 通过下面两组参数来控制容器内存的使用量。
-m 或--memory:设置内存的使用限额,例如100M, 1024M。
--memory-swap:设置内存swap 的使用限额。
当执行如下命令:
其含义是允许该容器最多使用200M 的内存和300M 的swap。
[root@huyang1 ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
--vm1:启动1 个内存工作线程。
--vm-bytes 280M:每个线程分配280M 内存。
默认情况下,容器可以使用主机上的所有空闲内存。与CPU 的cgroups 配置类似,docker 会自动为容器在目录/sys/fs/cgroup/memory/docker/<容器的完整长ID>中创建相应cgroup 配置文件。
因为280M 在可分配的范围(300M)内,所以工作线程能够正常工作,其过程是:
分配280M 内存。
释放280M 内存。
再分配280M 内存。
再释放280M 内存。
一直循环......
如果让工作线程分配的内存超过300M,分配的内存超过限额,stress 线程报错,容器退出。
(七)Block IO 的限制
默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight 参数来改变容器block IO 的优先级。
--blkio-weight 与--cpu-shares 类似,设置的是相对权重值,默认为500。
在下面的例子中,容器A 读写磁盘的带宽是容器B 的两倍。
[root@huyang1 ~]# docker run -it --name container_A --blkio-weight 600 centos:stress /bin/bash
[root@a4b63e72a03b /]# cat /sys/fs/cgroup/blkio/blkio.weight
600
[root@huyang1 ~]# docker run -it --name container_B --blkio-weight 300 centos:stress /bin/bash
[root@ee688a3bba2b /]# cat /sys/fs/cgroup/blkio/blkio.weight
300
(八)限制bps 和iops
如果在一台服务器上进行容器的混合部署,那么会存在同时几个程序写磁盘数据的情况,这时可以通过--device-write-iops选项来限制每秒写io次数来限制制定设备的写速度。相应的还有--device-read-iops选项可以限制读取IO的速度,但是这种方法只能限制设备,而不能限制分区,相应的Cgroup写配置文件为/sys/fs/cgroup/blkio/容器ID/ blkio.throttle.write_iops_device。
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
下面的示例是限制容器写/dev/sda 的速率为5 MB/s。
[root@huyang1 ~]# docker run -it --device-write-bps /dev/sda:5MB centos:stress /bin/bash [root@7fc31cd1514b /]# dd if=/dev/zero of=test bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 20.0051 s, 5.2 MB/s
通过dd 测试在容器中写磁盘的速度。因为容器的文件系统是在host /dev/sda 上的,在容器中写文件相当于对宿主机/dev/sda 进行写操作。另外,oflag=direct 指定用directIO 方式写文件,这样--device-write-bps 才能生效。
结果表明,bps 5.2 MB/s 在限速5MB/s 左右。作为对比测试,如果不限速,结果如下:
[root@huyang1 ~]# docker run -it centos:stress /bin/bash
[root@9128099a8947 /]# dd if=/dev/zero of=test bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.384372 s, 273 MB/s
四、Docker数据持久化
数据持久化介绍
在Docker中若要想实现容器数据的持久化(所谓的数据持久化即数据不随着Container的结束而销毁),需要将数据从宿主机挂载到容器中。目前Docker提供了三种不同的方式将数据从宿主机挂载到容器中。
(1)Volumes:Docker会管理宿主机文件系统的一部分资源,默认位于 /var/lib/docker/volumes 目录中;(最常用的方式)
测 试:
[root@huyang1 ~]# docker run -it -v /opt/ centos /bin/bash
[root@bda59433abd2 /]# touch /opt/test.txt
[root@bda59433abd2 /]# ls /opt/
test.txt
验 证:
[root@huyang1 ~]# ls
/var/lib/docker/volumes/7e6ef064e82bb0551336c11e053d8958e861c440a62d96ad142060e4a96a1f44/_data/
test.txt
目前所有Container的数据都保存在/var/lib/docker/volumes/目录下边,由于没有在创建时指定卷,所以Docker帮我们默认创建许多匿名(就上面这一堆很长ID的名字)卷。
(2)bind mounts:意为着可以指定存储在宿主机系统的任意位置;(比较常用的方式)
但是bind mounts在不同的宿主机系统之间是不可移植的,比如Windows和Linux的存储结构是不一样的,bind mount所指向的host目录也不能一样。这也是为什么bind mount不能出现在Dockerfile中的原因,因为会导致Dockerfile无法移植。
(3)tmpfs:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统;(一般都不会用的方式)
五、Volume的基本使用
(一)管理卷
创建一个自定义容器卷
[root@huyang1 ~]# docker volume create nginx-data
查看所有容器卷
[root@huyang1 ~]# docker volume ls
查看指定容器卷详情信息
[root@huyang1 ~]# docker volume inspect nginx-data
(二)创建使用指定卷的容器
有了自定义容器卷,我们可以创建一个使用这个数据卷的容器
[root@huyang1 ~]# docker run -d -it --name=nginx -p 8000:80 -v nginx-data:/usr/share/nginx/html nginx
[root@huyang1 ~]# docker exec -it nginx /bin/bash
root@59d8ae8657b9:/# ls /usr/share/nginx/html/
50x.html index.html
选项-v代表挂载数据卷,这里使用自定数据卷nginx-data,并且将数据卷挂载到 /usr/share/nginx/html (这个目录是yum安装nginx的默认网页目录)。如果没有通过-v指定,那么Docker会默认帮我们创建匿名数据卷进行映射和挂载。
注意:
数据卷下无文件,显示容器对应目录下的文件
数据卷下有文件,显示数据卷原有文件,并将容器对应目录的文件隐藏,显示数据卷文件
可以看到网页目录下有两个默认页面,这时我们可以查看宿主机文件系统的数据
[root@huyang1 ~]# ls /var/lib/docker/volumes/nginx-data/_data/
可以看到容器里面的两个默认页面,由此可知Volume帮我们做了类似于一个软链接的功能。在容器里边的改动,我们可以在宿主机里感知,而在宿主机里面的改动,在容器里边可以感知到。
如果我们手动stop并且remove当前nginx容器,我们会发现容器卷里面的文件还在,并没有随着容器被删除掉。
[root@huyang1 ~]# docker stop nginx
nginx
[root@huyang1 ~]# docker rm nginx
nginx
[root@huyang1 ~]# ls
/var/lib/docker/volumes/nginx-data/_data/
所以在数据卷里边的东西是可以持久化的。如果下次还需要创建一个nginx容器,那么时候复用当前数据卷里面文件的。
[root@huyang1 ~]# docker run -d -it --name=nginx2 -p 8001:80 -v nginx-data:/usr/share/nginx/html nginx
f21efa07e66d89004327f6cbb705af9d4464b0f423ffdcec54d9c352b90cbdcb
[root@huyang1 ~]# docker exec -it nginx2 /bin/bash
root@f21efa07e66d:/# ls /usr/share/nginx/html
50x.html index.html
此外,我们还可以启动多个nginx容器实例,共享同一个数据卷。数据卷的复用性和扩展性较强的。
(三)清理卷
如果不再使用自定义数据卷了,那么可以手动清理掉:
[root@huyang1 ~]# docker volume rm nginx-data
nginx-data
[root@huyang1 ~]# docker volume ls
备注:当卷正在被容器所使用的时候,是不可以删除的,强制删除也不可以,此时应当停止使用这个卷,才可以删除这个卷!