1.什么是容器卷?
目录
docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
2.使用数据卷
方式一 :直接使用命令挂载 -v
-v, --volume list Bind mount a volume
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口
[root@fedora home]# docker run -it -v /home/test:/home centos /bin/bash
[root@fedora home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df3f3769a002 centos "/bin/bash" 5 minutes ago Up 5 minutes sleepy_gould
# 通过 docker inspect 容器id 查看
[root@fedora home]# docker inspect df3f3769a002
......
"Mounts": [
{
"Type": "bind",
"Source": "/home/test",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
......
测试文件的同步
再来测试!
[root@df3f3769a002 home]# ls
hello
[root@df3f3769a002 home]# cat hello
# 容内hello文件为空
# 1、停止容器
[root@df3f3769a002 home]# exit
exit
# 2、宿主机修改文件
[root@fedora home]# ls
chrlie test
[root@fedora home]# cd test/
[root@fedora test]# vim hello
# 3、启动、进入容器
[root@fedora test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df3f3769a002 centos "/bin/bash" 20 minutes ago Exited (0) 49 seconds ago sleepy_gould
[root@fedora test]# docker start df3f3769a002
df3f3769a002
[root@fedora test]# docker exec -it df3f3769a002 /bin/bash
# 4、容器内的数据依旧是同步的
[root@df3f3769a002 /]# cd /home/
[root@df3f3769a002 home]# ls
hello
[root@df3f3769a002 home]# cat hello
hello world
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
3.实战:MySQL数据同步
思考:MySQL的数据持久化的问题
# 获取mysql镜像
[root@fedora ~]# docker pull mysql:5.7
# 运行容器,需要做数据挂载
# 安装启动mysql,需要配置密码,这是要注意点!
# 参考官网hub
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- name 容器名字
[root@fedora ~]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 启动成功之后,我们在本地使用sqlyog来测试一下
# sqlyog连接到服务器的3306和容器内的3306 映射
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
假设我们将容器删除 :
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能
4.具名和匿名挂载
三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
# 匿名挂载
[root@fedora ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
[root@fedora ~]# docker volume ls
DRIVER VOLUME NAME
local 4bd0a96149d19e42c416bc8ffe0ff70f2fefee91719622944e989277092d56de
......
local cd2b7473dc48824ed40de704699609e60b47908713ca14b137c0652ac27daf6e
# 这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径!
# 具名挂载
# 通过 -v 卷名:容器内路径
[root@fedora ~]# docker run -d -P --name nginx02 -v nginx02:/etc/nginx nginx
[root@fedora ~]# docker volume ls
DRIVER VOLUME NAME
......
local cd2b7473dc48824ed40de704699609e60b47908713ca14b137c0652ac27daf6e
local nginx02
# 查看一下这个卷
[root@fedora ~]# docker volume inspect nginx02
[
{
"CreatedAt": "2022-06-23T14:49:37+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx02/_data",
# 默认路径:/var/lib/docker/volumes/xxxx/_data
"Name": "nginx02",
"Options": null,
"Scope": "local"
}
]
# 所有的docker容器内的卷,没有指定目录的情况下
# 都是在 /var/lib/docker/volumes/xxxx/_data下
# 如果指定了目录,docker volume ls 是查看不到的。
# 指定路径挂载
[root@fedora ~]# docker run -d -P --name nginx03 -v /etc/nginx03:/etc/nginx nginx
[root@fedora ~]# docker volume ls
DRIVER VOLUME NAME
......
local cd2b7473dc48824ed40de704699609e60b47908713ca14b137c0652ac27daf6e
local nginx02
[root@fedora ~]# docker volume inspect nginx03
[]
Error: No such volume: nginx03
拓展:
# 通过 -v 容器内路径:ro / rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
docker run -d -P --name nginx -v nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx -v nginx:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
5.初识Dockerfile
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像
# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
# 编写dockerfile
[root@fedora ~]# touch dockerfile
[root@fedora ~]# chmod 755 dockerfile
[root@fedora ~]# vim dockerfile
[root@fedora ~]# cat dockerfile
FROM centos
VOLUME ["volume1","volume2"]
CMD echo "hello world !"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
# 使用dockerfile构建docker镜像
[root@fedora ~]# docker build -f /root/dockerfile -t test-centos:1.0 .
Sending build context to Docker daemon 27.65kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume1","volume2"]
---> Running in d372a812cc7d
Removing intermediate container d372a812cc7d
---> cf44dfcec98e
Step 3/4 : CMD echo "hello world !"
---> Running in 92cfcc99ea49
Removing intermediate container 92cfcc99ea49
---> bcb01dff9ca9
Step 4/4 : CMD /bin/bash
---> Running in 4ecd258bb6c4
Removing intermediate container 4ecd258bb6c4
---> 2b09bf17ffcc
Successfully built 2b09bf17ffcc
Successfully tagged test-centos:1.0
[root@fedora ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test-centos 1.0 2b09bf17ffcc 8 seconds ago 231MB
centos latest 5d0da3dc9764 9 months ago 231MB
# 启动镜像
[root@fedora ~]# docker run -it test-centos:1.0 /bin/bash
[root@d2e33c323777 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume2
dev home lib64 media opt root sbin sys usr volume1
# volume1和volume2就是生成镜像的时候,
# 自动挂载的 数据卷目录
# 查看一下卷挂载
[root@fedora ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2e33c323777 test-centos:1.0 "/bin/bash" 4 minutes ago Exited (0) 8 seconds ago condescending_poincare
[root@fedora ~]# docker inspect d2e33c323777
......
"Mounts": [
{
"Type": "volume",
"Name": "98c0a007f824d767f3b30fbd9d2ab044e93dc13aca0a75b4581cd32346f32ff2",
"Source": "/var/lib/docker/volumes/98c0a007f824d767f3b30fbd9d2ab044e93dc13aca0a75b4581cd32346f32ff2/_data",
# 卷挂载的路径
# 由于是匿名挂载,生成的名字比较长
"Destination": "volume1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "f03956b31478d2d3f543b9d83d57413e95980cc9d509706dc80b82f90e24037d",
"Source": "/var/lib/docker/volumes/f03956b31478d2d3f543b9d83d57413e95980cc9d509706dc80b82f90e24037d/_data",
"Destination": "volume2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
......
# 测试一下文件是否同步出去
[root@d2e33c323777 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume1 volume2
[root@d2e33c323777 /]# cd volume1
[root@d2e33c323777 volume1]# touch hello
[root@d2e33c323777 volume1]# ls
hello
[root@d2e33c323777 volume1]# exit
exit
[root@fedora ~]# cd /var/lib/docker/volumes/98c0a007f824d767f3b30fbd9d2ab044e93dc13aca0a75b4581cd32346f32ff2/_data
[root@fedora _data]# ls
hello
这种方式使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
6.数据卷容器
多个MySQL同步数据!
命名的容器挂载数据卷!
--volumes-from list Mount volumes from the specified container(s)
# 测试,我们通过刚才启动的
测试:可以删除docker01,查看一下docker02和docker03是否可以访问这个文件
测试依旧可以访问!
多个mysql实现数据共享
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!
结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!