Amazon EKS Auto Mode+CloudShellで最短コンテナ公開

はじめに

こんにちは。hiranoです。
Amazon EKSはKubernetesをAWS上で運用するための強力な選択肢ですが、初めて触ると「Kubernetesそのもの」だけでなく、EKS特有の考慮点が一気に増えて難しそうに見えがちです。
例えば、コントロールプレーンとデータプレーンの分離、ノードグループ/ワーカーノードの設計、そして高可用性・拡張性をどう担保するかなど、最初から決めることが多く「とりあえず動かして確認したいだけなのに、設計ポイントが多くて手が止まる」ということがあると思います。
そこで本記事では、EKSのオートモードを使って“まず動かす”ところまでのハードルを下げ、CloudShellからnginxをデプロイし、外部公開して動作確認するところまでを最短で進めます。
EKS=難しい、といった印象を少しでも上書きできれば幸いです。

前提・準備

前述の通りEKSのオートモードとCloudeShellで最短公開をしていきます。
Kubernetesクラスターに対する操作はCloudShellに限らず、AWS CLIとkubectlを準備した環境があれば実行できます。
例えば、踏み台用のEC2にAWS CLI/kubectlを入れて操作したり、手元のローカルPCにセットアップして操作することも可能です。ただし本記事では、環境構築でつまずくポイントを減らすため、ブラウザだけで使えるAWSCloudShellを利用します。

事前準備は以下のみです。
・VPC
・パブリックサブネット2つ(別々のAZ)

※外部公開はKubernetesのService(type=LoadBalancer)で行い、NLBが手順の中で自動作成されます。
※IAMロールは、ウィザード側で新規作成して進めます。
 もしウィザード側で作成ができない環境の場合は、必要となる権限を画像で載せていますので、別途用意しましょう。

本記事の流れ

以下の流れで実践していきます。
1. EKSクラスターの作成
  ⇒ オートモードを使用して作成します。
2. CloudShellでクラスターに接続
  ⇒ kubeconfig を設定し、kubectlが通ることを確認します。
3. Deployment作成
  ⇒ nginx用のDeploymentマニフェストを作成・適用します。
4. 外部公開
  ⇒ ServiceマニフェストからNLBを自動作成し、セキュリティ設定と動作確認も実施します。

実践

1. EKSクラスターの作成

EKSを通常のマネージド型ノードグループで構築する場合、クラスター作成に加えて「どんなノード(インスタンスタイプ、台数、更新方法)をどう用意するか」を自分で決めていく必要があり、最初の一歩で迷いやすいです。
一方、今回使用するEKSオートモードを使うと、まず動かす段階で必要になるノード周りの面倒をAWS側に寄せられるため、
クラスター作成 → デプロイ → 外部公開 までをスムーズに進めやすくなります。
では、以下の手順で作成していきます。

EKSクラスターの作成手順
①AWSマネジメントコンソールでElastic Kubernetes Serviceを開く
②左メニュー[クラスター] → [クラスターを作成] を押下
③設定オプション[クイック設定 (EKS オートモード付き)]を選択
④以下で設定し、[作成] を押下
 クラスター設定
 - 名前:eks-auto-mode-blog
 - Kubernetes バージョン:デフォルト(最新Verが入る想定)
 - クラスター IAM ロール:EKSClusterRole-eks-auto-mode-blog
 - ノード IAM ロール:EKSNodeRole-eks-auto-mode-blog
 - VPC/サブネット:事前に準備していたVPCとサブネット2つ
※それぞれのIAMロールはウィザード上で[新しいロールの作成]を押下すると、AWS管理ポリシーがデフォルトでアタッチされた状態で作成できます。今回はデフォルトで権限は足りていますが、必要に応じた追加/削除が必要です。
付与されるポリシーは以下画像を参照してみてください。

また、クラスター作成画面の下部の [クイック設定のデフォルトを表示する] を展開することで、オートモードに含まれる機能とその他クラスター設定、ネットワーキングを確認することができます。
大体がクラスター作成後に編集可能ではありますが、事前に設定を変えたい場合は「クイック設定」ではなく「カスタム設定+オートモード使用」で作成することになります。
今回は最短を意識してクイック設定です。

2. CloudShellでクラスターに接続

15分ほど待って、作成したクラスターがアクティブになったことを確認しました。
次はCloudeShellを使い、kubectlでクラスターを操作できる状態にします。
kubectlとは、Kubernetesクラスターに対して「状態確認」や「Deployment/Serviceなどの作成・更新」を行うための標準コマンドラインツールです。

CloudShellのkubectl疎通確認手順
①AWSマネジメントコンソールでCloudShellを開く
②以下のコマンドでkubeconfigを作成をする

aws eks update-kubeconfig \
  --name <クラスター名> \
  --region <対象リージョン>

③以下のコマンドでクラスタ疎通を確認する

# Namespaceの一覧を表示
kubectl get namespaces

# 現在kubectlが接続しているアクティブなコンテキストを表示
kubectl config current-context

コマンド実行例

★補足
上記は「何をする必要があるか」を明示したかったので一つずつ実施しましたが、 最短で同設定をしたい場合は、作成したEKSクラスター画面の [接続] を押下した際に表示されるコマンドを実行するのが最も簡単です。
このコマンドはkubectlの接続設定(kubeconfig作成・接続先切り替え)をまとめて行うショートカットになります。

3. Deployment作成

次は「アプリを動かす」段階です。
Kubernetesでは、コンテナを起動・維持する単位としてDeploymentを使うのが定番で、指定したコンテナを望ましい数だけ起動し続けるように管理してくれます。
ここではDeploymentを作成し、PodがRunningになることまで確認します。

Deployment作成手順
①以下のコマンドで作業用ディレクトリとDeploymentマニフェストのファイルを作成する

# 作業用ディレクトリ作成
mkdir -p ~/eks-auto-mode-blog
cd ~/eks-auto-mode-blog

# Deploymentマニフェスト作成(任意のファイル名)
vi deployment.yaml

②viエディタ上で以下を貼付し、保存する

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

③以下のコマンドでDeploymentを適用する

kubectl apply -f deployment.yaml

④以下のコマンドでPodが起動したことを確認

# Deployment「nginx」のロールアウトが完了したかを待ちながら状態表示する
kubectl rollout status deployment/nginx

# Deploymentの一覧を表示
kubectl get deploy

# Podの一覧を表示(-o wideオプションでより詳細に)
kubectl get pods -o wide

コマンド実行例
ロールアウト完了後にDeploymentが「READY 1/1」、Podが「READY 1/1」および「Runnning」状態であれば問題ないでしょう。

4. 外部公開

Deploymentでnginxが起動できましたので、最後に外部からアクセスできる入口を作ります。
KubernetesではServiceを「type: LoadBalancer」にすることで、EKS環境ではAWS側にNetwork Load Balancer(NLB)が自動作成され、外部公開用のDNS名(エンドポイント)が払い出されます。
ただし、NLBにアタッチされたSecurity Groupのルールは初期設定となっているため、注意が必要です。

外部公開手順
①以下のコマンドでServiceマニフェスト(任意のファイル名)を作成する

vi service.yaml

Serviceマニフェストの中身は以下です

apiVersion: v1
kind: Service
metadata:
  name: nginx-blog-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
    service.beta.kubernetes.io/aws-load-balancer-subnets: "<サブネットID>,<サブネットID>"
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80

②以下のコマンドでServiceを適用する

kubectl apply -f service.yaml

③以下のコマンドでNLBが払い出された(EXTERNAL-IPが存在する)ことを確認する

kubectl get svc nginx-blog-lb


④AWSコンソールからNLBをEXTERNAL-IPで検索し、対象のSecurity Groupのルールを制限する
 ※本記事の作成時には0.0.0.0/0が初期設定されていました。

上記まで完了したらhttp://< EXTERNAL-IP(=NLBのDNS名)>/でアクセスしてみます。

「Welcome to nginx!」が表示され、無事に公開できました。

★補足
ここで作成したNLBはServiceに紐づく入口です。
そのため、外部公開後にDeploymentのイメージを差し替えても、Serviceを変更しない限り、NLBのDNS名は基本そのままで、裏側でPodだけがローリング更新されます。

以下はイメージ更新例です。
imageを「nginxdemos/hello」に差し替え、再適用

同じURLでアクセスした結果 問題なく、更新されています。

まとめ

今回は、Amazon EKSでKubernetesの基盤の作成、nginxをデプロイ、ServiceでNLBを自動作成し、動作確認するところまで、
といった「まず動かす」ハンズオンでした。
オートモードを使うことで、最初から設計の細部を決め切らなくても検証を前に進め、Kubernetesの基本である「デプロイして動かし、必要な入口を作って確認する」ところまで到達しやすくなります。
「EKS=難しい」という印象に引っ張られすぎず、手を動かしながら必要な論点を後から積み上げていけることがオートモードの利点です。
EKSは奥が深い一方で、本記事を通し、“最初の一歩”をかなり軽くできることが感じられたかと思います。
もちろん、マネージド型ノードグループにも利点があります。
インスタンスタイプや台数、更新方針などを自分で設計できるため、要件に合わせた構成に寄せやすく、運用の自由度を確保したい場面では有力な選択肢になります。
(参考:EKS + ECR 入門:カスタム Docker イメージをクラスタにデプロイする
まずはオートモードで全体像を掴みつつ、求められる要件に応じて、マネージド型と使い分けてみてください。