【问题标题】:Enable logging in docker mysql container在 docker mysql 容器中启用日志记录
【发布时间】:2017-02-04 02:44:54
【问题描述】:

我正在尝试熟悉 docker 生态系统并尝试设置一个 mysql 数据库容器。 docker-compose 看起来像这样:

version: '2'
services:
  db:
    image: mysql:5.6.33@sha256:31ad2efd094a1336ef1f8efaf40b88a5019778e7d9b8a8579a4f95a6be88eaba
    volumes:
      - "./db/data:/var/lib/mysql"
      - "./db/log:/var/log/mysql"
      - "./db/conf:/etc/mysql/conf.d"
    restart: "yes"
    environment:
      MYSQL_ROOT_PASSWORD: rootpw
      MYSQL_DATABASE: db
      MYSQL_USER: db
      MYSQL_PASSWORD: dbpw

我的 conf 目录包含一个文件:

[mysqld]
log_error       =/var/log/mysql/mysql_error.log
general_log_file=/var/log/mysql/mysql.log
general_log     =1
slow_query_log  =1
slow_query_log_file=/var/log/mysql/mysql_slow.log
long_query_time =2
log_queries_not_using_indexes = 1

不幸的是,我没有以这种方式获得任何日志文件。设置本身是正确的,并且使用了 cnf 文件。连接到容器并创建 3 个文件后,将 chown 它们到 mysql 并重新启动容器,日志记录按预期工作。

我很确定这是一种常见的情况,而我目前运行它的方法似乎非常愚蠢。 正确的做法是什么?

我可以通过将所有这些东西移动到 Dockerfile 中来改进我的方法,但这对我来说仍然很奇怪。

【问题讨论】:

    标签: mysql logging docker


    【解决方案1】:

    连接到容器并创建 3 个文件后,将它们 chown 到 mysql 并重新启动容器,日志记录按预期工作。

    这表明存在主机卷权限问题。当您从容器映射到主机时,不会对用户 ID 进行映射,并且附加到容器内部 uid 的名称可能与外部非常不同。您需要使用容器用户可以写入的内容来初始化目录权限。一种简单的方法是创建一个组,该组有权写入主机和容器上的文件,然后在您的映像和主机操作系统上将各种用户添加到该组。另一种选择是使用您不能直接从主机访问的命名文件系统,并使用映像的目录权限对其进行初始化。


    编辑:使用 docker-compose.yml 命名卷的示例很简单:

    version: '2'
    volumes:
      mysql-data:
        driver: local
      mysql-log:
        driver: local
      mysql-conf:
        driver: local
    
    services:
      db:
        image: mysql:5.6.33
        volumes:
          - "mysql-data:/var/lib/mysql"
          - "mysql-log:/var/log/mysql"
          - "mysql-conf:/etc/mysql/conf.d"
        restart: unless-stopped
        environment:
          MYSQL_ROOT_PASSWORD: rootpw
          MYSQL_DATABASE: db
          MYSQL_USER: db
          MYSQL_PASSWORD: dbpw
    

    请注意,我还从您的图像名称中删除了 sha256,此引用会阻止您提取图像的修补版本。我也更喜欢“除非停止”的重启策略,这样 Docker 在重启时会做预期的事情。

    【讨论】:

    • 名称卷的文档似乎部分过时且不完整。这些数据存储在哪里?对不对,我仍然需要知道 mysql 容器的 uid 和 gid 才能使用此权限启动卷?
    • 命名卷存储在内部 Docker 文件夹中(通常是 /var/lib/docker)。如果您尝试在那里访问它们,则会产生与主机卷相同的问题。相反,您应该只通过 Docker 容器访问它们。您可以在多个容器中挂载同一个卷,这样您就可以拥有一个容器来执行更新和备份等操作。
    • 我将继续使用我的 sha,以确保我测试和部署相同的版本,但 unless-stopped 是一个很好的提示。
    • 对于 test/stage/prod 之间的版本控制,我建议使用私有注册服务器并标记您的特定图像。您可以拥有具有多个标签的相同图像,使 v5 之类的东西标记为测试,然后标记为登台非常易于管理。您可以从 Docker Hub 中提取、重新标记,甚至使用自己添加的内容进行构建,然后推送到您的私有注册表。所有 test/stage/prod 服务器只会从该私有注册表中提取。
    • 我想我的 conf 目录的最佳实践是基于 mysql 的新镜像,否则我将不得不以某种方式预填充卷?
    【解决方案2】:

    我一直在寻找完全相同的东西,现在,有更好的方法来做到这一点。

    docker mysql 写道:

    许多配置选项可以作为标志传递给 mysqld。这会 让您可以灵活地自定义容器,而无需 cnf 文件。例如,如果您想更改默认编码和 所有表的排序规则都使用 UTF-8 (utf8mb4) 只需运行 以下:

    $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    

    docker-compose 世界中,可以通过服务的"command" 部分传递这些参数:

    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    

    在我的用例中,我只想打开日志并指定日志文件的路径:

     command: mysqld --general-log=1 --general-log-file=/var/log/mysql/general-log.log
    

    有了足够的数量(例如- ./logs/mysql.log:/var/log/mysql/general-log.log),就很容易接触到它们。

    这很简单,避免处理本地配置。它可以与任何MySQL Docker images 一起使用,并且将保留图像所提供的my.cnf

    【讨论】:

    • 你还应该注意mysql.log的权限。解决它的一种方法是chmod 777
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2021-12-29
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 2021-08-18
    相关资源
    最近更新 更多