個人環境:
centos7.4
go.15.10
Docker version 19.03.13
部落格:帶你十天輕鬆搞定 Go 微服務系列(一) 學習筆記
一、建立目錄 mkdir 與 touch 命令
cd 目錄(你放專案的目錄)
mkdir gonivinck
cd gonivinck
mkdir dtm
cd dtm
touch config.yml
touch Dockerfile
其他目錄同上 返回上級目錄 cd ../
二、編寫 Dockerfile
不熟悉Dockerfile的點選這裡
golang 容器的
Dockerfile` 程式碼如下:
#基於golang:1.17 操作
FROM golang:1.17
#宣告維護者
LABEL maintainer="Ving <ving@nivin.cn>"
#設定環境變數 代理配置
ENV GOPROXY https://goproxy.cn,direct
#安裝必要的軟體包和依賴包
#指定使用者root run就執行後面的命令
USER root
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \
sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \
sed -i 's/security-cdn.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
curl \
zip \
unzip \
git \
vim
#安裝 goctl
USER root
RUN GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli
#安裝 protoc
USER root
RUN curl -L -o /tmp/protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v3.19.1/protoc-3.19.1-linux-x86_64.zip && \
unzip -d /tmp/protoc /tmp/protoc.zip && \
mv /tmp/protoc/bin/protoc $GOPATH/bin
#安裝 protoc-gen-go
USER root
RUN go get -u github.com/golang/protobuf/protoc-gen-go@v1.4.0
#$GOPATH/bin新增到環境變數中
ENV PATH $GOPATH/bin:$PATH
#清理垃圾
USER root
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \
rm /var/log/lastlog /var/log/faillog
#設定工作目錄
WORKDIR /usr/src/code
#宣告埠
EXPOSE 8000
EXPOSE 8001
EXPOSE 8002
EXPOSE 8003
EXPOSE 9000
EXPOSE 9001
EXPOSE 9002
EXPOSE 9003
其他服務容器 Dockerfile
例子:/gonivinck/dtm/Dockerfile 其他的依此類推
FROM yedf/dtm
LABEL maintainer="Ving <ving@nivin.cn>"
三、編寫 .env
配置檔案
為了讓環境執行 可以先直接複製部落格上的 後續再手打下 加深印象
version: '3.5'
# 網路配置
networks:
backend:
driver: ${NETWORKS_DRIVER}
# 服務容器配置
services:
golang: # 自定義容器名稱
build:
context: ./golang # 指定構建使用的 Dockerfile 檔案
environment: # 設定環境變數
- TZ=${TZ}
volumes: # 設定掛載目錄
- ${CODE_PATH_HOST}:/usr/src/code # 引用 .env 配置中 CODE_PATH_HOST 變數,將宿主機上程式碼存放的目錄掛載到容器中 /usr/src/code 目錄
ports: # 設定埠對映
- "8000:8000"
- "8001:8001"
- "8002:8002"
- "8003:8003"
- "9000:9000"
- "9001:9001"
- "9002:9002"
- "9003:9003"
stdin_open: true # 開啟標準輸入,可以接受外部輸入
tty: true
networks:
- backend
restart: always # 指定容器退出後的重啟策略為始終重啟
etcd: # 自定義容器名稱
build:
context: ./etcd # 指定構建使用的 Dockerfile 檔案
environment:
- TZ=${TZ}
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
ports: # 設定埠對映
- "${ETCD_PORT}:2379"
networks:
- backend
restart: always
mysql:
build:
context: ./mysql
environment:
- TZ=${TZ}
- MYSQL_USER=${MYSQL_USERNAME} # 設定 Mysql 使用者名稱稱
- MYSQL_PASSWORD=${MYSQL_PASSWORD} # 設定 Mysql 使用者密碼
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # 設定 Mysql root 使用者密碼
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql # 引用 .env 配置中 DATA_PATH_HOST 變數,將宿主機上存放 Mysql 資料的目錄掛載到容器中 /var/lib/mysql 目錄
ports:
- "${MYSQL_PORT}:3306" # 設定容器3306埠對映指定宿主機埠
networks:
- backend
restart: always
redis:
build:
context: ./redis
environment:
- TZ=${TZ}
volumes:
- ${DATA_PATH_HOST}/redis:/data # 引用 .env 配置中 DATA_PATH_HOST 變數,將宿主機上存放 Redis 資料的目錄掛載到容器中 /data 目錄
ports:
- "${REDIS_PORT}:6379" # 設定容器6379埠對映指定宿主機埠
networks:
- backend
restart: always
mysql-manage:
build:
context: ./mysql-manage
environment:
- TZ=${TZ}
- PMA_ARBITRARY=1
- MYSQL_USER=${MYSQL_MANAGE_USERNAME} # 設定連線的 Mysql 服務使用者名稱稱
- MYSQL_PASSWORD=${MYSQL_MANAGE_PASSWORD} # 設定連線的 Mysql 服務使用者密碼
- MYSQL_ROOT_PASSWORD=${MYSQL_MANAGE_ROOT_PASSWORD} # 設定連線的 Mysql 服務 root 使用者密碼
- PMA_HOST=${MYSQL_MANAGE_CONNECT_HOST} # 設定連線的 Mysql 服務 host,可以是 Mysql 服務容器的名稱,也可以是 Mysql 服務容器的 ip 地址
- PMA_PORT=${MYSQL_MANAGE_CONNECT_PORT} # 設定連線的 Mysql 服務埠號
ports:
- "${MYSQL_MANAGE_PORT}:80" # 設定容器80埠對映指定宿主機埠,用於宿主機訪問視覺化web
depends_on: # 依賴容器
- mysql # 在 Mysql 服務容器啟動後啟動
networks:
- backend
restart: always
redis-manage:
build:
context: ./redis-manage
environment:
- TZ=${TZ}
- ADMIN_USER=${REDIS_MANAGE_USERNAME} # 設定 Redis 視覺化管理的使用者名稱稱
- ADMIN_PASS=${REDIS_MANAGE_PASSWORD} # 設定 Redis 視覺化管理的使用者密碼
- REDIS_1_HOST=${REDIS_MANAGE_CONNECT_HOST} # 設定連線的 Redis 服務 host,可以是 Redis 服務容器的名稱,也可以是 Redis 服務容器的 ip 地址
- REDIS_1_PORT=${REDIS_MANAGE_CONNECT_PORT} # 設定連線的 Redis 服務埠號
ports:
- "${REDIS_MANAGE_PORT}:80" # 設定容器80埠對映指定宿主機埠,用於宿主機訪問視覺化web
depends_on: # 依賴容器
- redis # 在 Redis 服務容器啟動後啟動
networks:
- backend
restart: always
prometheus:
build:
context: ./prometheus
environment:
- TZ=${TZ}
volumes:
- ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml # 將 prometheus 配置檔案掛載到容器裡
ports:
- "${PROMETHEUS_PORT}:9090" # 設定容器9090埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
grafana:
build:
context: ./grafana
environment:
- TZ=${TZ}
ports:
- "${GRAFANA_PORT}:3000" # 設定容器3000埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
jaeger:
build:
context: ./jaeger
environment:
- TZ=${TZ}
ports:
- "${JAEGER_PORT}:16686" # 設定容器16686埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
dtm:
build:
context: ./dtm
environment:
- TZ=${TZ}
entrypoint:
- "/app/dtm/dtm"
- "-c=/app/dtm/configs/config.yaml"
volumes:
- ./dtm/config.yml:/app/dtm/configs/config.yaml # 將 dtm 配置檔案掛載到容器裡
ports:
- "${DTM_HTTP_PORT}:36789"
- "${DTM_GRPC_PORT}:36790"
networks:
- backend
restart: always
四、編寫 docker-compose.yml 配置檔案
不熟悉docker-composer.yml 點選這裡
version: '3.5'
# 網路配置
networks:
backend:
driver: ${NETWORKS_DRIVER}
# 服務容器配置
services:
golang: # 自定義容器名稱
build:
context: ./golang # 指定構建使用的 Dockerfile 檔案
environment: # 設定環境變數
- TZ=${TZ}
volumes: # 設定掛載目錄
- ${CODE_PATH_HOST}:/usr/src/code # 引用 .env 配置中 CODE_PATH_HOST 變數,將宿主機上程式碼存放的目錄掛載到容器中 /usr/src/code 目錄
ports: # 設定埠對映
- "8000:8000"
- "8001:8001"
- "8002:8002"
- "8003:8003"
- "9000:9000"
- "9001:9001"
- "9002:9002"
- "9003:9003"
stdin_open: true # 開啟標準輸入,可以接受外部輸入
tty: true
networks:
- backend
restart: always # 指定容器退出後的重啟策略為始終重啟
etcd: # 自定義容器名稱
build:
context: ./etcd # 指定構建使用的 Dockerfile 檔案
environment:
- TZ=${TZ}
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
ports: # 設定埠對映
- "${ETCD_PORT}:2379"
networks:
- backend
restart: always
mysql:
build:
context: ./mysql
environment:
- TZ=${TZ}
- MYSQL_USER=${MYSQL_USERNAME} # 設定 Mysql 使用者名稱稱
- MYSQL_PASSWORD=${MYSQL_PASSWORD} # 設定 Mysql 使用者密碼
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # 設定 Mysql root 使用者密碼
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql # 引用 .env 配置中 DATA_PATH_HOST 變數,將宿主機上存放 Mysql 資料的目錄掛載到容器中 /var/lib/mysql 目錄
ports:
- "${MYSQL_PORT}:3306" # 設定容器3306埠對映指定宿主機埠
networks:
- backend
restart: always
redis:
build:
context: ./redis
environment:
- TZ=${TZ}
volumes:
- ${DATA_PATH_HOST}/redis:/data # 引用 .env 配置中 DATA_PATH_HOST 變數,將宿主機上存放 Redis 資料的目錄掛載到容器中 /data 目錄
ports:
- "${REDIS_PORT}:6379" # 設定容器6379埠對映指定宿主機埠
networks:
- backend
restart: always
mysql-manage:
build:
context: ./mysql-manage
environment:
- TZ=${TZ}
- PMA_ARBITRARY=1
- MYSQL_USER=${MYSQL_MANAGE_USERNAME} # 設定連線的 Mysql 服務使用者名稱稱
- MYSQL_PASSWORD=${MYSQL_MANAGE_PASSWORD} # 設定連線的 Mysql 服務使用者密碼
- MYSQL_ROOT_PASSWORD=${MYSQL_MANAGE_ROOT_PASSWORD} # 設定連線的 Mysql 服務 root 使用者密碼
- PMA_HOST=${MYSQL_MANAGE_CONNECT_HOST} # 設定連線的 Mysql 服務 host,可以是 Mysql 服務容器的名稱,也可以是 Mysql 服務容器的 ip 地址
- PMA_PORT=${MYSQL_MANAGE_CONNECT_PORT} # 設定連線的 Mysql 服務埠號
ports:
- "${MYSQL_MANAGE_PORT}:80" # 設定容器80埠對映指定宿主機埠,用於宿主機訪問視覺化web
depends_on: # 依賴容器
- mysql # 在 Mysql 服務容器啟動後啟動
networks:
- backend
restart: always
redis-manage:
build:
context: ./redis-manage
environment:
- TZ=${TZ}
- ADMIN_USER=${REDIS_MANAGE_USERNAME} # 設定 Redis 視覺化管理的使用者名稱稱
- ADMIN_PASS=${REDIS_MANAGE_PASSWORD} # 設定 Redis 視覺化管理的使用者密碼
- REDIS_1_HOST=${REDIS_MANAGE_CONNECT_HOST} # 設定連線的 Redis 服務 host,可以是 Redis 服務容器的名稱,也可以是 Redis 服務容器的 ip 地址
- REDIS_1_PORT=${REDIS_MANAGE_CONNECT_PORT} # 設定連線的 Redis 服務埠號
ports:
- "${REDIS_MANAGE_PORT}:80" # 設定容器80埠對映指定宿主機埠,用於宿主機訪問視覺化web
depends_on: # 依賴容器
- redis # 在 Redis 服務容器啟動後啟動
networks:
- backend
restart: always
prometheus:
build:
context: ./prometheus
environment:
- TZ=${TZ}
volumes:
- ./prometheus/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml # 將 prometheus 配置檔案掛載到容器裡
ports:
- "${PROMETHEUS_PORT}:9090" # 設定容器9090埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
grafana:
build:
context: ./grafana
environment:
- TZ=${TZ}
ports:
- "${GRAFANA_PORT}:3000" # 設定容器3000埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
jaeger:
build:
context: ./jaeger
environment:
- TZ=${TZ}
ports:
- "${JAEGER_PORT}:16686" # 設定容器16686埠對映指定宿主機埠,用於宿主機訪問視覺化web
networks:
- backend
restart: always
dtm:
build:
context: ./dtm
environment:
- TZ=${TZ}
entrypoint:
- "/app/dtm/dtm"
- "-c=/app/dtm/configs/config.yaml"
volumes:
- ./dtm/config.yml:/app/dtm/configs/config.yaml # 將 dtm 配置檔案掛載到容器裡
ports:
- "${DTM_HTTP_PORT}:36789"
- "${DTM_GRPC_PORT}:36790"
networks:
- backend
restart: always
五、構建執行
docker-compose up -d
bug 1
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-dfbf6d743c13 -j RETURN: iptab les: No chain/target/match by that name.
(exit status 1))
解決:重啟docker即可 service docker restart
bug 2
debconf: delaying package configuration, since apt-utils is not installed
解決:可以安裝apt-utils,或忽略這個錯誤
bug 3 golang服務報錯
package github.com/tal-tech/go-zero/tools/goctl@cli: cannot use path@version syntax in GOPATH mode
ERROR: Service 'golang' failed to build : The command '/bin/sh -c GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli' returned a non-zero code: 1
解決:我的錯誤是因為 from go 1.17
被我改成 from go 1.15
網上類似情況解決
bug 4 signal: killed 雲伺服器配置(1核2g)較低
go build github.com/zeromicro/ddl-parser/gen: /usr/local/go/pkg/tool/linux_amd64/compile: signal: killed
ERROR: Service 'golang' failed to build : The command '/bin/sh -c GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@cli' returned a non-zero code: 1
解決:
- 土豪:加錢直接升級雲伺服器配置
- 屌絲:配置 swap 分割槽 參考
bug 4 埠被佔用
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint gonivinck_mysql_1 (aac3792c0966c870d1b350c5e61589df38bdd14eb0ba567da463f05c94c3a22d): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use
ERROR: for redis Cannot start service redis: driver failed programming external connectivity on endpoint gonivinck_redis_1 (f09a8ca17958070e81d93b7cfff9e8826b18a3f4261a990c599a8e7366d8abbc): Error starting userland proxy: listen tcp 0.0.0.0:6379: bind: address already in use
ERROR: for golang Cannot start service golang: driver failed programming external connectivity on endpoint gonivinck_golang_1 (8430bb625604162ae64b5d2addadc9fb2b897cc8b6d87e3af5ff6ae6ca7496f2): Error starting userland proxy: listen tcp 0.0.0.0:9001: bind: address already in use
ERROR: Encountered errors while bringing up the project.
解決:netstat -apn | grep 9001
netstat -apn | grep 3306
netstat -apn | grep 6379
找到程式 kill -9 pid 不行強行關掉宿主機佔用埠的服務
成功 我在我的雲伺服器啟動了docker-compose up -d
gonivinck_etcd_1 is up-to-date
Starting gonivinck_golang_1 ...
gonivinck_prometheus_1 is up-to-date
gonivinck_grafana_1 is up-to-date
Starting gonivinck_mysql_1 ...
gonivinck_dtm_1 is up-to-date
gonivinck_jaeger_1 is up-to-date
Starting gonivinck_golang_1 ... done
Starting gonivinck_mysql_1 ... done
Creating gonivinck_mysql-manage_1 ... done
docker ps
本作品採用《CC 協議》,轉載必須註明作者和本文連結