docker volume探索

背景

对docker的数据持久化用得比较少, 也没细究过, 今天抽空来研究一下。

docker数据持久化或者说存储,主要有两种形式:

环境

gerrylon@gerrylon-PC:/var/workspace/learn/docker$ cat /etc/os-release 
PRETTY_NAME="Deepin 20 Beta"
NAME="Deepin"
VERSION_ID="20 Beta"
VERSION="20 Beta"
ID=Deepin
HOME_URL="https://www.deepin.com/"
BUG_REPORT_URL="https://bbs.deepin.org/"
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker version
Client: Docker Engine - Community
 Version:           19.03.12
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        48a66213fe
 Built:             Mon Jun 22 15:45:50 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.12
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       48a66213fe
  Built:            Mon Jun 22 15:44:21 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

bind mounts

为了演示方便, 如无特别说明, 都在/var/workspace/learn/docker来操作

# 显示目录/文件结构
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ tree .
.
└── volume-test
    └── Dockerfile

1 directory, 1 file

查看docker volume,发现目前没有volume创建

gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker volume ls
DRIVER              VOLUME NAME

使用不存在的相对路径

# 容器中创建了个空目录
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v some-dir:/some-dir alpine sh
/ # ls some-dir/

# 宿主机上创建了个 docker volume
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ ls
volume-test
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker volume ls
DRIVER              VOLUME NAME
local               some-dir

使用存在的相对路径

# 容器中创建了个空目录
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v volume-test:/volume-test alpine sh
/ # ls volume-test/
/ # 

# 宿主机上创建了个 docker volume
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker volume ls
DRIVER              VOLUME NAME
local               some-dir
local               volume-test
  • 小结: -v使用相对目录, 总是会创建docker volume.

在做下边的实验前, 先删除下现有的volume: docker volume rm $(docker volume ls -q)

使用不存在的绝对路径

# 容器内自动创建
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v `pwd`/some-dir:/somedir alpine sh
/ # cd some-dir/
/some-dir # touch a

# 宿主机上目录文件与容器内同步
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ ls some-dir/a 
some-dir/a

使用存在的绝对路径

# 容器内自动映出到宿主机上的目录文件结构
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v `pwd`/volume-test:/volume-test alpine sh
/ # ls volume-test/
Dockerfile
/ # cd volume-test
/volume-test # echo hello > a.txt
/volume-test # 

# 宿主机上的文件与容器内同步
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ cat volume-test/a.txt 
hello

小结:使用绝对路径这种形式(容器内相应目录不存在时), 能实现容器内和宿主机上对应目录/文件的同步, 平时用的最多的也是这种形式, 让容器读取宿主机上的配置。
如:

docker run -p 8081:80 --name nginx-80 
-v /docker_data/data/nginx/html:/usr/share/nginx/html 
-v /docker_data/data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 
-v /docker_data/data/nginx/conf/conf.d:/etc/nginx/conf.d 
-v /docker_data/data/nginx/logs:/var/log/nginx 
-d nginx 

把容器内的文件映射出来

现在有一个很有意思的想法, 怎么把容器内的配置映射出来?
之所以想这样, 是因为类似nginx这类容器, 都有默认配置, 就想映出出来 然后就可以在其基础上修改了, 方便快捷。

# 显示Dockerfile内容
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ cat ./volume-test/Dockerfile 
FROM alpine

LABEL target=learn

RUN mkdir -p /var/workspace && echo 'hello' > /var/workspace/a.txt

gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker build -t myimage:1.0 volume-test/
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM alpine
 ---> a24bb4013296
Step 2/3 : LABEL target=learn
 ---> Using cache
 ---> dd29d7a61fef
Step 3/3 : RUN mkdir -p /var/workspace && echo 'hello' > /var/workspace/a.txt
 ---> Using cache
 ---> e7e9c25c0383
Successfully built e7e9c25c0383
Successfully tagged myimage:1.0

# 先看看容器内有没有我们创建的文件
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm  myimage:1.0 cat /var/workspace/a.txt
hello

上面基于alpine创建了镜像myapp:1.0, 并且创建了文件 /var/workspace/a.txt, 以此来演示如何将容器内的文件挂载出来 。

# 先看看宿主机的上的目录(无workspace目录)
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ ls
some-dir  volume-test

# 容器内, 发现a.txt没有了
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v `pwd`/workspace:/var/workspace  myimage:1.0 sh
/ # ls /var/workspace/
/ # 

# 再看宿主机上, 发现多了个空目录workspace
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ ls workspace/
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ 

以上面的实验为基础, 在宿主机workspace下创建个b.txt, 再看看:

gerrylon@gerrylon-PC:/var/workspace/learn/docker$ cat workspace/b.txt 
world

# 发现容器内的文件以宿主机上的为准
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it -v `pwd`/workspace:/var/workspace  myimage:1.0 sh
/ # cat var/workspace/b.txt 
world

也就是说这种这种方式不能把容器内的文件映射出来, 实验的效果显示:是以宿主机上的目录为准来设置容器目录的。
如果有哪位同学知道怎么把容器内的文件映射出来, 请指教。

volumes

# 使用相对路径的形式,会创建一个docker volume
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker run --rm -it  -v myworkspace:/var/workspace myimage:1.0 sh
/ # cat var/workspace/a.txt 
hello
/ # echo workd >> /var/workspace/a.txt 
/ # 

# 查看volume详情
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ docker volume inspect myworkspace 
[
    {
        "CreatedAt": "2020-07-11T13:33:18+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/myworkspace/_data",
        "Name": "myworkspace",
        "Options": null,
        "Scope": "local"
    }
]

# 看看文件同步情况
gerrylon@gerrylon-PC:/var/workspace/learn/docker$ sudo cat /var/lib/docker/volumes/myworkspace/_data/a.txt
hello
workd

可以看出, 使用volume这种形式, 挂载的内容会放到
/var/lib/docker/volumes/$volume_name/_data, 而且会实现文件同步

官方推荐使用volume: https://docs.docker.com/storage/volumes/

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure of the host machine, volumes are completely managed by Docker. Volumes have several advantages over bind mounts:

Volumes are easier to back up or migrate than bind mounts.
You can manage volumes using Docker CLI commands or the Docker API.
Volumes work on both Linux and Windows containers.
Volumes can be more safely shared among multiple containers.
Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
New volumes can have their content pre-populated by a container.

总结

  • -v path:/some-dir 会创建名为path的volume
  • -v /path:/some-dir 会创建目录(如果不存在的话)/path
  • -v /path:/some-dir 会将/path(如果存在的话)及其下的文件映射到容器内
  • 推荐使用docker volume来做容器的存储和共享数据

(完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值