Docker研学-容器数据卷

学习自b站狂神说Docker: https://www.bilibili.com/video/BV1og4y1q7M4/?spm_id_from=333.337.search-card.all.click

容器数据卷

docker的理念是将应用和环境打包成一个镜像,但数据若在容器中,容器删除,数据就会丢失(例如mysql的数据可以存储在本地,完成数据的持久化),故容器之间需要有数据共享技术,使docker容器中的数据同步到本地

这是卷技术,目录的挂载,将容器内目录挂载到Linux上,完成容器的持久化和同步操作,容器间可以数据共享
在这里插入图片描述

使用数据卷

方式一:直接使用命令挂载 -v (类似-p)

docker run -it -v 主机目录:容器内目录
#1.测试,启动centos进行挂载
[root@localhost home]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@9302ce5fe51a /]# 
#此刻可以再开一个线程看看本机的home中是否有ceshi 存在说明启动了

#2.查看卷是否挂载成功 docker inspect ,Mounts没信息说明挂载失败
[root@localhost /]# docker inspect 9302ce5fe51a
[
//......
"Mounts": [                                             挂载 -v卷
            {
                "Type": "bind",
                "Source": "/home/ceshi",                目的地,主机内的地址
                "Destination": "/home",                 docker容器内的地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
//......       
]

#3.在容器外ceshi存放数据会自动同步到容器内的home中(容器关闭也会同步),容器中的home存放数据容器外也会自动同步
[root@9302ce5fe51a home]# touch xinxin.java
[root@localhost ceshi]# ls
xinxin.java

#4.在容器关闭时,编辑挂载卷的文件,进入容器查看是否自动同步(已同步)
[root@localhost ceshi]# vi xinxin.java                     #编辑文件
[root@localhost /]# docker start 9302ce5fe51a              #启动容器
[root@localhost /]# docker attach 9302ce5fe51a             #进入运行中的容器
[root@9302ce5fe51a home]# vi xinxin.java                   #容器内的文件已实现自动同步

实战:安装Mysql

#1.安装mysql
[root@localhost /]# docker pull mysql:5.7

#2.运行容器时,做数据卷挂载,后台运行,暴露端口3310:3306,数据卷挂载主机下的配置文件,对应数据库的conf文件(配置文件)/home/mysql/conf:/etc/mysql/conf.d 同时将mysql中的数据文件也映射出来(可以映射多个)
#注意,安装mysql,需要配置密码 -e表示配置环境(在这里配置初始密码为root)
[root@localhost /]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7
a0e6d186b021e7f4c72df919fc7ea48b47daada5821cb26420a24a36e4377943

#常用可选项
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字

#3.启动成功后,可以在本地使用Navicat测试数据库是否能够连接,服务器3310-容器3306

#4.查询本地home目录下的mysql,查看是否挂载成功
[root@localhost mysql]# ls
conf  data

#5.在Navicat中建数据库(容器中),本地映射的data目录中也会增加文件
[root@localhost mysql]# cd data
[root@localhost data]# ls                           #创建数据库查看映射路径是否ok
auto.cnf    client-cert.pem  ibdata1      ibtmp1    private_key.pem  server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql     public_key.pem   sys
ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem  test

#6.持久化绑定到本地,容器删了也在,实现了容器数据持久化功能
[root@localhost /]# docker rm -f mysql01
[root@localhost data]# ls
auto.cnf    client-cert.pem  ibdata1      ibtmp1    private_key.pem  server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql     public_key.pem   sys
ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem  test

具名和匿名挂载

# 匿名挂载 不指定主机名(路径),自动生成对应路径 -v 容器内路径 -P(大写)随机映射端口
[root@localhost /]# docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看卷状态 docker volume 可选项
create 创建卷
ls 查看所有卷
rm 移除
inspect 查看卷怎么做的
prune 移除没有使用的

# 查看所有卷的情况,此刻这两条就是匿名挂载
[root@localhost /]# docker volume ls
DRIVER    VOLUME NAME
local     cc6e3e8ebdbd022d6a77e6cf1ea1497611bbcfc4a4a0c37b29811cf1c4e8fa36
local     ef566e18297260f726bddc62ca90e3f95280d66f6df43a129079db189eff9e4d

# 具名挂载 通过-v 卷名:容器内路径 
[root@localhost /]# docker run -d -P --name nginx21 -v juming-nginx:/etc/nginx nginx
8b1d73e525d94936ea699a16371328dd41cfcca05fd5a24abac9c685fdc83e80
[root@localhost /]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

# 查看卷的位置,所有docker容器内的卷,没指定目录都在/var/lib/docker/volumes/xxx/_data目录下
[root@localhost /]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2023-10-17T10:43:05+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",      挂载目录地址
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

# docker的工作目录 /var/lib/docker
[root@localhost docker]# ls
buildkit  containers  engine-id  image  network  overlay2  plugins  runtimes  swarm  tmp  volumes

# 卷目录 /var/lib/docker/volumes
[root@localhost volumes]# ls
backingFsBlockDev                                                 juming-nginx
cc6e3e8ebdbd022d6a77e6cf1ea1497611bbcfc4a4a0c37b29811cf1c4e8fa36  metadata.db
ef566e18297260f726bddc62ca90e3f95280d66f6df43a129079db189eff9e4d

# 可在目录下将nginx.conf配置文件拿出来做同步
[root@localhost volumes]# cd juming-nginx
[root@localhost juming-nginx]# ls
_data
[root@localhost juming-nginx]# cd _data
[root@localhost _data]# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params

# 查看配置文件 -n可以添加行号,cat命令,它可以创建,查看,连接和重定向文件
[root@localhost _data]# cat -n nginx.conf
     1	
     2	user  nginx;
     3	worker_processes  auto;
     4	
     5	error_log  /var/log/nginx/error.log notice;
     6	pid        /var/run/nginx.pid;
     7	
     8	
     9	events {
    10	    worker_connections  1024;
    11	}
    12	
    13	
    14	http {
    15	    include       /etc/nginx/mime.types;
    16	    default_type  application/octet-stream;
    17	
    18	    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    19	                      '$status $body_bytes_sent "$http_referer" '
    20	                      '"$http_user_agent" "$http_x_forwarded_for"';
    21	
    22	    access_log  /var/log/nginx/access.log  main;
    23	
    24	    sendfile        on;
    25	    #tcp_nopush     on;
    26	
    27	    keepalive_timeout  65;
    28	
    29	    #gzip  on;
    30	
    31	    include /etc/nginx/conf.d/*.conf;
    32	}
# 具名挂载很容易找到卷(常用),不建议使用匿名挂载

#如何区分是具名还是匿名挂载,还是指定路径挂载
-v 容器内路径                   #匿名挂载 在volumes下随机生成一个路径完成映射
-v 卷名:容器内路径               #具名挂载
-v /宿主机路径:容器内路径         #指定路径挂载

拓展:

# 可通过 -v 容器内路径:ro rw 改变读写权限
ro     #readonly 只读       说明这个路径只能通过宿主机来操作,容器内部是无法操作的
rw     #readwrite 可读可写
#一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了(相对于容器),容器挂载出来后容器内就不能操作了
docker run -d -P --name nginx21 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx21 -v juming-nginx:/etc/nginx:rw nginx

初识Dockerfile

方式二:用来构建docker镜像的构建文件,命令脚本

# 测试,创建一个目录,之后的文件挂载到这里
[root@localhost home]# mkdir docker-test-volume

# 进入目录,创建脚本文件,通过脚本可生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层
[root@localhost docker-test-volume]# vim dockerfile1

# 生成镜像用centos当做基础,通过VOLUME["volume01","volume02"]挂载卷(生成时就挂载,可以挂载多个目录),输出CMD的命令行(构建完成后输出),进入后默认走/bin/bash控制台 
# 指令(大写) 参数 这里每个命令就是镜像的一层
[root@localhost docker-test-volume]# cat dockerfile1
FROM centos
VOLUME ["volume01","volume02"]                   #匿名挂载
CMD echo "---end---"
CMD /bin/bash

# docker build通过文件构建镜像 -f 是文件的地址 -t 名字+版本 最后记得记上 .(加个点)
[root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t hailong/centos:1.0 .
[+] Building 0.0s (5/5) FINISHED                                       docker:default
 => [internal] load build definition from dockerfile1                        0.0s
 => => transferring dockerfile: 118B                                         0.0s
 => [internal] load .dockerignore                                            0.0s
 => => transferring context: 2B                                              0.0s
 => [internal] load metadata for docker.io/library/centos:latest             0.0s
 => [1/1] FROM docker.io/library/centos                                      0.0s
 => exporting to image                                                       0.0s
 => => exporting layers                                                      0.0s
 => => writing image sha256:139235ade34847ff60bb087950d6bfc135d69865c42012862ca936647598ae1e      0.0s
 => => naming to docker.io/hailong/centos:1.0                                0.0s
 
# 通过docker images查询创建的镜像
[root@localhost docker-test-volume]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
hailong/centos        1.0       139235ade348   2 years ago     231MB

# 进入创建的镜像,volume01,volume02这两个目录就是生成镜像时自动挂载的数据卷目录
[root@localhost docker-test-volume]# docker run -it 139235ade348 /bin/bash
[root@fa5086458ad4 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var	   volume02
dev  home  lib64  media       opt  root  sbin  sys  usr  volume01
#这个卷和外部一定有一个同步的目录,卷不存在目录是挂不上的

# 进入volume01,在容器内创建文件
[root@fa5086458ad4 /]# cd volume01
[root@fa5086458ad4 volume01]# touch container.txt

# 新启一个线程查看容器的具体信息(卷的挂载路径) inspect 获得对应的容器外目录(Source)
[root@localhost /]# docker inspect fa5086458ad4
"Mounts": [
            {
                "Type": "volume",
                "Name": "ada7159c7e5aa1987082aaf884aac1317cca7b34524ef0b19c4912887c9f9693",
                "Source": "/var/lib/docker/volumes/ada7159c7e5aa1987082aaf884aac1317cca7b34524ef0b19c4912887c9f9693/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "79b361c729b1a73c49eaf90a8fec26e2c04384a8fb851ff3119856dc434bc5f1",
                "Source": "/var/lib/docker/volumes/79b361c729b1a73c49eaf90a8fec26e2c04384a8fb851ff3119856dc434bc5f1/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        
# 测试一下刚才的文件是否同步出去(容器外)
[root@localhost _data]# ls
container.txt

数据卷容器-容器间数据同步

在这里插入图片描述

# 启动3个容器,通过刚才写的镜像

# 创建父容器docker01,必须写版本号不然会去找最新的(或者用镜像id启动),容器中有创建的挂载卷
[root@localhost /]# docker run -it --name docker01 hailong/centos:1.0

# 保持运行状态退出 ctrl+p+q

# 创建容器docker02进行挂载 --volumes-from 绑定(类似继承,数据同步) 该容器内也有两个卷
[root@localhost /]# docker run -it --name docker02 --volumes-from docker01 hailong/centos:1.0

# 进入docker01容器(数据卷容器)添加文件,查看docker02容器是否同步(仅挂载卷)
[root@localhost ~]# docker attach 7b23d2a7b9b9
[root@7b23d2a7b9b9 volume01]# touch docker01

# docker02容器已经同步(02容器内创建的01容器内也会自动同步)
[root@2596dde2bc79 volume01]# ls            
docker01

#该技术可以实现多个mysql,redis之间数据共享(匿名挂载,路径相同可以不写)
[root@localhost /]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7
[root@localhost /]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql02 --volumes-from mysql01 mysql:5.7

结论

容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止,但是一旦持久化到了本地,此时本地的数据是不会删除的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒疯狂展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值