Next.jsをEKSに載せたい[~deployment編]
ちょっと株式会社 アドベントカレンダー2023 12月23日の記事です。
環境のセットアップ
- AWS上でのIAMの作成
- Dockerのセットアップ
- 便利ツールのインストール
ここでは1~3に関しての詳細は割愛します。
- 今回は簡易的なものであるため、IAMロールにはAdministratorAccessをアタッチしました。
また、VSCode上でAWS CLIを使えるようにもしておきましょう。
- DockerDesktopは下記からインストールが可能です。
3の便利なツールについては下記です。
$ brew install kubectl
$ kubectl version --client
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
$ brew tap weaveworks/tap && brew install weaveworks/tap/eksctl
$ eksctl version
0.166.0
Next.jsの環境構築
今回は簡潔にするため、exampleのリポジトリを使用します。
npx create-next-app --example with-docker-compose sample-eks-next-app
上記のコマンドの実行でFE環境が整います。
今回はコンテナ環境であるため、スタンドアローンモードである必要があります。サンプルリポジトリをcloneしてるため、next.config.js
にてあらかじめ指定されてます✌️
READMEにあるコマンドを実行すればNextが起動することも確認できました 🙌
# Create a network, which allows containers to communicate
# with each other, by using their container name as a hostname
docker network create my_network
# Build prod
docker compose -f docker-compose.prod.yml build
# Up prod in detached mode
docker compose -f docker-compose.prod.yml up -d
ECRの作成
ECRはフルマネージドなDockerコンテナレジストリです。こちらを使用することでコンテナイメージの共有や保存が可能になります。
ECRはEKSと連携しているので、EKSで使用するイメージはECRで管理すると便利そうです。
公開/非公開の好みによって、Public/Privateのどちらかのregistryを選択してください。どちらでもいいのですが、今回はPrivateにし、名前は安直にsample-eks-next-app
にします。設定はデフォルトのまま作成しました。
リポジトリが作成されたら詳細ページへいき、プッシュコマンドをコピーしましょう。モーダルに表示されるコマンドを順に実行していきます(with-docker-composeのサンプルを使用する場合、下記コマンド内-t
(タグ)などを多少改変する必要があります)。
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxxxx.amazonaws.com
Login Succeeded
$ docker build -t sample-eks-next-app .
[+] Building 3.5s (24/24) FINISHED
$ docker tag sample-eks-next-app:latest xxxxxxxxxxx.amazonaws.com/sample-eks-next-app:latest
$ docker push xxxxxxxxxxx.amazonaws.com/sample-eks-next-app:latest
ここまで上手くいっていれば、詳細ページをリロードした際にイメージが追加されているはずです。
EKSクラスターの作成
EKSはKubernetes(=k8s)をAWS上で利用可能にするマネージドサービスです。実行基盤としてはEC2またはFargateの選択が可能となっています。今回はデフォであるEC2を使っていきます。
下記のドキュメントを参考にCLI上でクラスターの作成をしていきましょう。
$ eksctl create cluster --name sample-eks-next-app --version 1.27 --managed
00:00:00 [ℹ] eksctl version 0.166.0
.
. 10分ほど待機(少し時間がかかる)
.
00:00:00 [✔] EKS cluster "next-eks" in "ap-northeast-1" region is ready
クラスターやノードの情報については下記のコマンドで確認が可能です。
$ eksctl get cluster
$ kubectl cluster-info
$ kubectl get node
コンテナの最小単位であるPod(小さなサーバー的なもの)も確認してみます。
$ kubectl get namespace
NAME STATUS AGE
default Active 18m
kube-node-lease Active 18m
kube-public Active 18m
kube-system Active 18m
$ kubectl get pod -n kube-system -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-ksxpw 1/1 Running 0 20m
kube-system aws-node-zd2vl 1/1 Running 0 20m
kube-system coredns-8496bbc677-t49jq 1/1 Running 0 26m
kube-system coredns-8496bbc677-vgqh7 1/1 Running 0 26m
kube-system kube-proxy-jlhfv 1/1 Running 0 20m
kube-system kube-proxy-pdj52 1/1 Running 0 20m
各種マニフェストの作成
アプリケーションのデプロイのために、まずは名前空間を作成し、
$ kubectl create namespace sample-eks-next-app
次にデプロイマニフェストを作成します。今回はGHに落ちていたものを参照しました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-eks-next-app
spec:
selector:
matchLabels:
app: sample-eks-next-app
replicas: 2
template:
metadata:
labels:
app: sample-eks-next-app
spec:
containers:
- name: sample-eks-next-app
image: <ここにECRのURIをペースト。リポジトリの詳細ページからURIを取得することができます>
imagePullPolicy: Always
ports:
- containerPort: 3000
続いて、作成したymlを適用します。
$ kubectl apply -f deployments.yml -n sample-eks-next-app
ここでは、-n
オプションを使用し、名前空間を指定しましたが、kubensを使用するとデフォルトの名前空間をセットすることができて便利そうです。
この他にもマニフェストとして、サービスとイングレスがあり、同様の手順を踏み、yamlをapplyすることになるため、インストールしてもいいかもしれません。サービスおよびイングレスに関しては下記記事が分かりやすいです。
上記記事でいうところのdeploymentは先ほどのコマンドをもってリソース作成が完了しています。試しにget deployment
を実行し、確認。
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
sample-eks-next-app 2/2 2 2 73s
Podが2つ動いてることが確認できました。わーい。
エンドユーザーは、このPodに直接アクセスするのではなく、サービスを介してアクセスします。例えば、フロントエンドにアクセスする場合、フロントエンドのサービスを介してアクセスするというイメージです。イングレスは、クラスター内外のアクセスを制御するために使用されます。つまり、イングレスを通じてサービスにアクセスし、そのサービスを通じてPodにアクセスする流れです。
また、外部からのアクセス、例えばブラウザにURLを入力してアクセスする場合は、ALB Controllerの設定が必要です。
ALB Controllerを設定すると、イングレスのリソースを作成した際にAWSのロードバランサー(ALB)が自動的に作成され、外部からのアクセスが可能になります。便利〜〜。
まとめ
長くなってしまうため今回はブラウザ上での確認までは割愛しましたが、無事にdeploymentまで漕ぎ着けることができました。
また時間を取れた際にALBControllerの設定などもし、ブラウザ上でNextを確認するところまでやっていきたいと思います💪
参考
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion