ローカルでArgoCDを動かしてみよう

# はじめに
ちょっと勉強がてら、ローカル環境でargoCDを動かしてみます。
githubにクラスタ構成の変更差分をpushし、argoCDを使って実際にローカルのkubernetesクラスタに変更が反映されていることを確認します。
環境構築のためのメモ的な役割のため、中身のコードの解説などは少な目です。気になる方はぜひ調べてみてください！

argoCDを使うにはまずkubernetesクラスタを用意する必要があるらしいので、そこから始めて行こうと思います！

# 環境
- OS
    - Ubuntu 24.04.1 (wsl)
- メモリ
    - 15GB
- argoCD
    - v2.13.1+af54ef8
- Docker Desktop
    - 4.37.1 (178610)

# 本編
## 1.Kubernetesクラスタ作成
では、まず最初にKubernetesクラスタを作成します。
今回は、microk8sを使用してクラスタを構築します（microk8sを使う理由は特にないです）。

### Docker Desktopの設定
まずはDocker Desktopの設定です。
といっても、右上の設定→Kubernetesから「Enable Kubernetes」をonにするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/ddedfe53-0446-85e0-98b9-8547329670be.png)

### microk8sインストール
以下のコマンドでmicrok8sをインストールします。
```
sudo snap install microk8s --classic
```
もし、snapが入っていない場合は、以下のコマンドでsnapをインストールします。
```
sudo apt install snapd
```

### kubectlインストール
以下コマンドを実行して、最新バージョンのkubectlをインストールします。

最新バージョンをダウンロード
```
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
```
ダウンロードしたものをインストール
```
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
```
上記コマンドを実行したディレクトリに`kubectl`というファイルが生成されますが、インストール後に削除しても動作に影響はなさそうです。

インストールが完了したら、以下コマンドで正しくインストールできているか確認しましょう。
```
microk8s status
```
実行結果（初期状態の出力とはちょっとことなるかもです。）
<details>

```
$ microk8s status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dashboard            # (core) The Kubernetes dashboard
    dns                  # (core) CoreDNS
    ha-cluster           # (core) Configure high availability on the current node
    helm                 # (core) Helm - the package manager for Kubernetes
    helm3                # (core) Helm 3 - the package manager for Kubernetes
    hostpath-storage     # (core) Storage class; allocates storage from host directory
    metrics-server       # (core) K8s Metrics Server for API access to service metrics
    storage              # (core) Alias to hostpath-storage add-on, deprecated
  disabled:
    cert-manager         # (core) Cloud native certificate management
    cis-hardening        # (core) Apply CIS K8s hardening
    community            # (core) The community addons repository
    gpu                  # (core) Alias to nvidia add-on
    host-access          # (core) Allow Pods connecting to Host services smoothly
    ingress              # (core) Ingress controller for external access
    kube-ovn             # (core) An advanced network fabric for Kubernetes
    mayastor             # (core) OpenEBS MayaStor
    metallb              # (core) Loadbalancer for your Kubernetes cluster
    minio                # (core) MinIO object storage
    nvidia               # (core) NVIDIA hardware (GPU and network) support
    observability        # (core) A lightweight observability stack for logs, traces and metrics
    prometheus           # (core) Prometheus operator for monitoring and logging
    rbac                 # (core) Role-Based Access Control for authorisation
    registry             # (core) Private image registry exposed on localhost:32000
    rook-ceph            # (core) Distributed Ceph storage using Rook
$

```
</details>

### Kubernetes設定ファイルの作成
local-k8s.yamlというファイル名で、Kubernetesの諸々の設定を記述したファイルを作成します。

私はローカルで作成したイメージを使用したかったので、[こちらのサイト](https://microk8s.io/docs/registry-images)を参考にローカルのkubernetesにイメージを入れました。
そうでない方は、Docker Hub上にあるイメージ名を指定すればよいかと思います。

あとは、Docker Hubに自分で作成したイメージを追加する方法もあるみたいですね。

```
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  ports:
  ## クラスタ外部からアクセスする際のポート
  - nodePort: 31000
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: api
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      labels:
        app: server
    spec:
      containers:
        ## イメージ名を指定
      - image: 何かしらのイメージ（ex. nginx:latest）
        ## ローカルにイメージがある場合は、そこから取得
        imagePullPolicy: IfNotPresent
        name: server
        ## コンテナをrunning状態にするためのおまじない
        ## 通常であれば必要ないです
        command: ['tail', '-f', '/dev/null']
        ports:
        - containerPort: 8080
    　  ## volume周りは設定してなくても大丈夫です。
        volumeMounts:
          - mountPath: コンテナ側のパス
            name: server-volume
      volumes:
        - hostPath:
            path: ホスト側でマウントするパス
          name: server-volume
```

### kubernetesクラスタ作成
では、作成したyamlファイルを元にクラスタを作成します。
以下のコマンドを実行してください。クラスタの作成場所のnamespaceを指定しない場合は、`default`というnamespaceに作成されます。
ローカルで試してみる、くらいであればこれでよいですが、本番で運営する場合は、別のnamespaceを指定するのが良いでしょう。
```
kubectl apply -f local-k8s.yaml
```
実行が完了したら、以下のコマンドでpodが作成されていることを確認します。
```
kubectl get po 
```
```
$ kubectl get po
NAME                  READY   STATUS    RESTARTS   AGE
api-69bd9b484-l99dz   1/1     Running   0          136m
api-69bd9b484-z2m5x   1/1     Running   0          136m
$
```

ここまで完了したら、先ほど作成した`local-k8s.yaml`ファイルをgithub上にあげましょう。

## 2.argoCD
お次はargoCDの構築です。
基本的には、[こちらの公式](https://argo-cd.readthedocs.io/en/stable/getting_started/)を参考にすればいけます。

### argoCDのGUIにログイン
では、まずはargoCDをインストールする前に以下コマンドを実行します。kubernetes内のdnsを有効にする必要があるらしいですね。
```
microk8s enable dns && microk8s stop && microk8s start
```
次に以下コマンドを実行して、argoCDに必要な諸々のpodを作成します。
```
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

以下コマンドで、argoCDのCLIをダウンロード
GUIで操作を行う場合はいらないかもですね。
```
brew install argocd
```

次に、argoCDサーバのタイプをロードバランサーにするため、以下コマンドを実行します。
```
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
```

外部からアクセスするためのポートフォーワーディングを行います。
```
kubectl port-forward svc/argocd-server -n argocd 8080:443
```
これで、argoCDのwebUIにアクセスできるはずです。
[localhost:8080](http://localhost:8080)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/b797e8bf-813b-98ee-e6d2-3576943cdbf0.png)

ユーザ名は`admin`、パスワードは
```
argocd admin initial-password -n argocd
```
で出力されたものを使用すればログインできます。

### argoCDアプリケーション作成
ここからは、argoCDのGUIでアプリケーションを作成します。

まずはgithubリポジトリの設定を行います。
`Settings` -> `Repositories`から`+ CONNECT REPO`をクリックし、必要事項を記入します。
<!--
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/0b650b2b-0583-2709-1ab8-2851af58bbb2.png)
-->

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/27808507-b18f-cf52-6eee-e7e61708a6af.png)

<table>
    <tr>
        <td>Name</td><td>何でもよい</td>
    </tr>
    <tr>
        <td>Project</td><td>default</td>
    </tr>
    <tr>
        <td>Repository URL</td><td>自分で作成したリポジトリを指定</td>
    </tr>
    <tr>
        <td>SSH private key data</td><td>リポジトリでSSH接続するのに必要なsshキーを使用</td>
    </tr>
</table>

入力後、`CONNECT`ボタンを押してステータスが`Successful`になっていたら成功です。

次にいよいよアプリケーションの作成です。
左側のバーにある`Applications`から`+ NEW APP`を押してアプリケーションを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/30d5dc39-b813-5a3f-5e09-dcd225c855f0.png)
![argocd_set_application.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/df086c29-9cd0-246b-326b-8cfae56a8d36.png)


<table>
    <tr>
        <td>Application Name
</td><td>何でもよい</td>
    </tr>
    <tr>
        <td>Project Name
</td><td>default</td>
    </tr>
    <tr>
        <td>Sync Policy</td><td>manual</td>
    </tr>
    <tr>
        <td>Repository URL</td><td>先ほど作成したリポジトリが候補にあるはず</td>
    </tr>
    <tr>
        <td>Path</td><td>最初に作成したlocal-k8s.yamlファイルがあるディレクトリ</td>
    </tr>
    <tr>
        <td>Cluster URL
</td><td>https://kubernetes.default.svcを指定すると、ローカルのクラスタを指定できるっぽいです</td>
    </tr>
    <tr>
        <td>Namespace</td><td>default</td>
    </tr>
</table>

これでアプリが作成できたら、`SYNC`ボタンを押してgithub上のyamlファイルを元にpodを作成します。
こちらの処理には時間がかかるかもしれません。

![argocd_sync_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/68816916-3f6d-a642-8a4a-1cf3fdacf1a2.png)

```
$ kubectl get po
```
```
NAME                   READY   STATUS    RESTARTS      AGE
api-696bff74fb-4zxwf   1/1     Running   2 (20m ago)   18h
api-696bff74fb-wd2fx   1/1     Running   2 (20m ago)   18h
$
```

### githubにマニフェストの変更をPushして、ローカルクラスタに反映

最後に、githubリポジトリにpodの作成数を変更した修正をpushして、argoCDからローカルのクラスタへ変更を反映します。
今回は、作成されるpodの数を4つに変更してみます。

```diff
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
- replicas: 2
+ replicas: 4
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      labels:
        app: server
    spec:
```

上記のような修正をpushし、argoCDのwebUIから`SYNCHRONIZE`ボタンで修正をローカルクラスタに反映します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/f0fdcac6-19fb-09a7-e045-1258cd7e1885.png)
![argocd_sync.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3030828/7ca4b05e-9685-8799-ac2a-5a8ab0e3c9f3.png)

修正前
```
$ kubectl get po
NAME                   READY   STATUS    RESTARTS      AGE
api-696bff74fb-4zxwf   1/1     Running   2 (64m ago)   19h
api-696bff74fb-wd2fx   1/1     Running   2 (64m ago)   19h
$
```
修正後
```
$ kubectl get po
NAME                  READY   STATUS    RESTARTS   AGE
api-69bd9b484-9zkwz   1/1     Running   0          35s
api-69bd9b484-d5xvj   1/1     Running   0          33s
api-69bd9b484-nwzq5   1/1     Running   0          35s
api-69bd9b484-vp88d   1/1     Running   0          33s
$
```
これで、githubのマニフェストを元にローカルクラスタに修正を反映することができました！

# 参考サイト
- [argoCD公式のGetting Started](https://argo-cd.readthedocs.io/en/stable/getting_started/)
- [Kubernetesローカル環境構築](https://qiita.com/k-kano7/items/13558d2de844d2e901a1#3-6-2-deployment)
- [Ubuntuに軽量KubernetesクラスターのMicroK8sをインストールしてKubernetesを体験してみよう](https://qiita.com/yuichi1992_west/items/17f518fed99a3c487507)

# 今後
今回はGUIでargoCDのアプリケーションを作成しましたが、yamlファイルでも管理できるようなので、今度はそちらを使用したいですね。
また、volumeの設定回りがあまりよくわかっていないので、そこの勉強もしたいです！