Argo CDを利用してLinode Kubernetes Engine (LKE) の継続的デリバリーを実現する

# はじめに

Kubernetes上でアプリケーションを効果的に運用するためには、アプリケーションの迅速なデプロイと確実なバージョン管理が必要です。これを実現するためには、継続的インテグレーション/継続的デリバリー（Continuous Integration/Continuous Delivery、CI/CD）が不可欠です。
本記事では、GitOpsを実現する1つのツールであるArgo CDを使用し、Akamai Cloud Computing ServicesのLinode Kubernetes Engine (LKE) 上での設定方法を紹介します。

## GitOpsとは

GitOpsは、Weaveworks社が提唱したCI/CDの手法をインフラ管理に適用した運用モデルで、主にKubernetes管理にフォーカスしています。Kubernetesの状態と構成をGitリポジトリ内のコードとして管理し、宣言的に記載することができ、変更を自動的にデプロイすることができます。このアプローチにより、継続的なデリバリーを実現し、アプリケーションの運用をスムーズに行うことができます。

https://www.weave.works/technologies/gitops/

## Argo CDとは
Argo CDはPull型のGitOpsツールで、使いやすいGUIを備えているのが特徴となります。Argo CDはKubernetesからGitへの定期的なポーリングを行うことで差分を検知し、変更を適用します。
Kubernetesクラスター内のアプリケーションのデプロイとバージョン管理を容易に実現することができ、インフラ運用をより効果的かつ効率的に行えるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/90c7bfa5-56ad-041c-f3fe-f8ac0942a64f.png)

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

## Linode Kubernetes Engine (LKE)にArgo CDを構築する

Getting Startedを参考にArgo CDをLKEにインストールします。

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

- Akamai Cloud Managerにログインし、[LKEからクラスターを作成](https://www.linode.com/docs/products/compute/kubernetes/guides/create-cluster/
)します。
- ローカルの端末に[kubectl](https://kubernetes.io/docs/tasks/tools/)をインストールします。
- LKEのkubeconfigをダウンロードし、設定します。(デフォルト設定 ~/.kube/config)

準備が整ったらnamespaceを作成し、Argo CDをインストールします。

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

## Ingressの作成

外部からArgo CDへ接続するために、Ingress Controllerを作成します。

デフォルトの設定ではTLSの終端はargocd-serverとなっているためこれを無効にし、Ingress Controller側でTLSを処理する必要があります。

以下を参考に設定を行います。
本記事ではIngress ControllerにNginxを利用しています。

https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-ssl-termination-at-ingress-controller

argocd-serverのinsecure設定を有効化します。

```
kubectl edit configmap -n argocd argocd-cmd-params-cm
```

Configmapに以下の内容を追記します。

```yaml
apiVersion: v1
data: #追記する
  server.insecure: "true" #追記する
```

Configmapを反映させるためにargocd-serverを再起動します。

```
kubectl rollout restart deploy argocd-server -n argocd
```

Nginx Ingress ControllerのインストールとLet's Encryptで証明書の発行を行います。

手順は下記の記事を参考にしてください。

https://qiita.com/isss802/items/10b031d79c8aadec672d

証明書を作成する際のシークレットはnamespaceを同一にする必要があるため、下記のように各セクションにnamespaceを追記してください。

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: akamai-secret
  namespace: argocd # 設定する
```

証明書が正しく反映されていることを確認します。

```
kubectl get certificate -n argocd
NAME                 READY   SECRET          AGE
argocd-certificate   True    argocd-secret   58m
```

Ingressを作成します。
Argo CDには2つのIngressが必要となります。
- HTTP/HTTPS (UIやAPI用)
- gRPC(CLI用)

まずはHTTP/HTTPS用のIngresの設定を作成します。

```yaml:https-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-http-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    cert-manager.io/cluster-issuer: "letsencrypt-akamai-issuer"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: http
    host: argocd.example.com
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-secret
```

gRPC用のIngressの設定を作成します。

```yaml:grpc-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-grpc-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
    cert-manager.io/cluster-issuer: "letsencrypt-akamai-issuer"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: http
    host: grpc.argocd.example.com
  tls:
  - hosts:
    - grpc.argocd.example.com
    secretName: argocd-secret
```

作成した設定を適用します。

```
kubectl create -f https-ingress.yaml
kubectl create -f grpc-ingress.yaml
```

### 管理コンソールの初期設定

管理コンソールに接続するための初期設定を行います。

Argo CDのCLIをインストールします。

```terminal
brew install argocd
```

管理アカウントの初期パスワードを確認します。

```
argocd admin initial-password -n argocd
```

Argo CD CLIを利用して管理アカウントにログインをします。

```
argocd login grpc.argocd.example.com
WARNING: server certificate had error: tls: failed to verify certificate: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y
Username: admin
Password: 先程取得したパスワード
'admin:login' logged in successfully
```

初期パスワードから変更します。

```
argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
```

初期パスワードが格納されているシークレットを削除します。

```
kubectl --namespace argocd delete secret/argocd-initial-admin-secret
```

`https://argocd.example.com`にアクセスし、管理コンソールが表示されていることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/e551828c-f5f5-c91e-40be-fe73afd59edf.png)



## Arogo CDにサンプルのリポジトリを追加

Githubのプライベートリポジトリに今回サンプルとして構成するNginxのコードをプッシュします。

```yaml:apps/nginx/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: nginx
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host:
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
```

Argo CDからプライベートリポジトリに接続する方法として、本記事ではアクセストークンを発行して接続します。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens

https://argo-cd.readthedocs.io/en/release-1.8/user-guide/private-repositories/

Argo CDのメニューから「Settings」→「Repositories」にてプライベートリポジトリを追加します。
Tokenを発行したUsernameとToken情報をPasswordに入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/54ee02e1-05c4-2156-4138-c98c910e1bc4.png)


## アプリケーションの追加

追加したリポジトリの情報を元にNginxのアプリケーションを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/c930e4a4-4ea6-92a4-e5b3-47297797124d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/3f8c0576-2068-dbb7-37fe-c5c72cc01e03.png)

リポジトリの追加が完了するとSyncが開始され、設定内容がデプロイされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/0d2e4114-ebe7-3f78-c713-181a39622eb1.png)

Githubのプライベートリポジトリに格納してあるコードが自動的に取得され、Nginxの構成がデプロイされていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/3917e4ef-8317-3555-530c-a0ec6ca9ac78.png)

## Webhookの設定

Githubのコードがプッシュされた際に即時に変更を検知できるようにWebhookを設定します。

https://argo-cd.readthedocs.io/en/stable/operator-manual/webhook/

Secretは任意の値になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/a1f615b6-ed68-5b17-6761-094554a861f6.png)

## 自動反映の設定

作成時に自動反映の設定を行っていない場合には、後から修正して自動反映に変更することが可能です。

変更にはArgo CD CLIを利用します。

https://argo-cd.readthedocs.io/en/stable/user-guide/auto_sync/

```
argocd login grpc.argocd.example.com
argocd app set nginx --sync-policy automated
argocd app set nginx --auto-prune
```

## Helm chartの追加

Helm chartを利用する際には、Argo CDのメニューから「Settings」→「Repositories」から追加することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/22f85306-7460-6842-fa13-90ae9cce1a86.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/4e76ad7c-d4c6-efab-10fe-53ed79c9f9af.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/a1be2494-8ca5-ca42-6a7d-c060cf661f07.png)


## 構成の変更

Githubにプッシュしているコードのレプリカ数を変更し、即時反映されるか確認をします。
コードをマージした瞬間にWebhookで通知が行われ、構成に反映されます。

```yaml:apps/nginx/deploy.yaml
  replicas: 6
```

![Monosnap screencast 2023-11-20 13-29-12.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/d7d29764-e8f3-28f9-62f0-1f0ded5c1e66.gif)

コードをプッシュした際には上記のように自動的にKubernetesへの反映が行われます。

# まとめ
Akamai Cloud Computing ServicesのLinode Kubernetes Engine (LKE)にて構築したサービスを運用していくためには、持続的デリバリー（Continuous Integration/Continuous Delivery、CI/CD）の存在が不可欠です。
Argo CDは優れたUIにより複雑なサービスも簡単に可視化することができ、LKEでの運用も改善していくことができます。
ぜひ、LKEを利用した様々なサービスの構築に活用してみてください。


# 関連記事

アカマイ・テクノロジーズ合同会社はQiitaでAkamai Cloud Computing Services関連など開発者向けの記事を掲載しております。

https://qiita.com/xenbase/items/52e2956a64cedc772bd9