📝 はじめに
もう、夏ですね。皆さんは夏休みはどう過ごしますか。
僕は富良野に行く予定です✈ ラベンダー見てきます🌼
さて、半年ぶりの投稿ですが
今回のテーマは『CI/CD』です。
さまざまな業務を経験する中で、インフラ周りを見る機会もあり、開発エンジニアといえどもCI/CDは押さえておいて損はないなと思いました。
この記事では、CIとCDを分離したGitOps構成の基本を紹介し、Kubernetes環境にアプリを自動デプロイするまでの流れを解説します。(初学者のため、誤りがありましたらご指摘くださいmm)
「GitOpsってなに?」「GitHub ActionsやArgo CDって難しそう」と感じている方でも取り組みやすいように、図や具体例を交えたシンプルな構成で紹介していきます。
🎯 対象読者
- CI/CDについて知りたい方
- GitHub Actions, ArgoCD使ってみたい方
- 通りすがりの方
🔍GitOpsとは?
そもそも、GitOpsやCI/CDってなんなのって話ですよね
🧠 GitOpsの基本概念
**GitOps(Git Operations)**とは、*「インフラやアプリケーションの運用をすべてGitで管理し、自動化する手法」*です。
簡単に言うと、GitHub使ってボタンポチーで作成したアプリを自動で更新してくれるっていう仕組みです
以下の3つがキーワードになります:
-
宣言的(Declarative)
Kubernetesのように「最終的にこうなっていてほしい状態」をマニフェストで記述し、それをGitに保存します。 -
プル型(Pull-based)
デプロイのトリガーは人間が「kubectl apply
」などで手動で叩くのではなく、Argo CDなどのツールがGitを監視して取りに行くのが特徴です。 -
監査性(Auditability)
全ての変更はGitの履歴に残るため、**「いつ・誰が・何を変更したか」**が明確です。
→ 本番環境に何か起きたときも、git logを追えば状況が見えるようになります。
🔧 CIとCDの違い
GitOpsでは、CIとCDの役割を明確に分離します。
項目 | CI(Continuous Integration) | CD(Continuous Delivery/Deployment) |
---|---|---|
主な役割 | アプリケーションのビルド・テスト | マニフェストに従って環境へ反映 |
トリガー | ソースコードの変更(例: PR) | マニフェストの変更(例: image tag更新) |
実行場所 | GitHub Actions, CircleCIなど | Argo CD, Fluxなど |
CIでアプリをビルド&Dockerイメージをpushし、CDはそれをGit上のマニフェストに反映された変更を検知してデプロイします。
💡 なぜGitOpsが注目されているのか?
✅ 運用の再現性が高い
すべてがGit上にあるので、「このブランチを使えば staging 環境を再現できる」といったことが容易にできます。
✅ チーム運用に向いている
Gitのプルリク・レビュー・ログといったチーム開発で馴染みのあるワークフローをそのまま運用にも活かせます。
✅ 人的ミスを減らせる
kubectl
やhelm upgrade
といった手動操作は極力排除できるため、ヒューマンエラーの防止にもつながります。
✅ セキュリティ・監査面でも強い
Gitベースなので監査証跡が明確。誰がいつ本番に反映させたかが追跡可能です。
🛠 使用ツールと構成概要
今回のGitOps構成では、以下のツールを使用しています。
ツール | 役割 |
---|---|
GitHub Actions | アプリケーションのビルド・Dockerイメージのpush・マニフェストのイメージタグ更新を行うCIツール |
Argo CD | Gitリポジトリを監視し、Kubernetesにマニフェストを適用するCDツール |
Kubernetes | アプリケーションを動かすKubernetesクラスタ(今回はRancher Desktopを使用) |
GitHub (リポジトリ2種) | アプリケーション用(コードとCI)/ マニフェスト用(Kubernetes YAML管理) |
構成図
サンプル
実際に作成したリポジトリです
🚧 実装ステップ
本章では、GitHub Actions × Argo CD を使った GitOps構成を組むまでのステップを大きく3つに分けて紹介します。
✅ Step 1: アプリケーションリポジトリの準備(CI)
まずはアプリケーションのソースコードを GitHub にpushし、GitHub Actionsで以下を自動化します:
- Docker イメージのビルド
- GHCR(GitHub Container Registry)などへのpush
- manifest リポジトリの image: タグを更新して commit & push
今回、アプリケーションはSpring Bootアプリケーションにしています。
✅ Step 2: マニフェストリポジトリの準備(CD)
GitHub Actions から渡されたタグ付きイメージを使って、Kubernetes にデプロイするためのマニフェストを整備します。
📄 deployment.yaml の例
apiVersion: apps/v1
kind: Deployment
metadata:
name: cicd-study-service
spec:
replicas: 1
selector:
matchLabels:
app: cicd-study-service
template:
metadata:
labels:
app: cicd-study-service
spec:
containers:
- name: app
image: ghcr.io/matcha2smiley/cicd-study-service:8c1dbe4f47da43e5d339f79fb017deac3253dec4 # ← ここをCIで書き換える
ports:
- containerPort: 8080
✅ Step 3: Argo CD の設定
Argo CD にマニフェストリポジトリを登録し、GitOpsによる自動同期を有効化します。
💻 CLIでApp作成(UIでも可)
argocd app create your-app \
--repo https://github.com/your-org/manifest-repo.git \ # ここはご自身のリポジトリに設定してください
--path k8s \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--sync-policy automated
- --sync-policy automated を指定すると Git 差分を検知して自動で apply
🚀 ここまでで完成!
-
git push
でアプリのDockerイメージをビルド&push -
manifest
リポジトリのimage:
を自動で更新 - Argo CD が差分を検知して Kubernetes に apply
- Kubernetes がその image を pull してPodを立ち上げ
という一連の GitOps フローが自動化されます。
🧪 実際に動かしてみた
構成が一通りそろったところで、実際に GitHub にコードを push し、CI/CD の一連の流れが動作するかを検証してみました。
✅ 1. GitHub Actionsのワークフローを手動実行する(設定によってはpushでトリガーも可能)
- Docker イメージをビルド
- ghcr.io にイメージを push
- manifest リポジトリの image: タグを ${{ github.sha }} に書き換えて commit & push
「Actions から手動実行した画面」
CIは特に詰まることもなく動作し、GitHub Actions のログでも docker push まで確認できました。
✅ 2. Argo CD がマニフェスト変更を検知
マニフェストリポジトリの deployment.yaml
が更新されたことで、Argo CD が差分を検知。
- Argo CD UI 上ではステータスが OutOfSync に
- 自動同期(Auto Sync)を ON にしていたため、そのまま apply が実行されました
しっかりとCIで更新されたimage-tagに変わっていました。
✅ 3. Kubernetes に自動反映
Argo CD による apply によって、Deployment の image:
が更新され、新しい Pod が起動しました。
✅ 4. Argo CD の状態も「Synced」に
全てのリソースが Git の定義と一致したため、Argo CD 上のステータスも Synced になり、デプロイが完了したことを視覚的に確認できました。
⚠️ ハマりポイント・Tips
GitHub Actions × Argo CD を使った GitOps 構成は、慣れれば快適ですが、最初はいくつかつまずきやすいポイントもありました。ここでは実際にハマった or 注意したほうがよい点を紹介します。
🔐 1. GitHub Actions の Docker push 権限設定
GitHub Container Registry(ghcr)に push するには、docker login
が必要です。
echo ${{ secrets.GHCR_PAT }} | docker login ghcr.io -u USERNAME --password-stdin
GITHUB_TOKEN
はスコープが限定的なため、push
に失敗する場合があります。代わりに、GHCR_PAT
(GitHub Container Registry用のパーソナルアクセストークン)を使うのが確実です。
スコープには write:packages
, read:packages
, repo
を付けておくと安心
🔁 2. Argo CD が差分を検知しない?
これは自分の見落としだったのですが、CIにイメージタグを更新するjobを入れていなかったためにmanifestに差分が生じなかったことで起きてしまいました。
🕹 3. Argo CD の UI操作が便利
CLI だけでやろうとすると意外と見落としやすいですが、UI からの状態確認・手動同期・差分表示は非常に強力です。
CLI でも同様のことはできますが、初回は UI を併用する方がトラブルに気づきやすいです。
🎯 おまけ:ディレクトリ構成のベストプラクティス
マニフェストリポジトリの構成をシンプルに保つコツ:
📁 manifests/
├── base/
│ ├── deployment.yaml
│ └── service.yaml
├── overlays/
│ ├── dev/
│ └── prod/
-
kustomize
を使って環境分離しておくと、後々の本番運用でも困りません
✅ まとめ
本記事では、GitHub Actions と Argo CD を使って、GitOps の基本構成を構築・動作させるまでの流れを紹介しました。
特に意識したポイントは以下の3点です:
- CIとCDを明確に分離し、役割を整理すること
- Gitを使って、すべての状態を管理すること
- Argo CDを使ってKubernetesとの同期を自動化すること
シンプルな構成ではありますが、実際に自分で構築してみることで、CI/CDの自動化やGitOpsの思想が「概念」から「実感」に変わった気がします。
✍️ 感想
- Argo CD の UI や差分検知は非常に便利で、手動運用からの脱却感がすごい
- GitHub Actions との連携もスムーズで、Gitを中心に据えた開発・運用フローの強みを体感できました
- 概念としてはふわっと理解していたGitOpsでしたが、実際に構築してみたことで「なるほど、こうやって運用されるのか」という実感が得られました。
- 生成AI最高!!
🔮 今後やってみたいこと
- kustomize や Helm を使った環境ごとの構成分離
- Argo CD ApplicationSet で複数アプリの一元管理
- Alertmanager や Slack連携などの運用監視連携
- Argo Rolloutsを使ったカナリアリリースの実装
※本記事は筆者個人の見解であり、所属企業の公式見解ではありません。