APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Amazon EKS on AWS Fargate でお手軽 Kubernetes環境

はじめに

こんにちは、クラウド事業部の梅本です。

普段は AWS 以外のクラウドでコンテナや Kubernetes を業務で扱っています。 マネージドな Kubernetes に疎い私ですが、今回は Amazon EKS on AWS Fargete を使って、どのくらい楽に Kubernetes 環境が構築できるのかを実感していきたいと思います。 また、Amazon EKS / AWS Fargate で使われるリソースを把握し、構成の理解を深めていこうと思います。

環境情報

  • コマンド実行環境:AWS CloudShell
    • AWS ログイン後、上部のアイコンから起動できます。
    • 一定時間たつと環境ががリフレッシュされます。
  • AWS CLI:2.13.23 ★
  • kubectl:v1.27.4 ★
  • eksctl:0.161.0

※★は AWS CloudShell にインストール済み
※バージョンは、2023/10/11 時点のものです

eksctl インストール

まずは EKS の作成や管理を実行できるコマンドラインツールである eksctl をインストールします。下記、公式の手順通り実施します。

eksctl.io

$ ARCH=amd64
$ PLATFORM=$(uname -s)_$ARCH
$ echo $PLATFORM
Linux_amd64

$ curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
$ ls
eksctl_Linux_amd64.tar.gz
$ curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
eksctl_Linux_amd64.tar.gz: OK

$ tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
$ sudo mv /tmp/eksctl /usr/local/bin
$ eksctl version
0.161.0

コマンドコピペ用(クリックで展開)

ARCH=amd64
PLATFORM=$(uname -s)_$ARCH
curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
sudo mv /tmp/eksctl /usr/local/bin
eksctl version

EKS 作成

それでは早速 EKS Cluster を作成します。

# Create EKS Cluster
# --name : Cluster Name
# --region : Region
# --fargate : on Fargate
$ eksctl create cluster --name ume-cluster --region ap-northeast-1 --fargate
2023-10-11 14:06:44 []  eksctl version 0.161.0
2023-10-11 14:06:44 []  using region ap-northeast-1
2023-10-11 14:06:44 []  setting availability zones to [ap-northeast-1c ap-northeast-1a ap-northeast-1d]
2023-10-11 14:06:44 []  subnets for ap-northeast-1c - public:192.168.0.0/19 private:192.168.96.0/19
2023-10-11 14:06:44 []  subnets for ap-northeast-1a - public:192.168.32.0/19 private:192.168.128.0/19
2023-10-11 14:06:44 []  subnets for ap-northeast-1d - public:192.168.64.0/19 private:192.168.160.0/19
2023-10-11 14:06:44 []  using Kubernetes version 1.27
2023-10-11 14:06:44 []  creating EKS cluster "ume-cluster" in "ap-northeast-1" region with Fargate profile
2023-10-11 14:06:44 []  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=ume-cluster'
2023-10-11 14:06:44 []  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "ume-cluster" in "ap-northeast-1"
2023-10-11 14:06:44 []  CloudWatch logging will not be enabled for cluster "ume-cluster" in "ap-northeast-1"
2023-10-11 14:06:44 []  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-1 --cluster=ume-cluster'
2023-10-11 14:06:44 []  
2 sequential tasks: { create cluster control plane "ume-cluster", 
    2 sequential sub-tasks: { 
        wait for control plane to become ready,
        create fargate profiles,
    } 
}
2023-10-11 14:06:44 []  building cluster stack "eksctl-ume-cluster-cluster"
2023-10-11 14:06:45 []  deploying stack "eksctl-ume-cluster-cluster"
2023-10-11 14:07:15 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:07:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:08:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:09:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:10:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:11:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:12:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:13:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:14:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:15:45 []  waiting for CloudFormation stack "eksctl-ume-cluster-cluster"
2023-10-11 14:17:46 []  creating Fargate profile "fp-default" on EKS cluster "ume-cluster"
2023-10-11 14:19:57 []  created Fargate profile "fp-default" on EKS cluster "ume-cluster"
2023-10-11 14:20:27 []  "coredns" is now schedulable onto Fargate
2023-10-11 14:21:30 []  "coredns" is now scheduled onto Fargate
2023-10-11 14:21:30 []  "coredns" pods are now scheduled onto Fargate
2023-10-11 14:21:30 []  waiting for the control plane to become ready
2023-10-11 14:21:31 []  saved kubeconfig as "/home/cloudshell-user/.kube/config"
2023-10-11 14:21:31 []  no tasks
2023-10-11 14:21:31 []  all EKS cluster resources for "ume-cluster" have been created
2023-10-11 14:21:34 []  kubectl command should work with "/home/cloudshell-user/.kube/config", try 'kubectl get nodes'
2023-10-11 14:21:34 []  EKS cluster "ume-cluster" in "ap-northeast-1" region is ready

無事に作成されました。1コマンドであっさり Kubernetes の環境が作成できました。 コマンドが実行してくれる作業工程としては以下が行われていました。

  1. CloudFormation で AWS リソース作成
  2. CloudFormation で作成されるリソースが完了するまで待機
  3. Fargate のプロファイル作成
  4. coredns を ノード(Fargate) にデプロイ
  5. ローカルに EKS 接続用の kubeconfig を作成して配置

地味に kubeconfig の書き出しも行ってくれているのが◎です。 AWS リソースはCloudFormation を使って作られるため、作成状況は EKS の管理画面だけでなく CloudFormation の管理画面からも確認できます。

リソース構成

作成できた EKS について、早速 AWS のリソース構成を見てみましょう。 作成された CloudFormation のスタックからデザイナーで見ると、

少~し見づらいので、draw.ioで書き直すと以下になります(これでもまだ見づらいですが幾分ましかと・・・)。 赤線:NAT Gateway、青線:VPC、緑線:EKS、にそれぞれ関連しています。

  • VPC は Public/Private と各 AZ で Subnet が分かれている
  • Private Subnet はNAT Gateway を利用している
  • NAT Gateway は Public Subnet のいずれかに作成される(上図は1A)

NW はしっかり分離されて作られていました。

※描いた後に気づいたのですが、しっかり公式に構成図ありました・・・ご参考まで。

github.com

Kubernetes 動作確認

次に Kubernetes の状態を確認します。

# Namespace は Kubernetes 関連と default のみ
$ kubectl get ns
NAME              STATUS   AGE
default           Active   12m
kube-node-lease   Active   12m
kube-public       Active   12m
kube-system       Active   12m

# Kubernetes のバージョンはデフォルトで v1.27
# 2023/10/11 時点で選べる Kubernetes の最新バージョンは v1.28
# Node の数 = Pod の数
$ kubectl get node -owide
NAME                                                        STATUS   ROLES    AGE     VERSION               INTERNAL-IP      EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
fargate-ip-192-168-151-52.ap-northeast-1.compute.internal   Ready    <none>   4m25s   v1.27.1-eks-2f008fe   192.168.151.52   <none>        Amazon Linux 2   5.10.192-182.736.amzn2.x86_64   containerd://1.6.6
fargate-ip-192-168-186-86.ap-northeast-1.compute.internal   Ready    <none>   4m32s   v1.27.1-eks-2f008fe   192.168.186.86   <none>        Amazon Linux 2   5.10.192-183.736.amzn2.x86_64   containerd://1.6.6

# coredns の Pod が2つデプロイされた状態
$ kubectl get deploy,po -A -owide
NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                                                             SELECTOR
kube-system   deployment.apps/coredns   2/2     2            2           15m   coredns      602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/coredns:v1.10.1-eksbuild.1   eks.amazonaws.com/component=coredns,k8s-app=kube-dns

NAMESPACE     NAME                           READY   STATUS    RESTARTS   AGE    IP               NODE                                                        NOMINATED NODE   READINESS GATES
kube-system   pod/coredns-5c7c87f497-72tt2   1/1     Running   0          7m5s   192.168.151.52   fargate-ip-192-168-151-52.ap-northeast-1.compute.internal   <none>           <none>
kube-system   pod/coredns-5c7c87f497-bpzrp   1/1     Running   0          7m5s   192.168.186.86   fargate-ip-192-168-186-86.ap-northeast-1.compute.internal   <none>           <none>

Fargate を利用しているため、Pod 数分の Node が登録されています。

続いて Pod を追加してみます。

# nginx のコンテナを3つ追加
$ kubectl create deployment nginx -n default --image nginx:1.25.2 --replicas 3
deployment.apps/nginx created

# default Namespace に Pod が3つ起動する
$ kubectl get po -owide -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP                NODE                                                         NOMINATED NODE   READINESS GATES
default       nginx-7b66446657-8pd8c     1/1     Running   0          86s     192.168.174.174   fargate-ip-192-168-174-174.ap-northeast-1.compute.internal   <none>           <none>
default       nginx-7b66446657-hs4vd     1/1     Running   0          86s     192.168.171.205   fargate-ip-192-168-171-205.ap-northeast-1.compute.internal   <none>           <none>
default       nginx-7b66446657-sc627     1/1     Running   0          86s     192.168.138.222   fargate-ip-192-168-138-222.ap-northeast-1.compute.internal   <none>           <none>
kube-system   coredns-5c7c87f497-72tt2   1/1     Running   0          9m51s   192.168.151.52    fargate-ip-192-168-151-52.ap-northeast-1.compute.internal    <none>           <none>
kube-system   coredns-5c7c87f497-bpzrp   1/1     Running   0          9m51s   192.168.186.86    fargate-ip-192-168-186-86.ap-northeast-1.compute.internal    <none>           <none>

# Fargate の Node が3つ追加される
$ kubectl get no -owide
NAME                                                         STATUS   ROLES    AGE     VERSION               INTERNAL-IP       EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
fargate-ip-192-168-138-222.ap-northeast-1.compute.internal   Ready    <none>   2m22s   v1.27.1-eks-2f008fe   192.168.138.222   <none>        Amazon Linux 2   5.10.192-182.736.amzn2.x86_64   containerd://1.6.6
fargate-ip-192-168-151-52.ap-northeast-1.compute.internal    Ready    <none>   10m     v1.27.1-eks-2f008fe   192.168.151.52    <none>        Amazon Linux 2   5.10.192-182.736.amzn2.x86_64   containerd://1.6.6
fargate-ip-192-168-171-205.ap-northeast-1.compute.internal   Ready    <none>   2m16s   v1.27.1-eks-2f008fe   192.168.171.205   <none>        Amazon Linux 2   5.10.192-183.736.amzn2.x86_64   containerd://1.6.6
fargate-ip-192-168-174-174.ap-northeast-1.compute.internal   Ready    <none>   2m19s   v1.27.1-eks-2f008fe   192.168.174.174   <none>        Amazon Linux 2   5.10.192-183.736.amzn2.x86_64   containerd://1.6.6
fargate-ip-192-168-186-86.ap-northeast-1.compute.internal    Ready    <none>   10m     v1.27.1-eks-2f008fe   192.168.186.86    <none>        Amazon Linux 2   5.10.192-183.736.amzn2.x86_64   containerd://1.6.6

無事に Pod が起動しました。 先ほどの出力にもありますが、Pod が Node に対応しているため、IP アドレスも1:1で対応しています。

Pod が Node と 1:1 対応なので、毎度 Pull しているように見えました。コンテナイメージは基本的には軽量ではあると思いますが、気を付けたいところではあります。

$ kubectl describe po nginx-7b66446657-8pd8c
...
Events:
  Type     Reason           Age    From               Message
  ----     ------           ----   ----               -------
  Warning  LoggingDisabled  4m5s   fargate-scheduler  Disabled logging because aws-logging configmap was not found. configmap "aws-logging" not found
  Normal   Scheduled        3m25s  fargate-scheduler  Successfully assigned default/nginx-7b66446657-8pd8c to fargate-ip-192-168-174-174.ap-northeast-1.compute.internal
  Normal   Pulling          3m24s  kubelet            Pulling image "nginx:1.25.2"  ★
  Normal   Pulled           3m15s  kubelet            Successfully pulled image "nginx:1.25.2" in 8.49547279s (8.495569809s including waiting)  ★
  Normal   Created          3m15s  kubelet            Created container nginx
  Normal   Started          3m15s  kubelet            Started container nginx

$ kubectl describe po nginx-7b66446657-hs4vd
...
Events:
  Type     Reason           Age    From               Message
  ----     ------           ----   ----               -------
  Warning  LoggingDisabled  5m15s  fargate-scheduler  Disabled logging because aws-logging configmap was not found. configmap "aws-logging" not found
  Normal   Scheduled        4m32s  fargate-scheduler  Successfully assigned default/nginx-7b66446657-hs4vd to fargate-ip-192-168-171-205.ap-northeast-1.compute.internal
  Normal   Pulling          4m31s  kubelet            Pulling image "nginx:1.25.2"  ★
  Normal   Pulled           4m22s  kubelet            Successfully pulled image "nginx:1.25.2" in 8.663393863s (8.663406106s including waiting)  ★
  Normal   Created          4m22s  kubelet            Created container nginx
  Normal   Started          4m22s  kubelet            Started container nginx

最後にリソース(CPU/Memory)について確認していきます。 マニフェスト等の Requests で指定した CPU/Memory に依ったPodが配置されます。今回は指定なしのデフォルトで起動しています。

# CPU/Memory のサイズは 各 Pod の Annotation に記載
# 指定なしだったので、デフォルトの 0.25 vCPU / Memory 0.5 GB で設定されている
$ kubectl get po nginx-7b66446657-8pd8c -o jsonpath='{.metadata.annotations.CapacityProvisioned}'
0.25vCPU 0.5GB

# Node は Pod のサイズより大きめに起動する
$ kubectl describe node fargate-ip-192-168-174-174.ap-northeast-1.compute.internal
Name:               fargate-ip-192-168-174-174.ap-northeast-1.compute.internal
...
Capacity:                         : ★ノードのリソース量
  cpu:                2           : 2 vCPU
  ephemeral-storage:  30787492Ki  : 29.3 Gi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1970512Ki   : 1.87 Gi
  pods:               1
Allocatable:                      : ★Podで利用可能なリソース量
  cpu:                2           : 2 vCPU
  ephemeral-storage:  17690680Ki  : 16.8 Gi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1868112Ki   : 1.78 Gi
  pods:               1

以下、Fargate Pod の設定(CPU・Memory についてなど)のドキュメントです。設定できる CPU/Memory のサイズや考慮点はこちらで確認ができます。

docs.aws.amazon.com

片付け

最後に環境を削除して終わります。コマンドで一発です!

実行完了後も裏では CloudFormation が実行中なので、同一名で起動する場合などは注意が必要です。最終的には利用したCloudFormation の Stackも削除されます。

$ eksctl delete cluster --name ume-cluster --region ap-northeast-1
2023-10-11 15:25:17 []  deleting EKS cluster "ume-cluster"
2023-10-11 15:25:17 []  deleting Fargate profile "fp-default"
2023-10-11 15:27:26 []  deleted Fargate profile "fp-default"
2023-10-11 15:27:26 []  deleted 1 Fargate profile(s)
2023-10-11 15:27:27 []  kubeconfig has been updated
2023-10-11 15:27:27 []  cleaning up AWS load balancers created by Kubernetes objects of Kind Service or Ingress
2023-10-11 15:27:28 []  1 task: { delete cluster control plane "ume-cluster" [async] }
2023-10-11 15:27:28 []  will delete stack "eksctl-ume-cluster-cluster"
2023-10-11 15:27:29 []  all cluster resources were deleted

おわりに

今回は EKS on Fargate でお手軽 Kubernetes 環境を構築しました。コマンド1つで構築できるのは素早く検証できる点で良いと思いました。また、VMを管理する手間もないため気軽に検証できる点が良かったです。Node と Pod が 1:1 に対するメリデメ、考慮点などは利用しながら理解を深めて行ければと思います。

外部公開(Ingress や LB)やストレージについても学習を進めて行ければと思います。


APCはAWSセレクトティアサービスパートナー認定を受けております。

AWSセレクトティアサービスパートナー

その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

www.ap-com.co.jp

また、AWSの運用自動化ツールも展開しております。

www.ap-com.co.jp

一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 梅本
コンテナや k8s をメインにインフラ系のご支援を担当しています。
AWS は現在学び直し中! 普段は QiitaZenn に k8s を中心とした記事を投稿しております。よろしければ。