docker存储管理

docker存储管理

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:可写层数据永久化的方法之一:将容器提交为新镜像;

即将容器的某个目录挂载到宿主机的某个目录,或者远程网络存储提供的目录,容器停止后,其运行期间所有的数据变更仍会永久的保持在存储卷上,从而实现了数据的持久化;

存储卷示意图

image-20201029193826017

存储卷管理操作

手动指定宿主机存储卷目录

  1. 创建容器时,-v手动指定宿主机某目录,挂载到容器某目录(ro选项,可设置只读,如web容器挂载宿主机只读的静态文件)

  2. 向宿主机挂载目录写入数据

  3. 连入容器,查看数据是否存在

  4. 创建容器时,-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选项挂载宿主机目录
    
  5. 向宿主机挂载目录写入数据

    [root@host2 ~]# mkdir /data        
    [root@host2 ~]# mkdir /data/app1
    [root@host2 ~]# echo "this is volume from host" > /data/app1/index.html
       
    
  6. 连入容器,查看数据是否存在

    [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
    
  7. 容器内修改数据,查看宿主机文件变化

    [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
    
  8. 挂载一个只读的卷

    [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
    

数据卷特点

  1. 数据卷是目录,或文件,可供多个容器同时使用,(如多个web容器挂载一个数据卷)
  2. 对数据卷操作,容器内会立即更新
  3. 数据卷是永久保存,不会随之容器删除而删除
  4. 容器向里面写入数据,不会影响镜像

数据卷使用场景

  1. 容器运行中日志输出;
  2. web服务挂载静态页面文件;
  3. 应用配置文件;
  4. 多容器间,目录或文件共享;

手动文件挂载

​ 常用于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的数据变更是一致的

什么状态的容器卷可以被使用

由实验测试得知:

  1. 创建好容器卷后,其他容器可以用--volumes-from以其为模版挂载相同卷;

  2. 容器卷停止后,其他已挂载容器正常使用、也可以用停止状态的容器卷继续创建容器;

  3. 容器被rm -f删除后,其他已挂载容器正常使用、不可以其做模版继续创建容器;

    1. 报错如下:

      [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这个容器了
            
      
  4. 将删除后的数据卷容器,再相同命令创建一遍,又可以继续以其做模块创建新容器,其他已经创建的容器仍正常使用;

updatedupdated2020-11-012020-11-01
加载评论