M1 Docker에서 MySQL이 포함된 환경을 시작하기 위한 작업

7320 단어 DockerArmmacOStech

이 기사를 간단히 정리하자면


새로 개발하여 사용하는 환경이 움직이지 않는다.ω・`)


현재 부업이 찔린 현장에서 레일스를 활용한 신제품 개발이 진행 중이다.
Docker를 사용하여 환경을 구성합니다.실제 운용 환경에서는 아마존 RDS를 사용하기 위해 마이SQL 버전도 합쳐 8.0.20으로 구성했다.
지금까지 WSL에서 개발을 추진해 왔지만 제목처럼 모 PC가 발매됐을 거예요.원래 팀에는 나 혼자만 리눅스(WSL)와 다른 사람 맥(Mac)에서 개발했기 때문에 두 가지 환경에서 운동을 하기 위해 정비를 했다.다만, 요즘은 그 차이를 흡수하는 게 귀찮아요.그러고 보니 M1Mac, Developer 빌딩이지만 Docker가 활동을 시작해서 샀어요.
사전에 환경을 설정하고 Docker 명령의 동작을 확인한 후 아무 문제 없이 그냥 쳤다docker-compose build
8.0.20: Pulling from library/mysql
no matching manifest for linux/arm64/v8 in the manifest list entries

Docker 공식 이미지 mysql에arm 버전이 존재하지 않습니다


문제가 발생할 때 참조하는 이미지는 Docker의 공식 이미지를 사용합니다.
services:
  db:
    image: mysql:8.0.20
오류와 같이 이 공식 이미지에arm판이 존재하지 않는다.
https://hub.docker.com/_/mysql?tab=tags&page=1&ordering=last_updated
대신 mysql 공식적으로 준비한 mysql-server 이미지를 사용합니다.여기도arm판이 있어요.
https://hub.docker.com/layers/mysql/mysql-server/8.0.20/images/sha256-1ad56c783589bece03225650c0929b8f34a8b39527902bdced3dc5ea286d5669?context=explore
M1이라면 사용한 인상만 바꾸면 대응할 수 있다는 얘기다.
services:
  db:
    image: mysql/mysql-server:8.0.20

단순히 교체하는 것만으로는 해결할 수 없다


이미지 확인 작업을 바꾸면 DB에 연결할 때 다음 오류가 표시됩니다.
Host '172.19.0.4' is not allowed to connect to this MySQL server
꼭, my.cnf에서bind-adress 지정 누락 확인인 줄 알았는데, 잘 설정했습니다.
[mysqld]
bind-address=0.0.0.0
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4
원래 인상은 이렇게 하면 해결되지만 전환판이라도 일정한 시간과 정력이 필요하다.

회피책


처음엔 my.cnf 설정만으로는 아무것도 할 수 없지만 해결할 수 없음not allowed to connect을 조사한 결과 호스트 이름을 유효한 사용자로 지정하여 MySQL에 추가하는 방법을 채택하기로 결정했습니다.

실행 가능
Create USER root@'172.19.%';
GRANT ALL PRIVILEGES ON *.* TO root@'172.19.%' WITH GRANT OPTION;
.그럼에도 불구하고 환경을 만들 때마다 수공으로 실천하고 싶지 않다.물론 이쪽도 자동으로 집행됐으면 좋겠습니다.그것도 컨테이너 제작할 때 자동 집행됐으면 좋겠어요.
이를 실현하기 위해서는 두 가지 대응이 필요하다.
  • Docker 측 네트워크의 서브넷을 고정

  • 활용 docker-entrypoint-initdb.d
  • Docker 측면 네트워크의 서브넷 고정


    docker-compose를 직접 시작하면 docker network의 서브넷 설정에 따라 환경이 상승합니다.나는 이것이 각 PC에서 엉망진창이 될 것 같다고 생각한다.서브넷 설정은 다음과 같습니다.
    docker network inspect bridge
    
    {
            "Name": "bridge",
    ...
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16"
    
    MySQL에서 호스트 이름을 지정하고 사용자를 추가할 때 이 서브넷 범위 내의 내용을 설정해야 한다.그러나 환경마다 다른 서브넷을 설정할 수 있는 만큼 고정하기를 바란다.
    docker-compose.yml에서 서브넷을 설정할 수 있습니다.이렇게 고정시키면 돼요.
    https://runnable.com/docker/docker-compose-networking#custom-networks networks 추가 키, 아래 설정을 추가하면 된다.docker-compose 고정할 서브넷을 평소 사용하는 네트워크에 입력합니다.
    networks:
      default:
        ipam:
          config:
            - subnet: 172.18.0.0/16
    
    이번에는 172.18의 시작 부분에 변동이 발생하지 않도록 사전에 16bit로 범위를 지정한다.

    docker-entrypoint-initdb.유효 이용 d


    MySQL계의 Docker 이미지에는 컨테이너를 만들 때 임의의 스크립트를 실행할 수 있는 기능이 적혀 있다.이번에 사용한 mysql/mysql-server의 경우
    https://hub.docker.com/r/mysql/mysql-server/dockerfile
    부합
    RUN mkdir /docker-entrypoint-initdb.d
    
    .이 폴더에 실행하려는 파일(sql,sh)을 저장하면 컨테이너를 시작할 때 Docker file의 ENTRYPOINTentrypoint.sh를 호출합니다.여기서 /docker-entrypoint-initdb.d/* 다음 스크립트는 순서대로 실행됩니다.
    COPY docker-entrypoint.sh /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    
    # https://github.com/mysql/mysql-docker/blob/mysql-server/8.0/docker-entrypoint.sh#L149-L156
    for f in /docker-entrypoint-initdb.d/*; do
    	case "$f" in
    		*.sh)  echo "[Entrypoint] running $f"; . "$f" ;;
    		*.sql) echo "[Entrypoint] running $f"; "${mysql[@]}" < "$f" && echo ;;
    		*)     echo "[Entrypoint] ignoring $f" ;;
    	esac
    	echo
    done
    

    궁극적 대응


    # 1_allow-host-ip.sql として保存
    Create USER root@'172.18.%';
    GRANT ALL PRIVILEGES ON *.* TO root@'172.18.%' WITH GRANT OPTION;
    
    service:
      db:
        image: mysql/mysql-server:5.7
        ...
        volumes:
          - ./1_allow-host-ip.sql:/docker-entrypoint-initdb.d/1_allow-host-ip.sql
      ...
    networks:
      default:
        ipam:
          config:
            - subnet: 172.18.0.0/8
    

    좋은 웹페이지 즐겨찾기