Makefile 与 docker 进行多服务 一次性构建
不使用gitlab ci/cd, 在本机快速通过 makefile+docker-compose 编排多个服务

文章博客地址:https://blog.taoluyuan.com/posts/docker-makefile/

本机多服务一次性构建背景

  1. 本机开发多个服务,想要调试之间的调用,需要在本机启动多个
  2. 或者使用 gitlab ci/cd, push 后 构建服务
  3. 本文内容是 不使用 gitlab ci/cd, 而是直接 通过 makefile+docker-compose 编排 在本地一次部署多个服务
  4. 可执行源码:docker-makefile

正常cicd流程

本机 makefile +docker 部署流程

  1. 开发者写好功能,本地 go build 为二进制包
  2. dockerfile 基于 alpha 镜像,运行二进制包
  3. docker-compose 编排执行 dockerfile 运行多个服

golang 服务说明

├── api1_http
│   ├── main.go
├── api2_http
│   ├── main.go
├── api3_http
│   ├── main.go
├── grpc
│   ├── main.go
├── Makefile
|── docker-compose.yaml

四个golang服务,3个http api,1个grpc

编写makefile

SERVICES = api1_http api2_http api3_http grpc
DOCKERFILE_CONTENT = FROM alpine:latest\nWORKDIR /app
# 定义 alpine:3.12 镜像为基础镜像
IMAGE = alpine:3.12
.PHONY: build dockerfiles deploy

build:
	@rm -rf ./bin
	@echo "Building $$@"
	@for service in $(SERVICES) ; do \
		CGO_ENABLED=0 GOOS=linux go build -o ./bin/$$service ./$$service ; \
	done

dockerfiles:
	@for service in $(SERVICES) ; do \
		mkdir -p ./dockerfiles/$$service ; \
		echo "FROM $(IMAGE)" > ./dockerfiles/$$service/Dockerfile ; \
		echo "WORKDIR /app" >> ./dockerfiles/$$service/Dockerfile ; \
		echo "COPY ./bin/$$service ./" >> ./dockerfiles/$$service/Dockerfile ; \
		echo "CMD [\"./$$service\"]" >> ./dockerfiles/$$service/Dockerfile ; \
	done

deploy: build dockerfiles
	@docker-compose up --build

makefile 文件内容包含了三个部分

  1. build: 批量编译golang服务,生成二进制文件,放在根目录/bin下
  2. dockerfiles: 批量生成dockerfile文件,基于alpine:3.12镜像,运行二进制文件
  3. 为什么要基于alpine镜像运行二进制文件,单纯因为 alpine镜像体积小

生成的dockerfile文件内容类似如下

FROM alpine:3.12
WORKDIR /app
COPY ./bin/api1_http ./
CMD ["./api1_http"]

编写docker-compose.yaml

version: '3.8'
services:
  api1_http:
    build: 
      context: .
      dockerfile: ./dockerfiles/api1_http/Dockerfile
    ports:
      - 8081:8081
    env_file:
      - .env
  api2_http:
    build:
      context: .
      dockerfile: ./dockerfiles/api2_http/Dockerfile
    ports:
      - 8082:8081
    env_file:
      - .env

  api3_http:
    build:
      context: .
      dockerfile: ./dockerfiles/api3_http/Dockerfile
    ports:
      - 8083:8081
    env_file:
      - .env
  grpc:
    build:
      context: .
      dockerfile: ./dockerfiles/grpc/Dockerfile
    ports:
      - 8084:8082
    env_file:
      - .env
  jaeger:
    image: jaegertracing/all-in-one:1.6
    ports:
      - 16686:16686
      - 14268:14268
      - 16685:16685

docker-compose.yaml 包含了golang 服务 和 jaeger 服务

  1. golang服务 的context:. 代表 docker-compose.yaml 目录,也就是根目录, 所以dockerfile 文件里的COPY ./bin/api1_http ./ 会将根目录下的bin/api1_http 复制到镜像的/app目录下
  2. .env文件,里面包含了环境变量,主要是在golang业务代码里使用,不做过多介绍
  3. golang 业务里 会进行服务之间调用,集成了 jaeger 服务,所以需要将 jaeger 服务也编排进来

启动所有服务

在源码 https://github.com/webws/go-moda/tree/main/example/tracing/moda_tracing moda_tracing 目录下,执行以下命令即可

make deploy

查看 jaeger

我的 golang 服务 业务代码会互相调用,启动后 调用一个接口,就会在 jaeger 生成完整链路追踪

curl http://localhost:8081/api1

打开 jaeger 地址 http://localhost:16686


最后修改于 2023-05-16