什么是容器数据卷
为了实现数据持久化,使容器之间可以共享数据。可以将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享的操作。即使将容器删除,挂载到本地的数据卷也不会丢失。docker的理念回顾
将应用和环境打包成一个镜像
数据如果都在容器中,那么我们容器一旦删除,数据就会丢失 需求:数据可以持久化
MySQL,容器删了,删库跑路 需求:MySQL数据可以存储在本地
容器之间可以有一个数据共享的技术,Docker容器中产生的数据同步到本地
这就是卷技术,目录的挂载将我们容器内的目录挂载到Linux上面
容器的持久化和同步操作,容器间也是可以做数据共享的
使用数据卷
一、匿名挂载
1、即不指定挂载到主机上的路径,只指定容器内部需要挂载的目录。
-v 容器内路径
docker run -d -P --name 容器名称 -v 容器内路径 镜像名称
docker run -d -P --name nginx01 -v /etc/nginx nginx
kpsmile@kpsmile-machine:~$ docker run -d -P --name nginx01 -v /etc/nginx nginx
3fb5a0afb25f658e1a2f2b7cd22cc52b0fa45822e2707aea018e3b4e8d387249
kpsmile@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 nginx
kpsmile@kpsmile-machine:~$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
a24fc2e277ed8691d659adace64f4c010c726f8e62b7146a806a9ea5f32d7dd5
kpsmile@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 ubuntu
root@8e7564da3550:/# echo "test docker run -v" > /home/a.text
宿主机
kpsmile@kpsmile-machine:~/test$ pwd
/home/kpsmile/test
kpsmile@kpsmile-machine:~/test$ cat a.text
test docker run -v
宿主机操作文件
宿主机
# kpsmile用户权限不够,所以换了root用户
root@kpsmile-machine:/home/kpsmile/test# echo "host echo" >> a.text
容器内
root@8e7564da3550:/# cat /home/a.text
test docker run -v
host 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 ubuntu
docker run -it --privileged=true --volumes-from a8e05fd5907e --name u2 ubuntu
# u1
kpsmile@kpsmile-PC:~$ docker run -it --privileged=true -v /home/kpsmile/testExtend:/tmp --name u1 ubuntu
root@a8e05fd5907e:/# ls /tmp
a.txt
root@a8e05fd5907e:/# cat /tmp/a.txt
# u2
kpsmile@kpsmile-PC:~$ docker run -it --privileged=true --volumes-from a8e05fd5907e --name u2 ubuntu
root@a833d6b8c2de:/# ls /tmp
a.txt
root@a833d6b8c2de:/# cat /tmp/a.txt
# 宿主机
kpsmile@kpsmile-PC:~/testExtend$ pwd
/home/kpsmile/testExtend
kpsmile@kpsmile-PC:~/testExtend$ ls
a.txt
kpsmile@kpsmile-PC:~/testExtend$ cat a.txt
u1写入
# u1
root@a8e05fd5907e:/# echo "u1 wirte" >> /tmp/a.txt
root@a8e05fd5907e:/# cat /tmp/a.txt
u1 wirte
# u2
root@a833d6b8c2de:/# cat /tmp/a.txt
u1 wirte
# 宿主机
kpsmile@kpsmile-PC:~/testExtend$ cat a.txt
u1 wirte
u2写入
# u2
root@a833d6b8c2de:/# echo "u2 wirte" >> /tmp/a.txt
root@a833d6b8c2de:/# cat /tmp/a.txt
u1 wirte
u2 wirte
# u1
root@a8e05fd5907e:/# cat /tmp/a.txt
u1 wirte
u2 wirte
# 宿主机
kpsmile@kpsmile-PC:~/testExtend$ cat a.txt
u1 wirte
u2 wirte
宿主机写入
# 宿主机
kpsmile@kpsmile-PC:~/testExtend$ echo "host wirte" >> a.txt
kpsmile@kpsmile-PC:~/testExtend$ cat a.txt
u1 wirte
u2 wirte
host wirte
# u1
root@a8e05fd5907e:/# cat /tmp/a.txt
u1 wirte
u2 wirte
host wirte
# u2
root@a833d6b8c2de:/# cat /tmp/a.txt
u1 wirte
u2 wirte
host 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 -p
mysql> 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_ci
character_set_server = utf8
重启MySQL
kpsmile@kpsmile-machine:~/mysql$ docker restart c7be37c4ab1a
c7be37c4ab1a
kpsmile@kpsmile-machine:~/mysql$ docker exec -it c7be37c4ab1a bash
root@c7be37c4ab1a:/# mysql -uroot -p
mysql> 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)