すべてのプロダクト
Search
ドキュメントセンター

:ワークフロークラスターでのGolangプロジェクトのCIパイプラインの作成

最終更新日:Oct 30, 2024

Kubernetes (ACK One) 用分散クラウドコンテナプラットフォームワークフロークラスターは、オープンソースのArgoワークフローに基づいて開発されています。 超高弾力性、自動スケーリング、およびゼロO&Mコストの利点により、ホストされたArgoワークフローは、低コストで継続的統合 (CI) パイプラインを迅速に作成するのに役立ちます。 このトピックでは、ワークフロークラスターでGolangプロジェクトのCIパイプラインを作成する方法について説明します。

概要

ACK OneワークフロークラスターでCIパイプラインを作成するには、BuildKitを使用してコンテナーイメージをビルドおよびプッシュし、BuildKit Cacheを使用してイメージのビルドを高速化します。 Apsara File Storage NAS (NAS) を使用してGo modキャッシュを保存すると、Go TestおよびGo Buildの手順を高速化できます。 これにより、CIパイプラインの作成に必要な時間が大幅に短縮されます。

image

定義済みのClusterWorkflowTemplateの概要

デフォルトでは、ワークフロークラスターci-go-v1という名前の定義済みのClusterWorkflowTemplateを提供します。 テンプレートはBuildKit CacheとNASを使用してGo modキャッシュを格納するため、CIパイプラインの作成が大幅に高速化されます。

定義済みテンプレートを直接使用するか、定義済みテンプレートに基づいてカスタムテンプレートを作成できます。

定義済みのテンプレートは、次の手順で構成されます。

  1. Gitクローン&チェックアウト

    • Gitリポジトリを複製し、Gitリポジトリを宛先ブランチにチェックアウトします。

    • コミットIDを取得します。これは、イメージ構築中にイメージタグにサフィックスとして追加されます。

  2. Goテストの実行

    • デフォルトでは、すべてのテストケース (Goプロジェクト) をGitリポジトリで実行します。

    • パイプラインパラメーターenable_testを設定して、この手順を実行するかどうかを指定できます。

    • Go modキャッシュは、NASファイルシステムの /pkg/modディレクトリに保存され、Go TestGo Buildを高速化します。

  3. 画像をビルド&プッシュ

    • BuildKitを使用してコンテナーイメージをビルドおよびプッシュし、BuildKit Cacheでレジストリタイプのキャッシュを使用してイメージのビルドを高速化します。

    • デフォルトでは、imageタグは {container_tag}-{commit_id} 形式です。 パイプラインを送信するときに、イメージタグにコミットIDを追加するかどうかを指定できます。

    • イメージのプッシュ中に、イメージの最新バージョンがプッシュされ、現在のバージョンが上書きされます。

定義済みテンプレートの内容:

テンプレートコンテンツの表示

apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
  name: ci-go-v1
spec:
  entrypoint: main
  volumes:
  - name: run-test
    emptyDir: {}
  - name: workdir
    persistentVolumeClaim:
      claimName: pvc-nas
  - name: docker-config
    secret:
      secretName: docker-config
  arguments:
    parameters:
    - name: repo_url
      value: ""
    - name: repo_name
      value: ""
    - name: target_branch
      value: "main"
    - name: container_image
      value: ""
    - name: container_tag
      value: "v1.0.0"
    - name: dockerfile
      value: "./Dockerfile"
    - name: enable_suffix_commitid
      value: "true"
    - name: enable_test
      value: "true"
  templates:
    - name: main
      dag:
        tasks:
          - name: git-checkout-pr
            inline:
              container:
                image: alpine:latest
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    
                    apk --update add git
          
                    cd /workdir
                    echo "Start to Clone "{{workflow.parameters.repo_url}}
                    git -C "{{workflow.parameters.repo_name}}" pull || git clone {{workflow.parameters.repo_url}} 
                    cd {{workflow.parameters.repo_name}}
          
                    echo "Start to Checkout target branch" {{workflow.parameters.target_branch}}
                    git checkout --track origin/{{workflow.parameters.target_branch}} || git checkout {{workflow.parameters.target_branch}}
                    git pull
                    
                    echo "Get commit id" 
                    git rev-parse --short origin/{{workflow.parameters.target_branch}} > /workdir/{{workflow.parameters.repo_name}}-commitid.txt
                    commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                    echo "Commit id is got: "$commitId
                                        
                    echo "Git Clone and Checkout Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                resources:
                  requests:
                    memory: 1Gi
                    cpu: 1
                activeDeadlineSeconds: 1200
          - name: run-test
            when: "{{workflow.parameters.enable_test}} == true"
            inline: 
              container:
                image: golang:1.22-alpine
                command:
                  - sh
                  - -c
                  - |
                    set -eu
                    
                    if [ ! -d "/workdir/pkg/mod" ]; then
                      mkdir -p /workdir/pkg/mod
                      echo "GOMODCACHE Directory /pkg/mod is created"
                    fi
                    
                    export GOMODCACHE=/workdir/pkg/mod
                    
                    cp -R /workdir/{{workflow.parameters.repo_name}} /test/{{workflow.parameters.repo_name}} 
                    echo "Start Go Test..."
                    
                    cd /test/{{workflow.parameters.repo_name}}
                    go test -v ./...
                    
                    echo "Go Test Complete."
                volumeMounts:
                - name: "workdir"
                  mountPath: /workdir
                - name: run-test
                  mountPath: /test
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: git-checkout-pr    
          - name: build-push-image
            inline: 
              container:
                image: moby/buildkit:v0.13.0-rootless
                command:
                  - sh
                  - -c
                  - |         
                    set -eu
                     
                    tag={{workflow.parameters.container_tag}}
                    if [ {{workflow.parameters.enable_suffix_commitid}} == "true" ]
                    then
                      commitId=$(cat /workdir/{{workflow.parameters.repo_name}}-commitid.txt)
                      tag={{workflow.parameters.container_tag}}-$commitId
                    fi
                    
                    echo "Image Tag is: "$tag
                    echo "Start to Build And Push Container Image"
                    
                    cd /workdir/{{workflow.parameters.repo_name}}
                    
                    buildctl-daemonless.sh build \
                    --frontend \
                    dockerfile.v0 \
                    --local \
                    context=. \
                    --local \
                    dockerfile=. \
                    --opt filename={{workflow.parameters.dockerfile}} \
                    build-arg:GOPROXY=http://goproxy.cn,direct \
                    --output \
                    type=image,\"name={{workflow.parameters.container_image}}:${tag},{{workflow.parameters.container_image}}:latest\",push=true,registry.insecure=true \
                    --export-cache mode=max,type=registry,ref={{workflow.parameters.container_image}}:buildcache \
                    --import-cache type=registry,ref={{workflow.parameters.container_image}}:buildcache
                    
                    echo "Build And Push Container Image {{workflow.parameters.container_image}}:${tag} and {{workflow.parameters.container_image}}:latest Complete."
                env:
                  - name: BUILDKITD_FLAGS
                    value: --oci-worker-no-process-sandbox
                  - name: DOCKER_CONFIG
                    value: /.docker
                volumeMounts:
                  - name: workdir
                    mountPath: /workdir
                  - name: docker-config
                    mountPath: /.docker
                securityContext:
                  seccompProfile:
                    type: Unconfined
                  runAsUser: 1000
                  runAsGroup: 1000
                resources:
                  requests:
                    memory: 4Gi
                    cpu: 2
              activeDeadlineSeconds: 1200
            depends: run-test

次の表に、テンプレートのパラメーターを示します。

パラメーター

説明

エントリーポイント

エントリテンプレートを指定します。

メイン

repo_url

GitリポジトリのURL。

https://github.com/ivan-cai/echo-server.git

repo_name

リポジトリの名前。

エコーサーバー

target_branch

リポジトリの宛先ブランチ。

デフォルト値: main。

メイン

container_image

ビルドするイメージ。The image to be build. 形式: <ACR EEドメイン>/<ACR EE名前空間>/<リポジトリ名> 。

test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server

container_tag

画像タグ。

デフォルト: v1.0.0。

v1.0.0

dockerfile

Dockerfileのディレクトリと名前。

ルートディレクトリの相対パスを指定します。 デフォルト:. /Dockerfile.

. /Dockerfile

enable_suffix_commitid

イメージタグにコミットIDを付加するかどうかを指定します。 有効な値:

  • true: 追加します。

  • false: 追加しません。

デフォルト値:true

true

enable_test

Go Testステップを実行するかどうかを指定します。 有効な値:

  • true: ステップを実行します。

  • false: ステップを実行しないでください。

デフォルト値:true

true

前提条件

手順

CIパイプラインの作成方法を示す例として、パブリックGitリポジトリを使用します。 プライベートGitリポジトリを使用する場合は、まずCIパイプラインでプライベートリポジトリのクローンを作成する必要があります。

重要

コンテナーイメージとNASボリュームにアクセスするための資格情報を格納するSecretは、送信されるパイプラインの名前空間に属している必要があります。

手順1: Container Registry Enterprise Editionインスタンスにアクセスするためのワークフロークラスターでの資格情報の作成

資格情報は、BuildKitから画像をプルするために使用されます。

  1. Container Registry Enterprise Editionインスタンスのアクセス資格情報を設定します。 詳細については、「Container Registry Enterprise Editionインスタンスのアクセス資格情報の設定」をご参照ください。

  2. 次のコマンドを実行して、ワークフロークラスターにシークレットを作成し、資格情報を保存します。 資格情報はBuildKitによって使用されます。

    $username:$passwordを、Container Registry Enterprise Editionインスタンスへのアクセスに使用される資格情報に置き換えます。

    kubectl create secret generic docker-config --from-literal="config.json={\"auths\": {\"$repositoryDomain\": {\"auth\": \"$(echo -n $username:$password|base64)\"}}}"

手順2: NASボリュームをワークフロークラスターにマウントする

NASボリュームは、次の要件を満たすために使用されます。

  • クローンされたリポジトリに関する情報など、パイプラインのタスク間でデータを共有します。

  • CIパイプラインでGo TestおよびGo Buildステップを高速化するために使用されるGo modキャッシュを保存します。

次の手順を実行して、NASボリュームをワークフロークラスターにマウントします。

  1. NASファイルシステムのマウント対象を取得します。 詳細については、「マウントターゲットの管理」をご参照ください。

  2. 次のテンプレートに基づいて、ワークフロークラスターに永続ボリューム (PV) と永続ボリューム要求 (PVC) を作成します。 詳細については、「Use NAS volumes」をご参照ください。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-nas
      labels:
        alicloud-pvname: pv-nas
    spec:
      capacity:
        storage: 100Gi
      accessModes:
        - ReadWriteMany
      csi:
        driver: nasplugin.csi.alibabacloud.com
        volumeHandle: pv-nas   # Specify the name of the PV. 
        volumeAttributes:
          server: <your nas filesystem mount point address>
          path: "/"
      mountOptions:
      - nolock,tcp,noresvport
      - vers=3
    ---
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-nas
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 100Gi
      selector:
        matchLabels:
          alicloud-pvname: pv-nas

手順3: 定義済みのテンプレートに基づいてパイプラインを起動する

コンソールでパイプラインを送信する

  1. ACK Oneコンソールにログインします。 左側のナビゲーションウィンドウで、[ワークフロークラスター] をクリックします。

  2. [ワークフロークラスター] ページで、[基本情報] タブをクリックします。 [一般的な操作] セクションで、[ワークフローコンソール (アルゴ)] をクリックします。

  3. Argoワークベンチで、左側のナビゲーションウィンドウで [クラスターワークフローテンプレート] をクリックし、[ci-go-v1] という名前の定義済みテンプレートをクリックします。

    image

  4. テンプレートの詳細ページで、右上隅の [+ 送信] をクリックします。 表示されるパネルで、パラメータを設定し、[+ 送信] をクリックします。

    テンプレートパラメーターを参照し、パラメーターを設定します。

    image

    設定が完了したら、[ワークフロー] の詳細ページでパイプラインのステータスを確認できます。

    image

Argo CLIを使用してパイプラインを送信

  1. workflow.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。 テンプレートパラメーターを参照し、パラメーターを設定します。

    apiVersion: argoproj.io/v1alpha 1
    kind: ワークフロー
    メタデータ:
      generateName: ci-go-v1-
      ラベル:
        workflow. argoproj.io/workflow-template: ackone-ci
    spec:
      引数:
        parameters:
        -name: repo_url
          値: https://github.com/ivan-cai/echo-server.git
        -name: repo_name
          値: echo-server
        -name: target_branch
          値: メイン
        -name: container_image
          値: "test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server"
        -name: container_tag
          値: "v1.0.0"
        -name: dockerfile
          value: /Dockerfile
        -name: enable_suffix_commitid
          value: "true"
        -name: enable_test
          value: "true"
      workflowTemplateRef:
        名前: ci-go-v1
        clusterScope: true 
  2. 次のコマンドを実行してパイプラインを送信します。

    argo submit workflow.yaml