EKS × ArgoCD で GitOps の最小構成を構築してみた【初心者向け・ハンズオン

目次

はじめに

EKS や ArgoCD、GitOps という言葉はよく見かけるものの、「結局どんな構成で、何がどう動いているのか分かりづらい」と感じることはないでしょうか。本記事では、EKS を中心に ArgoCD を使った GitOps の最小構成を実際に構築し、その手順を備忘録としてまとめました。できるだけ構成をシンプルにし、
・EKS × ArgoCD × GitOps の全体像を掴む
・実際にアプリケーションがデプロイされるところまで動かす

ことを目的としています。「まずは GitOps を動かしてみたい」「EKS + ArgoCD の関係を理解したい」という方の参考になれば幸いです。

前提

  • インストール済みソフトウェア
    – JDK 21(Java 実行環境)
    – Git(ソースコード管理)
    ※ 上記ソフトウェアがローカル環境にインストールされている前提で進めます。
  • 想定コスト
    本手順は AWS 上で EKS を利用した検証を行うため、  約 900 円程度の AWS 利用料金が発生します。内訳は本記事の下部「Tips」でご確認ください。
    – 想定作業期間:8時間程度 (24時間以内にリソース削除)
    – 利用する主な有料リソース:  
    ・ Amazon EKS(コントロールプレーン)  
    ・ Amazon EC2(ワーカーノード)  
    ・ VPC / Load Balancer  
    ・ Amazon ECR
  • 全体構成(手順の概要込み)

※本来Cloudshellは利用せずとも可能ですが、環境制約により上記の構成としました。

EKS × ArgoCD GitOps 構築手順

demoアプリケーションの作成(Java-Spring ベース)

■demoプロジェクト作成
以下を参考にJava(spring boot)のサンプルプロジェクトを作成する(※本手順ではJDK21で実施していることに留意。Java以外で実施する場合は、他の言語を利用したプロジェクトに読み替えて実施ください。) https://maroon54321.com/archives/136

■podmanインストール
Windows11PCにてwslを起動後、以下のコマンドを実行しpodmanをインストールする。

sudo  dnf install -y podman
podman --version

■demoプロジェクトのビルド
demoプロジェクト配下で以下のコマンドを実行し、ビルドを実行する。
※本手順では、C:\\workにdemoプロジェクトを配置している。

cd /mnt/c/work/demo
sudo podman build -t demo .

※JDKについていくつか選択肢が表示されることがあるため「docker.io/library/eclipse-temurin:21-jdk」を選択する。

■demoプロジェクト起動確認
以下のコマンドを実行して、demoプロジェクトを起動する。

sudo podman run -d -p 8080:8080 demo

以下へアクセスして起動されていることを確認する。
http://localhost:8080/test

Githubリポジトリの作成

Gthubにアカウントがなければ作成し、Repositories > NewからdemoリポジトリをPrivateで作成する。

ECRリポジトリの作成

CloudShellを起動して以下のコマンドを実行してECRリポジトリを作成する。

aws ecr create-repository --repository-name demo-api --region ap-northeast-1

ECRをAWS上で開くと以下のようにECRにリポジトリが作成されている。

Cloudshellにてソース取得、dockerイメージの作成

■ECRへログイン
CloudShellを起動後、以下のコマンドを実行してECRにログインする。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {ECRリポジトリの作成で作成したリポジトリのURI}/demo-api

■ソースを取得

git clone {ソースURL}

■ビルド

cd demo
docker build -t demo-api:1.0 .

■タグ付け

docker tag demo-api:1.0 {ECRリポジトリの作成で作成したリポジトリのURI}/demo-api:1.0

■イメージをECRへpush

docker push {ECRリポジトリの作成で作成したリポジトリのURI}/demo-api:1.0

EKSクラスタの作成

■eksctlコマンドのダウンロード

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version


■クラスタ作成
前述の手順に引き続きCloudShellにて以下のコマンドを実行し、EKSクラスタを作成する。

eksctl create cluster --name demo-cluster --region ap-northeast-1 --node-type t3.medium --nodes 2

※コマンドを実行してから20~30分ほど待機する必要がある。20分なにもしないとclodshellのセッションが切れる可能性があるため注意する。なお、cloudFormation、EC2、VPCが自動で作成される

■クラスタ作成確認
以下のコマンドを実行し、nodeが2つ作成されていればOK。

kubectl get nodes

argocdの構築

■namespace作成&コンテナ構築
ArgoCD用のnamespace作成し、外部yamlから構築を実施。

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

■確認

kubectl get pods -n argocd

上記コマンドの実行結果が以下のようになっていればOK

NAME                                               READY   STATUS    RESTARTS   AGE								
argocd-application-controller-x                    1/1     Running   0          49s								
argocd-applicationset-controller-xxxxxxxxxxxxxxx   1/1     Running   0          49s								
argocd-dex-server-xxxxxxxxxxxxxxxx                 1/1     Running   0          49s								
argocd-notifications-controller-xxxxxxxxxxxxxxxx   1/1     Running   0          49s								
argocd-redis-xxxxxxxxxxxxxxxx                      1/1     Running   0          49s								
argocd-repo-server-xxxxxxxxxxxxxxxx                1/1     Running   0          49s								
argocd-server-xxxxxxxxxxxxxxxx                     1/1     Running   0          49s								

■httpモードに変更
本番稼働を行う際には、ALBやDNSを用いてhttpsにて実施することが望ましいが、本手順では簡易検証のためhttpモードでargoCDを稼働させる。以下のコマンドを実行し、httpモードに変更する。

kubectl patch configmap argocd-cmd-params-cm -n argocd -p '{"data": {"server.insecure": "true"}}'

■argoCDのpod再起動

kubectl rollout restart deployment argocd-server -n argocd
kubectl get pods -n argocd
kubectl get service -n argocd


「kubectl get service -n argocd」の実行結果が以下のようになっていたらOK。argocd-serverのEXTERNAL-IPに表示されているURLでargoCDにアクセスできる。

■アクセス確認

「kubectl get service -n argocd」で確認したURLにアクセスし、argocdにアクセスできることを確認する。

以下の情報でログイン
Username:admin
Password:下記コマンド実行でパスワードが表示

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

k8s設定(argo × Githubの設定 & demoアプリケーションに必要なk8s設定)

■k8sのファイル作成
demoプロジェクト配下に「k8s」フォルダを作成し、k8s用のファイル群を作成する。

それぞれファイル内容は以下の通り。
・application.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: demo
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/<YOUR_GITHUB_ORG_OR_USER>/<YOUR_REPO>.git
    targetRevision: master
    path: k8s
  destination:
    server: https://kubernetes.default.svc
    namespace: demo
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

・deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
        - name: demo
          image: {自身ECRのURL}/demo:1.0.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 20
            periodSeconds: 10

・ingress.yaml

apiVersion: networking.k8s.io/v1	
kind: Ingress	
metadata:	
  name: demo	
  namespace: demo	
spec:	
  ingressClassName: nginx	
  rules:	
    - http:	
        paths:	
          - path: /	
            pathType: Prefix   # ←これを追加	
            backend:	
              service:	
                name: demo	
                port:	
                  number: 80	

・namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
name: demo

・service.yaml

apiVersion: v1
kind: Service
metadata:
  name: demo
  namespace: demo
spec:
  selector:
    app: demo
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

上記を作成後、Githubのdemoへコミットする。

■argocd × Github同期設定
CloudShellを開き、以下のコマンドを実行して、同期設定を適用する。

git clone {リポジトリURL}
cd demo
kubectl apply -n argocd -f application.yaml
kubectl get applications -n argocd

上記コマンドを実行後、argocdへアクセスすると以下のようにdemoのアプリケーションが作成されている。
※この画像はStatusがHealthyとなっているが、実際はこの時点では失敗が正しい。

この時点ではGithubとの認証に失敗しているため、以下の通りsettings > Repositories > CONNECT REPOから認証情報を作成する。

上記入力後、上部の「connect」を押下すると、以下のように接続が成功する。

認証設定を実施してしばらくまつか、再度「kubectl apply -n argocd -f application.yaml」を実行すると、
以下の画像のように、Githubとargocdの同期が成功し、demoのnamespace等、必要なリソースが自動作成される。
※失敗する場合は、本記事の下部に記載しているTipsの「demoアプリにhealthチェック対応が必要である件について」を確認する。

demoアプリの外部アクセス設定

■外部yamlを基にしたingress適用
cloudshellを起動し、以下のコマンドを実行する。

cd demo/k8s
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/aws/deploy.yaml
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
kubectl get ingressclass
kubectl apply -f ingress.yaml
kubectl describe ingress demo -n demo
kubectl get svc -n ingress-nginx

「kubectl get svc -n ingress-nginx」を実行すると、以下のように表示される。


{EXTERNAL-IP}/testでdemoアプリケーションへアクセスし、正常に動作していることを確認できれば完了。

環境削除(課金を防ぐ)

■ECRのイメージ削除

aws ecr batch-delete-image --repository-name demo-api --image-ids imageTag=1.0 imageTag=1.1 imageTag=1.2

■EKSの削除

eksctl delete cluster --name demo-cluster --region ap-northeast-1

Tips

demoアプリにhealthチェック対応が必要である件について

deploymentの設定のlivenessProbeにて、20秒ごとにhealthチェックして起動していなかったら再起動するようにしているため、demoアプリケーション側でhealthチェックの受け口を用意する必要がある。
・deployment.yaml(該当箇所抜粋↓)

apiVer\sion: apps/v1
・・・
          livenessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 20
            periodSeconds: 10

・healthチェックの受け口(HealthContoller)

package com.example.demo.controller;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HealthController {

    @GetMapping("/")
    public String home() {
        return "OK";
    }
}

2回目以降のデプロイ

2回目以降は以下の手順にそってデプロイする。

1.Githubにソースをpush
2.dockerビルド(Cloudshell)

docker build -t demo-api:{バージョン} .  

3.タグ付け( ECR に push できる形の名前に変換)

 docker tag demo-api:{バージョン} 300615130428.dkr.ecr.ap-northeast-1.amazonaws.com/demo-api:{バージョン} 

4.ECRにイメージをpush

push aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 300615130428.dkr.ecr.ap-northeast-1.amazonaws.com 
docker push  300615130428.dkr.ecr.ap-northeast-1.amazonaws.com/demo-api:{バージョン}

5.deployment.yamlのバージョンの記載を修正してGithubへpush

6.アクセス確認

kubectl get svc -n ingress-nginx
{EXTERNAL-IP}/{任意のエンドポイント}

参考料金について

項目単価(USD)1日あたり(USD)日本円
EKS コントロールプレーン$0.10 / 時間$2.40約 360円
EC2(t3.medium ×2)$0.054 ×2 / 時間$2.592約 389円
EBS(20GB ×2)$0.0912/GB/月$0.1216約 18円
LoadBalancer ×2$0.0225 ×2 / 時間$1.08約 162円
合計$6.19約 929円

本番運用に向けて

本記事では簡易構成となっているので、本番運用するにあたってはALBやRoute53などを設定し、argocd、業務アプリケーション共にHTTPSでアクセスできるようにするのが望ましいと思います。
また、今回Cloudshellを使ってビルドやデプロイを実施しているため、本番運用ではGithubActionsを使ってよりGitOpsに近づけることが望ましいです。

おわりに

本記事では、EKS を中心に ArgoCD を用いた GitOps の最小構成を構築し、 実際にアプリケーションが自動デプロイされるところまでを確認しました。 最小構成ではありますが、
・Kubernetes(EKS)上でアプリケーションが動く流れ
・Git を起点に ArgoCD がデプロイを管理する GitOps の考え方
・EKS と ArgoCD の役割分担
といったポイントを一通り体験できたかと思います。
実運用では、ここからさらに ・Ingress / ALB の導入 ・HTTPS(ACM + Route53) ・複数環境(dev / stg / prod)の構成 ・ArgoCD の Application 分割や Project 設計 などを検討していくことになります。
まずは「Git を更新すると、EKS 上のアプリケーションが自動で反映される」 という GitOps の基本動作を体験することが第一歩です。 本記事が、EKS × ArgoCD × GitOps を理解するきっかけになれば幸いです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次