目次
どうも、ライアンでございます。
この記事では、以下のツールを用いてローカルマシンに「GitOpsワークフロー」を構築する方法を解説します。
- Argo CDサーバーとArgo CD Image Updaterの連携
- 新しいイメージがリポジトリにプッシュされる → Docker Hub → ArgoCD Image Updater → Github → ArgoCD → k8sリソースへ自動デプロイ
- リポジトリに新バージョンのイメージがアップロードされると、Argo CD Image Updaterが自動的にGitブランチのタグを更新し、その変更をトリガーとしてArgo CDがKubernetesリソースの同期・デプロイを自動実行します。
- Argo Rollout
- Argo RolloutsによるBlue/Greenデプロイメントの容易さを実際に検証します。
技術単語
GitOps
- Gitリポジトリをアプリケーションの理想状態の唯一のソースとして利用することで、従来の継続的デプロイメント戦略を短縮する手法。
ArgoCD
- GitリポジトリとKubernetesクラスター間の状態の同期を自動化する、Kubernetes向けのGitOpsツール。
ArgoCD Image updater
- Docker Hubなどのコンテナイメージレジストリから最新のイメージタグを自動的に検知し、Gitリポジトリを更新するツール。
ArgoCD rollout
- デフォルトのRolling Updateよりも安全で制御されたデプロイメント(例:Blue/Green、Canary)を提供する、Kubernetesのコントローラー。
minikube
- ローカルマシン上に単一ノードのKubernetesクラスターを素早く構築・実行するためのツール。
kustomize
- テンプレートを使わずに、ベースとなるYAMLファイルを維持したまま、デプロイされるリソースを環境ごとにカスタマイズできるツール。
前提条件
- ローカル環境構築:Docker, kubectl, minikubeは導入済みです。
- Gitリポジトリ:プライベートなGitHubリポジトリの作成が完了しています。
- コンテナイメージ:Docker Hubリポジトリへのイメージバージョンのアップロードも済んでいます。
ワークフローの概要
Stagingワークフロー
Argo CD Image Updaterは、イメージレジストリ内のタグの変更を常時監視しており、新しいタグが発見されると、その変更を自動的にGitブランチにコミットします。
その後、そのブランチを監視しているArgo CDが、コミットされた変更を検知し、Kubernetesリソースを自動で更新・デプロイします。

Productionワークフロー
これから、Argo Rolloutsの機能を利用して、新しいバージョンへのデプロイを手動Blue/Greenデプロイメントの形式で進めます。

Stagingワークフローの設定
Argo CDサーバーの起動
Minikubeを起動します。(Dockerエンジンが動作している)
minikube start --insecure-registry="registry-1.docker.io"
Argo CDリソースをargocd名前空間にインストールします。
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Argo CD CLIをインストールします。
brew install argocd
ポートフォワードを設定し、Argo CDのUIにアクセス可能にします。
kubectl port-forward svc/argocd-server -n argocd 8080:443
自動生成された初期パスワードを取得します。
argocd admin initial-password -n argocd
ユーザー名 adminと取得したパスワードを使って、CLIからArgo CDサーバーにログインします。
argocd login localhost:8080
パスワードを変更します。
argocd account update-password
これで、先ほど設定した新しい認証情報を使ってArgo CDサーバーのUIにログインできるようになりました。
しかし、その前に、GitHubリポジトリをArgo CDサーバーに接続する必要があります。
UIを使ってGitHubをArgo CDサーバーに接続する
今回はSSH接続を利用するため、まずSSHキーペアを作成します。
ssh-keygen -t ed25519 -C "your_email@example.com"
作成したGitHubのプライベートリポジトリに、作成済みの公開鍵をデプロイキーとして登録します。設定は以下の図の通りにしてください。

次に、作成した秘密鍵をArgo CDサーバーのUI上で認証情報(Credentials)としてGitHubリポジトリに追加します。

アプリケーションのデプロイ準備
Application CRDをデプロイする前に、まず、隔離(アイソレーション)のベストプラクティスに基づき、base、stg、prd環境それぞれに独立した名前空間を作成します。
kubectl create namespace base
kubectl create namespace stg
kubectl create namespace prd
フォルダ構成は以下の通りです。コード全体を確認するには、こちらを押してください。
> tree
.
├── argocd
│ ├── applications
│ │ ├── app_base.yaml
│ │ ├── app_prd.yaml
│ │ └── app_stg.yaml
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ ├── service.yaml
├── configmap
│ └── docker-access
│ └── argocd-img-updater-credentials.yaml
└── env
├── prd
│ ├── rollout.yaml
│ └── service.yaml
└── stg
├── kustomization.yaml
└── replica_count.yaml
ベースとなるリソースなしにオーバーレイをデプロイすることはできないため、まずKustomizeのベースとなるアプリケーションマニフェストを展開します。
Argo CDは「stg」ブランチの変更を監視し、このKubernetesリソースをbase名前空間へ自動的にデプロイします。
app_base.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:<github-url>
targetRevision: stg
path: base
destination:
server: https://kubernetes.default.svc
namespace: base
syncPolicy:
syncOptions:
- CreateNamespace=true
- Validate=true
- PrunePropagationPolicy=foreground
- PruneLast=true
automated:
selfHeal: true
prune: true
allowEmpty: false
アプリケーションマニフェストを適用します。
kubectl apply -f app_base.yaml
ご覧のように、Argo CDは最新のGitブランチへのコミット変更を検知し、Kubernetesリソースへ自動的に同期します。

ArgoCD Image Updaterの設定
Argo CD Image Updaterをインストールします。
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Argo CD Image UpdaterにDockerレジストリへのアクセス権を付与します。認証情報はSecretに安全に保存し、ConfigMapを経由して参照するように設定します。
argocd-img-updater-credentials.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: argocd
data:
registries.conf: |
registries:
- name: Docker Hub
api_url: https://registry-1.docker.io
prefix: docker.io
credentials: secret:argocd/dockerhub-credentials
Docker Hubにログインするための認証情報をKubernetesのSecretとして作成します。
kubectl create secret docker-registry dockerhub-credentials --namespace argocd --docker-server=docker.io --docker-username=<username> --docker-password=<password>
Image Updaterのアノテーションはまだ適用せず、まずはステージング環境にアプリケーションをデプロイします。
これにより、アプリがNginxアプリケーション(イメージ:<dockerhub-url>/nginx-demo:1.0.0)として確実に起動することを確認します。
app_stg.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-stg
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:<github-url>
targetRevision: stg
path: env/stg
destination:
server: https://kubernetes.default.svc
namespace: stg
syncPolicy:
syncOptions:
- CreateNamespace=true
- Validate=true
- PrunePropagationPolicy=foreground
- PruneLast=true
automated:
selfHeal: true
prune: true
allowEmpty: false
マニフェストを適用します。
kubectl apply -f app_stg.yaml

デモ:最新イメージへの自動デプロイを検証
ここからは、実際に最新イメージへの自動デプロイを検証します。
まずは、現在デプロイされているステージングサービスへアクセスできるよう、ポートフォワーディングを使って公開します。
kubectl port-forward svc/myapp-service-stg -n stg 8086:80
初期バージョンである 1.0.0 は、Nginxのイメージです。
❯ kubectl describe deployment myapp-stg -n stg | grep Image
Image: <dockerhub-url>/nginx-demo:1.0.0

Argo CD Image Updaterは、デプロイするイメージタグを決定する際、デフォルトでセマンティックバージョニング(SemVer)戦略を使用します。
ここで、ステージングアプリケーションに以下のアノテーションを追加します。
この設定により、Image Updaterは利用可能なタグの中から数値的に最も新しい(高い)バージョンを選択します。 例えば、現在の1.0.0から、タグ2.0.0に自動的に更新されます。
app_stg.yaml
....
namespace: argocd
annotations:
# image-list: The tag X means the image updater will update the image to the latest version.
argocd-image-updater.argoproj.io/image-list: <dockerhub-url>/nginx-demo:X
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/pull-secret: argocd:dockerhub-credentials
....
更新したマニフェストを再適用します。
kubectl apply -f app_stg.yaml
イメージの更新が成功したかどうかは、主に以下の3つの方法で検証できます。
まず、Image Updater podのログを確認します。
> kubectl get pods -n argocd
> kubectl logs -n argocd argocd-image-updater-57878df448-bxgc8
time="2025-09-23T11:23:22Z" level=info msg="Setting new image to <dockerhub-url>/nginx-demo:2.0.0" alias= application=myapp-stg image_name=<dockerhub-url>/nginx-demo image_tag=1.0.0 registry=
time="2025-09-23T11:23:22Z" level=info msg="Successfully updated image '<dockerhub-url>/nginx-demo:1.0.0' to '<dockerhub-url>/nginx-demo:2.0.0', but pending spec update (dry run=false)" alias= application=myapp-stg image_name= <dockerhub-url>/nginx-demo image_tag=1.0.0 registry=
次は、GitHubリポジトリのコミット履歴を確認します。イメージの更新は自動的にコミットされており、通常、そのファイル名は .argocd-source-<アプリケーション名>.yaml といった形式になっています。

最後に、ブラウザでアクセスして確認します。
以前のNginxのホーム画面が、ご覧の通りApacheのホーム画面に切り替わっていることを確認できます。

以前のコミットへのロールバック手順
Argo CDのUI上では、以下の手順で簡単に前のコミットへロールバックできます。
- 対象のApplication CRDを選択します。
- 画面上部の History and Rollback タブをクリックします。
- ロールバックしたいコミット履歴の右側にある三点リーダー(︙)ボタンを押します。
- 最後に Rollback ボタンを押して実行します。

メモ:以前のコミットにロールバックを実行した場合、自動同期(Auto Sync)は自動的に無効になります。
Productionワークフローの設定
Argo RolloutsではカナリアデプロイやBlue/Greenデプロイなど多様な戦略が提供されていますが、本記事ではBlue/Greenデプロイのみを実行します。
Argo Rolloutsの設定
まず、argo-rollout名前空間にargo-rolloutsコントローラーをインストールします。
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
kubectlのArgo RolloutsプラグインCLIをインストールします。
brew install argoproj/tap/kubectl-argo-rollouts
Rolloutマニフェストの手動デプロイ
ここでは、Argo CDの管理外で、Rolloutマニフェストを手動でデプロイします。
これは、Blue/Green戦略の動作確認のための一時的なデプロイ手順となります。
env/prd/rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-app-rollout
namespace: prd
spec:
replicas: 2
revisionHistoryLimit: 2
selector:
matchLabels:
app: my-app-rollout
template:
metadata:
labels:
app: my-app-rollout
spec:
containers:
- name: my-app-rollout
image: argoproj/rollouts-demo:blue
imagePullPolicy: Always
ports:
- containerPort: 8080
strategy:
blueGreen:
activeService: my-app-active
previewService: my-app-preview
autoPromotionEnabled: false
Rolloutマニフェストを適用します。
kubectl apply -f env/prd/rollout.yaml
Serviceマニフェストのデプロイ
RolloutのBlue/Green戦略に必須となる、preview用とactive用、両方のServiceマニフェストも同様に適用します。
これらのserviceが、デプロイ時にトラフィックの振り分けを担います。
env/prd/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-active
namespace: prd
spec:
selector:
app: my-app-rollout
ports:
- protocol: TCP
port: 8080
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-preview
namespace: prd
spec:
selector:
app: my-app-rollout
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Serviceマニフェストを適用します。
> kubectl apply -f env/prd/service.yaml
service/my-app-active created
service/my-app-preview created
デプロイされたServiceリソースが正しく作成されているか確認します。
❯ kubectl get svc -n prd
NAME TYPE CLUSTER-IP EXTERNAL
-IP PORT(S) AGE
my-app-active ClusterIP 10.109.32.210 <none>
8080/TCP 143m
my-app-preview ClusterIP 10.105.20.40 <none>
8080/TCP 142m
現在のデプロイ状況を可視化するために、ターミナルで以下のコマンドを実行します。
初期状態では、イメージタグは 「blue」 と表示されます。
> kubectl argo rollouts get rollout my-app-rollout -n prd --watch
Name: my-app-rollout
Namespace: prd
Status: ✔ Healthy
Strategy: BlueGreen
Images: argoproj/rollouts-demo:blue (stable, active)
Replicas:
Desired: 2
Current: 2
Updated: 2
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ my-app-rollout Rollout ✔ Healthy 21m
└──# revision:1
└──⧉ my-app-rollout-57bf9c5889 ReplicaSet ✔ Healthy 19m stable,active
├──□ my-app-rollout-57bf9c5889-487gx Pod ✔ Running 19m ready:1/1
└──□ my-app-rollout-57bf9c5889-bzlxs Pod ✔ Running 19m ready:1/1
Rolloutのプレビュー開始
ここから、新しい 「green」 イメージバージョンへのロールアウトを開始し、my-app-previewサービスにルーティングします。
kubectl argo rollouts set image my-app-rollout -n p
rd my-app-rollout=argoproj/rollouts-demo:green
現在、新しい「green」イメージバージョンは一時停止(Pause)状態にあり、previewサービスにのみルーティングされており、active
サービスでは提供されていません。
Name: my-app-rollout
Namespace: prd
Status: ॥ Paused
Message: BlueGreenPause
Strategy: BlueGreen
Images: argoproj/rollouts-demo:blue (stable, active)
argoproj/rollouts-demo:green (preview)
Replicas:
Desired: 2
Current: 4
Updated: 2
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ my-app-rollout Rollout ॥ Paused 104m
├──# revision:2
│ └──⧉ my-app-rollout-f75f67d6d ReplicaSet ✔ Healthy 64m preview
│ ├──□ my-app-rollout-f75f67d6d-552dc Pod ✔ Running 64m ready:1/1
│ └──□ my-app-rollout-f75f67d6d-zggsf Pod ✔ Running 64m ready:1/1
└──# revision:1
└──⧉ my-app-rollout-57bf9c5889 ReplicaSet ✔ Healthy 102m stable,active
├──□ my-app-rollout-57bf9c5889-487gx Pod ✔ Running 102m ready:1/1
└──□ my-app-rollout-57bf9c5889-bzlxs Pod ✔ Running 102m ready:1/1
以下のコマンドを使ってポートフォワーディングを行い、previewサービス経由で新しい「green」イメージバージョンにアクセスできるようにします。
kubectl port-forward svc/my-app-preview -n prd 8082:8080

こちらが、現在デプロイされているアクティブサービスです。初期の 「blue」イメージバージョンがトラフィックを処理している状態を確認できます。
kubectl port-forward svc/my-app-active -n prd 8081:8080

Preview中のRolloutをActiveへ昇格(プロモート)
新しいイメージバージョンを本番環境へ切り替える(プロモート)には、そのトラフィックをmy-app-activeサービスが受け持つようにする必要があります。
この切り替えは、以下のpromoteコマンドで実行できます。
> kubectl argo rollouts promote my-app-rollout -n prd
rollout 'my-app-rollout' promoted
このコマンドの実行により、以前の 「blue」 イメージバージョンのPodリソースも削除されます。
Name: my-app-rollout
Namespace: prd
Status: ✔ Healthy
Strategy: BlueGreen
Images: argoproj/rollouts-demo:green (stable, active)
Replicas:
Desired: 2
Current: 2
Updated: 2
Ready: 2
Available: 2
NAME KIND STATUS AGE INFO
⟳ my-app-rollout Rollout ✔ Healthy 159m
├──# revision:2
│ └──⧉ my-app-rollout-f75f67d6d ReplicaSet ✔ Healthy 119m stable,active
│ ├──□ my-app-rollout-f75f67d6d-552dc Pod ✔ Running 119m ready:1/1
│ └──□ my-app-rollout-f75f67d6d-zggsf Pod ✔ Running 119m ready:1/1
└──# revision:1
└──⧉ my-app-rollout-57bf9c5889 ReplicaSet • ScaledDown 157m
ポートフォワーディングを使って、my-app-activeサービスが更新されたことを確認できます。
kubectl port-forward svc/my-app-active -n prd 8081:8080

学びの要点
このチュートリアルを通して得られた学びの要点は以下の通りです。
- Minikubeの動作環境について: Minikubeを起動するには、DockerやOrbStackといったコンテナドライバーが必須である。
- Argo CDのApplication CRD (カスタムリソース定義)こそが、Gitブランチのディレクトリと、Kubernetesリソースのライブ状態を同期させるための設定そのものである。
- Image Updaterの前提条件: コンテナイメージの自動更新対象とするアプリケーションは、必ずArgo CDによって管理されている必要がある。
- Image Updaterの対応フォーマット: Argo CD Image Updaterがコンテナイメージを更新できるのは、アプリケーションマニフェストがKustomizeまたはHelmによってレンダリングされている場合に限られる。
まとめ
この記事では、Argo CDを使ったGitOpsの基本的な構成について、しっかりとした基礎を固めることができました。
特にArgo CDとImage Updaterは、リソースデプロイを効率化してくれる非常に便利なツールだと実感しています。
ただし、Argo Rollouts自体は強力な高度なデプロイ機能を提供してくれるものの、コアとなるArgo CDのワークフローと統合し、シームレスな更新を実現する点では、少々課題に直面しました。
統合時のつまずきはありましたが、このデバッグの過程こそが最高の学習機会でした。一つ一つ問題を解決していく中で、Argo CDがどのように動作しているのかを深く、実践的に理解できたからです。
GitOpsを体感したい方には、ぜひこのハンズオンでのアプローチを強くお勧めします!

