docker 的 volume 是什么
数据卷,用于保存持久化数据
volume 常用命令
# 查看 docker volume ls
[root@NameNode ~]# docker volume ls
DRIVER VOLUME NAME
local 5db87f5359d62a13c5844124f5b8cafdce7fe6c7b5a584e9d129318375e4c78e
# 删除 docker volume 数据卷名称
docker volume rm 5db87f5359d62a13c5844124f5b8cafdce7fe6c7b5a584e9d129318375e4c78e
# 创建 docker volume create 数据卷名称
docker volume create my-data
# 查看详细信息 docker volume inspect 数据卷名称
[root@NameNode ~]# docker volume inspect my-data
[
{
"CreatedAt": "2022-05-19T16:10:43+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-data/_data",
"Name": "my-data",
"Options": {},
"Scope": "local"
}
]
Data Volume
这里以mysql镜像为例
先把本地volume删除干净
首先启动两个mysql容器
# 删除本地volume
docker volume rm $(docker volume ls -q)
# 启动m1,m2 两个mysql容器
docker run -d --name=m1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
docker run -d --name=m2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
查看下volume
发现出现两个volume
[root@NameNode ~]# docker volume ls
DRIVER VOLUME NAME
local 0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346
local 1c6d8a561ced814f3a5984814e6d99de39208d054d8a04cc6797b503ce71c30a
查看下 volume 0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346
查看下 容器m1的详细信息
volume 都是挂载在var/lib/docker/volumes下的
去dockerhub上查看mysql的Dockerfile文件,发现其中 VOLUME /var/lib/mysql
Dockerfile中的VOLUME是匿名挂载,就是在不使用 -v指定挂载时,自动将容器内目录(如:/var/lib/mysql),挂载到volume上(如:0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346)
# 查看 volume
[root@NameNode ~]# docker volume inspect 0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346
[
{
"CreatedAt": "2022-05-19T17:14:18+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346/_data",
"Name": "0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346",
"Options": null,
"Scope": "local"
}
]
# 查看容器m1信息
docker inspect m1
# output 截取的主要输出部分
"Mounts": [
{
"Type": "volume",
"Name": "0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346",
"Source": "/var/lib/docker/volumes/0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
挂载是什么意思呢,你可以理解为同步
下面我去容器m1的 /var/lib/mysql 目录下添加一个a.txt 文件
那么 /var/lib/mysql 对应的挂载目录下也会出现 a.txt 文件
# 进入m1容器在/var/lib/mysql 下创建a.txt 文件
docker exec -it m1 bash
cd /var/lib/mysql
touch a.txt
# 查看对应挂载目录,发现了a.txt 文件
cd /var/lib/docker/volumes/0f304bd6ae8d2c1569ea08a5c88dd84dbe9cf3e054132ea501e727fbf564f346/_data && ls
启动时指定volume名称
好处在于起一个好记并且有意义的名称,便于下次启动使用指定的卷,使用指定的历史数据
# -v 卷名称 : 容器内部目录
docker run -d --name=m3 -v m1-data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
下面进入m3内部创建docker数据库
然后退出,创建m4容器指定使用m3用过的卷
然后进入m4容器内部查看有哪些库,发现了docker库
这样m4容器就能使用m3之前的数据了
# 进入m3 创建 docker库
docker exec -it m3 bash
mysql -uroot -p
create database docker;
# 停止m3
docker stop m3
# 启动m4 指定使用my-data卷
docker run -d --name=m4 -v m1-data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
# 进入m4,查看数据库
docker exec -it m4 bash
mysql -uroot -p
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| docker |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
Bind Mouting
相比较于volume
它主要用于外部目录和容器内部目录的同步,常用于代码同步
下面以nginx 为例
先创建一个Dockerfile,并将nginx的 index.html 换成自己的index.html
# index.html
<div>docker bind mouting</div>
# Dockerfile
FROM nginx
WORKDIR /usr/share/nginx/html
COPY index.html index.html
构建镜像
启动容器并映射端口80
docker build -t xrx/m-nginx .
docker run -d --name=n1 -p 80:80 xrx/m-nginx
# 查看下内容
[root@NameNode xrx]# curl localhost
<div>docker bind mouting</div>
上面的启动方式如果要修改index.html
需要进入容器来改变 /usr/share/nginx/html/index.html文件
但是如果我使用 -v 指定 当前目录和容器 /usr/share/nginx/html 挂载
那么我只要在当前目录改变index.html
容器内的index.html也会改变
docker stop n1
# $(pwd) 是代表当前目录
# 使用 -v 将当前目录与 /usr/share/nginx/html 绑定
docker run -d --name=n2 -v $(pwd):/usr/share/nginx/html -p 80:80 xrx/m-nginx
# 查看下内容
[root@NameNode xrx]# curl localhost
<div>docker bind mouting</div>
# 修改当前目录下 index.html
<div>docker bind mouting new</div>
# 查看下内容 发现内容改变了
[root@NameNode xrx]# curl localhost
<div>docker bind mouting new</div>