ACK One のワークフロークラスターは、ホスト型の Argo Workflows を実行し、組み込みの伸縮性と自動スケーリング機能を備えています。このトピックでは、Go リポジトリをクローンし、テストを実行し、コンテナイメージをビルドしてレジストリにプッシュする継続的インテグレーション (CI) パイプラインを設定する方法について説明します。各実行を高速に保つために、2 層の永続的なキャッシュを使用します。
仕組み
このパイプラインは、ci-go-v1 という名前の事前定義された ClusterWorkflowTemplate を使用します。各実行は、有向非循環グラフ (DAG) として 3 つのステップを実行します。
-
Git のクローンとチェックアウト — リポジトリをクローンし、ターゲットブランチをチェックアウトし、短いコミット ID を共有ファイルに書き込みます。
-
Go テスト — クローンされたソースに対して
go test -v ./...を実行します。Go モジュールキャッシュは、NAS ファイルシステムの/pkg/modディレクトリに保存されます。ある実行でダウンロードされたモジュールは次の実行で再利用されるため、go testとgo buildは依存関係の再ダウンロードをスキップします。 -
イメージのビルドとプッシュ —
buildctl-daemonless.sh(BuildKit) を使用してイメージをビルドし、Container Registry Enterprise Edition (ACR EE) にプッシュします。BuildKit は、:buildcacheタグでイメージレイヤーをレジストリにキャッシュします。変更されていないレイヤーは、後続の実行では再ビルドされません。
両方のキャッシュはパイプラインの実行をまたいで永続化します。NAS 上の Go モジュールキャッシュは単一の実行内のすべてのタスクで共有され、BuildKit レイヤーキャッシュは実行間でレジストリ内に存在します。
前提条件
開始する前に、以下が準備できていることを確認してください。
-
ワークフロークラスター。「ワークフロークラスターの作成」をご参照ください。
-
kubectl は、kubeconfig ファイルを使用してワークフロークラスターに接続されています。 詳細については、「kubectl を使用してクラスターに接続する」をご参照ください。
-
インストール済みの Alibaba Cloud Argo CLI。「Argo CLI のインストール」をご参照ください。
-
完了した RAM ユーザーの権限付与。「RAM ユーザーの権限付与」をご参照ください。
-
作成済みの File Storage NAS ファイルシステム。「NAS ファイルシステムの作成」をご参照ください。
-
作成済みの ACR EE インスタンス。「ACR EE インスタンスの作成」をご参照ください。
ステップ 1: ワークフロークラスターでのレジストリ認証情報の作成
BuildKit は、docker-config という名前のシークレットを使用してイメージをプルおよびプッシュします。パイプラインをサブミットする予定の名前空間に作成します。
シークレットと NAS ボリューム (ステップ 2 で作成) は、サブミットするパイプラインと同じ名前空間に属している必要があります。
-
ご利用の ACR EE インスタンスのアクセス認証情報を設定します。「アクセス認証情報の設定」をご参照ください。
-
次のコマンドを実行してシークレットを作成します。
$repositoryDomain、$username、$passwordをご利用の ACR EE ドメインと認証情報に置き換えます。kubectl create secret generic docker-config \ --from-literal="config.json={\"auths\": {\"$repositoryDomain\": {\"auth\": \"$(echo -n $username:$password|base64)\"}}}"
ステップ 2: ワークフロークラスターへの NAS ボリュームのマウント
NAS ボリュームは 2 つの目的を果たします。
-
タスク間のデータ共有: クローンされたリポジトリとコミット ID ファイルは、git-checkout-pr タスクによってここに書き込まれ、下流のタスクによって読み取られます。
-
Go モジュールキャッシュの永続化:
/pkg/mod内のキャッシュは、パイプラインの実行をまたいで再利用されます。最初の実行でモジュールがダウンロードされ、後続の実行ではそのステップがスキップされます。
NAS は ReadWriteMany アクセスモードを使用するため、すべてのパイプラインタスクがボリュームを同時に読み書きできます。
-
ご利用の NAS ファイルシステムのマウントターゲットアドレスを取得します。「マウントターゲットの管理」をご参照ください。
-
次のマニフェストを適用して、ワークフロークラスターに永続ボリューム (PV) と永続ボリューム要求 (PVC) を作成します。
<your nas filesystem mount point address>を実際ののマウントターゲットアドレスに置き換えます。詳細については、「NAS ボリュームの使用」をご参照ください。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 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: パイプラインのサブミット
事前定義された ci-go-v1 テンプレートは、すべてのワークフロークラスターで利用可能です。Argo ワークベンチまたは Argo CLI を使用してパイプラインの実行をサブミットします。
以下の例では、パブリック Git リポジトリを使用しています。プライベートリポジトリの場合は、Git のクローンとチェックアウトのステップの前に、保存された認証情報を使用してクローンするステップを追加してください。
Argo ワークベンチからのサブミット
-
ACK One コンソールにログインします。左側のナビゲーションウィンドウで、作成したワークフロークラスターを選択します。
-
[クラスター情報] ページで、[基本情報] タブをクリックします。[一般的な操作] セクションで、[ワークフローコンソール (Argo)] をクリックします。
-
Argo ワークベンチで、左側のナビゲーションウィンドウの [Cluster Workflow Templates] をクリックし、[ci-go-v1] という名前のテンプレートをクリックします。

-
右上隅の [+ SUBMIT] をクリックします。表示されるパネルでパラメーターを設定し (説明については「テンプレートパラメーター」をご参照ください)、[+ SUBMIT] をクリックします。

-
[Workflows] 詳細ページでパイプラインのステータスを表示できます。

Argo CLI を使用したサブミット
-
workflow.yamlという名前のファイルを次の内容で作成します。パラメーター値をご利用の環境に合わせて更新します。apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: ci-go-v1- labels: workflows.argoproj.io/workflow-template: ackone-ci spec: arguments: parameters: - name: repo_url value: https://github.com/ivan-cai/echo-server.git - name: repo_name value: echo-server - name: target_branch value: main - name: container_image value: "test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server" - name: container_tag value: "v1.0.0" - name: dockerfile value: ./Dockerfile - name: enable_suffix_commitid value: "true" - name: enable_test value: "true" workflowTemplateRef: name: ci-go-v1 clusterScope: true -
パイプラインをサブミットします。
argo submit workflow.yaml
テンプレートパラメーター
ci-go-v1 テンプレートは、次のパラメーターを受け入れます。
| パラメーター | 説明 | デフォルト | 例 |
|---|---|---|---|
repo_url |
Git リポジトリの URL | — | https://github.com/ivan-cai/echo-server.git |
repo_name |
リポジトリ名 (ローカルディレクトリ名として使用) | — | echo-server |
target_branch |
チェックアウトするブランチ | main |
main |
container_image |
ビルドしてプッシュするイメージ。フォーマット: <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 をイメージタグに追加し、<container_tag>-<commit_id> を生成します。ベースタグのみを使用するには、false に設定します。 |
true |
true |
enable_test |
Go テストステップを実行します。テストをスキップしてビルドに直接進むには、false に設定します。 |
true |
true |
事前定義テンプレートのリファレンス
カスタマイズ用に完全なテンプレートを以下に示します。主要なセクションには注釈が付いています。
apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
name: ci-go-v1
spec:
entrypoint: main
volumes:
- name: run-test
emptyDir: {} # run-test タスクにスコープされた一時ボリューム
- name: workdir
persistentVolumeClaim:
claimName: pvc-nas # NAS ボリューム: すべてのタスクで共有され、Go モジュールキャッシュを永続化します
- name: docker-config
secret:
secretName: docker-config # ステップ 1 で作成されたレジストリの認証情報
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" # enable_test=false の場合はスキップされます
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 # Go を NAS ベースのモジュールキャッシュに向けます
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 # 例: v1.0.0-abc1234
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
次のステップ
-
ci-go-v1のカスタマイズ — テンプレートをコピーしてステップを変更し (たとえば、lint ステップを追加したり、Go のバージョンを変更したり)、独自のClusterWorkflowTemplateを作成します。 -
パイプラインの自動トリガー —
argo submitをご利用の Git プラットフォームの Webhook と統合して、すべてのプッシュまたはプルリクエストでパイプラインを実行します。