• docker入门加实战—docker数据卷


    docker入门加实战—docker数据卷

    容器是隔离环境,容器内程序的文件、配置等都在容器的内部,要读写容器内的文件非常不方便。

    因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器进行解耦

    什么是数据卷

    数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。

    以Nginx为例,我们知道Nginx中有两个关键的目录:

    • html:放置一些静态资源;
    • conf:放置配置文件;

    如果我们要让Nginx代理我们的静态资源,最好是放到html目录;如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件。

    从dockerhub的nginx说明处,我们可以看到nginx静态文件的位置:

    nginx说明

    不过,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:

    图片示例

    在上图中:

    • 创建了两个数据卷:confhtml
    • Nginx容器内部的conf目录和html目录分别与两个数据卷关联
    • 而数据卷conf和html分别指向了宿主机的/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录

    这样,容器内的confhtml目录就与宿主机的confhtml目录关联起来,被称为挂载。此时,操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。

    数据卷命令

    数据卷的相关命令有:

    命令说明文档地址
    docker volume create创建数据卷docker volume create
    docker volume ls查看所有数据卷docs.docker.com
    docker volume rm删除指定数据卷docs.docker.com
    docker volume inspect查看某个数据卷的详情docs.docker.com
    docker volume prune清除数据卷docker volume prune

    注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

    从需求中学习数据卷命令1

    需求如下:

    • 创建Nginx容器,修改nginx容器内的html目录下的index.html文件内容

    • 将静态资源部署到nginx的html目录

    注意:

    1. 在执行docker run命令时,使用 -v 数据卷:容器内目录 可以完成数据卷挂载
    2. 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷
    
    • 1
    • 2

    删掉原有的nginx容器

    docker rm -f nginx
    
    • 1

    删除原有nginx容器

    创建容器并指定数据卷

    # 首先创建容器并指定数据卷,通过 -v 参数来指定数据卷
    docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
    
    • 1
    • 2

    查看数据卷

    docker volume ls
    
    • 1

    查看数据卷

    查看数据卷详情

    docker volume inspect html
    
    • 1

    查看数据卷详情

    可以看到映射到的宿主机的目录为

    映射到的宿主机的目录

    进入这个目录,修改对应的html文件即可。

    从需求中学习数据卷命令2

    需求:

    • 查看mysql容器,判断是否有数据卷挂载

    • 基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载(查阅官方镜像文档)

    1. 挂载/root/mysql/data到容器内的/var/lib/mysql目录
    2. 挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录
    3. 挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录
    
    • 1
    • 2
    • 3

    注意:

    1. 在执行docker run命令时,使用 -v 本地目录 : 容器内目录 可以完成本地目录挂载
    2. 本地目录必须以“/”或 "./" 开头,如果直接以名称开头,会被识别为数据卷而非本地目录
    	-v mysql : /var/lib/mysql 会被识别为一个数据卷叫mysql
    	-v ./mysql : /var/lib/mysql 会被识别为当前目录下的mysql目录
    
    • 1
    • 2
    • 3
    • 4

    查看MySQL容器是否有数据卷

    # 查看MySQL容器详细信息
    docker inspect mysql
    # 关注其中.Config.Volumes部分和.Mounts部分
    
    • 1
    • 2
    • 3

    .Config.Volumes部分:

    截图

    可以发现这个容器声明了一个本地目录,需要挂载数据卷,但是数据卷未定义。这就是匿名卷。

    .Mounts部分:

    截图

    可以发现,其中有几个关键属性:

    • Name:数据卷名称。由于定义容器未设置容器名,这里的就是匿名卷自动生成的名字,一串hash值。
    • Source:宿主机目录
    • Destination : 容器内的目录

    上述配置是将容器内的/var/lib/mysql目录,这时mysql数据存储的目录,与数据卷0d617a75a536b8d4a7ac0705403677721e1467a9859350d908861d340009a001挂载。于是在宿主机中就有了/var/lib/docker/volumes/0d617a75a536b8d4a7ac0705403677721e1467a9859350d908861d340009a001/_data这个目录。这就是匿名数据卷对应的目录,其使用方式与普通数据卷没有差别。

    挂载本地目录或文件

    数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:

    # 挂载本地目录
    -v 本地目录:容器内目录
    # 挂载本地文件
    -v 本地文件:容器内文件
    
    再次说明一下:
    本地目录必须以“/”或 "./" 开头,如果直接以名称开头,会被识别为数据卷而非本地目录
    	-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
    	-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    从文档中可以看到,配置mysql配置文件的目录如下:

    配置文件目录

    配置初始化脚本如下:

    初始化脚本

    只有第一次才会生效

    数据目录如下:

    image-20231012203554571

    操作演示

    删除并重新创建mysql容器,并完成本地目录挂载:

    • 挂载/root/mysql/data到容器内的/var/lib/mysql目录
    • 挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录(初始化的SQL脚本目录)
    • 挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录(这个是MySQL配置文件目录)
    1. 删除原来的MySQL容器

      docker rm -f mysql
      
      • 1

      删除原来的MySQL容器

    2. 进入root目录

      cd ~
      
      • 1
    3. 创建并运行新mysql容器,挂载本地目录

      先提前创建这些目录

      在 root目录操作
      mkdir mysql
      # 进入mysql目录
      cd mysql/
      #创建以下三个目录
      mkdir data
      mkdir conf
      mkdir init
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      把主备好的配置文件和脚本放到过去:

      本地的文件

      直接把目录上传到linux服务器:

      上传到远端

      上传后内容如下:

      conf目录文件

      init目录文件

      在root的家目录执行运行如下命令

      docker run -d \
        --name mysql \
        -p 3306:3306 \
        -e TZ=Asia/Shanghai \
        -e MYSQL_ROOT_PASSWORD=123 \
        -v ./mysql/data:/var/lib/mysql \
        -v ./mysql/conf:/etc/mysql/conf.d \
        -v ./mysql/init:/docker-entrypoint-initdb.d \
        mysql
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      运行命令

      可以看到data目录有文件了

      data目录

  • 相关阅读:
    MIT6.s081/6.828 lectrue4:page tables 以及 Lab3 心得
    linux ansible(三)
    [机缘参悟-29]:鬼谷子-内揵篇-与上司交往的五种层次
    KTL 一个支持C++14编辑公式的K线技术工具平台 - 第九版,数据分析工具。支持通达信日线数据。增强即时插件编程体现。
    第1章 Linux基础知识 -- 了解Linux历史和linux目录结构
    Dev-C++ 实用安装教程
    java:JDBC ResultSet结合Spring的TransactionTemplate事务模板的查询方式
    Java 如何检测Map集合中是否包含指定value呢?
    (c/c++)——STL
    【C#】复杂Json的反序列
  • 原文地址:https://blog.csdn.net/qq_41243472/article/details/133817849