Contents
1. 前提条件と環境要件
| 項目 | 推奨バージョン | 確認コマンド例 | 補足 |
|---|---|---|---|
| GitLab 本体 | 16.4.x 以上 (公式サポートは 16 系) | gitlab-rake gitlab:env:info |
変更履歴は https://docs.gitlab.com/ee/update/ を参照 |
| GitLab Runner Helm Chart | 0.58.0 以上(執筆時点) | helm search repo gitlab/gitlab-runner --versions \| head -n 5 |
--versions で全バージョンを取得し、最新を選択 |
| GitLab Agent Helm Chart | 1.12.0 以上(執筆時点) | helm search repo gitlab/gitlab-agent --versions \| head -n 5 |
同上 |
| Kubernetes クラスター | 1.28.x 以上 (公式サポートは v1.26‑v1.30) | kubectl version --short |
2026‑04‑20 時点での最新安定版は 1.29 系も利用可 |
| Ingress / NetworkPolicy | NGINX Ingress v1.9+、Calico v3.27+ 推奨 | kubectl get ingressclass,networkpolicy -A |
必要に応じて Service Mesh (Istio) でも代替可 |
※ バージョンは執筆時点の情報です。
Helm Chart の最新リリースは常にhelm repo update後に上記コマンドで確認してください。
ネットワーク要件
- Runner と Agent が外部 GitLab(gitlab.com または社内)へ HTTPS (443/tcp) で通信できること。
- 必要最小限の egress ルールだけを許可し、不要なポートは
NetworkPolicyでブロックします。
2. GitLab Runner の Helm デプロイとベストプラクティス
2‑1. Helm リポジトリ追加 & バージョン確認
|
1 2 3 4 5 6 7 8 |
helm repo add gitlab https://charts.gitlab.io helm repo update # 最新安定版を取得(例: 0.58.0) LATEST_RUNNER=$(helm search repo gitlab/gitlab-runner --versions \ | grep -E '^\s*gitlab/gitlab-runner' | head -n1 | awk '{print $2}') echo "Deploying Runner Chart version ${LATEST_RUNNER}" |
2‑2. カスタム values.yaml の構成ポイント
| 項目 | 推奨設定 | 理由 |
|---|---|---|
concurrent |
10(ジョブ同時実行数) | クラスタリソースとバランスを取る |
checkInterval |
30 秒 | Runner が GitLab と定期的に接続状態を確認 |
resources.limits / requests |
CPU: 2000m / 500m、Memory: 4Gi / 1Gi |
ジョブの過剰消費防止とスケジューラの安定化 |
affinity.nodeAffinity |
AMD64 ノード限定例(必要に応じて変更) | ハードウェア依存ジョブで失敗を回避 |
tls.enabled |
true | Runner ↔ GitLab 間の通信を暗号化 |
serviceAccount.name |
gitlab-runner-sa |
後述 RBAC と紐付けるために明示的指定 |
完全サンプル(runner-values.yaml)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# runner-values.yaml gitlabUrl: "https://gitlab.example.com/" runnerRegistrationToken: "<REGISTRATION_TOKEN>" concurrent: 10 checkInterval: 30 resources: limits: cpu: "2000m" memory: "4Gi" requests: cpu: "500m" memory: "1Gi" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: ["amd64"] tls: enabled: true insecureSkipVerify: false serviceAccount: create: false # 既存 SA を使用するので作成しない name: gitlab-runner-sa |
2‑3. デプロイ実行
|
1 2 3 4 5 |
helm upgrade --install gitlab-runner gitlab/gitlab-runner \ -n ci-cd --create-namespace \ -f runner-values.yaml \ --version "${LATEST_RUNNER}" |
デプロイ後の確認ポイント
|
1 2 3 4 5 6 |
# Pod が Running 状態かつ Ready になるまで待機 kubectl rollout status deployment/gitlab-runner -n ci-cd # Helm の設定が反映されたか検証 helm get values gitlab-runner -n ci-cd |
3. GitLab Agent for Kubernetes のインストール & kube‑context 連携
3‑1. Agent 用 Namespace と ServiceAccount の作成
|
1 2 3 |
kubectl create namespace gitlab-agent --dry-run=client -o yaml | kubectl apply -f - kubectl create serviceaccount gitlab-agent-sa -n gitlab-agent |
注:
gitlab-agent名前空間は他プロジェクトと分離できるように推奨します。
3‑2. Helm Chart のインストール(バージョン取得同様)
|
1 2 3 4 5 6 7 8 9 10 11 |
LATEST_AGENT=$(helm search repo gitlab/gitlab-agent --versions \ | grep -E '^\s*gitlab/gitlab-agent' | head -n1 | awk '{print $2}') echo "Deploying Agent Chart version ${LATEST_AGENT}" helm upgrade --install gitlab-agent gitlab/gitlab-agent \ -n gitlab-agent \ --create-namespace \ --set config.token="<AGENT_TOKEN>" \ --set serviceAccount.name=gitlab-agent-sa \ --version "${LATEST_AGENT}" |
3‑3. kubeconfig(kube‑context)取得手順
|
1 2 3 4 5 6 7 |
# Secret 名はデフォルトで gitlab-agent-kubeconfig kubectl get secret gitlab-agent-kubeconfig -n gitlab-agent \ -o jsonpath='{.data.kubeconfig}' | base64 -d > agent.kubeconfig # 権限テスト(例: Pod の一覧取得) KUBECONFIG=agent.kubeconfig kubectl get pods -A |
3‑4. GitLab UI でエージェントを登録
- Settings → Infrastructure → Kubernetes clusters
- 「Add existing cluster」→「Connect a cluster with an agent」
Kubernetes API URL、CA certificate、Tokenはagent.kubeconfigからコピー- 登録が完了するとプロジェクト側で kube‑context が自動生成され、CI/CD ジョブから利用可能に。
ポイント: Agent が作成した ServiceAccount に対しては、次節の RBAC ポリシーで最小権限を付与します。
4. .gitlab-ci.yml による安全なシークレット管理とデプロイ例
4‑1. Protected & Masked 変数の設定(GitLab UI)
| 項目 | 設定方法 |
|---|---|
| Key | DOCKER_REGISTRY_PASSWORD |
| Value | <シークレット> |
| Protect | ON (protected ブランチ/タグからのみ参照可) |
| Mask | ON(ジョブログでマスク表示) |
ベストプラクティス: 重要度が高いシークレットは environment‑specific protected variables に分離し、ステージング・本番で別々に管理します。
4‑2. 完全サンプル .gitlab-ci.yml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# .gitlab-ci.yml stages: - build - test - deploy variables: # Agent が自動生成した kubeconfig のパス(CI/CD 用にマスク不要) KUBE_CONFIG: "agent.kubeconfig" # Helm リポジトリ URL はプロジェクト固有のものに変更 HELM_REPO_URL: "https://charts.example.com" # ------------------------------------------------- # ビルドイメージ # ------------------------------------------------- build_image: stage: build image: docker:23.0 services: - docker:dind script: - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" . - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" only: - branches tags: - docker # ------------------------------------------------- # テスト(ユニット・静的解析などは省略) # ------------------------------------------------- test_job: stage: test image: node:20-alpine script: - npm ci && npm run lint && npm test only: - merge_requests tags: - node # ------------------------------------------------- # デプロイ(本番は manual、ステージングは自動) # ------------------------------------------------- .deploy_template: &deploy_base stage: deploy image: bitnami/kubectl:1.28 before_script: # agent.kubeconfig を CI 環境へコピー - mkdir -p $HOME/.kube - cp "$KUBE_CONFIG" $HOME/.kube/config script: # Helm リポジトリ登録(キャッシュ防止のため --force-update) - helm repo add app "${HELM_REPO_URL}" --force-update # デプロイ例:Helm upgrade with rollback on failure - helm upgrade --install myapp app/mychart \ --set image.tag=$CI_COMMIT_SHORT_SHA \ --namespace production \ --atomic --cleanup-on-fail only: - main when: manual # 本番は手動トリガー deploy_staging: <<: *deploy_base environment: name: staging url: https://staging.example.com when: on_success # 自動実行 deploy_production: <<: *deploy_base environment: name: production url: https://www.example.com tags: - prod-runner |
ポイント解説
KUBE_CONFIGは GitLab Runner がマウントしたシークレット(agent.kubeconfig)へのパス。ジョブ実行時にkubectlが自動的に使用できるよう$HOME/.kube/configにコピーしています。--atomic --cleanup-on-failは Helm デプロイ失敗時にロールバックし、リソースの残存を防止します。- 環境変数
environment:でステージングと本番を分離し、GitLab の環境別 URL 表示や保護ルール(protected environment)と連携可能です。
5. 運用・監視:RBAC、ServiceAccount、トラブルシューティング
5‑1. 最小権限の ServiceAccount と RBAC 設計
Runner 用 SA & Role
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# runner-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-runner-sa namespace: ci-cd --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: gitlab-runner-role namespace: ci-cd rules: # Pod の取得・削除(ジョブ実行に必要) - apiGroups: [""] resources: ["pods", "pods/exec", "secrets"] verbs: ["get", "list", "create", "delete"] # デプロイ関連リソースへの更新権限 - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["get", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: gitlab-runner-rb namespace: ci-cd subjects: - kind: ServiceAccount name: gitlab-runner-sa namespace: ci-cd roleRef: kind: Role name: gitlab-runner-role apiGroup: rbac.authorization.k8s.io |
Agent 用 SA & ClusterRole(例:Kubernetes API の read‑only)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# agent-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-agent-sa namespace: gitlab-agent --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: gitlab-agent-readonly rules: - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: gitlab-agent-crb subjects: - kind: ServiceAccount name: gitlab-agent-sa namespace: gitlab-agent roleRef: kind: ClusterRole name: gitlab-agent-readonly apiGroup: rbac.authorization.k8s.io |
実装ヒント
-ClusterRoleが必要になるのは、Agent が名前空間横断でリソースを参照するケースです。
- 本番環境ではPodSecurityPolicy(またはPod Security Standards)と組み合わせて、コンテナ実行時の権限も制限します。
5‑2. デバッグ・可観測性
| 手法 | 実施コマンド例 | 主な活用シーン |
|---|---|---|
| Job Trace (GitLab UI) | ジョブ失敗時に CI_DEBUG_TRACE=true を設定 |
スクリプトレベルのエラー原因特定 |
| kubectl logs | kubectl logs -n ci-cd -l app=gitlab-runner --tail=200 |
Runner Pod の標準出力・stderr 確認 |
| Prometheus metrics | Chart が自動生成する /metrics エンドポイントをスクレイプ |
CPU/Memory 使用率、ジョブ成功率の長期トレンド |
| Grafana ダッシュボード | 公式テンプレート gitlab-runner-dashboard.json をインポート |
ビジュアルでリソース異常やスパイク検知 |
Prometheus 設定例(GitLab Runner の metrics エクスポート)
|
1 2 3 4 5 6 |
# prometheus.yml に追記 scrape_configs: - job_name: 'gitlab-runner' static_configs: - targets: ['gitlab-runner-ci-cd:9252'] # Service が自動生成する名前 |
トラブルシューティングフロー
- ジョブ失敗 → GitLab UI で
CI_DEBUG_TRACEを有効にし再実行。 - Runner Pod が CrashLoopBackOff →
kubectl describe pod <pod> -n ci-cdとkubectl logsで原因を確認(例: 証明書エラー、リソース不足)。 - Agent の kubeconfig が無効 →
kubectl get nodesを実行し認証エラーが出たら ServiceAccount の RBAC と Secret マウント設定を再チェック。
6. まとめ & 参考リンク
本手順の要点
| 項目 | 実装ポイント |
|---|---|
| 前提条件 | GitLab 16.4+、K8s 1.28+、Ingress/NetworkPolicy の適切な設定 |
| Runner デプロイ | Helm Chart + values.yaml(リソース・affinity・TLS)で再現性確保 |
| Agent 紐付け | Helm でエージェントを導入 → UI で kube‑context を登録 → CI から安全に K8s 操作 |
| シークレット管理 | Protected + Masked 変数、environment 別に分割し漏洩リスク最小化 |
| RBAC・監視 | 最小権限 SA、Role/ClusterRole、Prometheus/Grafana による可観測性 |
参考リンク(2026‑04‑20 時点)
- GitLab Docs – Runner Helm Chart
- GitLab Docs – Agent for Kubernetes
- Helm Repository –
https://charts.gitlab.io - Kubernetes Official – RBAC Authorization
- Prometheus – Scrape Configuration
次のステップ:本リポジトリに
README.mdとして上記手順を掲載し、CI/CD パイプラインが成功したら自動で GitLab の Release を作成するワークフロー(例:semantic-release)を追加すると、運用効率がさらに向上します。