こんにちは、テクマトリックスの酒井です。
前回の記事では minikube と Argo CD を利用して、ローカル環境でコンテナを Kubernetes クラスターにデプロイする仕組みを構築しました。今回はこの環境で、ローカルの Kubernetes クラスターにアプリケーションをデプロイしてみます。
目次
振り返りとこれからやること
これまでに、ローカル PC に Kubernetes クラスターを作成することから始め、 Gitea を利用した Git リポジトリの作成、 Jenkins と Kaniko を利用してコンテナイメージをビルドする CI 環境の構築、Argo CD を利用して Kubernetes クラスター上にアプリケーションをデプロイする仕組みの構築を行ってきました。
今回は、 CI 環境でコンテナイメージがビルドされたと仮定して、アプリケーションをデプロイする仕組みを利用してコンテナイメージを Kubernetes クラスターで実行してみます。
以上を図にすると次のようになります。
構成
前回の記事で構築したローカル PC 上の Kubernetes クラスターにウェブサーバーをデプロイします。ウェブサーバーとして、 Docker Hub にある digitalocean/flask-helloworld
イメージを利用します。このイメージは、アクセスすると単に「Hello, World!」と表示するだけのウェブサーバーです。これに伴い、 Kubernetes 上のコンテナレジストリの代わりに Docker Hub を利用します。
ウェブサーバーをデプロイする方法は、話を単純にするために YAML 形式の Kubernetes マニフェストを作成することにします。マニフェストファイルを保存する Gitea のリポジトリを用意し、 Argo CD でこのリポジトリを参照するアプリケーションを作成します。これにより、マニフェストファイルを Gitea のリポジトリにプッシュすると、ウェブサーバーが Kubernetes クラスターにデプロイされます。
デプロイ用 Git リポジトリを作成
まずは Kubernetes マニフェストを保存する Git リポジトリを作成します。アプリケーション本体のソースコードや Dockerfile
などを保存するリポジトリと区別するため、今回作成するリポジトリを「デプロイ用 Git リポジトリ」と呼ぶことにします。 Windows Powershell にて次のスクリプトを実行します。
$RepoName = 'flask-helloworld' # リポジトリ名
$GiteaDomain = "git.$(minikube ip).nip.io" # Gitea のドメイン
$GiteaUsername = 'gitea_admin' # Gitea の初期ユーザー名
$GiteaPassword = 'r8sA8CPHD9!bt6d' # Gitea の初期ユーザーのパスワード
# Gitea API にアクセスするための認証情報
$Headers = @{ Authorization = "Basic "+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("${GiteaUsername}:${GiteaPassword}")) }
# リポジトリ flask-helloworld を作成。 README を自動生成
$Repo = Invoke-RestMethod -Method 'POST' `
-Uri "http://${GiteaDomain}/api/v1/user/repos" `
-Headers ${Headers} `
-ContentType 'application/json' `
-Body $(ConvertTo-Json @{ name = ${RepoName}; auto_init = $True })
echo ('クローン URL: ' + $Repo.clone_url)
リポジトリが作成できたら、このリポジトリをクローンします。
git clone $Repo.clone_url
cd $RepoName
Kubernetes マニフェストファイルを作成
クローンしたディレクトリに、デプロイメントを定義するマニフェストファイル flask-deployment.yaml
を作成します。このファイルの内容は以下のとおりです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-dep
labels:
app: flask-helloworld
spec:
replicas: 2
selector:
matchLabels:
app: flask-helloworld
template:
metadata:
labels:
app: flask-helloworld
spec:
containers:
- name: flask
image: digitalocean/flask-helloworld:latest
ports:
- containerPort: 5000
もう一つ、サービスのマニフェストファイル flask-service.yaml
を作成します。
apiVersion: v1
kind: Service
metadata:
name: flask-svc
labels:
app: flask-helloworld
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 5000
protocol: TCP
selector:
app: flask-helloworld
なお、上記の 2 つの YAML ファイルの内容は、コンテナイメージのドキュメントに記載の GitHub リポジトリの k8s
ディレクトリに保存されているものと同一です。
必要なファイルを作成したので、これらをコミット、プッシュします。
# ファイルを追加
git add .
# 変更をコミット
git commit -m 'デプロイメントとサービスを追加'
# コミットを Gitea のリポジトリにプッシュ
git push
# ユーザー名 (gitea_admin) とパスワードを入力
Argo CD にアプリケーションを追加
続いて、 Argo CD にて flask-helloworld
アプリケーションを追加します。前回の記事では GUI を操作して追加しましたが、今回は argocd
CLI を利用して追加してみます。 Windows Powershell で 1 つのコマンドを実行するだけです。
argocd app create flask-helloworld `
--repo "http://${GiteaDomain}/gitea_admin/flask-helloworld.git" `
--path . `
--dest-server https://kubernetes.default.svc `
--dest-namespace flask-helloworld `
--sync-policy automated `
--sync-option CreateNamespace=true
コマンドが完了するとすぐに Argo CD の GUI に flask-helloworld
アプリケーションが表示され、まもなくステータスが Progressing Synced
になりました。
APP HEALTH がいつまでも Progressing
のままなのが気になりますが、変わる気配がありませんし実害もなさそうなので、先に進みます。
GitOps してみる
ウェブサーバーはデプロイされたようですが、今の状態ではブラウザからウェブサーバーにアクセスできないため確認できません。そこでイングレスを追加してブラウザからアクセスできるようにします。
イングレスを追加するには、デプロイ用 Git リポジトリに flask-ingress.yaml
を追加します。ファイルの内容は次のとおりですが、 ${IPADDR}
は VM の IP アドレスに置き換えます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: flask-helloworld
namespace: flask-helloworld
spec:
rules:
- host: helloworld.${IPADDR}.nip.io
http:
paths:
- backend:
service:
name: flask-svc
port:
number: 80
path: /
pathType: Prefix
そしてファイルの追加をコミット・プッシュします。
# ファイルを追加
git add .
# 変更をコミット
git commit -m 'イングレスを追加'
# コミットを Gitea のリポジトリにプッシュ
git push
ブラウザで flask-helloworld
アプリケーションを見ていると、少し時間を置いて flask-helloworld
イングレスが追加され、アプリケーションのステータスが Synced
に変わります。
イングレス、または、一番左にあるアプリケーションに、右上向きの矢印アイコンが表示されています。このアイコンをクリックすると、新しいタブで「Hello, World!」と表示されます。これでGitOpsができていることが確認できました!
まとめ
ローカル環境の Kubernetes クラスターで Argo CD を利用して GitOps を体験しました。 Argo CD を利用することで、どうやってデプロイするかを気にする必要がなくなるため、 Git にプッシュすると環境が変わるという仕組みを簡単に構築でき、アプリケーションを簡単かつスムーズにデプロイできたと感じました。
今回はデプロイ用 Git リポジトリに YAML 形式の Kubernetes のマニフェストファイルを保存しました。いずれ Kubernetes に慣れてきたら、代わりに Kustomization ファイルや Helm チャートを作成しても良いと思います。
今回試した GitOps をコンテナイメージの CI 環境と組み合わせると、コンテナイメージがビルドされたら Kubernetes のマニフェストファイルを更新してテスト環境を作成することもできるでしょう。さらにエンドツーエンドテストを実行して、すべてのテストが成功したら……といったように、デリバリーパイプラインの自動化の範囲を広げ、開発とテストの効率をより高めることができそうです。