Janrs.com | 杨建勇
Janrs.com | 杨建勇

CICD部署08 - jenkins + gitlab + harbor + k8s

[!TIP]
Gitlab flow 常用开发流程实践

转载请注明出处:https://janrs.com


Gitlab Flow

[!NOTE]
80% 的项目可以用下面的流程规则开发以及交付。

官网介绍文档:(https://docs.gitlab.cn/jh/topics/gitlab_flow.html)

1.分支设置

项目分三个分支:develop 开发分支,test 测试分支,master 分支。测试分支跟发布分支要打 tag
后打包镜像发布,镜像版本跟 tag 版本一致。

代码合并过程:deveplop -> test -> master -> cicdtag 发布镜像和 yaml 进行 release 部署

master 分支只保存最终交付的生产代码。

2.开发流程

2-1.deveplop 阶段

程序员直接 pull develop 分支的代码在本地开发,开发后需要自己测试。自己测试没问题后提交到远程 develop 分支。

develop 分支的提交触发 gitlab 调用 webhook 执行 jenkinspipeline SCM 执行流水线操作。

该阶段的镜像版本可以设置一个 dev 前缀方便后期清理。

2-2.test 阶段

develop 合并代码到 test 分支。合并后调用 jenkinswebhook 触发 pipeline SCM 部署到 k8stest
环境,让测试人员进行测试。

2-3.release 阶段

发布阶段在 mastertag ,然后可以采用修改 release-jenkinsfile 文件,然后提交的时候 commit 写上 release-{日期}
。然后在 jenkins 设置有 commit 携带 release 即可触发 release-pipeline 进行部署。

3.实践

3-1.创建项目

创建项目,设置三个分支:main 主分支,test 测试分支,dev 开发分支。

分支顺序 dev -> test -> main

并且设置 main 分支以及 test 为保护分支,设置为不能 push

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-01.png

3-2.拉取项目

开发人员拉取 dev 开发分支进行功能开发。视情况看需不需要在 dev 分支上再 checkoutfeature 特性分支进行开发。

项目上设置 devops 文件夹用于 CICD

分别设置了:开发的 cicd ,测试的 cicd ,正式发布的 cicd 以及最后的回滚 cicd

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-02.png

3-3.新建 Jenkins 任务

任务中的每一条 pipeline 对应 项目中 devops 文件夹下的 jenkinsfile

  • devjenkinsfile 的触发条件设置为开发人员 push 之后就能触发。并且设置镜像标签格式为带 dev-
    前缀,例如: dev-{random_string} ,方便后面删除镜像。

  • testjenkinsfile 的触发条件为 merger request 。并且在 gitlab 以及镜像上打 tag

  • releasejenkinsfile 的触发条件也是设置为 merge request 。并且在 gitlab 以及镜像上打 tag

  • rollbackjenkinsfile 的触发条件也是设置为 merge request

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-03.png

3-4.配置 Jenkins 任务

参考 创建CD 步骤。地址:(https://janrs.com/#/md/micro-service/cicd/pratice_flow_cd)

[!NOTE]
创建 Jenkins 任务大致需要设置以下两个部分:

  • gitlab 设置好 jenkins 的任务回调地址,指定好分支以及触发条件。
  • jenkins 配置任务里面的流水线。设置 git 地址以及分支地址以及 jenkinsfile 文件的位置。

3-4-1.dev-pipeline 配置

gitlab 配置截图

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-04.png

jenkins 配置截图

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-05.png

流水线选择 SCM 并选择 Git 地址。注意指定的分支是 dev 分支

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-06.png

脚本路径注意最前面不要斜杠 /

https://cdn.janrs.com/wp-content/uploads/2023/02/gitflow-07.png
3-4-1-1.dev-pipeline – Dockerfile 代码示例

FROM golang:alpine AS builder

LABEL stage=gobuilder

ENV CGO_ENABLED 0
ENV GOPROXY https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

RUN apk update --no-cache && apk add --no-cache tzdata

WORKDIR /build

ADD go.mod .
ADD go.sum .
RUN go mod download
COPY ../.. .
COPY service/permission/api/etc /app/etc
RUN go build -ldflags="-s -w" -o /app/admin service/permission/api/permission.go

FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai

WORKDIR /app
COPY --from=builder /app/admin /app/admin
COPY --from=builder /app/etc /app/etc

CMD ["./admin", "-f", "etc/permission-api.yaml"]
3-4-1-2.dev-pipeline – Jenkinsfile 代码示例
pipeline{

    agent   any

    //选项
    options {
        //设置终端显示颜色
        ansiColor('gnome-terminal')
    }

    //全局变量
    environment {
        //设置镜像版本
        IMAGE_VERSION = "v1"
    }

    stages{
        //拉取项目代码
        stage('Pull Code'){
            steps{

                echo '>>>>>>>>>>>>>>>>>>START PULL CODE<<<<<<<<<<<<<<<<<<<<'

                checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[url: 'ssh://git@172.16.222.250:1122/janrs/gz-admin.git']]])

                echo '>>>>>>>>>>>>>>>>>>END PULL CODE <<<<<<<<<<<<<<<<<<<<'

            }
        }
        //构建镜像
        stage('Build Image'){
            steps{

                echo '>>>>>>>>>>>>>>>>>>START BUILD IMAGE<<<<<<<<<<<<<<<<<<<<'

                sh "docker build -t gz-admin:${IMAGE_VERSION} -f $WORKSPACE/service/permission/api/Dockerfile ."

                echo '>>>>>>>>>>>>>>>>>>START BUILD IMAGE<<<<<<<<<<<<<<<<<<<<'
            }
        }
        //推送镜像
        stage('Push Image'){
            steps{

                echo '>>>>>>>>>>>>>>>>>>START PUSH IMAGE<<<<<<<<<<<<<<<<<<<<'

                //账号密码脱敏
                withCredentials([usernamePassword(credentialsId: 'harbor_secret', passwordVariable: 'password', usernameVariable: 'username')]) {
                    sh "echo $password | docker login https://172.16.222.250:8443 -u $username --password-stdin"
                }

                sh "docker tag gz-admin:${IMAGE_VERSION} 172.16.222.250:8443/gz-admin/gz-admin:${IMAGE_VERSION}"
                sh "docker push 172.16.222.250:8443/gz-admin/gz-admin:${IMAGE_VERSION}"

                echo '>>>>>>>>>>>>>>>>>>END PUSH IMAGE<<<<<<<<<<<<<<<<<<<<'
            }
        }
        //删除镜像
        stage('Delete Image'){
            steps{

                echo '>>>>>>>>>>>>>>>>>>START DELETE IMAGE<<<<<<<<<<<<<<<<<<<<'

                //删除本地镜像
                sh "docker rmi gz-admin:${IMAGE_VERSION}"
                sh "docker rmi 172.16.222.250:8443/gz-admin/gz-admin:${IMAGE_VERSION}"

                //删除缓存的中间镜像。如果是第一次部署项目,可先将该命令注释。
                //后面再打开该参数。不删除的话,会一直增加中间镜像,占用磁盘空间。
                sh "docker image prune -f --filter \"until=10m\""

                echo '>>>>>>>>>>>>>>>>>>END DELETE IMAGE<<<<<<<<<<<<<<<<<<<<'

            }
        }
        //部署到 kubernetes
        stage('Deploy to k8s'){

            steps{

                echo '>>>>>>>>>>>>>>>>>>START DEPLOY<<<<<<<<<<<<<<<<<<<<'

                sh "kubectl apply -f $WORKSPACE/service/permission/api/gz-admin.yaml"

                echo '>>>>>>>>>>>>>>>>>>END DEPLOY<<<<<<<<<<<<<<<<<<<<'

            }
        }
    }
}
3-4-1-3.dev-pipeline – dev.yaml 代码示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: janrs-permission-api
  namespace: dev
  labels:
    app: janrs-permission-api
spec:
  selector:
    matchLabels:
      app: janrs-permission-api
  template:
    metadata:
      labels:
        app: janrs-permission-api
    spec:
      nodeSelector:
        dev-node: 'true'
      tolerations:
        - key: "node"
          value: "dev"
          operator: "Equal"
          effect: "NoSchedule"
      containers:
        - name: janrs-permission-api
          image: 172.16.222.250:8443/janrs-io/permission-api:v1
          ports:
            - containerPort: 11123
          readinessProbe:
            tcpSocket:
              port: 11123
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 11123
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
            limits:
              cpu: 1000m
              memory: 1024Mi
          volumeMounts:
            - name: timezone
              mountPath: /etc/localtime
      volumes:
        - name: timezone
          hostPath:
            path: /usr/share/zoneinfo/Asia/Shanghai

---

apiVersion: v1
kind: Service
metadata:
  name: janrs-permission-api
  namespace: dev
spec:
  ports:
    - port: 11123
  selector:
    app: janrs-permission-api

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: janrs-permission-api
  namespace: dev
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: janrs-permission-api.k8s.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: janrs-permission-api
                port:
                  number: 11123

上面的配置设置好以后,开发人员代码 push 到远程的 dev 分支后,将会触发 gitlab 设置的 webhook 。然后回调到 jenkins
就会读取 dev 分支下的文件:service/permission/devops/dev/jenkinsfile 执行 pipeline

3-4-2.test-pipeline 配置

如法炮制,跟 dev-pipeline 差不多。

3-4-3.release-pipeline 配置

如法炮制,跟 dev-pipeline 差不多。

3-4-4.rollback-pipeline 配置

如法炮制,跟 dev-pipeline 差不多。


至此。完整的 gitlab 实践完成。

如果你有任何问题,欢迎在底部留言。或者点击加入微信技术交流群 | 我的GitHub

码仔

文章作者

Janrs.com

发表回复

textsms
account_circle
email

Janrs.com | 杨建勇

CICD部署08 - jenkins + gitlab + harbor + k8s
[!TIP] Gitlab flow 常用开发流程实践 转载请注明出处:https://janrs.com Gitlab Flow [!NOTE] 80% 的项目可以用下面的流程规则开发以及交付。 官网介绍文档:(https://docs.gitlab.…
扫描二维码继续阅读
2022-12-19