欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Docker学习04:数据管理

程序员文章站 2022-07-14 20:19:01
...

一、概述

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:

  • 当该容器不再存在时,数据将不会持久保存,并且如果另一个进程需要它,则可能很难从容器中取出数据。
  • 容器的可写层与运行容器的主机紧密耦合。您不能轻易地将数据移动到其他地方。
  • 写入容器的可写层需要 存储驱动程序来管理文件系统。存储驱动程序使用Linux内核提供联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能 。
    Docker为容器提供了两个选项来将文件存储在主机中,以便即使容器停止后文件也可以持久存储:绑定安装。如果您在Linux上运行Docker,则还可以使用tmpfs挂载。如果您在Windows上运行Docker,则还可以使用命名管道

Docker学习04:数据管理

二、Docker 支持的存储类型

Volumes
存储在主机文件系统的一部分中,该文件系统由Docker管理/var/lib/docker/volumes/在Linux上)。非Docker进程不应修改文件系统的这一部分。卷是在Docker中持久保存数据的最佳方法。

Bind mounts
可以存储在主机系统上的任何位置。它们甚至可能是重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时对其进行修改

tmpfs mounts
仅存储在主机系统的内存中,并且永远不会写入主机系统的文件系统中。容器在其生存期内可以使用它来存储非持久状态或敏感信息。

三、类型的适用场景

Volumes

将数据持久保存在Docker容器和服务中的首选方法。卷的一些用例包括:

  • 在多个运行中的容器之间共享数据。如果未显式创建卷,则在首次将卷安装到容器中时将创建该卷。当该容器停止或卸下时,该卷仍然存在。多个容器可以同时装载相同的卷(读写或只读)。仅在显式删除卷时才将它们删除。

  • 不保证Docker主机具有给定的目录或文件结构时。卷可帮助您将Docker主机的配置与容器运行时解耦。

  • 当您要将容器的数据存储在远程主机或云提供商上时,而不是在本地。

  • 当您需要将数据从一个Docker主机备份,还原或迁移到另一个Docker主机时,卷是一个更好的选择。您可以停止使用该卷的容器,然后备份该卷的目录(例如/var/lib/docker/volumes/)。

Bind mounts

通常应尽可能使用VolumesBind mounts适用于以下类型的用例:

  • 将配置文件从主机共享到容器。
  • 在Docker主机上的开发环境和容器之间共享源代码或构建工件。例如,您可以将Maven target/ 目录安装到容器中,并且每次在Docker主机上构建Maven项目时,该容器都可以访问重建的工件。
  • 当确保Docker主机的文件或目录结构与容器所需的bind mounts一致时。

tmpfs mounts

最适合用于不希望数据在主机上或容器中持久存储的情况。

如果使用Bind mounts或volumes

  • 如果将空卷装入存在文件或目录的容器中的目录中,则这些文件或目录将传播(复制)到该卷中。同样,如果启动一个容器并指定一个尚不存在的卷,则会为您创建一个空卷。这是预填充另一个容器所需数据的好方法。
  • 如果将bind mount或非空的volumes卷到存在某些文件或目录的容器中的目录中,则这些文件或目录会被安装遮盖,就像您将文件保存到/mntLinux主机上然后再安装时一样。 USB驱动器插入/mnt。的内容/mnt将由USB驱动器,直至USB驱动器的内容被遮蔽被卸载。不会删除或更改被遮盖的文件,但是在装入绑定安装或卷时将无法访问这些文件。

四、volume的基本使用

volume是存储Docker容器生成和使用的数据的首选机制。

最初,-vor --volume标志用于独立容器,而--mount标志用于集群服务。但是,从Docker 17.06开始,您还可以使用--mount独立容器。总的来说, --mount是更明确和冗长的。最大的区别是该-v 语法将所有选项合并在一个字段中,而--mount 语法将它们分开。官方更推荐使用--mount

4.1 管理卷

创建卷

# docker volume create my-vol
my-vol

卷清单

# docker volume ls
DRIVER              VOLUME NAME
local               my-vol

卷信息

# docker volume inspect my-vol
[
    {
        "CreatedAt": "2020-04-02T19:15:03+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

清除卷

# docker volume rm my-vol 
my-vol

删除本地未使用的卷

// 删除所有容器
[aaa@qq.com ~]# docker rm -f `docker ps -a -q`
13447424224e
5c1bbb404fc9
4775f33b42fd

// 查看本地卷
[aaa@qq.com ~]# docker volume ls
DRIVER              VOLUME NAME
local               nginx-vol
local               nginx-vol01
// 删除未使用的卷,因为所有容器都删除了。现在所有卷都未被使用
[aaa@qq.com ~]# docker volume prune 
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
nginx-vol
nginx-vol01

Total reclaimed space: 2.212kB

4.2 创建使用指定卷的容器

如果使用不存在的卷启动容器,Docker将自动创建该卷。

// 使用 --mount 创建容器
[aaa@qq.com ~]# docker run -d \
  --name=nginxtest \
  --mount source=nginx-vol,destination=/usr/share/nginx/html \
  nginx:latest

// 使用 -v 创建
[aaa@qq.com ~]# docker run -d \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html \
  nginx:latest

检验卷是否创建与挂载正确

[aaa@qq.com ~]# docker inspect nginx-vol 
//查找mounts 字段
"Mounts": [
    {
        "Type": "volume",
        "Name": "nginx-vol",
        "Source": "/var/lib/docker/volumes/nginx-vol/_data",
        "Destination": "/usr/share/nginx/html",
        "Driver": "local",
        "Mode": "",
        "RW": false,
        "Propagation": ""
    }
],

删除正在使用卷的方法

//停止运行使用该卷的容器,container可以省去
[aaa@qq.com ~]# docker stop nginx-vol 

//删除容器
[aaa@qq.com ~]# docker container rm nginx-vol  

//删除卷
[aaa@qq.com ~]# docker volume rm nginx-vol 

4.3 设置只读卷

// --mount方式
[aaa@qq.com ~]# docker run -d \
  --name=nginxtest01 \
  --mount source=nginx-vol01,destination=/usr/share/nginx/html,readonly \
  nginx:latest
  
// -v方式
[aaa@qq.com ~]# docker run -d \
  --name=nginxtest01 \
  -v nginx-vol01:/usr/share/nginx/html:ro \
  nginx:latest

检验是否正确创建

[aaa@qq.com ~]# docker inspect nginxtest01
		"Mounts": [
            {
                "Type": "volume",
                "Name": "nginx-vol01",
                "Source": "/var/lib/docker/volumes/nginx-vol01/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "ro",		//权限,ro只读
                "RW": false,
                "Propagation": ""
            }
        ],

4.4 使用共享卷

创建一个容器

//容器名称webapp,映射端口81,使用webapp卷
[aaa@qq.com ~]# docker run -d -p 81:80 \
   --name=webapp \
   --mount source=webapp,destination=/usr/share/nginx/html \
   nginx:latest

往卷中写入一个html文件

[aaa@qq.com ~]# echo "Hello Docker" >/var/lib/docker/volumes/webapp/_data/hello.html
[aaa@qq.com ~]# ls /var/lib/docker/volumes/webapp/_data/
50x.html  hello.html  index.html

访问容器测试

[aaa@qq.com ~]# curl 127.0.0.1:81/hello.html
Hello Docker

创建一个新的容器,使用webapp卷

//容器名称webapp01,映射端口82,使用webapp卷
[aaa@qq.com ~]# docker run -d -p 82:80 \
   --name=webapp01 \
   --mount source=webapp,destination=/usr/share/nginx/html \
   nginx:latest

访问容器测试

[aaa@qq.com ~]# curl 127.0.0.1:82/hello.html
Hello Docker

五、bind volume的基本使用

使用bind volume时,会将主机上的文件或目录安装到容器中,文件或目录由主机上的完整或相对路径引用。

使用bind volume时,绑定目录必须存在。
如果挂载目标在容器中为非空目录,则该目录现有内容将被隐藏。

5.1 使用 bind mount启动容器

创建容器挂载目录

[aaa@qq.com ~]# mkdir -p /code/www
[aaa@qq.com ~]# echo 'this is bind volume!!!' >/code/www/index.html

启动容器(–mount 方式)

[aaa@qq.com ~]# docker run -d -it -p8081:80   --name devtest   --mount type=bind,source=/code/www,target=/usr/share/nginx/html/   nginx:latest

进容器查看

[aaa@qq.com ~]# docker exec -it devtest bash
aaa@qq.com:/# cat /usr/share/nginx/html/idenx.html 
this is bind volume!!!

访问测试

[aaa@qq.com ~]# curl 127.0.0.1:8081
this is bind volume!!!

在启动一个容器(-v方式)

[aaa@qq.com ~]# docker run -d -it -p8082:80   --name devtest01   -v /code/www:/usr/share/nginx/html/   nginx:latest

访问测试

[aaa@qq.com ~]# curl 127.0.0.1:8082
this is bind volume!!!

修改/code/www下的index文件

[aaa@qq.com ~]# echo 'onelpc.com  docker ' >/code/www/index.html 
[aaa@qq.com ~]# cat /code/www/index.html
onelpc.com  docker 

访问容器测试

[aaa@qq.com ~]# curl 127.0.0.1:8081
onelpc.com  docker 
[aaa@qq.com ~]# curl 127.0.0.1:8082
onelpc.com  docker 

5.2 验证绑定

[aaa@qq.com ~]# docker inspect devtest
        "Mounts": [
            {
                "Type": "bind",			//类型
                "Source": "/code/www",	//宿主机目录
                "Destination": "/usr/share/nginx/html",		//挂载到容器中的目录
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],