docker部署mysql出错:mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)

记一次使用docker compose在ubuntu 18.04部署mysql服务出错的Debug过程

原来在centos7正常运行的mysql服务,docker-compose.yaml文件定义如下:

version: "3.7"

services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    env_file:
      - .env
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    restart: always
    ports:
      - "3306:3306"
    privileged: true
    volumes:
      - "mysql_data:/var/lib/mysql"
    networks:
      - backend
    

volumes:
  mysql_data:

networks:
  backend:
    ipam:
      config:
        - subnet: 192.168.10.0/24

将该docker-compose.yaml的mysql服务在ubuntu启动,并查看状态

$ docker-compose up -d
$ docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS                         PORTS                              NAMES
d66bc17228ff        mysql:5.7                    "docker-entrypoint.s…"   26 seconds ago      Restarting (1) 2 seconds ago                                      mysql

发现mysql服务一直在重启,查看docker日志查找原因

$ docker logs mysql
2020-04-28 16:26:20+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started.
2020-04-28 16:26:20+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
	command was: mysqld --verbose --help
	mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2020-04-28 16:26:24+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.30-1debian10 started.
2020-04-28 16:26:24+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
	command was: mysqld --verbose --help
	mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
......

google一下,发现使用dockers安装MySQL这篇博文有提到需要关闭selinux。ubuntu 18.04 默认使用的selinux模块是AppArmor,禁用AppArmor命令如下:

# 停止apparmor服务
sudo /etc/init.d/apparmor stop
# 禁止开机启动
sudo update-rc.d -f apparmor remove
# 查看apparmor服务的状态
$ sudo /etc/init.d/apparmor status
● apparmor.service - AppArmor initialization
   Loaded: loaded (/lib/systemd/system/apparmor.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2020-04-29 00:09:39 CST; 24h ago
     Docs: man:apparmor(7)
           http://wiki.apparmor.net/
 Main PID: 552 (code=exited, status=0/SUCCESS)

但是禁用AppArmor之后重启mysql服务,还是报同样的错误。

几经周折,最后在这个Issues找到答案:原来是以docker的特权模式(privileged: true)运行mysql服务时,AppArmor配置文件不会应用在容器内,而是因为我已在主机中安装了mysql,并且由于在特权模式下,将应用主机中的AppArmor配置文件,以希望查看来自主机而不是来自容器的调用,而这正是导致了错误的发生。

于是在Ubuntu18.04系统下彻底删除MySQL并重启系统之后,以docker的特权模式运行的mysql服务正常启动。不过由于我的mysql服务采用了挂载docker数据卷,而不是挂载宿主机的/etc目录,其实并不需要开启特权模式,所以最好的解决办法其实是以普通权限运行mysql服务,而不需要禁用AppArmor或者卸载本机的mysql。
以普通权限运行mysql服务的docker-compose.yaml文件修改如下:

version: "3.7"

services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    env_file:
      - .env
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    restart: always
    ports:
      - "3306:3306"
    volumes:
      - "mysql_data:/var/lib/mysql"
    networks:
      - backend
    
volumes:
  mysql_data:

networks:
  backend:
    ipam:
      config:
        - subnet: 192.168.10.0/24

参考链接

  • Mysql, Privileged mode, cannot open shared object file #7512
  • mysql example failed: mysqld: Can’t read dir of ‘/etc/mysql/conf.d/’ (Errcode: 13 - Permission denied) #7906
  • Disable and remove AppArmor on Ubuntu based Linux distributions
  • 在Ubuntu18.04系统下彻底删除MySQL的方法

你可能感兴趣的:(mysql,mysql,docker,ubuntu)