【Argo CD】Kubernetesにおける継続的デリバリーの実現

# はじめに

近年、バグの早期発見やデプロイ作業の効率化を目的としてソフトウェア開発にCI/CDを取り入れることが多くなっています。
この記事ではCI/CDの内、CDの一部分を実現する**Argo CD**を使用したKubernetesにおける継続的デリバリーの実現について紹介します。

# CI/CDとは

CI/CDとは「Continuous Integration／Continuous Delivery」の略で、日本語では継続的インティグレーション／継続的デリバリーといいます。CI/CDは1つの技術を指すものでなく、ソフトウェアの変更を常にテストして自動で本番環境にリリース可能な状態にしておく、ソフトウェア開発の手法を意味します。CI/CDを取り入れると、バグを素早く発見したり、変更を自動でリリースしたりできるようになり、開発効率が大幅に向上することが期待できます。

# Argo CDとは

Kubernetes向けの継続的デリバリーツールとしては、Spinnakerや Jenkins Xなどが有名です。 これらのツールは継続的デリバリーのパイプラインを統合的に管理・実行するためのツールになっています。

一方の[Argo CD](https://argoproj.github.io/argo-cd/getting_started/)は、パイプライン全体を管理するのではなくパイプラインの中の1つの処理として動くコンポーネントになります。 このようなツールは継続的デリバリーコンポーネントと呼ばれることもあります。

![1_0MpcMgFb4hkcqXtflGSYNQ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/a970dfcf-ce7f-0fd6-9a03-bfd4bb1d0758.png)

([Introducing Argo CD — Declarative Continuous Delivery for Kubernetes](https://blog.argoproj.io/introducing-argo-cd-declarative-continuous-delivery-for-kubernetes-da2a73a780cd)より引用)

上図のように、開発者がアプリケーションのコードをGitリポジトリにPushすると、CIツールによってビルドされ、 コンテナイメージがコンテナリポジトリに登録されます。 そしてアプリケーションをデプロイするための設定(マニフェストファイル)をGitリポジトリにPushすると、 Argo CDはそのマニフェストを自動的にKubernetesクラスタに適用します。

このようにGitリポジトリに登録されている設定に基づいてデプロイする手法を GitOpsと呼びます。

今回Argo CDに焦点を当てた理由としては以下の２点です。

- 学習コストが低い
- GUIで操作可能でリソースを可視化できる

# 実際に使ってみる

以下の環境で実際にArgo CDを試してみました。Kubernetesはdocker-desktopを使用しています。

- Mac OS Catalina 10.15.2
- Kubernetes v1.15.5

## Argo CDのインストール

以下のコマンドでArgo CDをインストールする。

```shell
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

## Argo CD CLIのダウンロード

Argo CDのCLIをダウンロードする。

```shell
brew tap argoproj/tap
brew install argoproj/tap/argocd
```

## Argo CD APIサーバーへのアクセス

デフォルトでは、Argo CD APIサーバーは外部IPで公開されていません。以下の方法でArgo CD APIサーバーにアクセスできるようにします。

```shell
$ kubectl port-forward svc/argocd-server -n argocd 8080:443
```

フォアグラウンドで実行すると他のコマンドを実行できないので、もう一つターミナルを起動するか、バックグラウンドで実行してください。

## CLIを使用したログイン

初期パスワードは、Argo CD APIサーバーのポッド名になるように自動生成されます。次のコマンドで取得できます。

```shell
$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
```

ユーザー名adminと上記のパスワードを使用して、Argo CDのIPまたはホスト名にログインします。

```shell
$ argocd login localhost:8080
```

次のコマンドを使用してパスワードを変更します。

```shell
$ argocd account update-password
```

## Gitリポジトリからアプリケーションを作成する

ブラウザでArgo CDの外部UIを開き、前手順で設定した資格情報を使用してログインします。
ここまでの手順通りに実行していれば以下のURLからアクセスできます。
https://localhost:8080

<img width="1280" alt="スクリーンショット 2020-03-01 18.01.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/45db52c7-69fe-e867-6221-d410059be191.png">

ログイン後、以下に示すように[**+ NEW APP**]ボタンをクリックします。

<img width="1280" alt="スクリーンショット 2020-03-01 18.03.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/1163a9fd-356d-e6f8-66f4-822cc861db0b.png">

各種設定項目を入力していきます。

<img width="1280" alt="スクリーンショット 2020-03-01 18.05.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/fef70b05-f70d-428b-08f5-cf9dfb89e00d.png">

<img width="1280" alt="スクリーンショット 2020-03-01 18.05.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/699be854-0cc4-2351-0c9a-0a456fc7e9fb.png">

入力後、[**CREATE**]ボタンをクリックします。

Applicationページに追加したアプリケーションが表示されます。

<img width="1280" alt="スクリーンショット 2020-03-01 18.08.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/12491d8c-aca8-1662-6060-4062a7972ba6.png">

中身はこんな感じ

<img width="1280" alt="スクリーンショット 2020-03-01 18.09.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/a0e542f0-a95a-62ab-0ccc-3bdba41c6e50.png">

# CDを体感する

Argo CDで管理するアプリケーションの初期状態はこんな感じです。

<img width="1280" alt="スクリーンショット 2020-03-01 17.04.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/972aa45b-824b-6f18-f0ce-228be904b9ba.png">

ヘッダーの部分に**v1**と記載されています。

ここで、アプリケーションのhtmlファイルを編集し、**v1**を**v2**にします。
イメージをビルドし直し、アプリケーションのマニフェストファイルが参照しているレジストリにtagを変更してPushします。
それに合わせてマニフェストファイルのイメージのtagを変更し、git pushします。
２、３分後にもう一度アプリケーションにアクセスしてみると、、、

<img width="1280" alt="スクリーンショット 2020-03-01 17.36.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507052/74de9503-18d7-e0ad-d7a9-8d28dc9e332c.png">

しっかりと変更が反映されてました！
Gitリポジトリの内容を自動で反映してくれるのでKubernetesサーバー上でマニフェストファイルを持つ必要がなくなりますし、何よりkubectlコマンドを実行する必要がなくなります！
これにより、

1. アプリケーションを更新し、コードをGitリポジトリにPush
2. Dockerfileをビルドし、新しいtagを付与してコンテナレジストリにPush
3. 新しいtagのイメージをpullするように変更したマニフェストファイルをgitリポジトリにPush
4. テスト環境にGitリポジトリからPull
5. マニフェストファイルを適用

のような感じでデプロイ作業を行っていたところを4,5の作業をしなくて済みます。（本番環境への自動デプロイはさすがに危険か...、顧客や責任者の承認フロー等が必要かも）

# おわりに

この記事では、Argo CDを使ってGitリポジトリにPushされたマニフェストファイルを自動的にKubernetesクラスタ上のリソースに適用するということを行いました。Argo CD以外にも多くのCDツールがあるので、是非試してみてください。
また、本来ならアプリケーションコードをGitリポジトリにPushした時点からDockerfileのビルド、コンテナレジストリへのPush、マニフェストファイルの更新までの工程も自動で行いたいところです。
時間があったら残りの工程の自動化も行って、完全なCI/CD(Continuous Integration／Continuous Delivery)を実現させたいです。