什么是容器数据卷
为了实现数据持久化,使容器之间可以共享数据。可以将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享的操作。即使将容器删除,挂载到本地的数据卷也不会丢失。docker的理念回顾
将应用和环境打包成一个镜像
数据如果都在容器中,那么我们容器一旦删除,数据就会丢失 需求:数据可以持久化
MySQL,容器删了,删库跑路 需求:MySQL数据可以存储在本地
容器之间可以有一个数据共享的技术,Docker容器中产生的数据同步到本地
这就是卷技术,目录的挂载将我们容器内的目录挂载到Linux上面
容器的持久化和同步操作,容器间也是可以做数据共享的
使用数据卷
一、匿名挂载
1、即不指定挂载到主机上的路径,只指定容器内部需要挂载的目录。
-v 容器内路径docker run -d -P --name 容器名称 -v 容器内路径 镜像名称docker run -d -P --name nginx01 -v /etc/nginx nginxkpsmile@kpsmile-machine:~$ docker run -d -P --name nginx01 -v /etc/nginx nginx3fb5a0afb25f658e1a2f2b7cd22cc52b0fa45822e2707aea018e3b4e8d387249kpsmile@kpsmile-machine:~$ docker inspect 3fb5a0afb25f658e1a2f2b7cd22cc52b0fa45822e2707aea018e3b4e8d387249..."Mounts": [{"Type": "volume","Name": "ab1706dfd8a7352003d7198f1e353092264ac24d20b933f48cbe6adca29e89db","Source": "/var/lib/docker/volumes/ab1706dfd8a7352003d7198f1e353092264ac24d20b933f48cbe6adca29e89db/_data","Destination": "/etc/nginx","Driver": "local","Mode": "","RW": true,"Propagation": ""}],...# 挂载位置在ab1706dfd8a7352003d7198f1e353092264ac24d20b933f48cbe6adca29e89db这个卷下
二、具名挂载
1、给挂载位置添加名字,即具名挂载。
-v 卷名:容器内路径docker run -d -P --name 容器名称 -v 卷名:容器内路径 镜像名称例如:docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginxkpsmile@kpsmile-machine:~$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginxa24fc2e277ed8691d659adace64f4c010c726f8e62b7146a806a9ea5f32d7dd5kpsmile@kpsmile-machine:~$ docker inspect a24fc2e277ed8691d659adace64f4c010c726f8e62b7146a806a9ea5f32d7dd5..."Mounts": [{"Type": "volume","Name": "juming-nginx","Source": "/var/lib/docker/volumes/juming-nginx/_data","Destination": "/etc/nginx","Driver": "local","Mode": "z","RW": true,"Propagation": ""}]...
三、指定挂载
docker run -it -v 宿主机目录:dockers容器内目录 imageId
容器内操作文件
容器内
kpsmile@kpsmile-machine:~$ docker run -it --name ubuntu-test -v /home/kpsmile/test:/home ubunturoot@8e7564da3550:/# echo "test docker run -v" > /home/a.text
宿主机
kpsmile@kpsmile-machine:~/test$ pwd/home/kpsmile/testkpsmile@kpsmile-machine:~/test$ cat a.texttest docker run -v
宿主机操作文件
宿主机
# kpsmile用户权限不够,所以换了root用户root@kpsmile-machine:/home/kpsmile/test# echo "host echo" >> a.text
容器内
root@8e7564da3550:/# cat /home/a.texttest docker run -vhost echo
四、具名挂载、匿名挂载和指定路径挂载的区别
1、
-v 容器内部路径 #匿名挂载-v 卷名:容器内部路径 #具名挂载-v /宿主机路径:容器内部路径 #指定路径挂载
2、数据卷挂载还可以赋予权限
#通过-v容器内路径,ro rw改变读写权限 默认是rw权限,即可读可写。ro read only #只读rw read write #可读可写#一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:ro nginx$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:rw nginx#ro 即创建的这个卷是只读权限(read only),即容器内部职能读取,不能修改,必须通过宿主机来进行修改。
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个—privileged=true参数即可
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,
在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用—privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即
使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
卷的继承
docker run -it --privileged=true -v /home/kpsmile/testExtend:/tmp --name u1 ubuntudocker run -it --privileged=true --volumes-from a8e05fd5907e --name u2 ubuntu# u1kpsmile@kpsmile-PC:~$ docker run -it --privileged=true -v /home/kpsmile/testExtend:/tmp --name u1 ubunturoot@a8e05fd5907e:/# ls /tmpa.txtroot@a8e05fd5907e:/# cat /tmp/a.txt# u2kpsmile@kpsmile-PC:~$ docker run -it --privileged=true --volumes-from a8e05fd5907e --name u2 ubunturoot@a833d6b8c2de:/# ls /tmpa.txtroot@a833d6b8c2de:/# cat /tmp/a.txt# 宿主机kpsmile@kpsmile-PC:~/testExtend$ pwd/home/kpsmile/testExtendkpsmile@kpsmile-PC:~/testExtend$ lsa.txtkpsmile@kpsmile-PC:~/testExtend$ cat a.txt
u1写入
# u1root@a8e05fd5907e:/# echo "u1 wirte" >> /tmp/a.txtroot@a8e05fd5907e:/# cat /tmp/a.txtu1 wirte# u2root@a833d6b8c2de:/# cat /tmp/a.txtu1 wirte# 宿主机kpsmile@kpsmile-PC:~/testExtend$ cat a.txtu1 wirte
u2写入
# u2root@a833d6b8c2de:/# echo "u2 wirte" >> /tmp/a.txtroot@a833d6b8c2de:/# cat /tmp/a.txtu1 wirteu2 wirte# u1root@a8e05fd5907e:/# cat /tmp/a.txtu1 wirteu2 wirte# 宿主机kpsmile@kpsmile-PC:~/testExtend$ cat a.txtu1 wirteu2 wirte
宿主机写入
# 宿主机kpsmile@kpsmile-PC:~/testExtend$ echo "host wirte" >> a.txtkpsmile@kpsmile-PC:~/testExtend$ cat a.txtu1 wirteu2 wirtehost wirte# u1root@a8e05fd5907e:/# cat /tmp/a.txtu1 wirteu2 wirtehost wirte# u2root@a833d6b8c2de:/# cat /tmp/a.txtu1 wirteu2 wirtehost wirte
安装MySQL
docker run -d -p 3306:3306 --privileged=true -v /home/kpsmile/mysql/log:/var/log/mysql -v /home/kpsmile/mysql/data:/var/lib/mysql -v /home/kpsmile/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
此时进入容器内部
kpsmile@kpsmile-machine:~/mysql$ docker exec -it c7be37c4ab1a bash
运行MySQL
root@c7be37c4ab1a:/# mysql -uroot -pmysql> SHOW VARIABLES LIKE 'character%' ;+--------------------------+----------------------------+| Variable_name | Value |+--------------------------+----------------------------+| character_set_client | latin1 || character_set_connection | latin1 || character_set_database | latin1 || character_set_filesystem | binary || character_set_results | latin1 || character_set_server | latin1 || character_set_system | utf8 || character_sets_dir | /usr/share/mysql/charsets/ |+--------------------------+----------------------------+8 rows in set (0.00 sec)
CTRL+q+p回到宿主机
编写my.cnf
kpsmile@kpsmile-machine:~/mysql$ sudo vim conf/my.cnf[client]default_character_set=utf8[mysqld]collation_server = utf8_general_cicharacter_set_server = utf8
重启MySQL
kpsmile@kpsmile-machine:~/mysql$ docker restart c7be37c4ab1ac7be37c4ab1akpsmile@kpsmile-machine:~/mysql$ docker exec -it c7be37c4ab1a bashroot@c7be37c4ab1a:/# mysql -uroot -pmysql> SHOW VARIABLES LIKE 'character%' ;+--------------------------+----------------------------+| Variable_name | Value |+--------------------------+----------------------------+| character_set_client | utf8 || character_set_connection | utf8 || character_set_database | utf8 || character_set_filesystem | binary || character_set_results | utf8 || character_set_server | utf8 || character_set_system | utf8 || character_sets_dir | /usr/share/mysql/charsets/ |+--------------------------+----------------------------+8 rows in set (0.00 sec)
