ArgoCD実践 - GitOpsでKubernetesデプロイを自動化

中級 | 15分 で読める | 2026.04.24

公式ドキュメント

GitOpsとArgoCD

GitOpsは、Gitリポジトリを唯一の信頼できる情報源(Single Source of Truth)とし、システムの望ましい状態を宣言的に管理する運用モデルです。

GitOpsの原則

  1. 宣言的定義: システムの望ましい状態をGitで管理
  2. バージョン管理: すべての変更をGitコミットとして記録
  3. 自動反映: Gitの状態とクラスタを自動で一致させる
  4. 継続的調整: 差分を検出し自動修復(Self-Healing)

ポイント: ArgoCDはPull型デプロイを採用し、クラスタ内のエージェントがGitを監視します

Push型 vs Pull型デプロイ

方式動作セキュリティ
Push型CI/CDが直接クラスタに書き込む外部にクラスタ認証情報が必要GitHub Actions + kubectl
Pull型クラスタ内エージェントがGitを監視認証情報がクラスタ内で完結ArgoCD, Flux

ArgoCDのインストール

# 名前空間の作成
kubectl create namespace argocd

# ArgoCDのインストール
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# インストール確認
kubectl get pods -n argocd

# 初期パスワードの取得
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# ポートフォワードでUIにアクセス
kubectl port-forward svc/argocd-server -n argocd 8080:443

# ブラウザで https://localhost:8080 を開く
# ユーザー名: admin
# パスワード: 上記コマンドで取得した値

実践メモ: 本番環境ではIngress経由でArgoCDにアクセスし、SSOやRBACを設定します。

Ingress設定

# argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: argocd-server-ingress
 namespace: argocd
 annotations:
 cert-manager.io/cluster-issuer: letsencrypt-prod
 nginx.ingress.kubernetes.io/ssl-passthrough: "true"
 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
 ingressClassName: nginx
 rules:
 - host: argocd.example.com
 http:
 paths:
 - path: /
 pathType: Prefix
 backend:
 service:
 name: argocd-server
 port:
 name: https
 tls:
 - hosts:
 - argocd.example.com
 secretName: argocd-tls

ArgoCD CLI

# CLIのインストール(macOS)
brew install argocd

# Linux
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd

# ログイン
argocd login localhost:8080 --username admin --password <初期パスワード>

# パスワード変更
argocd account update-password

Applicationの作成

最小構成

# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-app
 namespace: argocd
spec:
 # プロジェクト(default or カスタム)
 project: default

 # Gitソース
 source:
 repoURL: https://github.com/example/my-app-manifests.git
 targetRevision: main
 path: kubernetes

 # デプロイ先クラスタ
 destination:
 server: https://kubernetes.default.svc
 namespace: production

 # 同期ポリシー
 syncPolicy:
 automated:
 prune: true # Gitから削除されたリソースを削除
 selfHeal: true # クラスタ側の手動変更を自動修復
 allowEmpty: false
 syncOptions:
 - CreateNamespace=true
 retry:
 limit: 5
 backoff:
 duration: 5s
 factor: 2
 maxDuration: 3m
# Applicationの作成
kubectl apply -f application.yaml

# または CLI経由
argocd app create my-app \
 --repo https://github.com/example/my-app-manifests.git \
 --path kubernetes \
 --dest-server https://kubernetes.default.svc \
 --dest-namespace production \
 --sync-policy automated \
 --auto-prune \
 --self-heal

# アプリケーション一覧
argocd app list

# 詳細確認
argocd app get my-app

# 同期(手動)
argocd app sync my-app

# ロールバック
argocd app rollback my-app 3

注意: automated同期ではprune: trueにするとGitから削除したリソースがクラスタからも削除されます。意図しない削除に注意してください。

Helmチャートのデプロイ

# helm-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-helm-app
 namespace: argocd
spec:
 project: default
 source:
 repoURL: https://github.com/example/helm-charts.git
 targetRevision: main
 path: charts/my-app
 helm:
 # values.yaml上書き
 valueFiles:
 - values-production.yaml
 parameters:
 - name: replicaCount
 value: "5"
 - name: image.tag
 value: "v1.2.3"
 # Helm release name
 releaseName: my-app
 destination:
 server: https://kubernetes.default.svc
 namespace: production
 syncPolicy:
 automated:
 prune: true
 selfHeal: true
 syncOptions:
 - CreateNamespace=true

Kustomizeのデプロイ

# kustomize-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-kustomize-app
 namespace: argocd
spec:
 project: default
 source:
 repoURL: https://github.com/example/kustomize-manifests.git
 targetRevision: main
 path: overlays/production
 kustomize:
 # イメージタグの上書き
 images:
 - myregistry.io/my-app:v1.2.3
 # ネームプレフィックス
 namePrefix: prod-
 # 共通ラベル
 commonLabels:
 env: production
 destination:
 server: https://kubernetes.default.svc
 namespace: production
 syncPolicy:
 automated:
 prune: true
 selfHeal: true

App of Apps パターン

複数のアプリケーションを一元管理するパターン。

# apps/root-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: root-app
 namespace: argocd
spec:
 project: default
 source:
 repoURL: https://github.com/example/argocd-apps.git
 targetRevision: main
 path: apps/production
 destination:
 server: https://kubernetes.default.svc
 namespace: argocd
 syncPolicy:
 automated:
 prune: true
 selfHeal: true
# apps/production/frontend.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: frontend
 namespace: argocd
spec:
 project: default
 source:
 repoURL: https://github.com/example/frontend.git
 targetRevision: main
 path: k8s
 destination:
 server: https://kubernetes.default.svc
 namespace: frontend
 syncPolicy:
 automated:
 prune: true
 selfHeal: true
# apps/production/backend.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: backend
 namespace: argocd
spec:
 project: default
 source:
 repoURL: https://github.com/example/backend.git
 targetRevision: main
 path: k8s
 destination:
 server: https://kubernetes.default.svc
 namespace: backend
 syncPolicy:
 automated:
 prune: true
 selfHeal: true

ポイント: App of Appsパターンでは、ルートアプリが子アプリケーションを管理し、環境ごとにディレクトリを分けます。

プロジェクト管理

# project.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
 name: platform
 namespace: argocd
spec:
 description: Platform team services

 # デプロイ可能なGitリポジトリ
 sourceRepos:
 - https://github.com/example/*

 # デプロイ可能なクラスタと名前空間
 destinations:
 - namespace: '*'
 server: https://kubernetes.default.svc
 - namespace: 'kube-system'
 server: https://prod-cluster.example.com

 # 許可するリソース種別
 clusterResourceWhitelist:
 - group: '*'
 kind: '*'

 # 拒否するリソース種別
 namespaceResourceBlacklist:
 - group: ''
 kind: ResourceQuota
 - group: ''
 kind: LimitRange

 # RBAC
 roles:
 - name: developer
 description: Developer role
 policies:
 - p, proj:platform:developer, applications, get, platform/*, allow
 - p, proj:platform:developer, applications, sync, platform/*, allow
 groups:
 - platform-developers

実践メモ: AppProjectでチームごとにデプロイ権限を分離し、マルチテナント運用を実現できます

Sync Waves と Hooks

Sync Waves

リソースの適用順序を制御します。

# database-secret.yaml
apiVersion: v1
kind: Secret
metadata:
 name: db-credentials
 annotations:
 argocd.argoproj.io/sync-wave: "0" # 最初に適用
stringData:
 username: myapp
 password: YOUR_DB_PASSWORD
# database-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: postgres
 annotations:
 argocd.argoproj.io/sync-wave: "1" # 2番目
spec:
 # ...
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-app
 annotations:
 argocd.argoproj.io/sync-wave: "2" # 最後
spec:
 # ...

Resource Hooks

# db-migration-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
 name: db-migration
 annotations:
 argocd.argoproj.io/hook: PreSync
 argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
 template:
 spec:
 containers:
 - name: migrate
 image: myregistry.io/my-app:v1.2.3
 command: ["npm", "run", "migrate"]
 restartPolicy: Never
Hook実行タイミング
PreSync同期前
Sync通常リソースと同時
PostSync同期後
SyncFail同期失敗時
Skipスキップ

マルチクラスタ管理

# クラスタの登録
argocd cluster add prod-cluster --name production

# クラスタ一覧
argocd cluster list

# Application定義
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-app-prod
spec:
 destination:
 server: https://prod-cluster.example.com # 外部クラスタ
 namespace: production

注意: マルチクラスタ構成では、ArgoCDが各クラスタにServiceAccountを作成します。最小権限の原則に従って設定してください

Notification設定

# argocd-notifications-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
 name: argocd-notifications-cm
 namespace: argocd
data:
 service.slack: |
 token: $slack-token
 template.app-deployed: |
 message: |
 Application {{.app.metadata.name}} is now running version {{.app.status.sync.revision}}.
 slack:
 attachments: |
 [{
 "title": "{{.app.metadata.name}}",
 "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
 "color": "#18be52",
 "fields": [{
 "title": "Sync Status",
 "value": "{{.app.status.sync.status}}",
 "short": true
 }, {
 "title": "Repository",
 "value": "{{.app.spec.source.repoURL}}",
 "short": true
 }]
 }]
 trigger.on-deployed: |
 - when: app.status.operationState.phase in ['Succeeded']
 send: [app-deployed]
# Application with notification
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-app
 annotations:
 notifications.argoproj.io/subscribe.on-deployed.slack: platform-alerts

Image Updater

# Image Updaterのインストール
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
# Application with image auto-update
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
 name: my-app
 annotations:
 argocd-image-updater.argoproj.io/image-list: myapp=myregistry.io/my-app
 argocd-image-updater.argoproj.io/myapp.update-strategy: semver
 argocd-image-updater.argoproj.io/myapp.allow-tags: regexp:^v[0-9]+\.[0-9]+\.[0-9]+$
 argocd-image-updater.argoproj.io/write-back-method: git
spec:
 source:
 repoURL: https://github.com/example/my-app-manifests.git
 targetRevision: main
 path: k8s
 kustomize:
 images:
 - myregistry.io/my-app:v1.0.0 # Image Updaterが自動更新

ポイント: Image Updaterはコンテナレジストリを監視し、新しいタグを検出すると自動的にGitリポジトリとArgoCDを更新します。

まとめ

この記事では、手順を追って動かしながら重要な確認ポイントを押さえることが大切です。まずは学習用の最小構成で動作確認し、本番利用する前にセキュリティ、権限、エラー処理、運用手順を見直してください。

参考リソース

  • 公式ドキュメント - ArgoCD実践 - GitOpsでKubernetesデプロイを自動化 を確認するための一次情報

関連記事

← 一覧に戻る
PR
PR
PR
PR