Skip to content

✍️ 필사 모드: 高度なCI/CDパイプライン構築ガイド — GitHub Actions、ArgoCD、Tekton、セキュリティパイプライン

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに

CI/CDを「コードをプッシュしたら自動でデプロイされるもの」程度に理解している段階を超え、プロダクションレベルのパイプラインとは何かを考えたことがあるだろうか。実際のプロダクション環境では、セキュリティスキャン、静的解析、コンテナイメージ署名、マルチクラスタデプロイ、自動ロールバックまで数十のステージが有機的に連携する必要がある。

本記事では、CI/CD成熟度モデルからGitHub Actionsの高度なパターン、ArgoCD GitOps、Tektonクラウドネイティブパイプライン、DevSecOpsセキュリティパイプライン、デプロイ戦略の深掘りまで包括的に解説する。


1. CI/CD成熟度モデル

組織のCI/CDレベルを客観的に評価するための5段階成熟度モデルである。各レベルは前のレベルの能力の上に構築される。

Level 1 - 手動 (Manual)

ビルドとデプロイを開発者が手動で実行する段階。ローカルでビルドし、FTPやSCPでサーバーに直接デプロイする。「自分のマシンでは動くのに」が日常的に発生し、デプロイサイクルは月単位であることが多い。

特徴: ドキュメント化された手順は存在するかもしれないが、自動化はほとんどない。デプロイ時のヒューマンエラーが頻繁で、ロールバックは前のバージョンを手動で再デプロイする方式である。

Level 2 - 基本自動化 (Basic Automation)

CIサーバーが導入され、コードプッシュ時に自動ビルドとテストが実行される。Jenkins、GitHub Actions、GitLab CIなどのツールを使用するが、パイプラインは単純なビルド-テスト-デプロイの直線構造である。

# Level 2: 基本パイプライン例
name: Basic CI/CD
on:
  push:
    branches: [main]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm test
      - run: npm run build
      - run: ./deploy.sh

Level 3 - 標準化 (Standardized)

パイプラインが組織全体で標準化され、再利用可能なパイプラインテンプレートが存在する。テストカバレッジゲート、コード品質チェック、セキュリティスキャンがデフォルトで含まれる。環境別(dev、staging、prod)のデプロイパイプラインが分離されている。

Level 4 - 高度な自動化 (Advanced Automation)

GitOpsベースの宣言的デプロイ、カナリア/ブルーグリーンデプロイ戦略、自動化されたセキュリティパイプライン(SAST、DAST、コンテナスキャン)、SBOM生成とアーティファクト署名がパイプラインに統合される。デプロイサイクルは日単位以下に短縮される。

Level 5 - 自己修復 (Self-Healing)

メトリクスベースの自動ロールバック、SLO違反時の自動復旧、MLベースの異常検知、プロダクションフィードバックがパイプラインに自動反映される。デプロイが完全に自動化され、開発者がデプロイを意識しない。

レベルデプロイサイクルロールバック方式セキュリティテスト
L1 手動月単位手動再デプロイなし手動
L2 基本週単位手動トリガーなし自動ユニット
L3 標準日単位ワンクリック基本スキャンユニット+結合
L4 高度時間単位自動カナリア全パイプラインユニット+結合+E2E
L5 修復継続的デプロイSLOベース自動継続的検証カオス含む

2. GitHub Actionsの高度なパターン

GitHub Actionsの基本を超える高度なパターンを解説する。

2-1. 再利用可能なワークフロー (Reusable Workflows)

複数のリポジトリで同一のパイプラインロジックを共有するには、再利用可能なワークフローを活用する。呼び出し側ではusesキーワードで外部ワークフローを参照する。

# .github/workflows/reusable-build.yml(共有リポジトリ)
name: Reusable Build
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'
      registry-url:
        required: true
        type: string
    secrets:
      npm-token:
        required: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          registry-url: ${{ inputs.registry-url }}
      - run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.npm-token }}
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/
# 呼び出しワークフロー
name: App CI
on: [push]
jobs:
  call-build:
    uses: my-org/shared-workflows/.github/workflows/reusable-build.yml@v2
    with:
      node-version: '20'
      registry-url: 'https://npm.pkg.github.com'
    secrets:
      npm-token: ${{ secrets.NPM_TOKEN }}

2-2. Composite Actions

一つのアクション内に複数のステップをまとめて再利用するパターンである。再利用可能なワークフローと異なり、単一ジョブのステップとして挿入される。

# .github/actions/setup-and-test/action.yml
name: 'Setup and Test'
description: 'Node.js環境セットアップ後テスト実行'
inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '20'
runs:
  using: 'composite'
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'
    - run: npm ci
      shell: bash
    - run: npm test -- --coverage
      shell: bash
    - uses: actions/upload-artifact@v4
      with:
        name: coverage
        path: coverage/

2-3. マトリクスビルド戦略

複数の環境の組み合わせを並列でテストしつつ、不要な組み合わせを除外する高度なマトリクス設定である。

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [18, 20, 22]
        exclude:
          - os: macos-latest
            node: 18
        include:
          - os: ubuntu-latest
            node: 22
            experimental: true
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.experimental || false }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test

2-4. OIDCによるクラウド認証

長期シークレット(Access Key)の代わりにOIDC(OpenID Connect)トークンを使用してクラウドに安全に認証する方式である。AWS、GCP、Azureすべてに対応している。

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
          aws-region: ap-northeast-1
      - run: aws s3 sync ./dist s3://my-bucket
      - run: aws cloudfront create-invalidation --distribution-id E1234 --paths "/*"

OIDCの最大のメリットはシークレット管理が不要になることである。GitHubが発行した短期トークンをAWS STSが検証し、一時的な認証情報を発行する。トークンはワークフロー実行中のみ有効であり、漏洩しても悪用が困難である。


3. GitOpsとArgoCD

3-1. GitOpsの原則

GitOpsはGitを単一の真実の源(Single Source of Truth)として使用し、インフラストラクチャとアプリケーションの宣言的な状態を管理する運用モデルである。4つのコア原則がある。

宣言的設定: システムの望ましい状態を宣言的に記述する。「何を」望むかを定義し、「どのように」達成するかを命令しない。

Gitを真実の源として: すべての変更はGitを通じて行われ、Git履歴がそのまま監査ログとなる。

自動適用: Gitの宣言的状態が変更されると、自動的にシステムに適用される。

継続的調整: エージェントが実際の状態と望ましい状態を継続的に比較し、差分(ドリフト)を修正する。

3-2. ArgoCDアーキテクチャ

ArgoCDはKubernetes向けの宣言的GitOps継続的デリバリーツールである。

# ArgoCD Applicationリソース
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/k8s-manifests.git
    targetRevision: main
    path: apps/my-app/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

syncPolicy.automatedを設定すると、Gitの変更が自動的にクラスタに反映される。selfHeal: trueは、誰かが手動でクラスタの状態を変更しても、自動的にGitの状態に復元する機能である。

3-3. App of Appsパターン

大規模環境では数十から数百のApplicationを管理する必要がある。App of Appsパターンは、一つのルートApplicationが他のすべてのApplicationを管理する構造である。

# root-app.yaml - 他のApplicationを管理するルート
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/argocd-apps.git
    targetRevision: main
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
# apps/frontend.yaml - ルートが管理する子Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: frontend
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/k8s-manifests.git
    path: apps/frontend/overlays/production
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: frontend

3-4. ApplicationSetによるマルチクラスタデプロイ

ApplicationSetは一つのテンプレートから複数のApplicationを自動生成するArgoCDの機能である。クラスタリスト、Gitディレクトリ、PRイベントなどに基づいて動的に生成する。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-app-set
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
  template:
    metadata:
      name: 'my-app-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/my-org/k8s-manifests.git
        targetRevision: main
        path: 'apps/my-app/overlays/{{metadata.labels.region}}'
      destination:
        server: '{{server}}'
        namespace: my-app

4. Tekton Pipelines

4-1. Tektonとは

TektonはKubernetesネイティブのCI/CDフレームワークである。GitHub ActionsやJenkinsと異なり、パイプラインのすべてのコンポーネントがKubernetesカスタムリソース(CRD)として定義される。各タスクが別々のPodとして実行されるため、完全な分離とスケーラビリティを提供する。

コアコンポーネント:

  • Task: 一つ以上のStepで構成される実行単位。Pod一つにマッピングされる。
  • Pipeline: 複数のTaskを接続したDAG(有向非巡回グラフ)構造のワークフロー。
  • TaskRun / PipelineRun: TaskやPipelineの実行インスタンス。Kubernetesリソースとして追跡可能。
  • Workspace: Task間のデータ共有のためのボリューム。

4-2. Taskの定義

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: build-and-push
spec:
  params:
    - name: image-url
      type: string
    - name: image-tag
      type: string
      default: latest
  workspaces:
    - name: source
  steps:
    - name: build
      image: gcr.io/kaniko-project/executor:latest
      args:
        - --dockerfile=Dockerfile
        - --context=$(workspaces.source.path)
        - --destination=$(params.image-url):$(params.image-tag)
        - --cache=true
        - --cache-ttl=24h

4-3. Pipelineの定義

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: ci-pipeline
spec:
  params:
    - name: repo-url
      type: string
    - name: image-url
      type: string
  workspaces:
    - name: shared-workspace
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: shared-workspace
      params:
        - name: url
          value: $(params.repo-url)

    - name: run-tests
      taskRef:
        name: npm-test
      runAfter:
        - fetch-source
      workspaces:
        - name: source
          workspace: shared-workspace

    - name: build-image
      taskRef:
        name: build-and-push
      runAfter:
        - run-tests
      workspaces:
        - name: source
          workspace: shared-workspace
      params:
        - name: image-url
          value: $(params.image-url)

    - name: security-scan
      taskRef:
        name: trivy-scan
      runAfter:
        - build-image
      params:
        - name: image-url
          value: $(params.image-url)

4-4. PipelineRunで実行

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  generateName: ci-pipeline-run-
spec:
  pipelineRef:
    name: ci-pipeline
  params:
    - name: repo-url
      value: https://github.com/my-org/my-app.git
    - name: image-url
      value: ghcr.io/my-org/my-app
  workspaces:
    - name: shared-workspace
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi

5. セキュリティパイプライン(DevSecOps)

5-1. セキュリティパイプラインの構成要素

プロダクションレベルのセキュリティパイプラインは、以下のステージを自動的に実行する。

ステージツール目的
SAST(静的解析)SonarQube, Semgrep, CodeQLソースコードの脆弱性検出
SCA(依存関係解析)Snyk, Dependabot, OWASP DCOSS依存関係の脆弱性検出
シークレットスキャンGitLeaks, TruffleHogコードに含まれる秘密情報の検出
コンテナスキャンTrivy, Grypeコンテナイメージの脆弱性検出
DAST(動的解析)OWASP ZAP, Nuclei実行中アプリケーションの脆弱性検出
SBOM生成Syft, CycloneDXソフトウェア構成要素リストの生成
アーティファクト署名Cosign, Notationビルドアーティファクトの完全性保証

5-2. SAST - SonarQubeの統合

# GitHub ActionsでのSonarQube解析
name: Security Pipeline
on: [push, pull_request]

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: SonarSource/sonarqube-scan-action@v3
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
        with:
          args: >
            -Dsonar.projectKey=my-project
            -Dsonar.sources=src/
            -Dsonar.tests=tests/
            -Dsonar.coverage.exclusions=**/*.test.ts
      - uses: SonarSource/sonarqube-quality-gate-check@v1
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

5-3. コンテナイメージスキャン - Trivy

  container-scan:
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'ghcr.io/my-org/my-app:latest'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'

TrivyはOSパッケージと言語固有の依存関係の両方をスキャンする。exit-code: '1'を設定すると、CRITICALまたはHIGHの脆弱性が検出された場合にパイプラインが失敗する。

5-4. SBOM生成とCosign署名

SBOM(Software Bill of Materials)はソフトウェアに含まれるすべてのコンポーネントのリストである。米国大統領令14028以降、サプライチェーンセキュリティの必須要素となった。

  sbom-and-sign:
    runs-on: ubuntu-latest
    needs: [container-scan]
    permissions:
      id-token: write
      packages: write
    steps:
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/my-org/my-app:latest
          format: spdx-json
          output-file: sbom.spdx.json

      - name: Install Cosign
        uses: sigstore/cosign-installer@v3

      - name: Sign Container Image
        run: |
          cosign sign --yes \
            ghcr.io/my-org/my-app:latest

      - name: Attach SBOM to Image
        run: |
          cosign attach sbom \
            --sbom sbom.spdx.json \
            ghcr.io/my-org/my-app:latest

CosignはSigstoreプロジェクトの一部で、キーレス(keyless)署名をサポートする。OIDCトークンを使用して、別途の署名鍵管理なしにイメージに署名できる。

5-5. シークレットスキャン - GitLeaks

  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

6. テスト自動化戦略

6-1. テストピラミッド

プロダクションCI/CDでは、テストの種類と比率が重要である。

ユニットテスト(70%): 最も高速で最も多くあるべきテスト。個別の関数、メソッド、コンポーネントを分離テストする。

結合テスト(20%): 複数のモジュールが連携して正しく動作することを検証する。DB、API、メッセージキューなど外部依存関係との相互作用をテストする。

E2Eテスト(10%): ユーザーシナリオを最初から最後まで検証する。最も遅く不安定であるため、コアフローのみテストする。

6-2. 並列テストとテスト分割

大規模テストスイートの実行時間を短縮するための戦略である。

jobs:
  test:
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: Run Tests (Shard ${{ matrix.shard }}/4)
        run: |
          npx jest --shard=${{ matrix.shard }}/4 \
            --ci --coverage --forceExit
      - uses: actions/upload-artifact@v4
        with:
          name: coverage-${{ matrix.shard }}
          path: coverage/

  merge-coverage:
    needs: [test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          pattern: coverage-*
          merge-multiple: true
      - name: Merge Coverage Reports
        run: npx istanbul-merge --out merged-coverage.json coverage-*/coverage-final.json

6-3. Playwright E2Eテスト

  e2e:
    runs-on: ubuntu-latest
    needs: [deploy-staging]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run E2E Tests
        run: npx playwright test --reporter=html
        env:
          BASE_URL: https://staging.my-app.com
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

7. デプロイ戦略の深掘り

7-1. Argo Rolloutsによるカナリアデプロイ

Argo RolloutsはKubernetesで高度なデプロイ戦略を実装するコントローラである。標準のDeploymentを置き換えるRolloutリソースを提供する。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    canary:
      canaryService: my-app-canary
      stableService: my-app-stable
      trafficRouting:
        istio:
          virtualServices:
            - name: my-app-vsvc
              routes:
                - primary
      steps:
        - setWeight: 5
        - pause:
            duration: 5m
        - setWeight: 20
        - pause:
            duration: 5m
        - setWeight: 50
        - pause:
            duration: 10m
        - setWeight: 80
        - pause:
            duration: 5m
      analysis:
        templates:
          - templateName: success-rate
        startingStep: 2
        args:
          - name: service-name
            value: my-app-canary
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ghcr.io/my-org/my-app:v2.0.0
          ports:
            - containerPort: 8080

7-2. AnalysisTemplate - メトリクスベースの自動判断

カナリアデプロイ中にPrometheusメトリクスを照会し、自動的にプロモート(昇格)またはアボート(ロールバック)を判断する。

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 60s
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{
              service="{{args.service-name}}",
              status=~"2.."
            }[5m])) /
            sum(rate(http_requests_total{
              service="{{args.service-name}}"
            }[5m]))

成功率が95%未満の解析が3回連続で発生すると、自動的にロールバックする。これがLevel 5自己修復パイプラインの核心である。

7-3. ブルーグリーンデプロイ

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app-bluegreen
spec:
  replicas: 5
  strategy:
    blueGreen:
      activeService: my-app-active
      previewService: my-app-preview
      autoPromotionEnabled: false
      prePromotionAnalysis:
        templates:
          - templateName: smoke-test
      postPromotionAnalysis:
        templates:
          - templateName: success-rate
      scaleDownDelaySeconds: 300
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ghcr.io/my-org/my-app:v2.0.0

ブルーグリーンデプロイでは、新バージョン(グリーン)が完全に準備された後、トラフィックを一度に切り替える。prePromotionAnalysisで切り替え前にスモークテストを実行し、scaleDownDelaySecondsで旧バージョンを一定時間維持して迅速なロールバックを可能にする。

7-4. トラフィックミラーリング(シャドウトラフィック)

実際のプロダクショントラフィックを新バージョンに複製して実際の負荷でテストするが、新バージョンのレスポンスはユーザーに配信しない方式である。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-app
spec:
  hosts:
    - my-app.example.com
  http:
    - route:
        - destination:
            host: my-app-stable
            port:
              number: 80
      mirror:
        host: my-app-canary
        port:
          number: 80
      mirrorPercentage:
        value: 100.0

8. マルチ環境管理

8-1. 環境構造の設計

プロダクションパイプラインは最低3つの環境を運用する。

  • dev: 開発者のfeatureブランチデプロイ。不安定でも問題ない。
  • staging: mainブランチデプロイ。プロダクションと同一の設定でなければならない。
  • production: 実際のユーザートラフィックを処理する環境。

8-2. Kustomize Overlays

KustomizeはKubernetesマニフェストを環境ごとにカスタマイズするツールである。ベース設定の上に環境別のオーバーレイを適用する。

k8s/
  base/
    deployment.yaml
    service.yaml
    kustomization.yaml
  overlays/
    dev/
      kustomization.yaml
      replica-patch.yaml
    staging/
      kustomization.yaml
      replica-patch.yaml
    production/
      kustomization.yaml
      replica-patch.yaml
      hpa.yaml
# k8s/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml
# k8s/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
  - hpa.yaml
patches:
  - path: replica-patch.yaml
namePrefix: prod-
commonLabels:
  env: production
# k8s/overlays/production/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 5
  template:
    spec:
      containers:
        - name: my-app
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
            limits:
              cpu: 1000m
              memory: 1Gi

8-3. Helm Valuesの環境別管理

# values-dev.yaml
replicaCount: 1
image:
  tag: latest
resources:
  requests:
    cpu: 100m
    memory: 128Mi
ingress:
  host: dev.my-app.internal
autoscaling:
  enabled: false
# values-production.yaml
replicaCount: 5
image:
  tag: v2.0.0
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1000m
    memory: 1Gi
ingress:
  host: my-app.example.com
  tls: true
autoscaling:
  enabled: true
  minReplicas: 5
  maxReplicas: 20
  targetCPU: 70
# 環境ごとのデプロイ
helm upgrade --install my-app ./chart \
  -f values-production.yaml \
  --namespace production \
  --wait --timeout 5m

9. モニタリングとロールバック

9-1. デプロイ後モニタリングチェックリスト

デプロイ直後に確認すべきコアメトリクスである。

即時確認(0〜5分):

  • Podステータス:すべてのPodがRunning/Ready状態か
  • エラーログ:新バージョンで例外が急増していないか
  • ヘルスチェック:readiness/livenessプローブが正常か

短期確認(5〜30分):

  • 応答時間:p50、p95、p99レイテンシが前バージョンと同等か
  • エラー率:5xx比率が閾値以内か
  • スループット:リクエスト処理量が予想範囲内か

中期確認(30分〜数時間):

  • メモリ使用量:メモリリークの兆候がないか
  • CPU使用量:CPU使用が安定しているか
  • ビジネスメトリクス:注文数、コンバージョン率などが正常か

9-2. Prometheusベースの自動ロールバック

# PrometheusRule - 自動ロールバックトリガー
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: deployment-rollback-rules
spec:
  groups:
    - name: deployment-health
      rules:
        - alert: HighErrorRate
          expr: |
            sum(rate(http_requests_total{status=~"5.."}[5m]))
            /
            sum(rate(http_requests_total[5m]))
            > 0.05
          for: 2m
          labels:
            severity: critical
            action: rollback
          annotations:
            summary: "Error rate above 5 percent for 2 minutes"

        - alert: HighLatency
          expr: |
            histogram_quantile(0.99,
              sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
            ) > 2
          for: 3m
          labels:
            severity: critical
            action: rollback
          annotations:
            summary: "p99 latency above 2 seconds for 3 minutes"

9-3. SLOベースのデプロイゲート

サービスレベル目標(SLO)をデプロイ判断の基準として活用する。エラーバジェットが消耗した場合、デプロイを停止する戦略である。

# SLO定義例
apiVersion: sloth.slok.dev/v1
kind: PrometheusServiceLevel
metadata:
  name: my-app-slo
spec:
  service: my-app
  labels:
    team: platform
  slos:
    - name: requests-availability
      objective: 99.9
      sli:
        events:
          errorQuery: sum(rate(http_requests_total{status=~"5.."}[5m]))
          totalQuery: sum(rate(http_requests_total[5m]))
      alerting:
        name: MyAppAvailability
        pageAlert:
          labels:
            severity: critical
        ticketAlert:
          labels:
            severity: warning

エラーバジェットの計算方法は以下の通りである。SLOが99.9%の場合、1ヶ月あたり約43分のダウンタイムが許容される。すでに30分を消耗している場合、残り13分のエラーバジェットではリスクの高いデプロイを進めるべきではない。


10. 実践:プロダクションパイプラインアーキテクチャ

10-1. 全体アーキテクチャ

プロダクションレベルの完全なCI/CDパイプラインは以下の構造を持つ。

開発者コードPush
    |
    v
[CIステージ - GitHub Actions]
    |-- コードチェックアウト
    |-- 依存関係インストール(キャッシュ活用)
    |-- リント + フォーマットチェック
    |-- ユニットテスト(並列4シャード)
    |-- 結合テスト
    |-- SAST(SonarQube)
    |-- シークレットスキャン(GitLeaks)
    |-- 依存関係脆弱性スキャン(Snyk)
    |-- コンテナビルド(Kaniko)
    |-- コンテナスキャン(Trivy)
    |-- SBOM生成(Syft)
    |-- イメージ署名(Cosign)
    |-- イメージレジストリPush
    |
    v
[CDステージ - ArgoCD / GitOps]
    |-- マニフェストリポジトリ自動更新
    |-- ArgoCD同期
    |-- dev環境自動デプロイ
    |-- staging環境自動デプロイ
    |-- E2Eテスト(Playwright)
    |-- DASTOWASP ZAP    |
    v
[プロダクションデプロイ - Argo Rollouts]
    |-- カナリア5%デプロイ
    |-- メトリクス分析(AnalysisTemplate)
    |-- カナリア20%増加
    |-- 再分析
    |-- カナリア50%増加
    |-- 最終分析
    |-- 100%プロモーションまたは自動ロールバック
    |
    v
[モニタリング - Prometheus / Grafana]
    |-- SLOダッシュボード
    |-- エラーバジェット追跡
    |-- 自動ロールバックアラート

10-2. パイプライン最適化のコツ

キャッシュ戦略: 依存関係インストール、Dockerレイヤー、テスト結果をキャッシュすることで、パイプライン時間を50%以上短縮できる。

- uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      node_modules
    key: deps-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      deps-

条件付き実行: 変更されたファイルに応じて関連するタスクのみ実行し、不要なビルドを防止する。

- uses: dorny/paths-filter@v3
  id: changes
  with:
    filters: |
      backend:
        - 'src/api/**'
        - 'src/models/**'
      frontend:
        - 'src/components/**'
        - 'src/pages/**'
      infra:
        - 'terraform/**'
        - 'k8s/**'

並列化: 独立したタスクは並列に実行する。リント、テスト、セキュリティスキャンは相互に依存しないため、同時実行が可能である。

10-3. パイプラインメトリクス

パイプライン自体のパフォーマンスも測定する必要がある。

メトリクス説明目標
Lead Timeコミットからプロダクションデプロイまでの時間1時間以下
デプロイ頻度1日のプロダクションデプロイ回数日10回以上
変更失敗率デプロイ後のロールバック比率5%以下
MTTR障害発生後の復旧時間30分以下
パイプライン実行時間CI全体の所要時間15分以下
テストカバレッジコードカバレッジ比率80%以上

これがDORAメトリクス(Lead Time、デプロイ頻度、変更失敗率、MTTR)の核心である。Eliteレベルのチームはこの4つのメトリクスすべてで最高ランクを達成する。


まとめ

CI/CDパイプラインは単純な自動化ツールではなく、ソフトウェアの品質と開発速度を決定する重要なインフラストラクチャである。本記事で取り上げた内容を要約すると以下の通りである。

  1. 成熟度モデルを基準に現在のレベルを把握せよ。 一度にLevel 5を目指さず、段階的に能力を構築せよ。
  2. 再利用可能なパイプラインを設計せよ。 GitHub Actionsの再利用可能なワークフローとComposite Actionsを活用して、組織全体のパイプラインを標準化せよ。
  3. GitOpsを導入せよ。 ArgoCDなどのツールで宣言的デプロイを実装すれば、監査証跡、自動復旧、一貫性をすべて確保できる。
  4. セキュリティをパイプラインに組み込め。 DevSecOpsは別のステージではなく、パイプラインのすべてのステージにセキュリティが溶け込むことである。
  5. メトリクスベースで意思決定せよ。 SLOとエラーバジェットを活用して、デプロイリスクを定量的に管理せよ。
  6. DORAメトリクスを追跡せよ。 パイプライン自体のパフォーマンスを継続的に改善せよ。

プロダクションレベルのCI/CDは一朝一夕に完成するものではない。しかし、各構成要素を理解し段階的に導入すれば、チームのデプロイ能力は確実に変わるだろう。

현재 단락 (1/816)

CI/CDを「コードをプッシュしたら自動でデプロイされるもの」程度に理解している段階を超え、プロダクションレベルのパイプラインとは何かを考えたことがあるだろうか。実際のプロダクション環境では、セキュリ...

작성 글자: 0원문 글자: 19,194작성 단락: 0/816