Dockerで起動できるReactアプリをEKSにデプロイしてみた
EKSに触れたことがなかったのでReactアプリをEKSにデプロイしてみました。
大まかな流れは以下のようになります。
- VPC、サブネット準備
- kubectlインストール
- kubectxインストール
- IAM作成
- EKSクラスター作成
- Config編集
- ノード作成
- docker image作成
- docker imageをECRにpush
- namespace作成
- deployment作成
- service作成
VPC、サブネット準備
まずはVPCを作成します。
サブネット等も一緒に作成したいので、「VPC・サブネットなど」の方にチェックを入れます。
名前タグのところにeks-testと入力し、自動生成にチェックを入れます。こうするとサブネット名とかがeks-testから始まる名前に勝手に設定されます。
AZ、パブリック・プライベートサブネットは2つずつにします。
NATゲートウェイは料金が高いのでなしでVPCエンドポイントもなしにします。
「DNS ホスト名を有効化」と「DNS 解決を有効化」の両方にチェックを入れて作成をクリック。
作成完了後、サブネットのページに移動しeksで検索します。
今回作成したサブネットが表示されるので、publicが名前に含まれるサブネットを編集し、「パブリック IPv4 アドレスの自動割り当てを有効化」にチェックを入れます。
kubectlインストール
Kubernetesを操作するためにkubectlをインストールします。
私はbrewでインストールしました
brew install kubectl
その後、kubectl version --short --client
でバージョンが表示されたらOKです。
kubectxインストール
kubernetesの名前空間の切り替え等をするためにkubectxをインストールします。
こちらもbrewでインストールしました。
brew install kubectx
IAM作成
次に後から必要になってくるIAMを作成します。
まずはEKSクラスターにつけるロールから作成します。
IAMロールの画面に移動し、ロールを作成をクリック
信頼されたエンティティタイプはAWSのサービスにチェックを入れます。
ユースケースはEKSと入力してEKS - Clusterを選択して次へボタンをクリック。
ロール名にmyAmazonEKSClusterRoleを指定し「ロールを作成」をクリックして作成します
参考
↓のステップ1
次にEKSのノードにつけるロールを作成します。
またIAMロールのページにアクセス、ロールを作成をクリック。
信頼されたエンティティタイプはAWSのサービスにチェックを入れ、ユースケースはEC2にチェックを入れます。
許可ポリシーとして以下の3つのポリシーをアタッチします
- AmazonEKSWorkerNodePolicy
- AmazonEC2ContainerRegistryReadOnly
- AmazonEKS_CNI_Policy
入力欄に「eks」と入力すると1つ目と3つ目が表示されるのでチェックを入れます。
「フィルターをクリア」を押してから入力欄にEC2と入力すると、2つ目が表示されるのでチェックを入れます。
許可ポリシーの横に(選択済み 3/xxx)と表示されていればOKです。「次へ」をクリックしてください。
ロール名は「AmazonEKSNodeRole」として「ロールを作成」をクリック
参考
EKSクラスター作成
いよいよEKSクラスターを作成します。
AWS CLIで作成しました。コマンドは以下です。
aws eks create-cluster --region ap-northeast-1 --name eks-test-cluster --kubernetes-version 1.21 --role-arn myAmazonEKSClusterRoleのarn --resources-vpc-config subnetIds=subnet-xxxxx,subnet-xxxxx
上記コマンドを実行した後、AWSのマネジメントコンソールのEKSのページにアクセスすると、クラスター名「eks-test-cluster」のクラスターが表示され、ステータスが作成中になっていると思います。
しばらくする(約10分ほど)とステータスが「作成中」から「アクティブ」に変わります。アクティブになったら次のステップに進んでください。
参考
Config編集
「eks-test-cluster」をクリックするとクラスターの概要、ワークロード、設定が見れます。この時、画面上部に「現在のユーザーまたはロールには、この EKS cluster上の Kubernetes オブジェクトへのアクセス権がありません」と表示されていると思います。
これはクラスターを作成したIAMユーザーと、マネジメントコンソールにログインしているIAMユーザーが違うからです。kubernetesの権限とIAMの権限は違うらしく、アドミン権限を持つユーザーでログインしていてもこのメッセージが表示されます。
まずは下記コマンドを実行し、自分のコンピュータとクラスターを繋げます。
aws eks update-kubeconfig --region ap-northeast-1 --name eks-test-cluster
その後、 kubectl get svc
を実行しNAMEとかTYPEとかが表示されればOKです。
しかしこれだけではマネジメントコンソールにログインしているユーザーが全ての情報を見れません。
まず設定マップをダウンロードします。
curl -o aws-auth-cm.yaml https://amazon-eks.s3.us-west-2.amazonaws.com/cloudformation/2020-10-29/aws-auth-cm.yaml
そしてダウンロードしたaws-auth-cm.yamlを下記のように編集します。
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: 先ほど作成したIAMロールAmazonEKSNodeRoleのarn
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
mapUsers: |
- userarn: マネジメントコンソールにログインしているIAMユーザーのarn
username: マネジメントコンソールにログインしているIAMユーザーの名前
groups:
- system:masters
最後に kubectl apply -f aws-auth-cm.yaml
を実行して設定を適用します。
成功すると configmap/aws-auth created
と表示されます。マネジメントコンソールでEKSクラスターを見ると「現在のユーザーまたはロールには、この EKS cluster上の Kubernetes オブジェクトへのアクセス権がありません」が表示されなくなっていると思います。
ノード作成
次にノードを作成します。ノードはマネジメントコンソールで作成します。
eks-test-clusterの設定タブを開き、さらにコンピューティングをクリックします。そしてノードグループを追加をクリックしてください。
名前は適当にeks-test-node-groupに、IAMロールは先ほど作成したAmazonEKSNodeRoleを選択します。
あとはデフォルトのままで次へをクリック。
インスタンスタイプはデフォルトではt3.mediumになっていますが、必要に応じて変更してください。私は1番小さいt3.microにしました。
ノードグループのスケーリング設定は全部2にしました。
ノードグループのネットワーク設定のサブネットは最初に作成したサブネットのパブリックの2つを指定。
最後に確認して作成。
ステータスが作成中からアクティブに変わればOKです。
docker image作成
Reactアプリのdocker imageを作っていきます。今回はnginxも使用しました。
FROM node:14.2.0 as builder
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json", "./"]
RUN npm install
COPY [".", "./"]
RUN npm run build
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY ["/usr/src/app/build", "./"]
COPY ["nginx/default.conf", "/etc/nginx/conf.d"]
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm
try_files $uri /index.html;
}
}
下記コマンドでビルド
docker build -t eks-test .
ビルド完了後、docker run -p 3000:80 eks-test
を実行し localhost:3000でアクセスできればOKです。
docker imageをECRにpush
先ほど作成したdocker imageをECRにpushします。
まずはAWSのマネジメントコンソールにログインし、ECRのリポジトリを作成します。
プライベートリポジトリの方で「リポジトリを作成」をクリックします。
プライベートにチェックを入れ、リポジトリ名はeks-test(docker imageの名前と同じ)にします。
そして「プッシュ時にスキャンを有効にする」にチェックを入れ、作成ボタンを押します。
リポジトリ一覧の中からeks-testをクリックすると次のような画面が現れるので、「プッシュコマンドの表示」をクリックします。
そこで提示されたコマンドを実行するとECRにdocker imageがpushされます。
このようになっていればOKです。
そしてこのlatestをクリックするとイメージのURIが表示されるので控えておきます。
namespace作成
名前空間を作成します。
下記のコマンドを実行します
kubectl create namespace eks-test
namespace/eks-test created
と表示されればOKです。
そして kubens eks-test
を実行し、namespaceを選択します。
deployment作成
eks-test-deployment.yamlという名前のファイルを作成し、以下を貼り付けます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: eks-test
spec:
selector:
matchLabels:
app: eks-test
replicas: 1
template:
metadata:
labels:
app: eks-test
spec:
containers:
- name: eks-test
image: ECRのURL
imagePullPolicy: Always
ports:
- containerPort: 80
kubectl apply -f eks-test-deployment.yaml -n eks-test
を実行してデプロイします。
service作成
deploymentだけではまだwebアプリにアクセスできません。serviceを作成する必要があります。
eks-test-service-lb.yamlという名前のファイルを作成し、以下を記述します。
apiVersion: v1
kind: Service
metadata:
name: eks-test
spec:
type: LoadBalancer
selector:
app: eks-test
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl apply -f eks-test-service-lb.yaml -n eks-test
を実行。
kubectl get service -n eks-test
を実行。
そうするとEXTERNAL-IPが表示されるのでそれをコピーしてブラウザのURL欄に貼り付けます。
するとReactアプリが画面に表示されます。
後片付け
今回作成したリソースをそのままにしておくとお金が多くかかってしまうので削除しておきます。
namespace削除
まずは下記コマンドを実行し、namespaceごと削除します。
kubectl delete namespace eks-test
これでeks-test-service-lb.yamlで作成したロードバランサーが削除されます。
ECRリポジトリ削除
次にECRリポジトリを削除します。
aws ecr delete-repository --repository-name eks-test --force --region ap-northeast-1
ノードグループ削除
次はノードグループを削除します。
まずこのコマンドでクラスターにあるノードグループを確認します
aws eks list-nodegroups --cluster-name eks-test-cluster --region ap-northeast-1
本記事の手順に沿って作成していた場合は、eks-test-node-groupというノードグループが表示されると思います。そのノードグループを下記コマンドで削除します。
aws eks delete-nodegroup --nodegroup-name eks-test-node-group --cluster-name eks-test-cluster --region ap-northeast-1
ステータスが削除中になっていると思うのでしばらく待ちます。
10分ほどで削除されます。すると起動していた2台のEC2も消えているのが分かると思います。
EKSクラスター削除
最後にEKSクラスターを削除します。
下記コマンドを実行します。
aws eks delete-cluster --name eks-test-cluster --region ap-northeast-1
こちらもまたステータスが削除中になっていると思います。
こちらはすぐに削除されました。
これでお金がかかりそうなリソースは削除できたと思います。
あとのIAMやVPC等は残しておいても大丈夫ですが、不要なものを残しておきたくない場合は消しておきましょう。
終わりに
今回初めてEKSを触ってみましたが、ノードグループとかserviceとかdeploymentなどの知らない単語や抽象的な概念が多くて難しく感じました。またIAMの権限とは別でk8sでの権限があり、アドミン権限のIAMユーザーでログインしていても権限がなく表示されないなど今までに経験していなかったことに遭遇し少し戸惑いました。
最後に今回eksにReactアプリを上げるために参考にした記事等を共有して終わりにしたいと思います。
Discussion