docker存储管理
作者:互联网
docker存储概念
容器本地存储与Docke存储驱动
容器本地存储:每个容器都被自动分配了内部存储,即容器本地存储。采用的是联合文件系统。通过存储驱动进行管理。
容器本地存储空间:分层结构构成,由一个可写容器层和若干只读的镜像层组成。
联合文件系统:Docker的一种底层技术,由存储驱动(Storage Driver)实现。相应的存储驱动有aufs、overlay、overlay2、devicemapper、btrfs、zfs、vfs等。
存储驱动:控制镜像和容器在 docker 主机上的存储和管理方式。
每个Docker主机只能选择一种存储驱动,不能为每个容器选择不同的存储驱动。
查看主机支持的存储驱动
[root@localhost ~]# docker info
# 找到如下信息
Storage Driver: overlay2 # 存储驱动是overlay2
Backing Filesystem: xfs # 底层文件系统是xfs
Supports d_type: true # 支持d_type
Native Overlay Diff: true
userxattr: false
更改现有的存储驱动
可以根据需要修改现有的存储驱动。
注意:
- 一个主机只能选择一个存储驱动。
- 系统版本和存储驱动的兼容问题。
- 更改存储驱动会使得现有的容器和镜像不可访问(原因:每种存储驱动存储镜像层的位置是不同的)
- 但恢复存储驱动,可以再次访问之前的镜像和容器
# 修改daemon.json文件来更改存储引擎配置
[root@localhost ~]# vi /etc/docker/daemon.json
{
"registry-mirror":["https://registry.docker-cn.com"],
"storage-driver":"overlay" 《————————添加这个信息
}
# 重启docker生效
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker info
# 找到如下信息
Storage Driver: overlay 《————————修改生效
Backing Filesystem: xfs
Supports d_type: true
# 更改存储驱动会使得现有的容器和镜像不可访问
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 恢复存储驱动,可以再次访问之前的镜像和容器
[root@localhost ~]# vi /etc/docker/daemon.json
{
"registry-mirror":["https://registry.docker-cn.com"]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 825d55fb6340 2 weeks ago 72.8MB
centos latest 5d0da3dc9764 7 months ago 231MB
容器和非持久化数据
非持久化数据:不需要保存的数据。容器本地存储中的数据属于非持久化数据。
容器创建时会创建非持久化存储,非持久化存储自动创建,从属于容器,生命周期与容器相同。删除容器也会删除全部非持久化数据。
非持久化数据存在问题:
- 这类数据从属于容器,生命周期与容器相同,会随着容器的删除而被删除。(易丢失)
- 当该容器不再运行时,数据不会持久保存,如果另一个进程需要,则可能很难从该容器中获取数据。(难获取)
- 容器的可写层与运行容器的Docker主机紧密耦合,无法轻松地将数据转移到其他位置。(难转移)
- 写入容器的可写层需要Docker存储驱动管理文件系统。存储驱动使用Linux内核提供的联合文件系统,其性能不如直接写入主机文件系统的Docker卷。(读写性能差)
容器和持久化数据
持久化数据:需要保存的数据。例如:日志、业务数据、客户信息等有用的数据。
外部存储:Docker通过将主机中的文件系统挂载到容器中供容器存取,从而实现持久化数据存储。
容器持久化数据存储方式:Docker目前支持卷、绑定挂载,这两种挂载类型实现容器的持久化。
卷(数据卷):Docker中进行持久化数据存储的最佳方式。本质是Docker主机文件系统中的目录或文件直接挂载到容器的文件系统中。
卷和容器是解耦的,可以独立地创建并管理卷
卷不与容器的生命周期绑定(容器的停止删除和卷无关)
可以将任意数量的卷装入容器,多个容器也可以共享一个或多个卷(多对多关系)
挂载类型
往容器中挂载的外部文件系统主要有:卷、绑定挂载、tmpfs挂载。无论哪种挂载,对容器内部来说是一样的,都会显示为文件或目录。
卷
卷存储在主机文件系统中由Docker管理的位置,在Linux主机上该位置默认就是/var/lib/docker/volumes
目录。
卷是Docker持久化存储数据的最佳方式。卷支持使用卷驱动,可以让用户将数据存储在远程主机或云提供商处等。
可以以命名方式或匿名方式挂载卷:
- 匿名卷(Anonymous Volumes):首次挂载容器未指定名称,Docker为其随机指定一个唯一名称。
- 命名卷(Named Volumes):指定明确名称,和匿名卷其他特性相同。
卷由Docker创建并管理,卷适合以下应用场景。
- 在多个正在运行的容器之间共享数据。(数据共享)
- 当Docker主机不能保证具有特定目录结构时,卷有助于将Docker主机的配置与容器运行时解耦。(构建新目录与主机不同)
- 当需要将容器的数据存储到远程主机或云提供商处,而不是本地时。(可以远程挂载卷,公有云、灾备等场景)
- 当需要在两个Docker主机之间备份、恢复或迁移数据时。(主机间备份迁移)
绑定挂载
绑定挂载可以存储到主机系统的任意位置,甚至会存储到一些重要的系统文件或目录中。
特点:
- 主机上进程或容器可以随时修改。
- 相比卷,功能更受限、性能更高。
- 绑定挂载运行访问敏感文件。
绑定挂载适合以下应用场景。
- 在主机和容器之间共享配置文件。
- 在Docker主机上的开发环境和容器之间共享源代码或构建工件。
- 当Docker主机上的目录结构保证与容器要求的绑定挂载一致时。
tmpfs挂载
tmpfs挂载仅限于运行Linux操作系统的Docker主机使用,它只存储在主机的内存中,不会被写到主机的文件系统中,因此不能持久保存容器的应用数据。
在不需要将数据持久保存到主机或容器中时,tmpfs挂载最合适。
如果容器产生了非持久化数据,那么可以考虑使用tmpfs挂载避免将数据永久存储到任何位置,并且通过避免写入容器的可写层来提高容器的性能。
docker卷
docker volume
是Docker卷的管理命令。
# 语法
[root@localhost volumes]# docker volume
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume # 创建卷
inspect Display detailed information on one or more volumes # 查看卷的详细信息
ls List volumes # 列出本地docker主机上的卷
prune Remove all unused local volumes # 删除未被使用的卷
rm Remove one or more volumes # 删除指定卷
创建卷
使用 docker volume create
命令创建卷。
# 语法
[root@localhost volumes]# docker volume create --help
Usage: docker volume create [OPTIONS] [VOLUME]
Create a volume
Options:
-d, --driver string Specify volume driver name (default "local") # 说明卷驱动名称(默认是'local')
--label list Set metadata for a volume # 设置卷元数据
-o, --opt map Set driver specific options (default map[]) # 设置驱动特殊选项
# 案例1:创建普通卷
[root@localhost volumes]# docker volume create test-vol01
test-vol01
[root@localhost volumes]# docker volume inspect test-vol01
[
{
"CreatedAt": "2022-04-27T17:02:27+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test-vol01/_data",
"Name": "test-vol01",
"Options": {},
"Scope": "local"
}
]
# 案例2:创建tmpfs卷,大小100m,uid为1000
[root@localhost volumes]# docker volume create --driver local \
> --opt type=tmpfs \
> --opt device=tmpfs \
> --opt o=size=100m,uid=1000 \
> test-vol02
test-vol02
[root@localhost volumes]# docker volume inspect test-vol02
[
{
"CreatedAt": "2022-04-27T17:10:21+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test-vol02/_data",
"Name": "test-vol02",
"Options": {
"device": "tmpfs",
"o": "size=100m,uid=1000",
"type": "tmpfs"
},
"Scope": "local"
}
]
# 案例3:设置元数据
[root@localhost volumes]# docker volume create --label city=wuhan test-vol03
test-vol03
[root@localhost volumes]# docker volume inspect test-vol03
[
{
"CreatedAt": "2022-04-27T17:07:44+08:00",
"Driver": "local",
"Labels": {
"city": "wuhan"
},
"Mountpoint": "/var/lib/docker/volumes/test-vol03/_data",
"Name": "test-vol03",
"Options": {},
"Scope": "local"
}
]
查看卷列表
使用 docker volume ls
命令列出当前的卷。
format关键词:
Placeholder | Description |
---|---|
.Name | Volume name |
.Driver | Volume driver |
.Scope | Volume scope (local, global) |
.Mountpoint | The mount point of the volume on the host |
.Labels | All labels assigned to the volume |
.Label | Value of a specific label for this volume. For example {{.Label "project.version"}} |
# 语法
[root@localhost volumes]# docker volume ls --help
Usage: docker volume ls [OPTIONS] 《——————注意选项不能写在ls之前
List volumes
Aliases:
ls, list
Options:
-f, --filter filter Provide filter values (e.g. 'dangling=true') # 条件筛选
--format string Pretty-print volumes using a Go template # 内容过滤输出
-q, --quiet Only display volume names # 只打印卷名
# 案例1:普通查看
[root@localhost volumes]# docker volume ls
卷驱动 卷名称
DRIVER VOLUME NAME
local test-vol01
local test-vol02
local test-vol03
# 案例2:条件筛选
# 没有被使用的卷
[root@localhost volumes]# docker volume ls -f dangling=true
DRIVER VOLUME NAME
local test-vol01
local test-vol02
local test-vol03
# 驱动为local的卷
[root@localhost volumes]# docker volume ls -f driver=local
DRIVER VOLUME NAME
local test-vol01
local test-vol02
local test-vol03
# 根据label元数据筛选
[root@localhost volumes]# docker volume ls --filter label=city
DRIVER VOLUME NAME
local test-vol03
# 根据名称筛选
[root@localhost volumes]# docker volume ls -f name=03
DRIVER VOLUME NAME
local test-vol03
[root@localhost volumes]# docker volume ls -f name=vol
DRIVER VOLUME NAME
local test-vol01
local test-vol02
local test-vol03
# 案例3:只打印卷名
[root@localhost volumes]# docker volume ls -q
test-vol01
test-vol02
test-vol03
# 案例4:内容过滤输出
[root@localhost volumes]# docker volume ls --format "{{.Name}}: {{.Driver}}"
test-vol01: local
test-vol02: local
test-vol03: local
[root@localhost volumes]# docker volume ls --format "{{.Name}}: {{.Mountpoint}}: {{.Labels}}"
test-vol01: /var/lib/docker/volumes/test-vol01/_data:
test-vol02: /var/lib/docker/volumes/test-vol02/_data:
test-vol03: /var/lib/docker/volumes/test-vol03/_data: city=wuhan
查看卷详细信息
使用 docker volume inspect
命令查看卷详细信息。包含卷在Docker主机文件系统中的具体位置。
# 语法
[root@localhost ~]# docker volume inspect --help
Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
Display detailed information on one or more volumes
Options:
-f, --format string Format the output using the given Go template
# 案例
[root@localhost ~]# docker volume create --driver local \
> --opt type=tmpfs \
> --opt device=tmpfs \
> --opt o=size=100m,uid=1000 \
> --label city=wuhan \
> --label type=tmpfs \
> test-vol
70eefb6835df2daafcc3e678395af214dae4a98241fd6886e5822bbc9e7de920
[root@localhost ~]# docker volume inspect test-vol
[
{
"CreatedAt": "2022-04-28T00:36:35+08:00",
"Driver": "local",
"Labels": {
"city": "wuhan",
"type": "tmpfs"
},
"Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
"Name": "test-vol",
"Options": {
"device": "tmpfs",
"o": "size=100m,uid=1000",
"type": "tmpfs"
},
"Scope": "local"
}
]
[root@localhost ~]# docker volume inspect --format '{{ .Mountpoint }}' test-vol
/var/lib/docker/volumes/test-vol/_data
[root@localhost ~]# docker volume inspect --format '{{ .Options }}' test-vol
map[device:tmpfs o:size=100m,uid=1000 type:tmpfs]
[root@localhost ~]# docker volume inspect --format '{{ .Options.o }}' test-vol
size=100m,uid=1000
[root@localhost ~]# docker volume inspect --format '{{ .Labels.city }}' test-vol
wuhan
删除卷
使用 docker volume rm
删除指定卷(不能删除正在被容器使用的卷)。
# 语法
[root@localhost ~]# docker volume rm --help
Usage: docker volume rm [OPTIONS] VOLUME [VOLUME...]
Remove one or more volumes. You cannot remove a volume that is in use by a container.
Aliases:
rm, remove
Options:
-f, --force Force the removal of one or more volumes 强制删除
# 案例
[root@localhost ~]# docker volume rm test-vol01
test-vol01
[root@localhost ~]# docker volume rm $(docker volume ls -q)
test-vol
test-vol02
test-vol03
使用 docker volume prune
删除未被容器或服务使用的所有卷。
# 语法
[root@localhost ~]# docker volume prune --help
Usage: docker volume prune [OPTIONS]
Remove all unused local volumes
Options:
--filter filter Provide filter values (e.g. 'label=<label>')
-f, --force Do not prompt for confirmation
# 案例
[root@localhost ~]# 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:
test-vol01
test-vol02
test-vol03
Total reclaimed space: 0B
实战
[root@localhost ~]# docker volume create volume-01
volume-01
[root@localhost ~]# docker volume inspect volume-01
[
{
"CreatedAt": "2022-04-27T19:09:29+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volume-01/_data",
"Name": "volume-01",
"Options": {},
"Scope": "local"
}
]
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local volume-01
[root@localhost ~]# docker run -it -v volume-01:/world centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
[root@d09338cc1750 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var world
[root@d09338cc1750 /]# ls /world/
[root@d09338cc1750 /]# exit
exit
[root@localhost ~]# docker inspect --format="{{json .Mounts}}" d09338cc1750
[{"Type":"volume","Name":"volume-01","Source":"/var/lib/docker/volumes/volume-01/_data","Destination":"/world","Driver":"local","Mode":"z","RW":true,"Propagation":""}]
[root@localhost ~]# docker rm -f d09338cc1750
d09338cc1750
[root@localhost ~]# docker volume rm volume-01
volume-01
容器文件系统挂载
使用 docker run
或 docker create
命令的相关选项将外部的文件系统挂载到容器中。
早期版本:
- 卷和绑定挂载都可以通过
-v
和--mount
选项挂载到容器中,主要是两者的语法的细微区别。 -v
用于独立容器,--mount
用于集群服务。- tmpfs挂载可以使用
--tmpfs
选项。
docker 17.06或更高版本:
- 建议所有的容器或服务,绑定挂载、卷、tmpfs都使用
--mount
选项。(语法清晰、定制详细) --mount
选项也可以用于独立容器。
-v
和--mount
的区别:
-v
语法是将选项组合在一个字段中,--mount
的语法是将它们分开。--mount
采用键值对写法支持更多的设置选项,-v
写法更加简洁。
-v(--volume)选项
选项包括冒号分隔的三个字段。必须按照正确顺序排序。
# 语法
[root@localhost ~]# docker run(create)
-v, --volume=[host-src:]container-dest[:<options>]: Bind mount a volume.
第一个host-src字段表示挂载源,来自主机的文件系统,为绝对路径或名称变量。
第二个container-dest字段表示挂载目标,即容器的挂载点,可以是目录或文件路径(绝对路径)
第三个options字段可选,以逗号分隔选项列表,如:[rw|ro], [z|Z], [[r]shared|[r]slave|[r]private], and [nocopy].
rw:读写模式??
ro:只读模式
nocopy:禁止自动复制到卷存储地址
命名卷,copy是默认模式,copy模式不支持绑定挂载的卷。
如果既没有指定rw又没有指定ro,卷挂载为读写模式。
# 案例:绑定挂载类型
[root@localhost ~]# docker run -d \
> -it \
> --name devtest \
> -v "$(pwd)"/target:/app \
> nginx:latest
9c9bd6c4b7898f272b162683bf7370fe2fde2d04b30a361bda7443bc6a2d2bf4
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c9bd6c4b789 nginx:latest "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 80/tcp devtest
[root@localhost ~]# docker exec -ti 9c9bd6c4b789 /bin/bash
root@9c9bd6c4b789:/# ls
app boot docker-entrypoint.d etc lib media opt root sbin sys usr
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
root@9c9bd6c4b789:/# df -H
Filesystem Size Used Avail Use% Mounted on
overlay 19G 5.5G 13G 30% /
tmpfs 68M 0 68M 0% /dev
tmpfs 1.1G 0 1.1G 0% /sys/fs/cgroup
shm 68M 0 68M 0% /dev/shm
/dev/mapper/centos-root 19G 5.5G 13G 30% /app
--mount选项
绑定挂载、卷、tmpfs类型都使用--mount
选项。
--mount
选项的参数由多个由逗号分隔的键值对组成。
特殊键如下:
- type:指定要挂载的类型,值可以是bind(绑定挂载)、volume(卷)或tmpfs。
- source(或src):指定挂载源
- destination(或dst、target):指定挂载目标,即容器中的挂载点,必须采用绝对路径的形式
- readoly:指定只读选项,表示源以只读方式挂载到容器中。
- 其他键:可以被多次指定,由若干键值对组成。卷和绑定挂载有不同的键。
[root@localhost ~]# docker run(create)
--mount <键>=<值>,<键>=<值>,... Attach a filesystem mount to the container
# 案例
[root@localhost ~]# docker run -d --name devtest01 --mount source=myvol2,target=/app nginx:latest
65e5132a4a64d40f688d2bcb80fe2f6d9a2fb504e092ca628b59398dd207b2a3
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local myvol2
[root@localhost ~]# docker volume inspect myvol2
[
{
"CreatedAt": "2022-04-28T02:45:45+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/myvol2/_data",
"Name": "myvol2",
"Options": null,
"Scope": "local"
}
]
[root@localhost ~]# docker exec -ti devtest01 /bin/bash
root@65e5132a4a64:/# cd /app/
标签:存储管理,--,volume,test,docker,root,localhost 来源: https://www.cnblogs.com/kongshuo/p/16014132.html