0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初めてのAmazon EKS

Posted at

普段のお仕事ではAmazon ECSしか使用することがなく、ちゃんとEKSを使用してコンテナをデプロイしたことがなかったので入門してみました。

やること

今回はEKS上にApacheのコンテナをデプロイしてWebページを表示してみます。

Kubernetesとは

Kubernetesはコンテナ化されたアプリケーションを管理・運用するためのオープンソースのシステムです。
負荷に応じてコンテナの数をスケーリングしたり、問題が発生したコンテナを停止して新しいコンテナに入れ替えたりといったことを行ってくれます。

Kubernetesはクラスターと呼ばれる単位の中でコントロールプレーン (ノードの管理などを行う部分) とノード (実際にコンテナが動く環境) と呼ばれる部分に分かれます。
自分たちですべて運用するとコントロールプレーンとノードの管理が必要になってきますが、EKSを使用することでコントロールプレーンの部分をAWS側に任せることができます。

設定

前準備

EKSを触る前にAWS CLI、kubectl、eksctl、Helmをインストールしておきます。
以下のドキュメントの手順でそれぞれご利用の環境に合わせてインストールを行ってください。

構築

クラスターの作成までは以下のドキュメントを参考に作成を進めていきます。

1. ネットワーク部分作成

AWS CLIをインストールした環境で以下のコマンドを実行します。
コマンドを実行すると東京リージョン (ap-northeast-1) にCloudFormationスタックが作成されネットワークリソースがデプロイされます。

aws cloudformation create-stack \
  --region ap-northeast-1 \
  --stack-name my-eks-vpc-stack \
  --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml

AWSが用意したCloudFormationテンプレートですが、デプロイが完了すると以下の構成が作成されます。
eks.drawio.png

2. クラスター作成

ネットワークリソースの作成が完了したらEKSクラスターを作成していきます。

まずはクラスターの使用するIAMロールを作成します。
以下のコマンドを実行してIAMロールを作成します。
コマンドを実行すると「myAmazonEKSClusterRole」という名前でIAMロールが作成されます。

cat <<EOF > eks-cluster-role-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "eks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam create-role \
  --role-name myAmazonEKSClusterRole \
  --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"

aws iam attach-role-policy \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
  --role-name myAmazonEKSClusterRole

IAMロールの作成が完了したら以下のURLから東京リージョンのEKSクラスター画面へアクセスします。
https://ap-northeast-1.console.aws.amazon.com/eks/clusters?region=ap-northeast-1

アクセス後、「クラスターを作成」をクリックします。
スクリーンショット 2025-11-02 230447.png

クラスターの設定画面から設定オプション欄で「カスタム設定」を選択します。
スクリーンショット 2025-11-02 230701.png

EKS オートモードは今回使用しないのでオフにします。
クラスター設定欄でクラスターの名前とIAMロールを設定します。
スクリーンショット 2025-11-02 232226.png

バージョン設定欄ではk8sのバージョンを選択できます。
基本的に新しく作成するときは最新のバージョンを選択しておけば問題ないと思います。
スクリーンショット 2025-11-02 232325.png

クラスターアクセス欄,エンベロープ暗号化欄、ARC ゾーンシフト欄はデフォルトのままにします。
ここまで設定したら画面を一番下までスクロールして次へをクリックします。

ネットワーキング欄ではVPC、サブネット、セキュリティグループの選択を行います。
サブネットはプライベートサブネットを選択してください。
スクリーンショット 2025-11-02 233010.png

クラスターエンドポイントアクセス欄では「CIDR ブロック」でご自身の使用しているパブリックIPアドレス (ご自宅のパブリックIPアドレスなど) を入力してください。
スクリーンショット 2025-11-02 233400.png

入力したら画面下の次へをクリックします。

メトリクス欄で「CloudWatch」にチェックを入れます。
チェックを入れたら次へをクリックします。

アドオンの設定画面ではデフォルトのまま画面下の次へをクリックします。

Amazon CloudWatch Observability欄で「推奨ロールを作成」をクリックします。
クリックするとIAMロール作成画面に推移するのでそのままIAMロールを作成していきます。
アタッチするポリシーはCloudWatchAgentServerPolicyです。

次にAmazon VPC CNI欄でも同じく「推奨ロールを作成」をクリックします。
アタッチするポリシーはAmazonEKS_CNI_Policyです。

次に外部 DNS欄で「推奨ロールを作成」をクリックします。
アタッチするポリシーはAmazonRoute53FullAccessです。
ここまで設定ができたら画面下の次へをクリックします。

最後の確認画面で問題が無ければ画面下の作成をクリックします。

3. ECRとコンテナイメージ作成

クラスターの作成が完了したらECRの作成とコンテナイメージの作成を行います。

ECRの作成は以下のCloudFormationテンプレートで行います。

AWSTemplateFormatVersion: "2010-09-09"
Description: ECR

Metadata:
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------# 
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label: 
          default: Parameters for env Name
        Parameters:
          - env

Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------# 
  env:
    Type: String
    Default: dev
    AllowedValues:
      - dev

Resources:
# ------------------------------------------------------------#
# ECR
# ------------------------------------------------------------# 
  ECR:
    Type: AWS::ECR::Repository
    Properties:
      EmptyOnDelete: true
      EncryptionConfiguration:
        EncryptionType: AES256
      RepositoryName: !Sub ecr-${env}

上記のCloudFormationテンプレートをファイルに保存したら以下のコマンドでデプロイします。

aws cloudformation create-stack \
  --stack-name ecr \
  --template-body file://CloudFormationテンプレートファイル名 \
  --region ap-northeast-1

ECRの作成が完了したら以下のDockerfileを使用してコンテナイメージの作成を行います。
HTMLファイルはお好きなものを使用してください。

FROM public.ecr.aws/docker/library/httpd:2.4
COPY ./html/ /usr/local/apache2/htdocs/

Dockerfileを作成したら以下のコマンドでコンテナイメージの作成とECRへのプッシュを行います。

ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t ecr-dev .
docker tag ecr-dev:latest $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest
docker push $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest

4. コンテナデプロイ

ECRの作成が完了してEKSクラスターのステータスがアクティブになったら以下のコマンドを実行します。

aws eks update-kubeconfig --region ap-northeast-1 --name クラスター名

コマンドの実行が完了したらEKSクラスターの画面でコンピューティングタブを開いてノードグループ欄で「追加」をクリックします。
スクリーンショット 2025-11-03 003406.png

ノードグループの設定欄で「名前」と「ノード IAM ロール」を設定します。
IAMロールは「推奨ロールを作成」をクリックしてIAMロールを作成するとECRからコンテナイメージを取得するために必要な権限などがアタッチされます。

名前とIAMロールを設定したら画面下の次へをクリックします。
スクリーンショット 2025-11-03 163154.png

ノードグループのコンピューティング設定欄で「インスタンスタイプ」を選択してください。
今回は負荷のかかるコンテナを起動しないのでt3.microを選択しました。
t3.microで設定したところ、podの起動がうまくできなかったのでt3.mediumで作成しなおしました。
おそらくスペック不足で起動に失敗していたと考えられます。(知識不足でどこに問題があるか確認できなかったのでここはいずれ調べたいと思います)
それ以外の設定はデフォルトとして画面下の次へをクリックします。
スクリーンショット 2025-11-03 163720.png

ノードグループのネットワーク設定欄ではプライベートサブネットを選択します。
スクリーンショット 2025-11-03 164108.png

最後の確認画面で設定を確認して問題が無ければ作成してください。

ノードが作成できたらマニフェストファイルを作成します。
マニフェストファイルとはKubernetesクラスター内の設定を記載したものになります。
例えばノード内でいくつPodを起動するかなどを記載して反映します。
今回使用するのはDeployment、Ingress、Serviceを使用します。

apache_deployment.yamlではpodの個数やコンテナイメージの設定を行っています。
以下の設定ではreplicasでpodの個数を指定しています。

apache_deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-deployment
  labels:
    app: apache
spec:
  replicas: 2
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
    spec:
      containers:
        - image: AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-dev:latest
          name: apache
          ports: 
            - containerPort: 80

apache_service.yamlではapache_deployment.yamlで設定したpodを1つのサービスとして公開するための設定を行っています。

apache_service.yaml
apiVersion: v1
kind: Service
metadata:
  name: apache-service
spec:
  ports:
  - port: 80
  selector:
    app: apache
  type: NodePort

apache_ingress.yamlではALBの設定を行っています。
annotations内のパラメータでALBのタグや使用するセキュリティグループの指定などが可能です。

apache_ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apache-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: apache-service
            port:
              number: 80

マニフェストファイルの作成が完了したら以下のドキュメントの手順でOIDCプロバイダーの作成を行います。

OIDCプロバイダーを作成したら以下のコマンドを実行してIAMロールの作成とコントローラーのインストールをします。

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/install/iam_policy.json

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

eksctl create iamserviceaccount \
    --cluster=test-cluster \
    --namespace=kube-system \
    --name=aws-load-balancer-controller \
    --attach-policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \
    --override-existing-serviceaccounts \
    --region ap-northeast-1 \
    --approve

helm repo add eks https://aws.github.io/eks-charts

helm repo update eks

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=test-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --version 1.14.1

kubectl get deployment -n kube-system aws-load-balancer-controller

コントローラーの追加が完了したら以下のコマンドを実行してサブネットにタグをつけていきます。
どうやらk8s側でALBを配置する際にサブネットへ設定されたタグからプライベートサブネットやパブリックサブネットを判定しているようです。

aws ec2 create-tags \
  --resources パブリックサブネットのID プライベートサブネットのID \
  --tags Key=kubernetes.io/cluster/test-cluster,Value=shared \
  --region ap-northeast-1

# 以下のコマンドはAWSの準備したCFnテンプレートでネットワークリソースを作成している場合実行不要です
aws ec2 create-tags \
  --resources プライベートサブネットのID \
  --tags Key=kubernetes.io/role/internal-elb,Value=1 \
  --region ap-northeast-1

# 以下のコマンドはAWSの準備したCFnテンプレートでネットワークリソースを作成している場合実行不要です
aws ec2 create-tags \
  --resources プライベートサブネットのID \
  --tags Key=kubernetes.io/role/internal-elb,Value=1 \
  --region ap-northeast-1

上記の設定完了後、EKSによって作成された起動テンプレートから新しいバージョンを作成して「メタデータレスポンスのホップ制限」を2へ変更します。
変更後、デフォルトのバージョンを2へ変更します。
というのもこの設定を変更しないとインスタンスメタデータからVPC IDを取得できずにaws-load-balancer-controllerの起動に失敗してしまいます。(ここがわからずにサービスがデプロイできず数時間無駄にしました)

スクリーンショット 2025-11-03 211445.png

変更後、EC2 AutoScalingから起動テンプレートのバージョンを2へ変更してEC2を更新します。
おそらくマネジメントコンソールからだとこの方法しか現状は変更できなさそうでした。
以下のブログで紹介されているようにTerraformなどAPIからの操作であれば設定できそうです。

EC2が起動したら以下のコマンドでコンテナをデプロイしていきます。

kubectl apply -f apache_deployment.yaml
kubectl apply -f apache_service.yaml
kubectl apply -f apache_ingress.yaml

コマンドを実行するとALBの作成が行われます。
ALBのステータスがアクティブになったらブラウザからALBのDNS名にアクセスするとApacheで配信しているページにアクセスできます。
スクリーンショット 2025-11-03 213815.png

さいごに

今回はAmazon EKSをマネジメントコンソールから構築してみました。
手順を見ていただいたらわかる通り設定内容がかなり複雑で必要になる知識も広いため使いこなすのはかなり難しそうです。
また、この内容をIaC化していくのはかなり骨が折れそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?