Argo CDでKubernetesコンテナ環境のCI/CDに入門！（Oracle Cloud編）

この記事は[OCIアドベントカレンダー](https://qiita.com/advent-calendar/2022/oci)の24日目のエントリーです。
弊社メンバーが他にも記事を書いてくれているので、ぜひ併せてお楽しみください。
- @multilayer：[Autonomous DatabaseのSLAを99.995%にしてみた！](https://zenn.dev/multilayer/articles/9a7f2ad07edb8f)
- @tokidesu：[Autonomous Databaseでマルチデータを扱ってみた](https://qiita.com/tokidesu/items/a1654bf5171511be48fe)


# Argo CDとは
コンテナ利用時のオーケストレーションツールとして人気の高いKubernetes。
そんなプラットフォーム上で利用可能なエコシステムのなかで代表的なCI/CDツールの一つがArgo CDです。

https://argo-cd.readthedocs.io/en/stable/

Argo CDはGitOpsと呼ばれる、Gitで管理されたリポジトリーを中心として継続的な開発＆デリバリーを実現するツールセットの一つです。名前のとおり、CD（デリバリー）に特化しているのでCIには別のツール（例：GitHub Actions）などを組み合わせる必要があります。

CI/CDは抽象的な概念のため、実際にツールを触ってみると格段に理解が深まります。
今回は最近エンプラ界隈で人気上昇中のOracle Cloudを利用してKubernetes環境を準備し、そこで実際にArgo CDを動かしてみることにします。


# 実際に使ってみた

### Kubernetesクラスターの構築

https://oracle-japan.github.io/ocitutorials/cloud-native/oke-for-commons/

OCIアカウントを作成し、OKEコンソールにアクセス。クラスターの作成を実行します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313633333835362f38663465313464302d626665662d323335362d623063322d6162633365643034646537382e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/7e519357-dec2-882b-bc0e-2d9c293992eb.png)

クイック作成で進めます。
ワーカーノードのシェイプは `VM.Standard.E4.Flex` を選択。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313633333835362f38623939353036332d343035342d316637382d313564302d6233373532333137343633352e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/b40555bd-bc4b-068e-eabb-b430eb9e781a.png)

OCIも既にKubernetes 1.24がリリースされているんですね。
クラスターの構築はさすがに時間がかかるので、ガイドにもある通り、先にCloud Shellの設定を進めておきます。右上のターミナルアイコンからCloud Shellを起動。
![screencapture-cloud-oracle-containers-clusters-ocid1-cluster-oc1-ap-tokyo-1-aaaaaaaaxc4jepqcftsg6jxk5xcuxbrkar4ripkxpprp6h6xgcw7ppw2zpia-2022-12-18-15_58_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/bd356629-3385-9918-d3b8-1c154faa107c.png)

先ほど構築したOKEクラスターの設定画面から、Cloud Shellアクセス用の `create-kubeconfig` コマンドをコピペし実行。
![スクリーンショット 2022-12-18 16.04.27a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/44371c2e-fd1a-ea96-f368-8964b7ba5d8c.png)

試しに `get nodes` が通ったら疎通成功です。

```bash
$ kubectl get nodes
NAME          STATUS   ROLES   AGE     VERSION
10.0.10.118   Ready    node    2m56s   v1.24.1
10.0.10.53    Ready    node    2m44s   v1.24.1
10.0.10.64    Ready    node    2m15s   v1.24.1
```


### Argo CDのインストール

CNCF系は公式のGetting Startedが充実しておりありがたいですね。これをみながら進めます。

https://argo-cd.readthedocs.io/en/stable/getting_started/

また、詰まりそうなところはクラメソさんの記事も参照しました。AWSのEKS前提ですがほぼ同じです。

https://dev.classmethod.jp/articles/getting-started-argocd/

まず、以下のコマンドをCloud Shellで実行してOKEクラスター上にArgo CDをデプロイします。

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

次に、クライアントにArgo CD用のCLIをインストールします。
Cloud Shellだとsudoがうまく動かなかったため、手元のMacを利用しました。

```zsh
% brew install argocd
```

完了後はバージョン確認をしておきます。

```zsh
% argocd version  
argocd: v2.5.5+fc3eaec.dirty
  BuildDate: 2022-12-16T18:35:58Z
  GitCommit: fc3eaec6f498ddbe49a5fa9d215a219191fba02f
  GitTreeState: dirty
  GoVersion: go1.19.4
  Compiler: gc
  Platform: darwin/arm64
FATA[0000] Argo CD server address unspecified 
```

次にArgo CDサーバーへの接続を可能にするため、OKEクラスター上で設定変更を行います。
Cloud Shellから以下を実行します。

```bash
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
service/argocd-server patched
```

そしてArgo CDサーバーへのログイン用IPアドレス（External IP）と初期パスワードを確認しておきます。

```bash
$ kubectl get svc argocd-server -n argocd
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                      AGE
argocd-server   LoadBalancer   10.96.218.35   ***.***.***.***   80:31928/TCP,443:32240/TCP   21m

$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
*******
```

試しにMacのChromeで上記IPにアクセスすると、Argo CDのログイン画面にアクセスできました！
![スクリーンショット 2022-12-18 16.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/d9aa1988-daf8-3195-f96b-68b77f339656.png)

先ほど控えたadminユーザーのパスワードでログインも成功。
![スクリーンショット 2022-12-18 16.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/67c12fb4-1284-7b84-4774-f6747647bf4b.png)

### Argo CDで実際にアプリケーションをデプロイしてみる

Getting StartedガイドにGUI版の操作手順も載せてくれているので、GUIを利用してみます。
`New App` ボタンからサンプルアプリのリポジトリーを追加。
（ちなみにアプリ名を日本語で `あいさつ帳` にしようとしたらエラーで怒られたので諦めました）

![スクリーンショット 2022-12-18 16.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/197d5665-6bce-0e87-75ae-d45a7005cb4c.png)

そして　`Sync` ボタンを押すだけでサンプルアプリをデプロイしてくれるようです。
その前に、Cloud Shell上でデプロイ前の`default` ネームスペースの状況を確認しておきます。

```bash
$ kubectl get pods
No resources found in default namespace.

$ kubectl get deployments
No resources found in default namespace.

$ kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP,12250/TCP   52m
```

そしてArgo CDのGUIで `Sync` ボタンをクリック。
![スクリーンショット 2022-12-18 16.50.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/5f43132d-c898-dbb8-9143-7c9187b83b24.png)

ステータスが `Healthy / Synced` になったら、CLoud Shellで再度OKEの状況を確認します。

```bash
$ kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
guestbook-ui-76f97c94c-vlrdn   1/1     Running   0          18s

$ kubectl get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
guestbook-ui   1/1     1            1           27s

$ kubectl get services
NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
guestbook-ui   ClusterIP   10.96.13.21   <none>        80/TCP              13s
kubernetes     ClusterIP   10.96.0.1     <none>        443/TCP,12250/TCP   53m
```

`guestbook-ui` なるアプリの各リソースがデプロイされていますね！
Argo CD上でアプリケーションをクリックすると、各リソースを視覚的に表示してくれます。
![スクリーンショット 2022-12-18 17.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/54bc4031-b4be-f581-9fb4-8f2066c3e075.png)

せっかくなのでサンプルアプリにブラウザからアクセスしてみましょう。
今のままだと `guestbook-ui` サービスにExternal IPが付与されていないので、以下のコマンドをCloud Shellで実行してみます。

```bash
$ kubectl patch svc guestbook-ui -p '{"spec": {"type": "LoadBalancer"}}'
service/guestbook-ui patched

$ kubectl get svc
NAME           TYPE           CLUSTER-IP    EXTERNAL-IP       PORT(S)             AGE
guestbook-ui   LoadBalancer   10.96.13.21   ***.***.***.***   80:32390/TCP        13m
kubernetes     ClusterIP      10.96.0.1     <none>            443/TCP,12250/TCP   66m
```

出現した外部IPにブラウザーでアクセスしてみると、FancyなGuestbookが表示されました！
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313633333835362f33396661336530642d636231662d396434632d663832372d3965323065663739336161652e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/a7877946-0897-1cb8-7699-e20974d824f5.png)


# まとめ

CNCF系のエコシステムは、K8s環境さえあれば簡単にGetting Startedできるのがありがたいですね。
「Conteniuous Delivery」と聞くとなんだか難しそうですが、ようはGitリポジトリーとKubernetesクラスターを紐づけておいて、ワンプッシュでアプリケーションをデプロイできる便利なツールなんだな〜というのがよく分かったと思います。

Oracle Cloudは近年、急速な投資で3大メガクラウドを追いかけていますが、エンプラ色を出しつつもこういったクラウドネイティブな機能もしっかり揃えてくれているのはかなり好印象ですね。
K8s系のOSSはパブリッククラウド製品が変わってもそのまま通用するので、アプリケーション資源の移行性という観点だけでなくエンジニアのスキル観点でもポータビリティが上がりそうです。