Docker 容器数据卷 & 安装MySQL

容器数据卷

Docker:将应用和环境打包成一个镜像
如果数据都在容器中,那么将容器删除,数据就会丢失,风险太高,所以需要将数据持久化。
例:
Mysql容器 → 删除 == 删库跑路!
所以要将Mysql数据可以存储在本地,这就需要容器之间有一个数据共享的技术,来将Docker容器中产生的数据同步到本地!
这就是卷技术!(目录的挂载,将我们容器内的目录,挂载到Linux上面)

image.png

卷技术:容器的持久化和同步操作!容器间也是可以数据共享的!

方式一:直接使用命令来挂载 -v

# 双向绑定
docker run -it -v 主机目录:容器内目录

# 启动centos容器 并将容器内/home与容器外linux的/home/ceshi目录进行同步操作
[root@liuyi home]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@d977f2605373 /]# 

# 新开窗口 查看是否挂载成功
[root@liuyi home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
d977f2605373   centos    "/bin/bash"   16 minutes ago   Up 16 minutes             sad_feynman
[root@liuyi home]# docker inspect d977f2605373
结果内容很多,找到以下部分则是挂载成功:
"Mounts": [
    {
        "Type": "bind",
        "Source": "/home/ceshi", # 宿主机目录
        "Destination": "/home", # docker容器目录
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],

# 测试 - 容器内/home下新建test.java
[root@d977f2605373 home]# ls
[root@d977f2605373 home]# touch test.java
[root@d977f2605373 home]# ls
test.java
[root@d977f2605373 home]# 

# 测试 - 宿主机/home/ceshi/下查看 发现同步文件成功
[root@liuyi ceshi]# ls
test.java
[root@liuyi ceshi]# 

* 同样的在宿主机/home/ceshi/目录下创建文件,也会同步至容器内/home目录下
* 编辑文件也是一样会同步,即使exit退出了容器,在宿主机/home/ceshi/目录下创建、删除文件,修改文件内容,在 docker start 容器id (docker ps -a 查询运行过的容器id) 启动容器之后查看容器内/home目录下的文件也被同步了操作

测试步骤:
  1.停止容器
  2.宿主机上修改文件
  3.启动容器
  4.容器内的数据依旧是同步的
a2cc87b6-ea64-4f43-be24-2e3d391617e0.png

容器数据卷优点:同步后只需求在宿主机上修改文件,容器内会自动同步,无需再进入容器修改。

安装MySQL

解决MySQL数据持久化问题

# 获取镜像
[root@liuyi home]# docker pull mysql:5.7

# 运行容器,需要做数据挂载 (注意:安装mysql时需要配置密码)
# 官方命令:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag
# -d  后台运行
# -p  端口映射(宿主机端口:容器端口)
# -v  卷挂载 (可以多个-v 挂载多个目录)
# -e  环境配置
# --name 容器名字
[root@liuyi home]# 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=123456 --name mysql01 mysql:5.7

# 连接测试
1.可以使用数据库工具连接测试
2.使用数据库工具创建新建一个数据库test_database
3.查看宿主机/home/mysql/data/目录下会多一个test_database文件

删除容器,但是映射到宿主机目录的文件不会受影响!!!

# 删除容器(彻底删除 docker ps 和 docker ps -a 都无法查到)
[root@liuyi home]# docker rm -f mysql01
mysql01
[root@liuyi home]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@liuyi home]# docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS                      PORTS     NAMES
74e143012e3c   tomcat                "catalina.sh run"        47 hours ago   Exited (143) 27 hours ago             heuristic_leavitt
30ea50a45640   portainer/portainer   "/portainer"             2 days ago     Exited (2) 47 hours ago               elastic_keller
d1fa45a53424   tomcat                "catalina.sh run"        3 days ago     Exited (143) 47 hours ago             tomcat01
d0f8c656fcfb   nginx                 "/docker-entrypoint.…"   3 days ago     Exited (0) 3 days ago                 nginx01
95160a4accd1   centos                "/bin/bash"              3 days ago     Exited (0) 3 days ago                 dreamy_keller
f014391a9c38   hello-world           "/hello"                 4 days ago     Exited (0) 4 days ago                 quizzical_goldwasser
[root@liuyi home]# 

# 查看宿主机映射目录,发现挂载到本地的数据卷没有丢失,这就实现了容器数据持久化功能!
[root@liuyi /]# cd /home//mysql/
[root@liuyi mysql]# ls
conf  data
[root@liuyi mysql]# cd data
[root@liuyi 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_database
[root@liuyi data]# 

具名挂载和匿名挂载

1、 匿名挂载(随机指定挂载目录,只写容器内路径,不写容器外路径)
-v 容器内路径

# -p 宿主机端口:容器内端口
# -P 随机分配端口 (大写的P)
[root@liuyi home]# docker run -d -P --name nginx01 -v /etc/nginx nginx
01fa63a5c003729500cde10d153b09e61cac3fe2f89192d7d8674db7c380a7f7
[root@liuyi home]# docker volume --help     # 查看volume帮助文档
Usage:  docker volume COMMAND
Manage volumes
Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove unused local volumes
  rm          Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
[root@liuyi home]# docker volume ls     # 查看的都是匿名挂载的卷
DRIVER    VOLUME NAME
local     4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a
local     27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88
[root@liuyi home]# 

2、具名挂载
-v 卷名:容器内路径 (卷名前没有“/”)

注意: 
  -v juming-nginx:/etc/nginx 与 -v /juming-nginx:/etc/nginx 有“/”和没有“/”是不同的,
  juming-nginx是给卷起了一个名字,
  /juming-nginx是具体目录,没有会自动生成。

# 具名挂载
[root@liuyi home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
0aa82586251bdb8a3652286bc07ed0d2e2caf8746e678c5fc5763438fc8524c6
[root@liuyi home]# docker volume ls
DRIVER    VOLUME NAME
local     4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a    # 卷名
local     27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88    # 卷名
local     juming-nginx      # ********* 挂载时取的名字,这就是具名挂载 *********
[root@liuyi home]# 

# 查看卷路径(docker volume inspect 卷名)
[root@liuyi home]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2026-02-28T15:12:54+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",      # ********* 这就是卷的路径 *********
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]
[root@liuyi home]# 

所有的docker容器内的卷,没有指定目录的情况下都是在“/var/lib/docker/volumes/卷名/_data”。(_data数据)

# docker的核心目录 工作目录
[root@liuyi home]# cd /var//lib/docker/
[root@liuyi docker]# ll
total 52
drwx--x--x  4 root root  4096 Feb 24 10:19 buildkit
drwx--x--- 14 root root  4096 Feb 28 15:12 containers    # 容器
-rw-------  1 root root    36 Feb 24 10:19 engine-id
drwx------  3 root root  4096 Feb 24 10:19 image    # 镜像
drwxr-x---  3 root root  4096 Feb 24 10:19 network    # 网络配置
drwx--x--- 67 root root 12288 Feb 28 15:12 overlay2
drwx------  4 root root  4096 Feb 24 10:19 plugins    # 插件
drwx------  2 root root  4096 Feb 24 10:57 runtimes
drwx------  2 root root  4096 Feb 24 10:19 swarm
drwx------  2 root root  4096 Feb 26 09:02 tmp
drwx-----x  5 root root  4096 Feb 28 15:12 volumes    # 卷挂载
[root@liuyi docker]# 

# 卷目录
[root@liuyi docker]# cd volumes/
[root@liuyi volumes]# ll
total 36
drwx-----x 3 root root   4096 Feb 26 09:02 27e406fe83d635c6aafe1b1564e3608d523f81ecd9e105ef6599454d7ca06f88
drwx-----x 3 root root   4096 Feb 28 14:58 4eabcfb7cda6790a3882bb4345398dc01251dd03dab3a4be482fac977fa6272a
brw------- 1 root root 253, 1 Feb 24 10:57 backingFsBlockDev
drwx-----x 3 root root   4096 Feb 28 15:12 juming-nginx
-rw------- 1 root root  32768 Feb 28 15:12 metadata.db
[root@liuyi volumes]# cd juming-nginx/
[root@liuyi juming-nginx]# ls
_data
[root@liuyi juming-nginx]# cd _data/
[root@liuyi _data]# ll
total 28
drwxr-xr-x 2 root root 4096 Feb 28 15:12 conf.d
-rw-r--r-- 1 root root 1007 Dec 28  2021 fastcgi_params
-rw-r--r-- 1 root root 5349 Dec 28  2021 mime.types
lrwxrwxrwx 1 root root   22 Dec 28  2021 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root  648 Dec 28  2021 nginx.conf    # ****** nginx配置文件 ******
-rw-r--r-- 1 root root  636 Dec 28  2021 scgi_params
-rw-r--r-- 1 root root  664 Dec 28  2021 uwsgi_params
[root@liuyi _data]# cat nginx.conf     # 查看

通过具名挂载可以方便的找到挂载的一个卷,大多数情况都是使用‘具名挂载’,不建议使用匿名挂载!

总结:
-v  容器内路径                # 匿名挂载
-v  卷名:容器内路径           # 具名挂载
-v  /宿主机路径:容器内路径     # 指定路径挂载

拓展

# 通过 -v 容器内路径:宿主机路径:ro rw 改变读写权限
ro  # readonly 只读
rw  # readwrite 可读可写

# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# 只要看到 ro ,就说明这个路径的内容只能通过宿主机来操作,容器内部是无法操作的!

方式二:DockerFile 挂载

DockerFile就是用来构建 docker 镜像的构建文件!一个命令脚本!
通过这个脚本就可以生成镜像,镜像是一层一层的,每个命令都是一层!

# 在/home下创建一个docker-test-volume文件夹
[root@liuyi home]# mkdir docker-test-volume
[root@liuyi home]# ls
apps dist  docker-test-volume  liuyi.java  project  usr
[root@liuyi home]# cd docker-test-volume/

# 创建文件dockerfile1并写入命令 名字随机 内容里指令需要大写  (cat dockerfile1的结果就是写入的命令)
[root@liuyi docker-test-volume]# vim dockerfile1
[root@liuyi docker-test-volume]# cat dockerfile1 
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

# 执行构建镜像的命令
# 注意:命令最后有一个“.”,不可遗忘!!!
[root@liuyi docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t liuyi/centos:1.0 .
[+] Building 0.2s (5/5) FINISHED                                                                                                                                                                                                                               docker:default
 => [internal] load build definition from dockerfile1                                                                                                                                                                                                                    0.0s
 => => transferring dockerfile: 120B                                                                                                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                                                                                                                                                                         0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                          0.0s
 => [1/1] FROM docker.io/library/centos:latest                                                                                                                                                                                                                           0.0s
 => exporting to image                                                                                                                                                                                                                                                   0.0s
 => => exporting layers                                                                                                                                                                                                                                                  0.0s
 => => writing image sha256:88a327c6cfeef6087c83f9cbfdf13f022fe72f5c346e9500b5932d19e9d2d522                                                                                                                                                                             0.0s
 => => naming to docker.io/liuyi/centos:1.0                                                                                                                                                                                                                              0.0s

# 查看镜像
[root@liuyi docker-test-volume]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED       SIZE
tomcat02              1.0       9449b0c673c4   3 days ago    684MB
nginx                 latest    605c77e624dd   4 years ago   141MB
tomcat                9.0       b8e65a4d736d   4 years ago   680MB
mysql                 5.7       c20987f18b13   4 years ago   448MB
hello-world           latest    feb5d9fea6a5   4 years ago   13.3kB
centos                latest    5d0da3dc9764   4 years ago   231MB
liuyi/centos          1.0       88a327c6cfee   4 years ago   231MB # ****** 自己构建的镜像 ******
[root@liuyi docker-test-volume]# 

# 启动静茹构建的镜像
[root@liuyi docker-test-volume]# docker run -it 88a327c6cfee /bin/bash
[root@56c29c81e6bb /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  360 Mar  2 06:57 dev
drwxr-xr-x   1 root root 4096 Mar  2 06:57 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 147 root root    0 Mar  2 06:57 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x  11 root root 4096 Sep 15  2021 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Mar  2 06:57 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var
drwxr-xr-x   2 root root 4096 Mar  2 06:57 volume01 # ****** 这个目录就是我们生成镜像的时候自动挂载的,数据卷目录(dockerfile1) ******
drwxr-xr-x   2 root root 4096 Mar  2 06:57 volume02 # ****** 这个目录就是我们生成镜像的时候自动挂载的,数据卷目录(dockerfile1) ******
[root@56c29c81e6bb /]# 

dockerfile1文件中只写了容器内的目录["volume01","volume02"],所以这是一个匿名挂载,这个卷和外部一定有一个同步的目录!

# 进入volume01文件夹 创建 container.txt 文件
[root@56c29c81e6bb /]# cd volume01
[root@56c29c81e6bb volume01]# touch container.txt
[root@56c29c81e6bb volume01]# ls
container.txt
[root@56c29c81e6bb volume01]# 

# 新开窗口(宿主机)
# docker inspect 查看镜像信息 (用CONTAINER ID查看)
[root@liuyi docker-test-volume]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                     NAMES
56c29c81e6bb   88a327c6cfee   "/bin/bash"              20 minutes ago   Up 20 minutes                                             eager_khorana
0aa82586251b   nginx          "/docker-entrypoint.…"   2 days ago       Up 2 days       0.0.0.0:32769->80/tcp, :::32769->80/tcp   nginx02
01fa63a5c003   nginx          "/docker-entrypoint.…"   2 days ago       Up 2 days       0.0.0.0:32768->80/tcp, :::32768->80/tcp   nginx01
[root@liuyi docker-test-volume]# docker inspect 56c29c81e6bb

# 结果很长 找到Mounts部分
"Mounts": [
    {
        "Type": "volume",
        "Name": "12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3",
        "Source": "/var/lib/docker/volumes/12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3/_data", # ****** 容器外目录 ******
        "Destination": "volume01",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    },
    {
        "Type": "volume",
        "Name": "a744b02a4aefc9830813321b8d4b3fdb774b81049f3225e06d2ad38ebb2baba2",
        "Source": "/var/lib/docker/volumes/a744b02a4aefc9830813321b8d4b3fdb774b81049f3225e06d2ad38ebb2baba2/_data", # ****** 容器外目录 ******
        "Destination": "volume02",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],

# 查看在容器内创建的 container.txt 文件 已经同步过来了
[root@liuyi docker-test-volume]# cd /var/lib/docker/volumes/12ae134e781e1d02f2259a6e6a8f9806ff0125924a6370ef7dac6502f1610aa3/_data
[root@liuyi _data]# ls
container.txt
[root@liuyi _data]# 

这种方式会经常使用,因为我们经常会构建自己的镜像!
如果构建镜像时没有挂载卷,就要手动镜像挂载 -v 卷名:容器内路径!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 什么是容器数据卷 从docker的理念说起,docker将应用和环境打包成一个镜像,运行镜像(生成容器)就可以访问...
    甜点cc阅读 307评论 0 1
  • 考虑到容器内的数据会因为删除容器而丢失(es,mysql等)所以容器内不可以存储数据,而是应该将容器中的数据同步到...
    chanyi阅读 321评论 0 0
  • 前言、Docker中的数据管理 Docker镜像是由多个只读层叠加而成,启动容器时,Docker会加载只读层并会在...
    Cehae阅读 449评论 0 1
  • 1.数据卷是什么 先来看看Docker的理念: 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们...
    Minority阅读 370评论 0 2
  • 镜像下载、域名解析、时间同步请点击 阿里云开源镜像站[https://developer.aliyun.com/m...
    萌褚阅读 211评论 0 1

友情链接更多精彩内容