正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

Kubernetesへのデプロイを開始する

このページでは、GitLabでサポートされている方法を使用したKubernetesへのデプロイについて紹介します。最終的に、以下を理解できます:

  • Fluxを使用したデプロイ方法
  • GitLab CI/CDのパイプラインから、クラスターに対してコマンドをデプロイまたは実行する方法
  • FluxとGitLab CI/CDを組み合わせて最良の結果を得る方法

はじめる前

このチュートリアルは、KubernetesクラスターをGitLabに接続するで作成したプロジェクトをベースにしています。そのチュートリアルで作成したのと同じプロジェクトを使用します。ただし、接続されたKubernetesクラスターとブートストラップされたFluxインストールがある任意のプロジェクトを使用できます。

GitLab CI/CDからクラスターに対してコマンドを実行

Kubernetes用エージェントはGitLab CI/CDパイプラインと統合します。CI/CDを使用して、kubectl applyhelm upgradeのようなコマンドをクラスターに対して安全かつスケーラブルな方法で実行できます。

このセクションでは、GitLabのパイプラインインテグレーションを使用して、クラスター内にシークレットを作成し、それを使用してGitLabのコンテナレジストリにアクセスします。このチュートリアルの残りの部分では、デプロイされたシークレットを使用します。

  1. デプロイトークンを作成し、read_registryのスコープを設定します。

  2. デプロイトークンとユーザー名をCONTAINER_REGISTRY_ACCESS_TOKENおよびCONTAINER_REGISTRY_ACCESS_USERNAMEというCI/CD変数として保存します。

  3. 以下のスニペットを.gitlab-ci.ymlファイルに追加し、両方のAGENT_KUBECONTEXT変数をプロジェクトのパスに合わせて更新します:

    stages:
    - setup
    - deploy
    - stop
    
    create-registry-secret:
      stage: setup
      image: "portainer/kubectl-shell:latest"
      variables:
        AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
      before_script:
        # The available agents are automatically injected into the runner environment
        # You need to select the agent to use
        - kubectl config use-context $AGENT_KUBECONTEXT
      script:
        - kubectl delete secret gitlab-registry-auth -n flux-system --ignore-not-found
        - kubectl create secret docker-registry gitlab-registry-auth -n flux-system
          --docker-password="${CONTAINER_REGISTRY_ACCESS_TOKEN}" --docker-username="${CONTAINER_REGISTRY_ACCESS_USERNAME}" --docker-server="${CI_REGISTRY}"
      environment:
        name: container-registry-secret
        on_stop: delete-registry-secret
    
    delete-registry-secret:
      stage: stop
      image: ""
      variables:
        AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
      before_script:
        # The available agents are automatically injected into the runner environment
        # You need to select the agent to use
        - kubectl config use-context $AGENT_KUBECONTEXT
      script:
        - kubectl delete secret -n flux-system gitlab-registry-auth
      environment:
        name: container-registry-secret
        action: stop
      when: manual

続行する前に、CI/CDで他のコマンドを実行する方法を検討してください。

シンプルなマニフェストをOCIイメージにビルドし、クラスターにデプロイする

本番環境のユースケースでは、GitリポジトリとFluxCD間のキャッシュレイヤーとしてOCIリポジトリを使用することがベストプラクティスです。FluxCDはOCIリポジトリで新しいイメージをチェックし、GitLabのパイプラインはFlux準拠のOCIイメージをビルドします。エンタープライズのベストプラクティスの詳細については、エンタープライズの考慮事項を参照してください。

このセクションでは、シンプルなKubernetesマニフェストをOCIアーティファクトとしてビルドし、それをクラスターにデプロイします。

  1. 指定されたOCIイメージを取得し、そのコンテンツをデプロイする場所をFluxに指示するために、以下のflux CLIコマンドを実行します。GitLabのインスタンスに合わせて--urlの値を調整します。デプロイ > コンテナレジストリでコンテナレジストリのURLを見つけることができます。Fluxがデプロイするマニフェストをどのように見つけるかをよりよく理解するために、作成されたclusters/testing/nginx.yamlファイルを検査できます。

    flux create source oci nginx-example \
     --url oci://registry.gitlab.example.org/my-group/optional-subgroup/my-repository/nginx-example \
     --tag latest \
     --secret-ref gitlab-registry-auth \
     --interval 1m \
     --namespace flux-system \
     --export > clusters/testing/nginx.yaml
     flux create kustomization nginx-example \
     --source OCIRepository/nginx-example \
     --path "." \
     --prune true \
     --target-namespace default \
     --interval 1m \
     --namespace flux-system \
     --export >> clusters/testing/nginx.yaml
  2. 例としてNGINXをデプロイします。次のYAMLをclusters/applications/nginx/nginx.yamlに追加します:

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: nginx-example
       namespace: default
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: nginx-example
       template:
         metadata:
           labels:
             app: nginx-example
         spec:
           containers:
             - name: nginx
               image: nginx:1.25
               ports:
                 - containerPort: 80
                   protocol: TCP
     ---
     apiVersion: v1
     kind: Service
     metadata:
       name: nginx-example
       namespace: default
     spec:
       ports:
         - port: 80
           targetPort: 80
           protocol: TCP
       selector:
         app: nginx-example
  3. 次に、以前のYAMLをOCIイメージにパッケージ化しましょう。.gitlab-ci.ymlファイルに以下のスニペットを追加し、再度AGENT_KUBECONTEXT変数を更新します:

     nginx-deployment:
         stage: deploy
         variables:
             IMAGE_NAME: nginx-example   # Image name to push
             IMAGE_TAG: latest
             MANIFEST_PATH: "./clusters/applications/nginx"
             IMAGE_TITLE: NGINX example   # Image title to use in OCI annotation
             AGENT_KUBECONTEXT: my-group/optional-subgroup/my-repository:testing
             FLUX_OCI_REPO_NAME: nginx-example  # Flux OCIRepository to reconcile
             NAMESPACE: flux-system  # Namespace for the OCIRepository resource
         # This section configures a GitLab environment for the nginx deployment specifically
         environment:
             name: applications/nginx
             kubernetes:
                 agent: $AGENT_KUBECONTEXT
                 dashboard:
                   namespace: default
                   flux_resource_path: kustomize.toolkit.fluxcd.io/v1/namespaces/flux-system/kustomizations/nginx-example  # You will deploy this resource in the next step
         image:
             name: "fluxcd/flux-cli:v2.4.0"
             entrypoint: [""]
         before_script:
             - kubectl config use-context $AGENT_KUBECONTEXT
         script:
             # This line builds and pushes the OCI container to the GitLab container registry.
             # You can read more about this command in https://fluxcd.io/flux/cmd/flux_push_artifact/
             - flux push artifact oci://${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}
                 --source="${CI_REPOSITORY_URL}"
                 --path="${MANIFEST_PATH}"
                 --revision="${CI_COMMIT_SHORT_SHA}"
                 --creds="${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}"
                 --annotations="org.opencontainers.image.url=${CI_PROJECT_URL}"
                 --annotations="org.opencontainers.image.title=${IMAGE_TITLE}"
                 --annotations="com.gitlab.job.id=${CI_JOB_ID}"
                 --annotations="com.gitlab.job.url=${CI_JOB_URL}"
             # This line triggers an immediate reconciliation of the resource. Otherwise Flux would reconcile following its configured reconciliation period.
             # You can read more about the various reconcile commands in https://fluxcd.io/flux/cmd/flux_reconcile/
             - flux reconcile source oci -n ${NAMESPACE} ${FLUX_OCI_REPO_NAME}
  4. 変更をプロジェクトにコミットしてプッシュし、ビルドパイプラインが完了するのを待ちます。

  5. 左サイドバーで操作 > 環境を選択し、利用可能なKubernetesのダッシュボードを確認します。applications/nginx環境は正常である必要があります。

GitLabパイプラインアクセスを保護する

  • プラン: Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

以前にデプロイされたエージェントは、.gitlab/agents/testing/config.yamlファイルを使用して設定されます。デフォルトでは、GitLabパイプラインが実行されるプロジェクトで設定されたクラスターへのアクセスが有効になっています。デフォルトでは、このアクセスはデプロイされたエージェントのサービスアカウントを使用してクラスターに対するコマンドを実行します。このアクセスは、静的なサービスアカウントIDに制限するか、CI/CDジョブをクラスター内のIDとして使用することで制限できます。さらに、通常のKubernetes RBACを使用して、クラスター内のCI/CDジョブのアクセスを制限できます。

このセクションでは、すべてのCI/CDジョブにIDを追加し、クラスター内でそのジョブを代理実行することで、CI/CDアクセスを制限する方法を説明します。

  1. CI/CDジョブの代理実行を設定するには、.gitlab/agents/testing/config.yamlファイルを編集し、次のスニペットを追加します(path/to/projectを置き換えます):

    ci_access:
       projects:
          - id: my-group/optional-subgroup/my-repository
            access_as:
               ci_job: {}
  2. CI/CDジョブにはまだクラスターバインディングがないため、GitLab CI/CDからKubernetesコマンドを実行することはできません。CI/CDジョブがflux-systemネームスペースでSecretオブジェクトを作成できるようにしましょう。次の内容でclusters/testing/gitlab-ci-job-secret-write.yamlファイルを作成します:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
       name: secret-manager
       namespace: default
    rules:
       - apiGroups: [""]
         resources: ["secrets"]
         verbs: ["create", "delete"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
       name: gitlab-ci-secrets-binding
       namespace: default
    subjects:
       - kind: Group
         name: gitlab:ci_job
         apiGroup: rbac.authorization.k8s.io
    roleRef:
       kind: Role
       name: secret-manager
       apiGroup: rbac.authorization.k8s.io
  3. CI/CDジョブがFluxCDの調整もトリガーできるようにしましょう。以下の内容でclusters/testing/gitlab-ci-job-flux-reconciler.yamlファイルを作成します:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
        name: ci-job-admin
    roleRef:
        name: flux-edit-flux-system
        kind: ClusterRole
        apiGroup: rbac.authorization.k8s.io
    subjects:
        - name: gitlab:ci_job
          kind: Group
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
        name: ci-job-view
    roleRef:
        name: flux-view-flux-system
        kind: ClusterRole
        apiGroup: rbac.authorization.k8s.io
    subjects:
        - name: gitlab:ci_job
          kind: Group

CI/CDアクセスに関する詳細については、KubernetesクラスターでGitLab CI/CDを使用するを参照してください。

リソースをクリーンアップする

最後に、デプロイしたリソースを削除し、コンテナレジストリへのアクセスに使用したシークレットを削除します:

  1. clusters/testing/nginx.yamlファイルを削除します。Fluxがクラスターから関連リソースの削除を処理します。
  2. container-registry-secret環境を停止します。環境を停止すると、そのon_stopジョブがトリガーされ、クラスターからシークレットが削除されます。

次の手順

このチュートリアルで紹介した手法を使用して、プロジェクト全体でデプロイをスケールできます。OCIイメージは別のプロジェクトでビルドでき、Fluxが適切なレジストリを指している限り、Fluxはそれを取得します。この演習は読者に任されています。

さらなる練習として、/clusters/testing/flux-system/gotk-sync.yamlにある元のFlux GitRepositoryOCIRepositoryに変更してみてください。

最後に、FluxとGitLabのKubernetesとのインテグレーションに関する詳細については、以下のリソースを参照してください: