iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 14
0

本日文章內容目標能讓我們了解,Dockerfile 撰寫的格式與啟動的效果,並且使用 docker-compose 啟動多個 containers,並建立兩個 containers 溝通的橋樑。

Dockerfile

Basic Syntax

  • FROM : 建立 image 的 基底image 名稱,可指定版號
  • ENV : 設定 container 環境變數
  • WORKDIR : 決定啟動後所在目錄,若目錄不存在則創建一個
  • RUN : Container 準備階段時指定執行命令,例如 apt-get install -y vim
  • EXPOSE : 對外暴露出可使用的 ports,建立的容器如果沒有特別將 ports 暴露出來的話,是無法使用特定 port 的
  • COPY : 建立 container 時想從本機一併複製過去的檔案或目錄
  • ADD : 除了與 COPY 同樣可以複製本機目錄外,ADD 可以接收來自 URL 的 zip 並解壓縮
  • CMD : Container 啟動階段時指定執行命令,僅能執行一次次

Build

利用 docker build command 將 Dockerfile 實體化成 image。

  • -t : 標記 image tag(名稱)
  • --no-cache : 避免被 cache 住,而造成沒有 build 到修改過的 Dockerfile

從 build 的 steps 可以觀察,其對應到 Dockerfile 的部分

Dockerfile Download

> docker build -t hello . --no-cache

Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM alpine:latest
 ---> 961769676411
Step 2/5 : MAINTAINER weiweiwesley
 ---> Running in 1350ac7c19e7
Removing intermediate container 1350ac7c19e7
 ---> 175f0044181f
Step 3/5 : ENV NAME=weiweiwesley
 ---> Running in 9f25017cc330
Removing intermediate container 9f25017cc330
 ---> 7da2d1f41c19
Step 4/5 : WORKDIR /app
 ---> Running in 98f19e2d7877
Removing intermediate container 98f19e2d7877
 ---> 5e6f0ee5eb49
Step 5/5 : CMD echo hello $NAME
 ---> Running in b314aeac61b7
Removing intermediate container b314aeac61b7
 ---> 78f27a6b37d5
Successfully built 78f27a6b37d5
Successfully tagged hello:latest

Run

利用 docker run command,直接執行我們剛剛 build 好的 image。若沒有指定版號,預設為 :latest

> docker run hello

hello weiweiwesley

Docker-compose

docker-compose

docker-compose

實務上服務跟服務可能是有相依關係的,如果我們希望 mysql-slave 需要在 mysql-master 啟動後才能運行的話,docker-compose 可以幫助我們完成需求。

docker-compose.yml

  • version : docker-compose 本身版本,會影響 yml 寫法
  • services : 每個 service 會啟動一個 container
  • image : 同 Dockerfile 是用來決定基底 image 的設定
  • container_name : 容器名稱
  • ports : 決定容器要 expose 出來的 ports
  • volumes : 掛載本機目錄至容器內部
  • environment : 同 Dockerfile 為環境變數設定
  • depends_on : 等待特定 service 建立後方可建立
  • command : 同 Dockerfile 為容器啟動後命令
  • networks : 用來建立 containers 內部間溝通用網路

範例

請下載完整範例

docker-compose.yml

version: '3.7'

services:
  mysql-master:
    image: 'mysql:8.0.21'
    container_name: mysql-master
    ports:
      - '3307:3306'
    volumes:
      - type: bind
        source: ./config/master.cnf
        target: /etc/mysql/conf.d/master.cnf
    environment:
      - MYSQL_ROOT_PASSWORD=root
    networks:
      - internal_network_sql

  mysql-slave:
    image: 'mysql:8.0.21'
    container_name: mysql-slave
    ports:
      - '3308:3306'
    volumes:
      - type: bind
        source: ./config/slave.cnf
        target: /etc/mysql/conf.d/slave.cnf
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_REPLICATION_MODE=slave
      - MYSQL_REPLICATION_USER=slave_user
      - MYSQL_REPLICATION_PASSWORD=password
    depends_on:
      - mysql-master
    command: [
      "--skip-log-bin",
      "--skip-log-slave-updates",
    ]
    networks:
      - internal_network_sql

  adminer:
    image: adminer
    ports:
      - 8080:8080
    networks:
      - internal_network_sql

networks:
    internal_network_sql:
        driver: bridge

於 mysql-master 建立 mysql-slave 同步用使用者帳號

mysql> CREATE USER 'slave_user'@'%' IDENTIFIED BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%';

設定 slave_user 同步 mysql-master

mysql> CHANGE MASTER TO 
  MASTER_HOST='mysql-master',
  MASTER_PORT=3306,
  MASTER_USER='slave_user',
  MASTER_PASSWORD='password',
  GET_MASTER_PUBLIC_KEY=1,
  MASTER_AUTO_POSITION=1;

啟用 slave

mysql> START SLAVE;

上面的範例我們利用 docker-compose.yml 啟動了,兩個 mysql container & mysql web admin(127.0.0.1:8080),僅需要一份 compose file,便可以確保這組 slave-master 的啟用,如果 replica 想要有多個只需往下增加 services,並且在 mysql.cnf 裏使用不同 server_id 即可。

9/23 更新
針對 docker container 重啟後,relay-log 因 host name 更換導致slave 無法跟上的問題修正,請參考完整修正內容

  • 指定 relay-log 名稱
relay-log=/var/lib/mysql/orders-relay-bin

上一篇
Day13 Docker
下一篇
Day15 Http Server & Gorm
系列文
Go Distributed & Go Consistently30

尚未有邦友留言

立即登入留言