需求:go项目,开发提交代码到仓库,修改配置文件(配置mysql/redis),使用 dockerfile进行编译配置;

一、思路分析

  • mysql/redis:模拟真实环境,大家需要准备好mysql及redis(docker run起来即可);
  • go项目和java类似,需要编译成二进制文件执行;
  • configs目录中配置了所有环境的配置文件;
  • 一套代码模拟全环境;

二、准备mysql和redis

#在master01节点上启动mysql
docker run -d \
  --name=mysql-container \
  -e MYSQL_DATABASE=go_gin_api \
  -e MYSQL_ROOT_PASSWORD=7JzvMVf9Cpdv6hmj \
  -p 3306:3306 \
  registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23

#在master01节点上启动redis
docker run -d \
  --name=redis-container \
  -p 6379:6379 \
  registry.cn-hangzhou.aliyuncs.com/abroad_images/redis:6.2 \
  redis-server --requirepass cc8hhFg4eTvLkbMT

#验证
[root@master01 go-gin-api]# docker ps
CONTAINER ID   IMAGE                                                          COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
4f4293691c31   registry.cn-hangzhou.aliyuncs.com/abroad_images/redis:6.2      "docker-entrypoint.s…"   2 hours ago      Up 2 hours      0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis-container
8fbdb5b44146   registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:5.7.23   "docker-entrypoint.s…"   2 hours ago      Up 2 hours      0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-container

三、修改配置文件

[root@master01 ~]# cd /root/5/go-gin-api/
[root@master01 go-gin-api]# vim configs/fat_configs.toml

[hashids]
  length = 12
  secret = "6ab6122836cfef95f8db"

[language]
  local = "zh-cn"

[mail]
  host = "smtp.163.com"
  pass = ""
  port = 465
  to = ""
  user = ""

#修改为如下信息
[mysql]

  [mysql.base]
    connmaxlifetime = 60
    maxidleconn = 60
    maxopenconn = 10

  [mysql.read]
    addr = "10.0.0.60:3306"
    name = "go_gin_api"
    pass = "7JzvMVf9Cpdv6hmj"
    user = "root"

  [mysql.write]
    addr = "10.0.0.60:3306"
    name = "go_gin_api"
    pass = "7JzvMVf9Cpdv6hmj"
    user = "root"

#修改为如下信息
[redis]
  addr = "10.0.0.60:6379"
  db = "0"
  maxretries = 3
  minidleconns = 5
  pass = "cc8hhFg4eTvLkbMT"
  poolsize = 10

四、打包镜像并上传

[root@master01 go-gin-api]# cat Dockerfile
# FROM 基于 golang:1.16-alpine
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/golang:1.16-alpine AS builder

# ENV 设置环境变量
ENV GOPATH=/opt/repo
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct

# COPY 源路径 目标路径
COPY . $GOPATH/src/github.com/xinliangnote/go-gin-api

# RUN 执行 go build .
RUN cd $GOPATH/src/github.com/xinliangnote/go-gin-api && go build .

# FROM 基于 alpine:latest
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/alpine:3.6

# RUN 设置代理镜像
RUN echo -e http://mirrors.ustc.edu.cn/alpine/v3.13/main/ > /etc/apk/repositories

# RUN 设置 Asia/Shanghai 时区
RUN apk --no-cache add tzdata  && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

# COPY 源路径 目标路径 从镜像中 COPY
COPY --from=builder /opt/repo/src/github.com/xinliangnote/go-gin-api /opt

# EXPOSE 设置端口映射
EXPOSE 9999/tcp

# WORKDIR 设置工作目录
WORKDIR /opt

# CMD 设置启动命令
CMD ["./go-gin-api", "-env", "fat"]

#构建镜像
[root@master01 go-gin-api]# docker build --network=host -t go-web:v1 .

#重新定义标签
[root@master01 python-demoapp]# docker tag go-web:v1 harbor.zhang-qing.com/demo/go-web:v1

#推送镜像
[root@master01 python-demoapp]# docker push harbor.zhang-qing.com/demo/go-web:v1

五、初始化项目

启动临时容器,用于初始化数据

#下载源码
[root@master01 ~]# cd /root/5/go-gin-api
[root@master01 go-gin-api]# git clone https://github.com/xinliangnote/go-gin-api.git

#替换镜像为国内镜像
[root@master01 ~]# cd /root/5/go-gin-api/go-gin-api/
[root@master01 go-gin-api]# cat Dockerfile
# FROM 基于 golang:1.16-alpine
#FROM golang:1.16-alpine AS builder
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/golang:1.16-alpine AS builder

# ENV 设置环境变量
ENV GOPATH=/opt/repo
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct

# COPY 源路径 目标路径
COPY . $GOPATH/src/github.com/xinliangnote/go-gin-api

# RUN 执行 go build .
RUN cd $GOPATH/src/github.com/xinliangnote/go-gin-api && go build .

# FROM 基于 alpine:latest
#FROM alpine:latest
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/alpine:3.6

# RUN 设置代理镜像
RUN echo -e http://mirrors.ustc.edu.cn/alpine/v3.13/main/ > /etc/apk/repositories

# RUN 设置 Asia/Shanghai 时区
RUN apk --no-cache add tzdata  && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

# COPY 源路径 目标路径 从镜像中 COPY
COPY --from=builder /opt/repo/src/github.com/xinliangnote/go-gin-api /opt

# EXPOSE 设置端口映射
EXPOSE 9999/tcp

# WORKDIR 设置工作目录
WORKDIR /opt

# CMD 设置启动命令
CMD ["./go-gin-api", "-env", "fat"]

#重新编译
[root@master01 ~]# cd /root/5/go-gin-api/go-gin-api/
[root@master01 go-gin-api]# docker build -t go-web:v11 .

#启动容器
[root@master01 go-gin-api]# docker run --restart=always -d -p 9999:9999 go-web:v11

#验证
[root@master01 go-gin-api]# docker ps | grep go-web
69699f04f505   go-web:v11                                                     "./go-gin-api -env f…"   16 minutes ago   Up 16 minutes   0.0.0.0:9999->9999/tcp, :::9999->9999/tcp              hungry_thompson

遇到的问题:构建go项目时,执行docker run --restart=always -d -p 9999:9999 go-web:v11命令启动容器进行输出化项目时容器因环境问题导致一直处于restrating状态

#问题现象:
[root@master01 go-gin-api]# docker ps
CONTAINER ID   IMAGE                                                          COMMAND                  CREATED         STATUS                                  PORTS                                                  NAMES
b899357d7233   go-web:v11                                                     "./go-gin-api -env f…"   3 seconds ago   Restarting (1) Less than a second ago

上述问题解决方法:

#下载源码
[root@master01 ~]# cd /root/5/go-gin-api
[root@master01 go-gin-api]# git clone https://github.com/xinliangnote/go-gin-api.git

#替换镜像为国内镜像
[root@master01 ~]# cd /root/5/go-gin-api/go-gin-api/
[root@master01 go-gin-api]# cat Dockerfile
# FROM 基于 golang:1.16-alpine
#FROM golang:1.16-alpine AS builder
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/golang:1.16-alpine AS builder

# ENV 设置环境变量
ENV GOPATH=/opt/repo
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct

# COPY 源路径 目标路径
COPY . $GOPATH/src/github.com/xinliangnote/go-gin-api

# RUN 执行 go build .
RUN cd $GOPATH/src/github.com/xinliangnote/go-gin-api && go build .

# FROM 基于 alpine:latest
#FROM alpine:latest
FROM registry.cn-hangzhou.aliyuncs.com/abroad_images/alpine:3.6

# RUN 设置代理镜像
RUN echo -e http://mirrors.ustc.edu.cn/alpine/v3.13/main/ > /etc/apk/repositories

# RUN 设置 Asia/Shanghai 时区
RUN apk --no-cache add tzdata  && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

# COPY 源路径 目标路径 从镜像中 COPY
COPY --from=builder /opt/repo/src/github.com/xinliangnote/go-gin-api /opt

# EXPOSE 设置端口映射
EXPOSE 9999/tcp

# WORKDIR 设置工作目录
WORKDIR /opt

# CMD 设置启动命令
CMD ["./go-gin-api", "-env", "fat"]

#重新编译
[root@master01 ~]# cd /root/5/go-gin-api/go-gin-api/
[root@master01 go-gin-api]# docker build -t go-web:v11 .

#启动容器
[root@master01 go-gin-api]# docker run --restart=always -d -p 9999:9999 go-web:v11

打开浏览器输入10.0.0.60:9999/install进行数据库初始化

  • 配置Redis
  • 地址:10.0.0.60:6379
  • 密码:cc8hhFg4eTvLkbMT
  • 配置MySQL
  • 地址:10.0.0.60:3306
  • 密码:7JzvMVf9Cpdv6hmj

image-20231224162337913

停掉临时容器,使用k8s部署项目

docker rm -f 69699f04f505

六、创建deployment.yaml资源

[root@master01 go-gin-api]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-web
  template:
    metadata:
      labels:
        app: go-web
    spec:
      containers:
      - name: go-web
        image: harbor.zhang-qing.com/demo/go-web:v1
        resources:
          limits:
            memory: "2Gi"
            cpu: "1"
          requests:
            memory: "1Gi"
            cpu: "500m"
        ports:
          - containerPort: 9999
            name: web
        livenessProbe:
          httpGet:
            port: web
            path: /
          timeoutSeconds: 2       # 表示容器必须在2s内做出相应反馈给probe否则视为探测失败
          periodSeconds: 30       # 探测周期每30s探测一次
        readinessProbe:
          tcpSocket:
            port: web
          initialDelaySeconds: 10 # 容器启动后10s开始探测

#应用
[root@master01 go-gin-api]# kaf deployment.yaml

#验证
[root@master01 go-gin-api]# kgp | grep go-web
go-web-5bb6998bc9-vv5fc       1/1     Running   0             14m

七、创建service.yaml资源

[root@master01 go-gin-api]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
  name: go-web
spec:
  type: ClusterIP
  selector:
    app: go-web
  ports:
  - name: http
    port: 9999
    protocol: TCP
    targetPort: 9999

#应用
[root@master01 go-gin-api]# kaf service.yaml

八、创建ingress.yaml资源

[root@master01 go-gin-api]#  cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    konghq.com/https-redirect-status-code: "301"
    konghq.com/protocols: http
    konghq.com/regex-priority: "1000"
  name: go-web-ing
spec:
  ingressClassName: nginx
  rules:
  - host: go-web.zhang-qing.com
    http:
      paths:
      - backend:
          service:
            name: go-web
            port:
              number: 9999
        path: /
        pathType: ImplementationSpecific

#应用
[root@master01 go-gin-api]# kaf ingress.yaml

重启后,打开浏览器输入go-web.harbor-local.cn登录,账号和密码都是admin

[root@master01 go-gin-api]# k delete po go-web-5bb6998bc9-vv5fc

image-20231224163603421

image-20231224163642284

九、环境复原

# 删除容器
[root@master01 ~]# cd /root/5/go-gin-api
[root@master01 go-gin-api]# docker rm -f $(docker ps -aq)

# 删除资源
[root@master01 ~]# cd /root/5/go-gin-api
[root@master01 go-gin-api]# k delete -f ingress.yaml -f service.yaml -f deployment.yaml