본문 바로가기

Infra

[Docker][MySQL] Access denied for user 'root'@'172.17.0.xx'

도커로 mysql 컨테이너를 올려 로컬에서 커넥션을 맺을때, Access Denied 메시지가 뜨는 경우가 있습니다.

 

도커 컨테이너는 기본적으로 완전히 격리된 네트워크를 지닙니다. 하지만 우리는 localhost 의 -p 옵션으로 바인딩한 포트를 통하여 

도커 컨테이너에 접속할 수 있습니다. 

 

도커 컨테이너는 docker0 이라는 도커 설치시 생성되는 네트워크 브릿지를 통하여 외부와 연결이 될 수 있습니다.

각각의 컨테이너는 실행시 172.17.0.xx 대역의 가상 IP를 가진 veth 인터페이스를 호스트에 생성하고 할당받습니다.

생성된 veth 인터페이스는 docker0 브릿지에 연결됩니다.

 

최종적으로 docker0 브릿지는 호스트의 eth0, eth1 등의 이더넷과 연결되며 컨테이너와 통신이 가능하게 됩니다.

 

자 이제 문제를 살펴봅시다.

 

docker 를 통하여 실행한 mysql 에 접속할때, Access denied for user 'root'@'172.17.0.1' 오류

mysql 컨테이너가 3306 -> 3306 포트로 떠있다고 가정할때,

 

호스트에서는 localhost:3306 으로 mysql 로 커넥션 요청을 보냈을것이지만,

컨테이너에는 docker0을 통하여 패킷이 전달되기 때문에, 커넥션 요청이 계정@docker0의 ipAddress 로 전달된것입니다.

즉 계정@localhost 로 생성한 계정에는 Access Denied 라는 응답을 회신하게 됩니다.

 

해결법 

해결법은 매우 간단합니다.

1. 직접 컨테이너로 접속하여 계정@docker0 ipAddress 유저를 생성하는 방법

2. MySQL 컨테이너가 뜰때, 유저를 '%' 권한으로 생성하는 방법

이 있습니다.

 

1 번 방법

docker exec -it test-mysql /bin/bash

mysql -u root -p
# CREATE USER '<name>@<ip>' IDENTIFIED BY '<password>’;
# GRANT ALL PRIVILEGES ON *.* TO  '<name>@<ip>' WITH GRANT OPTION

 

2 번 방법

많은 방법이 있겠지만 저는 volume 을 통하여 init sql 을 전달합니다.

 

/docker/mysql/init/initsql.sql

   CREATE USER IF NOT EXISTS 'test';
   CREATE DATABASE IF NOT EXISTS `test_db`;
   GRANT ALL ON `test_db`.* TO 'test'@'%';

docker-compose.yml

  version: '3'
  
  networks:
    network:
  
  services:
    mysql:
      platform: linux/amd64
      image: mysql:5.7
      command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --explicit_defaults_for_timestamp=1
      container_name: test-mysql
      networks:
        - network
      ports:
        - 11500:3306
      environment:
        - MYSQL_ROOT_PASSWORD=test
        - MYSQL_USER=test
      volumes:
        - ./docker/mysql/init:/docker-entrypoint-initdb.d

 

 

 

 

 

 

 

 

'Infra' 카테고리의 다른 글

EC2 ELK 적용  (0) 2022.03.18