Docker 容器数据卷
Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据也就消失了。需要对数据进行持久化。
为了保存docker中的数据,可以使用数据卷。
是什么
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生命周期,因此Docker不会在容器删除时删除其挂载的数据卷。
通俗来说,就是将docker容器内的数据保存进宿主机的磁盘中。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
–privileged=true???
-
Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可
如果是CentOS7,安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用–privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也就是使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
特点:
- 数据卷可在容器间共享或重用数据
- 数据卷更改实时生效
- 数据卷的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
添加数据卷
docker run -it --privileged=true -v /宿主机目录:/容器内目录 镜像名
-
添加数据卷
docker run -it --name="ubuntu-j" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu f706429da9df /bin/bash
[root@VM-4-9-centos /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE 121.4.126.115:5000/ubuntu-j 1.0 f706429da9df 5 hours ago 186MB mysql latest f6360852d654 4 days ago 565MB redis latest 7e89539dd8bd 2 weeks ago 130MB [root@VM-4-9-centos /]# docker run -it --name="ubuntu-j" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu f706429da9df /bin/bash root@74221444a50b:/#
-
查看数据卷是否挂载成功docker inspect 容器id
[root@VM-4-9-centos ubuntu]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 74221444a50b f706429da9df "/bin/bash" 13 minutes ago Up 13 minutes ubuntu-j f5346aab9063 registry "/entrypoint.sh /etc…" 6 hours ago Up 3 hours 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp ecstatic_goldwasser 3bb8baf477a0 portainer/portainer "/portainer" 2 days ago Up 3 hours 8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp mystifying_knuth [root@VM-4-9-centos ubuntu]# docker inspect 74221444a50b ...... "Mounts": [ { "Type": "bind", "Source": "/dockerbackup/ubuntu", "Destination": "/tmp/ubuntu", "Mode": "", "RW": true, "Propagation": "rprivate" } ...... [root@VM-4-9-centos ubuntu]#
-
测试1:
-
在容器相应目录新建a.txt文件
root@74221444a50b:/tmp/ubuntu# pwd /tmp/ubuntu root@74221444a50b:/tmp/ubuntu# touch a.txt root@74221444a50b:/tmp/ubuntu# ls a.txt
-
查看宿主机相应目录
[root@VM-4-9-centos ~]# ls /dockerbackup/ubuntu/ a.txt
-
-
测试2:
-
在宿主机相应目录新建b.txt
[root@VM-4-9-centos ubuntu]# pwd /dockerbackup/ubuntu [root@VM-4-9-centos ubuntu]# touch b.txt [root@VM-4-9-centos ubuntu]# ls a.txt b.txt
-
查看容器相应目录
root@74221444a50b:/tmp/ubuntu# pwd /tmp/ubuntu root@74221444a50b:/tmp/ubuntu# ls a.txt b.txt
-
读写规则映射添加说明
读写(默认)
docker run -it --privileged=true -v /宿主机目录:/容器内目录:rw 镜像名
- rw:read+write
- 默认(不写rw)就是具备读写的
只读
docker run -it --privileged=true -v /宿主机目录:/容器内目录:ro 镜像名
- ro:read only
- 此时如果宿主机写,可以同步到容器,容器可以读取到,但是容器不支持写
-
添加数据卷
[root@VM-4-9-centos /]# docker run -it --name="ubuntu-j2" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu:ro f706429da9df /bin/bash root@99c6b59ff576:/# cd tmp/ubuntu/ root@99c6b59ff576:/tmp/ubuntu# ls a.txt b.txt root@99c6b59ff576:/tmp/ubuntu#
-
测试1:
-
宿主机写c.txt
[root@VM-4-9-centos ubuntu]# pwd /dockerbackup/ubuntu [root@VM-4-9-centos ubuntu]# touch c.txt [root@VM-4-9-centos ubuntu]# ls a.txt b.txt c.txt [root@VM-4-9-centos ubuntu]#
-
查看容器相应目录
root@99c6b59ff576:/tmp/ubuntu# ls a.txt b.txt c.txt root@99c6b59ff576:/tmp/ubuntu#
-
-
测试2:
-
容器写d.txt(发现不能写,只读)
root@99c6b59ff576:/tmp/ubuntu# touch d.txt touch: cannot touch 'd.txt': Read-only file system root@99c6b59ff576:/tmp/ubuntu#
-
卷的继承和共享
-
容器1完成和宿主机的卷映射
docker run -it --name="ubuntu-j2" --privileged=true -v /dockerbackup/ubuntu:/tmp/ubuntu:ro f706429da9df /bin/bash
-
容器2继承容器1的卷规则
docker run -it --name="ubuntu-j3" --privileged=true --volumes-from ubuntu-j2 f706429da9df /bin/bash
-
测试
-
查看容器2信息
[root@VM-4-9-centos ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 30045c2c0dbd f706429da9df "/bin/bash" 29 seconds ago Up 28 seconds ubuntu-j3 99c6b59ff576 f706429da9df "/bin/bash" 14 minutes ago Up 14 minutes ubuntu-j2 f5346aab9063 registry "/entrypoint.sh /etc…" 7 hours ago Up 3 hours 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp ecstatic_goldwasser 3bb8baf477a0 portainer/portainer "/portainer" 2 days ago Up 4 hours 8000/tcp, 9443/tcp, 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp mystifying_knuth [root@VM-4-9-centos ~]# docker inspect 30045c2c0dbd ...... "Mounts": [ { "Type": "bind", "Source": "/dockerbackup/ubuntu", "Destination": "/tmp/ubuntu", "Mode": "", "RW": false, "Propagation": "rprivate" } ], ...... [root@VM-4-9-centos ~]#
-
查看容器2内相应目录
root@30045c2c0dbd:/# cd tmp/ubuntu/ root@30045c2c0dbd:/tmp/ubuntu# ls a.txt b.txt c.txt root@30045c2c0dbd:/tmp/ubuntu#
-
宿主机写e.txt
[root@VM-4-9-centos ubuntu]# pwd /dockerbackup/ubuntu [root@VM-4-9-centos ubuntu]# ls a.txt b.txt c.txt [root@VM-4-9-centos ubuntu]# touch e.txt [root@VM-4-9-centos ubuntu]# ls a.txt b.txt c.txt e.txt [root@VM-4-9-centos ubuntu]#
-
查看容器2
root@30045c2c0dbd:/tmp/ubuntu# ls a.txt b.txt c.txt e.txt root@30045c2c0dbd:/tmp/ubuntu#
-
查看容器1
root@99c6b59ff576:/tmp/ubuntu# ls a.txt b.txt c.txt e.txt root@99c6b59ff576:/tmp/ubuntu#
-
简单应用部署
1、部署MySQL
- 搜索mysql镜像
docker search mysql
- 拉取mysql镜像
docker pull mysql:5.7
- 创建容器,设置端口映射、目录映射
# 在/root目录下创建mysql目录用于存储mysql数据信息
mkdir ~/mysql
cd ~/mysql
docker run -id \
-p 3307:3306 \
--name=c_mysql \
--privileged=true \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=admin \
mysql:5.7
- 参数说明:
- -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
- -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
- -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
- -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
- **-e MYSQL_ROOT_PASSWORD=123456:**初始化 root 用户的密码。
- 进入容器,操作mysql
docker exec –it c_mysql /bin/bash
- 使用外部机器连接容器中的mysql
中文乱码问题:
-
进入docker容器中的mysql查看编码
SHOW VARIABLES LIKE 'character%';
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) mysql>
-
character_set_client和character_set_database都是latin1编码,需将其改为utf-8,否则会引起中文乱码问题。
-
通过容器卷同步配置给mysql容器实例
[root@VM-4-9-centos conf]# pwd /root/mysql/conf [root@VM-4-9-centos conf]# vim my.cnf [root@VM-4-9-centos conf]# cat my.cnf [client] default_character_set=utf8 [mysqld] collation_server = utf8_general_ci character_set_server = utf8 [root@VM-4-9-centos conf]#
-
查看容器实例字符编码
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) mysql>
-
2、部署Tomcat
最新版首页需修改,可以使用8版本:
docker pull billygoo/tomcat8-jdk8
docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
最新版:
- 搜索tomcat镜像
docker search tomcat
- 拉取tomcat镜像
docker pull tomcat
- 创建容器,设置端口映射、目录映射
# 在/root目录下创建tomcat目录用于存储tomcat数据信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
-
参数说明:
-
**-p 8080:8080:**将容器的8080端口映射到主机的8080端口
**-v $PWD:/usr/local/tomcat/webapps:**将主机中当前目录挂载到容器的webapps
-
- 使用外部机器访问tomcat
3、部署Nginx
- 搜索nginx镜像
docker search nginx
- 拉取nginx镜像
docker pull nginx
- 创建容器,设置端口映射、目录映射
# 在/root目录下创建nginx目录用于存储nginx数据信息
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在~/nginx/conf/下创建nginx.conf文件,粘贴下面内容
vim nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
- 参数说明:
- -p 80:80:将容器的 80端口映射到宿主机的 80 端口。
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机当前目录下的 /conf/nginx.conf 挂载到容器的 :/etc/nginx/nginx.conf。配置目录
- -v $PWD/logs:/var/log/nginx:将主机当前目录下的 logs 目录挂载到容器的/var/log/nginx。日志目录
- 使用外部机器访问nginx
4、部署Redis
- 搜索redis镜像
docker search redis
- 拉取redis镜像
docker pull redis:6.0.8
- 创建容器,置端口映射、目录映射
# 在/app目录下创建redis目录用于存储redis数据信息
mkdir -p /app/redis
cd /app/redis
# 将一份redis.conf文件模板拷贝到宿主机挂载目录下,并修改一些配置
[root@VM-4-9-centos redis]# pwd
/app/redis
[root@VM-4-9-centos redis]# ls
redis.conf
[root@VM-4-9-centos redis]# vim redis.conf
# 开启登录验证 可选
requirepass 123
# 允许redis外地连接 必须
# 注释掉 bind 127.0.0.1
# 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
daemonize no
# 开启aof 可选
appendonly yes
docker run -d \
-p 6380:6379 \
--name myredis \
--privileged=true \
-v /app/redis/redis.conf:/etc/redis/redis.conf \
-v /app/redis/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf
- 使用外部机器连接redis
./redis-cli.exe -h 121.4.126.115 -p 6380