All Products
Search
Document Center

Container Service for Kubernetes:Bangun pipeline CI untuk proyek Golang menggunakan kluster alur kerja

Last Updated:Mar 27, 2026

Kluster alur kerja ACK One menjalankan Argo Workflows yang dihosting dengan elastisitas dan auto scaling bawaan. Topik ini menjelaskan cara menyiapkan pipeline Continuous Integration (CI) untuk mengkloning repositori Go, menjalankan pengujian, membangun gambar kontainer, dan mendorongnya ke registri—dilengkapi dua lapis cache persisten agar setiap eksekusi tetap cepat.

image

Cara kerja

Pipeline ini menggunakan ci-go-v1, yaitu ClusterWorkflowTemplate yang telah ditentukan sebelumnya. Setiap eksekusi menjalankan tiga langkah dalam bentuk directed acyclic graph (DAG):

  1. Git clone and checkout — mengkloning repositori, melakukan checkout pada branch target, dan menulis ID commit pendek ke file bersama.

  2. Go test — menjalankan go test -v ./... terhadap kode sumber yang telah dikloning. Cache modul Go disimpan dalam direktori /pkg/mod pada sistem file NAS. Modul yang diunduh dalam satu eksekusi dapat digunakan kembali pada eksekusi berikutnya, sehingga perintah go test dan go build tidak perlu mengunduh ulang dependensi.

  3. Build and push image — menggunakan buildctl-daemonless.sh (BuildKit) untuk membangun gambar dan mendorongnya ke Container Registry Enterprise Edition (ACR EE). BuildKit menyimpan cache layer gambar di registri dengan tag :buildcache. Layer yang tidak berubah tidak akan dibangun ulang pada eksekusi berikutnya.

Kedua cache tersebut bertahan lintas eksekusi pipeline: cache modul Go pada NAS dibagikan oleh semua task dalam satu eksekusi, sedangkan cache layer BuildKit disimpan di registri dan digunakan antar eksekusi.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Langkah 1: Buat kredensial registri di kluster alur kerja

BuildKit melakukan pull dan push gambar menggunakan Secret bernama docker-config. Buat Secret tersebut di namespace tempat Anda akan mengirimkan pipeline.

Penting

Secret dan volume NAS (yang dibuat di Langkah 2) harus berada dalam namespace yang sama dengan pipeline yang Anda kirimkan.

  1. Konfigurasikan kredensial akses untuk instans ACR EE Anda. Lihat Konfigurasikan kredensial akses.

  2. Jalankan perintah berikut untuk membuat Secret. Ganti $repositoryDomain, $username, dan $password dengan domain dan kredensial ACR EE Anda.

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

Langkah 2: Pasang volume NAS ke kluster alur kerja

Volume NAS memiliki dua fungsi:

  • Berbagi data antar task: repositori yang dikloning dan file ID commit ditulis di sini oleh task git-checkout-pr dan dibaca oleh task downstream.

  • Persistensi cache modul Go: cache di /pkg/mod digunakan kembali lintas eksekusi pipeline. Eksekusi pertama mengunduh modul; eksekusi berikutnya melewatkan langkah tersebut.

NAS menggunakan mode akses ReadWriteMany sehingga semua task pipeline dapat membaca dan menulis volume secara konkuren.

  1. Dapatkan alamat titik pemasangan sistem file NAS Anda. Lihat Kelola titik pemasangan.

  2. Terapkan manifes berikut untuk membuat persistent volume (PV) dan persistent volume claim (PVC) di kluster alur kerja. Ganti <your nas filesystem mount point address> dengan alamat titik pemasangan aktual Anda. Untuk informasi lebih lanjut, lihat Gunakan volume NAS.

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-nas
      labels:
        alicloud-pvname: pv-nas
    spec:
      capacity:
        storage: 100Gi
      accessModes:
        - ReadWriteMany          # Diperlukan: semua task pipeline membaca dan menulis volume ini secara konkuren
      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             # Templat yang telah ditentukan mereferensikan nama ini — jangan ubah
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 100Gi
      selector:
        matchLabels:
          alicloud-pvname: pv-nas

Langkah 3: Kirim pipeline

Templat ci-go-v1 yang telah ditentukan tersedia di semua kluster alur kerja. Gunakan Argo Workbench atau Argo CLI untuk mengirimkan eksekusi pipeline.

Contoh di bawah menggunakan repositori Git publik. Untuk repositori pribadi, tambahkan langkah yang melakukan kloning menggunakan kredensial yang telah disimpan sebelum langkah Git clone and checkout.

Kirim dari Argo workbench

  1. Masuk ke Konsol ACK One. Di panel navigasi kiri, pilih kluster alur kerja yang telah Anda buat.

  2. Di halaman Cluster Information, klik tab Basic Information. Di bagian Common Operations, klik Workflow Console (Argo).

  3. Di Argo Workbench, klik Cluster Workflow Templates di panel navigasi kiri, lalu klik templat bernama ci-go-v1.

    image

  4. Klik + SUBMIT di pojok kanan atas. Konfigurasikan parameter di panel yang muncul (lihat Parameter templat untuk deskripsi), lalu klik + SUBMIT.

    image

  5. Anda dapat melihat status pipeline di halaman detail Workflows.

    image

Kirim menggunakan Argo CLI

  1. Buat file bernama workflow.yaml dengan konten berikut. Perbarui nilai parameter agar sesuai dengan lingkungan Anda.

    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
  2. Kirim pipeline:

    argo submit workflow.yaml

Parameter templat

Templat ci-go-v1 menerima parameter berikut.

Parameter Deskripsi Default Contoh
repo_url URL repositori Git https://github.com/ivan-cai/echo-server.git
repo_name Nama repositori (digunakan sebagai nama direktori lokal) echo-server
target_branch Branch yang akan di-checkout main main
container_image Gambar yang akan dibangun dan didorong. Format: <ACR EE domain>/<namespace>/<repository> test-registry.cn-hongkong.cr.aliyuncs.com/acs/echo-server
container_tag Tag gambar dasar v1.0.0 v1.0.0
dockerfile Path relatif ke Dockerfile dari root repositori ./Dockerfile ./Dockerfile
enable_suffix_commitid Tambahkan ID commit pendek ke tag gambar, menghasilkan <container_tag>-<commit_id>. Atur ke false untuk hanya menggunakan tag dasar. true true
enable_test Jalankan langkah Go test. Atur ke false untuk melewatkan pengujian dan langsung ke pembangunan. true true

Referensi templat yang telah ditentukan

Templat lengkap disediakan di bawah ini untuk kustomisasi. Bagian-bagian penting telah diberi anotasi.

apiVersion: argoproj.io/v1alpha1
kind: ClusterWorkflowTemplate
metadata:
  name: ci-go-v1
spec:
  entrypoint: main
  volumes:
  - name: run-test
    emptyDir: {}          # Volume sementara yang terbatas pada task run-test
  - name: workdir
    persistentVolumeClaim:
      claimName: pvc-nas  # Volume NAS: dibagikan di semua task, menyimpan cache modul Go
  - name: docker-config
    secret:
      secretName: docker-config  # Kredensial registri yang dibuat di Langkah 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"  # Dilewati saat 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  # Arahkan Go ke cache modul berbasis 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  # contoh: 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 \  # Simpan cache layer ke registri
                    --import-cache type=registry,ref={{workflow.parameters.container_image}}:buildcache            # Gunakan kembali cache layer dari eksekusi sebelumnya

                    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

Langkah selanjutnya

  • Kustomisasi ci-go-v1 — salin templat tersebut dan modifikasi langkah-langkahnya (misalnya, tambahkan langkah lint atau ubah versi Go) untuk membuat ClusterWorkflowTemplate Anda sendiri.

  • Picu pipeline secara otomatis — integrasikan argo submit dengan webhook platform Git Anda untuk menjalankan pipeline pada setiap push atau pull request.

Referensi