服务部署

生产环境搭建

docker & k8s搭建

具体请看我的下一篇文章

git公有仓库 & 容器公有仓库 & CI、DI

具体请看我的下一篇文章

配置文件编写 & 生成

dockerfile

咱们先用网关局部代码来演示

  • 执行代码
./cmd.sh gen dockerfile gateway
  • 生成文件 code/service/gateway/api/Dockerfile
### 加载根底镜像FROM golang:alpine AS builderLABEL stage=gobuilderENV CGO_ENABLED 0ENV GOOS linux### 设置 go module 代理ENV GOPROXY https://goproxy.cn,directWORKDIR /build/zero### 下载依赖文件ADD go.mod .ADD go.sum .RUN go mod downloadCOPY . .COPY service/gateway/api/etc /app/etc### 编译源代码RUN go build -ldflags="-s -w" -o /app/gateway service/gateway/api/gateway.go### 生成docker镜像FROM alpineRUN apk update --no-cache && apk add --no-cache ca-certificates tzdataENV TZ Asia/ShanghaiWORKDIR /appCOPY --from=builder /app/gateway /app/gatewayCOPY --from=builder /app/etc /app/etcCMD ["./gateway", "-f", "etc/gateway.prod.yaml"]

从生成的Dockerfile能够看到次要有两个局部

  1. 加载golang根底镜像,将代码编译为二进制文件
  2. 加载运行环境根底镜像并生成gateway运行环境的docker镜像

为啥分为两个局部呢,咱们不能间接把编译代码和打包镜像放一起吗,这当然是能够的,然而这样会导致docker镜像包会很大,而把编译和打包离开后能够大大减少docker镜像包的大小,不便咱们疾速散发和部署。

编译代码&镜像打包

➜  go-zero-mall git:(master) ✗ ./cmd.sh docker build gateway-------- docker build gateway  --------time: 2022-05-02 00:19:58 msg: ------------ docker build gateway ------------Untagged: gateway:latestDeleted: sha256:0eedc326b97f06a3c5d19665309369c4c163e430b6c3d17de8ba9a1ebaf37ca8[+] Building 31.9s (19/19) FINISHED                                                   => [internal] load build definition from Dockerfile                            0.0s => => transferring dockerfile: 733B                                            0.0s => [internal] load .dockerignore                                               0.0s => => transferring context: 2B                                                 0.0s => [internal] load metadata for docker.io/library/alpine:latest                3.7s => [internal] load metadata for docker.io/library/golang:alpine                3.4s => [builder 1/8] FROM docker.io/library/golang:alpine@sha256:42d35674864fbb57  0.0s => [internal] load build context                                               1.2s => => transferring context: 35.78MB                                            1.1s => [stage-1 1/5] FROM docker.io/library/alpine@sha256:4edbd2beb5f78b1014028f4  0.0s => CACHED [builder 2/8] WORKDIR /build/zero                                    0.0s => CACHED [builder 3/8] ADD go.mod .                                           0.0s => CACHED [builder 4/8] ADD go.sum .                                           0.0s => CACHED [builder 5/8] RUN go mod download                                    0.0s => [builder 6/8] COPY . .                                                      0.6s => [builder 7/8] COPY service/gateway/api/etc /app/etc                         0.0s => [builder 8/8] RUN go build -ldflags="-s -w" -o /app/gateway service/gatew  26.1s => CACHED [stage-1 2/5] RUN apk update --no-cache && apk add --no-cache ca-ce  0.0s => CACHED [stage-1 3/5] WORKDIR /app                                           0.0s => CACHED [stage-1 4/5] COPY --from=builder /app/gateway /app/gateway          0.0s => CACHED [stage-1 5/5] COPY --from=builder /app/etc /app/etc                  0.0s => exporting to image                                                          0.0s => => exporting layers                                                         0.0s => => writing image sha256:0eedc326b97f06a3c5d19665309369c4c163e430b6c3d17de8  0.0s => => naming to docker.io/library/gateway:latest                               0.0sUse 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

docker images查看docker镜像信息

➜  go-zero-mall git:(master) ✗ docker imagesREPOSITORY                  TAG       IMAGE ID       CREATED         SIZEgateway                     latest    0eedc326b97f   7 days ago      41.6MB

主动部署文件编写deploy.yaml

apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: go-zero-mall-gateway  name: go-zero-mall-gateway  namespace: zero   #肯定要写名称空间spec:  progressDeadlineSeconds: 600  replicas: 3  selector:    matchLabels:      app: go-zero-mall-gateway  strategy:    rollingUpdate:      maxSurge: 50%      maxUnavailable: 50%    type: RollingUpdate  template:    metadata:      labels:        app: go-zero-mall-gateway    spec:      imagePullSecrets:        - name: aliyun-docker-hub  #提前在我的项目下配置拜访阿里云的账号密码      affinity:        podAntiAffinity:          preferredDuringSchedulingIgnoredDuringExecution:            - weight: 100              podAffinityTerm:                labelSelector:                  matchLabels:                    app: go-zero-mall-gateway                topologyKey: kubernetes.io/hostname      containers:        - image: $REGISTRY/$ALIYUNHUB_NAMESPACE/gateway:latest          imagePullPolicy: Always          name: app          ports:            - containerPort: 8000              protocol: TCP          resources:            limits:              cpu: 200m              memory: 60Mi          terminationMessagePath: /dev/termination-log          terminationMessagePolicy: File      dnsPolicy: ClusterFirst      restartPolicy: Always      terminationGracePeriodSeconds: 30---apiVersion: v1kind: Servicemetadata:  labels:    app: go-zero-mall-gateway  name: go-zero-mall-gateway  namespace: zerospec:  ports:    - name: http      port: 8000      protocol: TCP      targetPort: 8000  selector:    app: go-zero-mall-gateway  sessionAffinity: None  type: ClusterIP

通过主动部署文件咱们能够指定一些要害指标

  • 服务名称
  • pod数量
  • 主动扩容阀值
  • 服务权重
  • 容器端口
  • cpu&memory最大使用量

通过这些指标咱们的服务根本能够稳固运行啦

Jenkins文件编写Jenkinsfile

pipeline {  agent {    node {      label 'go'    }  }  stages {    stage('clone code') {      agent none      steps {        git(url: 'https://gitee.com/go-open-project/go-zero-mall.git', changelog: true, poll: false)        sh 'ls -al'      }    }    stage('deploy user') {      // agent none      steps {        container ('go') {          withCredentials([            kubeconfigFile(              credentialsId: env.KUBECONFIG_CREDENTIAL_ID,              variable: 'KUBECONFIG'            )])             {              sh 'envsubst < code/service/user/rpc/deploy.yaml | kubectl apply -f -'            }        }      }    }    stage('deploy product') {      // agent none      steps {        container ('go') {          withCredentials([            kubeconfigFile(              credentialsId: env.KUBECONFIG_CREDENTIAL_ID,              variable: 'KUBECONFIG'            )])             {              sh 'envsubst < code/service/product/rpc/deploy.yaml | kubectl apply -f -'            }        }      }    }    stage('deploy order') {      // agent none      steps {        container ('go') {          withCredentials([            kubeconfigFile(              credentialsId: env.KUBECONFIG_CREDENTIAL_ID,              variable: 'KUBECONFIG'            )])             {              sh 'envsubst < code/service/order/rpc/deploy.yaml | kubectl apply -f -'            }        }      }    }    stage('deploy gateway') {      // agent none      steps {        container ('go') {          withCredentials([            kubeconfigFile(              credentialsId: env.KUBECONFIG_CREDENTIAL_ID,              variable: 'KUBECONFIG'            )])             {              sh 'envsubst < code/service/gateway/api/deploy.yaml | kubectl apply -f -'            }        }      }    }  }  environment {    DOCKER_CREDENTIAL_ID = 'dockerhub-id'    GITHUB_CREDENTIAL_ID = 'github-id'    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'    REGISTRY = 'registry.cn-shanghai.aliyuncs.com'    DOCKERHUB_NAMESPACE = 'ttsimple'    ALIYUNHUB_NAMESPACE = 'ttsimple'    GITHUB_ACCOUNT = 'kubesphere'    APP_NAME = 'go-zero-mall-gateway'  }  parameters {    string(name: 'TAG_NAME', defaultValue: '', description: '')  }}

咱们在 DevOps 中设置好环境变量、仓库地址、webhook 后便可在咱们推送代码后主动部署咱们的我的项目

阐明:咱们的容器是在开发环境打包的,咱们当然也能够通过 Jenkins 来主动打包镜像

  • 主动部署状态

  • 服务运行状态

  • 调用线上用户登录接口

总结

  • 通过 go-zero 能够不便生成dockerfile
  • deploy.yaml 中指定服务部署指标
  • Jenkinsfile 中指定服务从哪里来,别离须要部署哪些服务,等等。
  • 公有部署

    • 镜像服务能够应用Harbor搭建,
    • 镜像制品能够应用云服务或Jenkins来打包生成,
    • 公有仓库能够应用云服务,gitee,开源仓库服务来搭建