docker存储卷
容器可写层数据生命周期
[root@host2 ~]# docker stop app1
app1
[root@host2 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77498e80db24 notechbb/haproxy:v1.7.12 "/bin/sh -c /etc/hap…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp, 0.0.0.0:9999->9999/tcp ha1
e62ae92f39b4 notechbb/app2:v1 "/bin/sh -c '/usr/lo…" 4 hours ago Up 4 hours 8009/tcp, 0.0.0.0:8081->8080/tcp app2
9f09c0ddf426 notechbb/app1:v1 "/bin/sh -c '/usr/lo…" 4 hours ago Exited (143) 2 seconds ago app1
[root@host2 ~]# ll /var/lib/docker/containers/
total 0
drwx------ 4 root root 237 Oct 29 16:22 77498e80db24220aeae6d1075109834b50161297dc41ee1c699dc7f1934ae4e7
drwx------ 4 root root 237 Oct 29 19:50 9f09c0ddf426c26aacc4f116cca24ccbeb46cb951cf918d11906c9d39500ed15
drwx------ 4 root root 237 Oct 29 16:05 e62ae92f39b4703ae1c583ee6538f6035941296f430e183753692104cd50b625
[root@host2 ~]# docker rm -f app1
app1
[root@host2 ~]# ll /var/lib/docker/containers/
total 0
drwx------ 4 root root 237 Oct 29 16:22 77498e80db24220aeae6d1075109834b50161297dc41ee1c699dc7f1934ae4e7
drwx------ 4 root root 237 Oct 29 16:05 e62ae92f39b4703ae1c583ee6538f6035941296f430e183753692104cd50b625
# 在/var/lib/docker/containers目录下,是各个容器运行时可写层数据的存放目录;
# 由上可以看出,每个容器在目录下,都由一个专属数据目录,命名为容器的长id;
# 在容器停止时,数据目录不会被删除,
# 只有容器被删除后,数据目录会随之删除,期间数据变更也不复存在;
# 为了容器数据的持久化,引入2个方法:
1、存储卷:即挂载宿主机或网络存储的目录,开放给容器使用: 又分为:
docker管理的卷:docker分配宿主机目录给容器
手动指定的卷:手动指定宿主机目录给容器
2、数据容器:将数据存储于容器中;
docker的数据保存机制
数据容器
启动一个容器a,做server端,其提供数据给其他容器如b,c,也起到了在b和c之间共享数据的作用;b和c是容器a的客户端;
存储卷
运行中的docker容器,所有发生的数据修改都会保存在镜像文件最上面的一层:可写层;并且,随之容器的停止而消失,因此,为了持久化保存容器运行中产生的数据,往往需要引入存储卷:
ps:可写层数据永久化的方法之一:将容器提交为新镜像;
即将容器的某个目录挂载到宿主机的某个目录,或者远程网络存储提供的目录,容器停止后,其运行期间所有的数据变更仍会永久的保持在存储卷上,从而实现了数据的持久化;
存储卷示意图
存储卷管理操作
手动指定宿主机存储卷目录
-
创建容器时,-v手动指定宿主机某目录,挂载到容器某目录(ro选项,可设置只读,如web容器挂载宿主机只读的静态文件)
-
向宿主机挂载目录写入数据
-
连入容器,查看数据是否存在
-
创建容器时,-v手动指定宿主机某目录,挂载到容器某目录(ro选项,可设置只读,如web容器挂载宿主机只读的静态文件)
[root@host2 ~]# docker run -d --name app1 -v /data/app1/:/usr/local/tomcat/webapps/app1 -p 800:8080 notechbb/app1:v1 e9a318704d7c9bc45a596e26f25beccb96f4f029f61420f07736b6c46132fb7e # 运行容器,-v选项挂载宿主机目录
-
向宿主机挂载目录写入数据
[root@host2 ~]# mkdir /data [root@host2 ~]# mkdir /data/app1 [root@host2 ~]# echo "this is volume from host" > /data/app1/index.html
-
连入容器,查看数据是否存在
[root@host2 ~]# /root/docker-in.sh app1 [root@e9a318704d7c /]# yum install -y iproute # 连接入容器,可以看到数据 [root@e9a318704d7c webapps]# pwd /usr/local/tomcat/webapps [root@e9a318704d7c webapps]# cat app1/index.html this is volume from host
-
容器内修改数据,查看宿主机文件变化
[root@e9a318704d7c webapps]# echo some-change >> app1/index.html [root@e9a318704d7c webapps]# exit logout [root@host2 ~]# cat /data/app1/index.html this is volume from host some-change
-
挂载一个只读的卷
[root@host2 ~]# docker run -d -p 801:8080 -v /data/app1/:/usr/local/tomcat/webapps/app1:ro --name app2 notechbb/app2:v1 01c725aac42cd62b3c2fb81cea4f06a1ebb7ef3b87c11e045957bff8ee69b5cb # -v选项,指定时,末尾加个ro选项即可; # 可以看到,容器内不能对其做数据修改,(适合web服务容器,挂载只读的静态资源文件) [root@01c725aac42c /]# cat /usr/local/tomcat/webapps/app1/index.html this is volume from host some-change [root@01c725aac42c /]# echo haha >> !$ echo haha >> /usr/local/tomcat/webapps/app1/index.html -bash: /usr/local/tomcat/webapps/app1/index.html: Read-only file system
数据卷特点
- 数据卷是目录,或文件,可供多个容器同时使用,(如多个web容器挂载一个数据卷)
- 对数据卷操作,容器内会立即更新
- 数据卷是永久保存,不会随之容器删除而删除
- 容器向里面写入数据,不会影响镜像
数据卷使用场景
- 容器运行中日志输出;
- web服务挂载静态页面文件;
- 应用配置文件;
- 多容器间,目录或文件共享;
手动文件挂载
常用于nginx,tomcat等程序的配置文件;一般较少修改;
[root@host2 ~]# echo 1.conf > /data/1.conf
[root@host2 ~]# docker run -it --rm --name c1 -v /data/1.conf:/etc/1.conf:ro centos /bin/bash
[root@4f7e820c9e71 /]# cat /etc/1.conf
1.conf
# 宿主机准备文件,然后利用-v挂载到需要的位置即可;
# 修改配置时,只需要修改宿主机上的文件即可;
手动挂载多个目录
使用多个-v选项即可
[root@host2 ~]# echo 2.conf > /data/2.conf
[root@host2 ~]# docker run -it --rm --name c2 -v /data/1.conf:/etc/1.conf:ro -v /data/2.conf:/etc/2.conf centos /bin/bash
[root@ec752c8c1c0b /]# cat /etc/1.conf
1.conf
[root@ec752c8c1c0b /]# cat /etc/2.conf
2.conf
[root@ec752c8c1c0b /]# echo change > /etc/1.conf
bash: /etc/1.conf: Read-only file system
[root@ec752c8c1c0b /]# echo change > /etc/2.conf
[root@ec752c8c1c0b /]# cat /etc/2.conf
change
容器卷使用
【容器卷,实现了多容器间数据共享,尤其大批需要相同数据的容器时,简化了启动命令,只需一个数据卷容器作为模版,其他的容器采用--volumes-from即可挂载相同数据】
采用了数据卷容器的,文件权限,取决于模版容器卷挂载时的权限;
【常用于类nfs的文件共享】
[root@host2 ~]# docker run --name c1 -d -v /data/app1/:/data/app1 centos tail -f /etc/hosts
a8acb89d042fba57eaa96567ee528ae5d4229a0b565d23e7af9e739da5d8d034
# 启动一个容器c1
[root@host2 ~]# /root/docker-in.sh c1
[root@a8acb89d042f /]# ls /data/app1/
index.html
[root@a8acb89d042f /]# exit
logout
# 进入c1查看挂载目录/data/app1
[root@host2 ~]# docker run --name c2 -d --volumes-from c1 centos tail -f /etc/hosts
99c1ef9dca75b8c7b30ba720fa0b15f2463a9f0b3fd1f204406b9892dccb3b41
[root@host2 ~]# docker run --name c3 -d --volumes-from c1 centos tail -f /etc/hosts
0e32af6e03bc7141f148e4d9f0837677cb23701862a72e3799bdc8b452c710fe
# 再启动2容器,c2和c3,采用--volumes-from参数,即可实现和c1一样的目录挂载;
[root@host2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e32af6e03bc centos "tail -f /etc/hosts" 2 seconds ago Up 1 second c3
99c1ef9dca75 centos "tail -f /etc/hosts" 10 seconds ago Up 9 seconds c2
a8acb89d042f centos "tail -f /etc/hosts" 3 minutes ago Up 3 minutes c1
[root@host2 ~]# /root/docker-in.sh c3
[root@0e32af6e03bc /]# ls /data/app1/
index.html
[root@0e32af6e03bc /]# touch /data/app1/c3.file
[root@0e32af6e03bc /]# ls /data/app1/
c3.file index.html
[root@0e32af6e03bc /]# exit
logout
[root@host2 ~]# /root/docker-in.sh c2
[root@99c1ef9dca75 /]# ls /data/app1/
c3.file index.html
[root@99c1ef9dca75 /]# touch /data/app1/c2.file
[root@99c1ef9dca75 /]# ls /data/app1/
c2.file c3.file index.html
# 可以看到,c2 c3的数据变更是一致的
什么状态的容器卷可以被使用
由实验测试得知:
-
创建好容器卷后,其他容器可以用--volumes-from以其为模版挂载相同卷;
-
容器卷停止后,其他已挂载容器正常使用、也可以用停止状态的容器卷继续创建容器;
-
容器被rm -f删除后,其他已挂载容器正常使用、不可以其做模版继续创建容器;
-
报错如下:
[root@host2 ~]# docker run --name c5 -d --volumes-from c1 centos tail -f /etc/hosts docker: Error response from daemon: No such container: c1. # 已经找不到c1这个容器了
-
-
将删除后的数据卷容器,再相同命令创建一遍,又可以继续以其做模块创建新容器,其他已经创建的容器仍正常使用;