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

Container Compute Service:ACS クラスターで GitLab Runner を使用して CI/CD 環境を構築する

最終更新日:Dec 27, 2024

GitLab Runner は、Go で記述されたオープンソースアプリケーションです。GitLab Runner は、GitLab によって配布される継続的インテグレーションおよび継続的デリバリー (CI/CD) ジョブを実行するエージェントとして機能します。CI ジョブに必要な計算能力は定期的に変化します。Container Compute Service (ACS) は、オンデマンドでリソースを提供し、高速スケーリングをサポートして、CI ジョブの動的なリソース要件を満たします。ACK は、ビジネスのキャパシティプランニングを簡素化し、全体的なリソースコストを削減します。ACK は、スケーラブルなクラウド リソースに基づいて弾力性を提供し、CI ジョブの同時実行性を大幅に向上させます。このトピックでは、GitLab Runner を使用して ACK に本番環境をデプロイする方法と、推奨される構成について説明します。

背景情報

GitLab Runner は、GitLab CI/CD パイプラインでジョブを実行するためのオープンソースプロジェクトです。GitLab Runner は、Shell や Kubernetes などのさまざまなエグゼキューターを提供する外部ジョブ実行フレームワークであり、データセンターまたはクラウドで CI ジョブを実行できます。ジョブが完了すると、GitLab Runner は結果を GitLab に返します。

GitLab Runner の主要な構成には、ランナー マネージャー ポッドの構成と初期化設定、および Kubernetes エグゼキューターの構成が含まれます。詳細については、GitLab Runner の構成 を参照してください。

手順

次の図は、このトピックで説明する手順を示しています。

前提条件

kubectl クライアントがクラスターに接続されていること。詳細については、クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する を参照してください。

インストール手順

この例では、gitlab-runner 17.3.1 がインストールされています。gitlab-runner 17.3.1 のインストールに使用されるチャートのバージョンは 0.68.1 です。gitlab-runner のインストール方法の詳細については、GitLab Runner Helm chart を参照してください。

  1. GitLab Runner チャートを取得します。

    1. GitLab Helm リポジトリを追加します。

      helm repo add gitlab https://charts.gitlab.io
    2. チャートを更新します。

      helm repo update gitlab
    3. GitLab runner チャートを取得します。

      helm pull gitlab/gitlab-runner --version 0.68.1 && tar zvxf gitlab-runner-0.68.1.tgz
  2. ランナーを登録します。

    GitLab コンソールでトークンを登録し、ランナートークンを記録する必要があります。詳細については、ランナーの登録 を参照してください。

  3. values.yaml という名前のファイルを作成して、初期化設定を構成します。

    YAML ファイルの内容を表示

    ## GitLab Runner イメージ
    ##
    ## デフォルトでは、registry.gitlab.com/gitlab-org/gitlab-runner:alpine-v{VERSION} を使用しています。
    ## {VERSION} は Chart.yaml の appVersion フィールドから取得されます。
    ##
    ## 参照: https://gitlab.com/gitlab-org/gitlab-runner/container_registry/29383?orderBy=NAME&sort=asc&search[]=alpine-v&search[]=
    ##
    ## 注: イメージを ubuntu リリースに変更する場合
    ##       securityContext を変更することを忘れないでください。
    ##       これらのイメージは異なるユーザー ID で実行されます。
    ##
    ...
    
    ## ランナーを登録する GitLab サーバーの URL (プロトコル付き)
    ## 参照: https://docs.gitlab.com/runner/commands/index.html#gitlab-runner-register
    ##
    gitlabUrl: https://jihulab.com/
    
    ## 非推奨: GitLab サーバーに新しいランナーを追加するための登録トークン。
    ##
    ## 参照: https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html
    ##
    # runnerRegistrationToken: ""
    
    ## GitLab サーバーに新しいランナーを追加するためのランナートークン。これは
    ## GitLab インスタンスから取得する必要があります。これは、すでに登録されているランナーのトークンです。
    ## 参照: (まだドキュメントはありませんが、既存のトークンを使用したいと考えています)
    ##
    runnerToken: "glrt-t3_sz6xxxxxxxxxDsWF77"
    #
    
    ## 終了前にすべてのランナーの登録を解除する
    ##
    ## ランナーのチャートバージョンまたは構成を更新すると、ランナーコンテナが
    ## 終了し、再作成されます。これにより、Gitlab インスタンスが
    ## 存在しないランナーを参照する可能性があります。終了前にランナーの登録を解除すると、この問題が軽減されます。
    ## 参照: https://docs.gitlab.com/runner/commands/index.html#gitlab-runner-unregister
    ##
    unregisterRunners: true
    
    ## ランナーを停止するときは、ジョブが終了するまで待つ時間を与えます。
    ##
    ## ランナーのチャートバージョンまたは構成を更新すると、ランナーコンテナが
    ## 優雅な停止リクエストで終了します。terminationGracePeriodSeconds は
    ## Kubernetes に対して、ランナーポッドが正常に終了するまで十分な時間待つように指示します。
    ## 参照: https://docs.gitlab.com/runner/commands/#signals
    terminationGracePeriodSeconds: 3600
    
    ## GitLab Runner が使用するカスタム証明書を渡すには、certsSecretName を設定します。
    ## 同じ名前空間にある Kubernetes Secret オブジェクトのリソース名を指定します。
    ## これは、/home/gitlab-runner/.gitlab-runner/certs/ ディレクトリにデータを入力するために使用されます。
    ## 参照: https://docs.gitlab.com/runner/configuration/tls-self-signed.html#supported-options-for-self-signed-certificates-targeting-the-gitlab-server
    ##
    # certsSecretName:
    
    ## 同時ジョブの最大数を構成する
    ## 参照: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
    ##
    concurrent: 10
    
    ...
    
    ## RBAC サポートの場合:
    rbac:
      ## ロールとロールバインディングを作成するかどうかを指定します
      ## この値を `true` に設定した場合、`serviceAccount.create` も `true` または `false` に設定する必要があります
      ##
      create: true
      ## create が true に設定されている場合に生成される serviceAccountName を定義します
      ## 指定しない場合、デフォルトは "gitlab-runner.fullname" です
      ## 非推奨: 代わりに `serviceAccount.name` を使用してください
      generatedServiceAccountName: ""
    ...
    
    ## ランナーが新しいジョブごとに起動するポッドの構成
    ##
    runners:
      # ランナー構成。複数行の文字列はテンプレートとして評価されるため、
      # 内部で helm 値を指定できます。
      #
      # tpl: https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function
      # ランナー構成: https://docs.gitlab.com/runner/configuration/advanced-configuration.html
      config: |
        [[runners]]
          [runners.kubernetes]
            namespace = "{{.Release.Namespace}}"
            image = "alpine"
    
      ## 既存のランナー構成ファイルの絶対パス
      ## 外部構成ファイルを使用するために "volumes" および "volumeMounts" と一緒に使用できます
      ## runners.config が空または null の場合にアクティブになります
      configPath: ""
    ...

    パラメーター

    説明

    gitlabUrl

    ランナーを登録する GitLab サーバーの URL。例: https://gitlab.example.com

    runnerToken

    前の手順で取得したランナートークンを指定します。ランナーのトークンは、ランナーの識別子です。ランナー マネージャーは、マネージャーによって作成されたポッドとシークレットを、トークンに基づいてトークンに関連付けます。

    rbac

    ロールベースのアクセス制御 (RBAC) を有効にするかどうかを指定します。RBAC を有効にすると、サービスアカウントが自動的に作成されます。

    rbac:
      create: true

    concurrent

    ジョブの同時実行性。デフォルト値: 10。マネージャー ポッドは、ジョブを管理するときに特定量のメモリを消費します。ジョブの同時実行性が高い場合は、マネージャー ポッドのリソース構成を増やすことをお勧めします。

    unregisterRunners

    マネージャー ポッドを終了するには、unregister コマンドを実行します。ランナー登録トークンを使用してランナーを登録する場合、新しいトークンが生成されるたびにジョブが関連付けられなくなる可能性があります。この構成を追加することで、この問題を解決できます。詳細については、FAQ を参照してください。

    runners.config

    ランナーの構成。構成は複数行の文字列で指定されます。文字列を変更して、ランナーの構成を変更できます。

  4. ACK クラスターに GitLab Runner をインストールします。

    helm install --namespace default gitlab-runner -f values.yaml --version 0.68.1 gitlab/gitlab-runner
  5. 次のコマンドを実行して、GitLab Runner のステータスを確認します。

    kubectl get pod | grep gitlab

    予期される出力:

    gitlab-runner-7c5b4xxxxx-xxxxx   1/1     Running     0          5m17s

    出力は、GitLab Runner がインストールされていることを示しています。

イメージをビルドする

このセクションでは、Docker-in-Docker モードと kaniko を使用してイメージをビルドする方法について説明します。このセクションでは、ビルド手順で ACK の機能が使用されます。このセクションで使用されるサンプルプロジェクトの詳細については、Java デモ を参照してください。

Docker-in-Docker モードでイメージをビルドする

  1. values.yaml という名前のファイルを作成して、ランナーの構成を再構成します。

    ランナーと同じ名前空間にある gitlab-runner ConfigMap を変更することで、ランナーの構成を変更することもできます。helm upgrade コマンドを実行して、ランナーの構成を更新することをお勧めします。
    ...
    runners:
      config: |
        [[runners]]
          [runners.kubernetes]
            namespace = "{{.Release.Namespace}}"
            image = "registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind"
            privileged = true
            cpu_limit = 2
            cpu_request = 2
            memory_limit = "4Gi"
            memory_request = "4Gi"
            ephemeral_storage_request = "30Gi"
            ephemeral_storage_limit = "30Gi"
          [[runners.kubernetes.volumes.empty_dir]]
            name = "docker-certs"
            mount_path = "/certs/client"
            medium = "Memory"
          [[runners.feature_flags]]
            FF_USE_POD_ACTIVE_DEADLINE_SECONDS = true
    ...        

    次の表は、上記のコードブロックのパラメーターについて説明しています。

    パラメーター

    説明

    image

    Docker-in-Docker モードでイメージをビルドするために使用されるベースイメージ。この例では、Docker コミュニティによって提供される dind イメージが使用されます。

    privileged

    ランナーポッドの特権モードを有効にするかどうかを指定します。この例では、値は true に設定されています。

    説明

    この操作を実行するには、チケットを提出して、ACK ポッドの特権モードを有効にする必要があります。

    cpu_request

    cpu_limit

    コンテナの CPU 仕様。デフォルトでは、ACK でサポートされる最小 CPU 仕様は 0.25 vCPU です。ビジネス要件に基づいて CPU 仕様を調整できます。

    memory_request

    memory_limit

    コンテナのメモリ仕様。デフォルトでは、ACK でサポートされる最小メモリ仕様は 0.5 GiB です。ビジネス要件に基づいてメモリ仕様を調整できます。

    ephemeral_storage_request

    ephemeral_storage_limit

    一時ストレージのサイズ。デフォルトでは、ACK は 30 GiB の一時ストレージを無料で提供します。ACK がポッドを作成すると、イメージは一時ストレージを使用して自動的にキャッシュされます。イメージキャッシュにより、後続のジョブの起動が高速化されます。より大きな一時ストレージスペースが必要な場合は、ビジネス要件に基づいて構成を調整できます。

    FF_USE_POD_ACTIVE_DEADLINE_SECONDS

    activeDeadlineSeconds 機能ゲートを有効にするかどうかを指定します。機能ゲートを有効にすると、activeDeadlineSeconds パラメーターはジョブのタイムアウト期間に設定されます。これにより、不明な原因で関連付けられていないポッドが終了します。

    その他のパラメーターの詳細については、Kubernetes executor を参照してください。

  2. gitlab-ci という名前のファイルを作成して、ビルド手順を構成します。

    この例では、dind コンテナはサービスコンテナによって要求されません。代わりに、dockerd プロセスはビルドコンテナで直接起動されます。

    image: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/docker:27-dind
    
    stages:
      - build
    
    variables:
      # dind サービスを使用する場合は、Docker に対して
      # サービス内で起動されたデーモンと通信するように指示する必要があります。デーモンは
      # デフォルトの /var/run/docker.sock ソケットではなく、ネットワーク接続で使用できます。
      DOCKER_HOST: tcp://localhost:2376
      #
      # 'docker' ホスト名は、https://docs.gitlab.com/ee/ci/services/#accessing-the-services で説明されているように、サービスコンテナのエイリアスです。
      # Kubernetes エグゼキューターと Kubernetes 1.6 以前で GitLab Runner 12.7 以前を使用している場合、
      # Kubernetes エグゼキューターがサービスをジョブコンテナに接続する方法のため、
      # 変数を tcp://localhost:2376 に設定する必要があります
      # DOCKER_HOST: tcp://localhost:2376
      #
      # 証明書を作成する場所を Docker に指定します。Docker は
      # 起動時に自動的に証明書を作成し、`/certs/client` を作成して
      # config.toml からのボリュームマウントのおかげで、サービスとジョブコンテナ間で共有します
      DOCKER_TLS_CERTDIR: "/certs"
      # これらは通常、エントリポイントによって指定されますが、
      # Kubernetes エグゼキューターはエントリポイントを実行しません
      # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125
      DOCKER_TLS_VERIFY: 1
      DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
    
    before_script:
      - echo "タスク前"
      - sh /usr/local/bin/dockerd-entrypoint.sh &
      - sleep 10s
    
    build_image:
      stage: build
      tags:
        - demo
      script:
        - docker info
        - sleep 1d
        - docker build --network host -t demo:v1.0.0 -f Dockerfile .
        - docker push demo:v1.0.0

    次の表は、ビルド手順の手順について説明しています。

    手順

    説明

    before_scrip

    この手順では、dockerd プロセスを起動します。次に、システムは docker プロセスが初期化されるのを待ちます。

    build_image

    この手順では、イメージをビルドします。

    重要

    イメージビルド手順では、ホストネットワークモードを使用して、dockerd プロセスがコンテナネットワークを介して外部ネットワークと通信できるようにします。

kaniko を使用して非特権モードでイメージをビルドする

kaniko は、Docker がインストールされていない環境で実行できるオープンソースツールです。さらに、kaniko は特権モードを必要としません。kaniko は、システムが Docker へのアクセスを制限している場合、またはシステムが Kubernetes 環境で実行されている場合に適しています。

  1. values.yaml ファイルを構成します。

    ...
    runners:
      config: |
        [[runners]]
          [runners.kubernetes]
            namespace = "{{.Release.Namespace}}"
            ephemeral_storage_request = "30Gi"
            ephemeral_storage_limit = "30Gi"
          [[runners.feature_flags]]
            FF_USE_POD_ACTIVE_DEADLINE_SECONDS = true
    ...        
  2. gitlab-ci という名前のファイルを作成して、ビルド手順を構成します。

    重要

    GitLab CI は、コマンド実行に Shell エグゼキューターに依存しています。これは、ベースイメージが sh コマンドをサポートしている必要があることを意味します。この例では、kaniko エグゼキューターイメージのデバッグバージョンが使用されます。

    stages:
      - build
    
    variables:
      KUBERNETES_POD_LABELS_1: "alibabacloud.com/compute-class=general-purpose"
      KUBERNETES_POD_LABELS_2: "alibabacloud.com/compute-qos=best-effort"
    
    build_image:
      stage: build
      image:
        name: registry.cn-hangzhou.aliyuncs.com/acs-demo-ns/kaniko-executor:v1.21.0-amd64-debug
        entrypoint: [""]
      tags:
        - demo
      script:
        - /kaniko/executor
          --context "${CI_PROJECT_DIR}"
          --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
          --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"

ACK スケーリングポリシーに基づいて CI リソースコストを削減する

次のいずれかの方法を選択して、ACK が提供する BestEffort ポッドを使用して、CI/CD パイプラインでのジョブ実行のリソースコストを削減できます。

  1. クラスター内のすべてのポッド、またはプロジェクトに属するポッドに対して BestEffort QoS クラスを構成します。

    クラスター内のすべてのポッドに対して BestEffort QoS クラスを構成することをお勧めします。ビジネス要件に基づいて他の QoS クラスを選択することもできます。
    1. runners パラメーターを構成して、クラスター内のすべてのポッドに対して BestEffort QoS クラスを指定します。

      ...
      runners:
        config: |
          [[runners]]
            [runners.kubernetes]
              ...
              pod_labels_overwrite_allowed = ".*" # 変数に基づいてプロジェクトポッドのラベルを上書きできるようにします。
            [[runners.kubernetes.pod_labels]]
            "app" = "acs-gitlab-runner"
            "alibabacloud.com/compute-class" = "general-purpose"
            "alibabacloud.com/compute-qos" = "best-effort" # ポッドに BestEffort QoS クラスを構成します。
      ...      
    2. gitlab-ci.yml ファイルを使用して、ビジネス要件に基づいてリポジトリごとにポッド QoS クラスを構成できます。これを行うには、gitlab-ci.yml ファイルに variables パラメーターを追加します。詳細については、このトピックの kaniko を使用して非特権モードでイメージをビルドする セクションを参照してください。

  2. ResourcePolicy を構成して弾力性を確保します。

    ResourcePolicy を使用してカスタムスケジューリングポリシーを構成し、CI ジョブのリソースコストを削減できます。これにより、CI ジョブは、費用対効果の高い BestEffort ジョブに優先的にスケジュールされます。リージョンで BestEffort ポッドが使い果たされると、システムは自動的に Default ポッドを作成して、CI ジョブの継続性と可用性を確保します。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: rp-demo
      namespace: default
    spec:
      selector: # ポッドの選択に使用されるラベルセレクターを指定します。この例では、ResourcePolicy は app=stress ラベルが付いたポッドに適用されます。
        app: acs-gitlab-runner
      units: # ポッドスケジューリングのためのさまざまなタイプのノードの優先順位を指定します。
      - resource: acs # BestEffort リソースを優先します。
        podLabels:
          alibabacloud.com/compute-class: general-purpose
          alibabacloud.com/compute-qos: best-effort
      - resource: acs # 前のリソースが在庫切れになったときに Default リソースを適用します。
        podLabels:
          alibabacloud.com/compute-class: general-purpose
          alibabacloud.com/compute-qos: default

FAQ

マネージャーポッドを再作成または再起動した後、残りのポッドを削除するにはどうすればよいですか?

原因

システムは異なるランナートークンを使用して、マネージャーポッドを再作成または再起動しました。ランナーのトークンは、ランナーの識別子です。この場合、マネージャーポッドは元のジョブポッドを管理できません。

解決策

  • GitLab コンソールに移動し、ランナーを再作成します。ランナー構成ファイルでランナートークンを指定します。

  • 起動プロセス中にランナー登録に registration token が使用される場合、シークレットをマネージャーポッドにマウントし、最初のランナー登録中に生成されたトークンをシークレットで指定することをお勧めします。これにより、マネージャーポッドが再起動されるたびに最初のトークンが使用されます。

  • FF_USE_POD_ACTIVE_DEADLINE_SECONDS 機能ゲートを有効にすることをお勧めします。これにより、各ランナーワーカーの有効期間 (TTL) を指定できます。これは、リソース再利用ポリシーに似ています。