使用Argo workflows构建 CI 流水线

4,089 阅读3分钟

本文将介绍如何使用Argo workflows构建java CI流水线,将过程中躺过的坑都记录下来。

如何配置gitlab事件触发CI流水线,请参考我的另一篇博客基于argo的CI = gitlab+webhook+argoEvents+argoWorkflows

如果你们是想基于argo自研平台级的流水线,你可以直接调用argo的api来做到灵活处理。请参考官方文档github.com/argoproj/ar…

Argo workflows介绍

Argo Workflows 是一个开源的容器原生的工作流引擎,实现为 Kubernetes CRD,可在 Kubernetes 上编排并行作业。

Argo Workflows安装

github.com/argoproj/ar…

下载代码直接用argocd纳管就行。

CI流程

参考:

CI/CD with Argo on Kubernetes

在 Kubernetes 上使用 Argo 实现

使用Argo workflows构建java CI流水线

流水线各容器公用的存储卷,方便中间产物流转

VolumeClaimTemplates is a list of claims that containers are allowed to reference. The Workflow controller will create the claims at the beginning of the workflow and delete the claims upon completion of the workflow

VolumeClaimTemplates是一组容器们都能访问的存储声明,工作流控制器在工作流开始时创建声明并在结束时进行删除。

请查阅官方文档参考 argoproj.github.io/argo-workfl…

我添加了一个我配置的storageclass。

  volumeClaimTemplates:
    - metadata:
        name: work
        annotations:
          volume.beta.kubernetes.io/storage-class: "tmp-nfs-client-storageclass"
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 1Gi

clone代码仓和配置仓

git仓代码clone如何配置用户和密码 在请求串中加入身份信息即可: 格式

  https://[username]:[password]@gitee.com/project.git

直接写密码肯定是不安全的

gitlab可以生成token,如下:

image.png

然后使用如下命令可以进行访问

git clone https://[username]:[token]@xxxxxx.com/MyUser/MyRepo.git

code-repo配置成https://[username]:[token]@xxxxxx.com/MyUser/MyRepo.git

    - name: clone-code
      inputs:
        parameters:
          - name: code-repo
          - name: code-branch
      container:
        volumeMounts:
          - mountPath: /work
            name: work
        image: alpine/git:v2.26.2
        workingDir: /work
        # Do a shallow clone, which is the fastest way to clone, by using the
        # --depth, --branch, and --single-branch options
        args:
          - clone
          # - --depth
          # - "1"
          - --branch
          - "{{inputs.parameters.code-branch}}"
          - --single-branch
          - "{{inputs.parameters.code-repo}}"
          - .

代码仓或者镜像仓是域名可以通过在spec下添加hostAliases来进行域名解析

  hostAliases:
  - ip: "10.114.61.24"
    hostnames:
    - "git.xxxxxx.com"
  - ip: "10.120.43.49"
    hostnames:
    - "xxxxxx.xxxxxx.com"

maven构建

通过maven编译的时候,统一通过settings.xml来配置本地仓库来加速构建过程。settings.xml可以放到代码仓下,但是这样就不通用了,每一个代码仓都需要添加一份。可以通过把settings.xml放到配置仓,加一个clone配置仓库的步骤和clone代码仓一起,然后将其也挂在到build的容器的某个路径就好了。

首先我们定义一个名字叫workflow-build-pv-claim的pvc,然后在spce中声明这个卷maven-repo。

  volumes:
    - name: maven-repo
      persistentVolumeClaim:
        claimName: workflow-build-pv-claim

workflow-build-pv-claim是我配置的一个持久化卷,专门用的存储第三方包。底层存储使用的是nfs。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: workflow-build-pv-claim
  namespace: argo
spec:
  storageClassName: nfs-storageclass
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi

然后将maven-repo这个卷挂载到build容器的某个路径下,如“/maven-repo”。

    - name: build
      inputs:
        parameters:
          - name: code-path
      container:
        image: maven:3-alpine
        volumeMounts:
          - mountPath: /work
            name: work
          - mountPath: /config
            name: config
          - mountPath: /maven-repo
            name: maven-repo
        workingDir: /work/
        command:
          - mvn
        args:
          - --settings=/config/settings.xml
          - -B
          - -DskipTests
          - clean 
          - deploy

settings.xml的localRepository设置为“/maven-repo”

<localRepository>/maven-repo</localRepository>

kaniko打包镜像

Kaniko 是 Google 造的轮子之一,用于在 Kubernetes 上无需特权模式构建 docker image

Kaniko 不依赖Docker daemon守护程序,而是完全在userspace中执行Dockerfile中的每个命令。这使您可以在没有特权模式或没有运行Docker daemon的环境(例如:Kubernetes集群)中构建容器镜像。

我们需要将镜像产物推送到镜像仓库,我的镜像仓库是Harbor.

image.png

可以创建一个机器人账号,然后使用如下命令创建一个secret

kubectl create secret kaniko-secret docker-registry-creds --docker-server="https://xxxxxxxxxxxx.com" --docker-username='robot$xxxxxxxxxxxx' --docker-password='hghghjhoigtfgiohgtyfuyuhugftybhyuftuy'

然后在spec下定义kaniko-secret的卷

  volumes:
    - name: kaniko-secret
      secret:
        secretName: kaniko-secret
        items:
          - key: .dockerconfigjson
            path: config.json

然后就可以在容器中mount到容器的路径/kaniko/.docker下

    - name: image
      inputs:
        parameters:
          - name: path
          - name: image
          - name: dockerfile
          - name: cache-image
      container:
          image: daocloud.io/gcr-mirror/kaniko-project-executor:debug
          volumeMounts:
            - name: kaniko-secret
              mountPath: /kaniko/.docker
            - name: work
              mountPath: /work
          workingDir: /work
          args: ["--dockerfile={{inputs.parameters.dockerfile}}",
                  "--context=/work",
                  "--insecure=false",
                  "--skip-tls-verify=false",
                  "--destination={{inputs.parameters.image}}"]