将MySQL数据存储在图像文件中(格式为ext4)

时间:2018-10-08 08:21:57

标签: docker mariadb

我正在尝试使用Docker容器化一个MySQL(实际上是MariaDB)数据库。我想出了如何将MySQL数据(/ var / lib / mysql)存储在从主机目录挂载的卷中。

但是,由于基础文件系统因主机而异,因此存在一些不一致之处,例如表名称在NTFS(Windows)上不区分大小写。同样,如果数据库是在Linux主机上创建的,则它似乎无法在Windows主机上运行(还没有弄清楚为什么会这样)。

因此,我想将数据存储在磁盘映像上并将其安装在容器内,即db-data.img格式为ext4。但是在将此图像装入容器中时,我面临一个奇怪的问题:

$ docker run -v $PWD:/outside --rm -it ubuntu /bin/bash
# dd if=/dev/zero of=/test.img bs=1M count=100
# mkfs.ext4 test.img
# mount -o loop -t ext4 test.img /mnt
mount: /mnt: mount failed: Operation not permitted.

使用另一个目录代替/mnt也不起作用。

为什么拒绝挂载img文件?

4 个答案:

答案 0 :(得分:0)

我建议使用docker-compose并仅使用docker-compose.yml配置中声明的卷。

类似这样的东西:

version: '3'

services:
    mysql:
        image: mysql
        environment:
            MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
            MYSQL_USER: $MYSQL_USER
            MYSQL_PASS: $MYSQL_PASSWORD
        volumes:
            - mysql-data:/var/lib/mysql
volumes:
    mysql-data:

mysql-data卷应作为独立的卷存储,与主机操作系统无关。与仅在主机上安装目录的区别在于,它基本上是在安装卷容器(您也可以在没有 docker-compose 的情况下执行此操作,但这需要更多工作)。

答案 1 :(得分:0)

它在docker映像内部不起作用,Docker阻止访问安装文件系统(和循环设备)。应该更容易些,更早地创建这些映像,通过-v作为文件夹安装并连接到docker。

P.S。另一种选择是将数据库转储到sql并从Windows恢复。

答案 2 :(得分:0)

我设法通过使用docker-compose.yml中的privileged选项解决了这个问题:

privileged: true

(或docker命令中的--privileged

这是我最后的docker-compose.yml:

version: '3'
services:
  db:
    build: ./db
    image: my_db
    container_name: db
    privileged: true
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
    volumes:
      - ${MYSQL_DATA_IMG}:/data.img
    restart: always

Dockerfile:

FROM mariadb

COPY my-custom.cnf /etc/mysql/conf.d/custom.cnf

COPY run.sh /usr/local/bin/run-mariadb.sh
ENTRYPOINT ["run-mariadb.sh"]

和执行mount的自定义入口点脚本(run.sh):

#!/bin/sh

# For this mount comamnd to work the DB container must be started
# with --privileged.
mount -o loop /data.img /var/lib/mysql

# Call the entry point script of MariaDB image.
exec /usr/local/bin/docker-entrypoint.sh mysqld

答案 3 :(得分:0)

用于存储数据库数据,使docker-compose.yml看起来像 如果要使用Dockerfile

version: '3.1'

services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html/
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - mysql-data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
volumes:
  mysql-data:

您的docker-compose.yml看起来像 如果要使用映像而不是Dockerfile

version: '3.1'   

services:
  php:
    image: php:7.4-apache
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html/
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - mysql-data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
volumes:

如果要存储或保存mysql的数据,则 必须记住在docker-compose.yml中添加两行

volumes:
  - mysql-data:/var/lib/mysql

volumes:
  mysql-data:

之后使用此命令

docker-compose up -d

现在,您的数据将保持不变,即使使用此命令也不会被删除

docker-compose down

额外:-但如果要删除所有数据,则将使用

docker-compose down -v

另外,您可以通过此命令检查数据列表

docker volume ls

DRIVER              VOLUME NAME
local               35c819179d883cf8a4355ae2ce391844fcaa534cb71dc9a3fd5c6a4ed862b0d4
local               133db2cc48919575fc35457d104cb126b1e7eb3792b8e69249c1cfd20826aac4
local               483d7b8fe09d9e96b483295c6e7e4a9d58443b2321e0862818159ba8cf0e1d39
local               725aa19ad0e864688788576c5f46e1f62dfc8cdf154f243d68fa186da04bc5ec
local               de265ce8fc271fc0ae49850650f9d3bf0492b6f58162698c26fce35694e6231c
local               phphelloworld_mysql-data