概要
AWS re:Invent 2019にて Amazon EKS on AWS Fargate がGAになったと発表された模様なので、遅ればせながら触れてみた備忘録を残してみたいと思います。
ちなみに[この記事](Amazon EKS on AWS Fargate Now Generally Available)を参考にしながら動かしてみました。
準備
事前に必要なものとしては eksctl
なるものがあると良いとのこと。
AWS CLI
をいれておくのと、 AWS CLI Credentials
を作成しておけばOK。
eksctl
eksctl
とはAmazon EKS上にkubernates clusterを作ったり管理したりできるコマンドラインツールとのこと。
Getting Started with eksctlを参考に準備してみる。
インストール
自分は macOS
なので brew
を使ってインストールしてみます。
-
Weaveworks Homebrew tap
のインストール
$ brew tap weaveworks/tap
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.
==> Tapping weaveworks/tap
Cloning into '/usr/local/Homebrew/Library/Taps/weaveworks/homebrew-tap'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 10 (delta 1), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (10/10), done.
Tapped 4 formulae (30 files, 10.5KB).
-
eksctl
のインストール
$ brew install weaveworks/tap/eksctl
==> Installing eksctl from weaveworks/tap
==> Installing dependencies for weaveworks/tap/eksctl: kubernetes-cli and aws-iam-authenticator
==> Installing weaveworks/tap/eksctl dependency: kubernetes-cli
・・・・・
🍺 /usr/local/Cellar/kubernetes-cli/1.17.1: 235 files, 49MB
==> Installing weaveworks/tap/eksctl dependency: aws-iam-authenticator
・・・・・
🍺 /usr/local/Cellar/aws-iam-authenticator/0.4.0: 5 files, 24.9MB
==> Installing weaveworks/tap/eksctl
・・・・・
🍺 /usr/local/Cellar/eksctl/0.12.0: 3 files, 87.0MB, built in 14 minutes 43 seconds
$ eksctl version
[ℹ] version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.12.0"}
クラスタの作成
インストールしたeksctlでクラスタを作成してみます。
$ eksctl create cluster --name demo-newsblog --region ap-northeast-1 --fargate
[ℹ] eksctl version 0.12.0
[ℹ] using region ap-northeast-1
[ℹ] setting availability zones to [ap-northeast-1d ap-northeast-1a ap-northeast-1c]
[ℹ] subnets for ap-northeast-1d - public:〜 private:〜
[ℹ] subnets for ap-northeast-1a - public:〜 private:〜
[ℹ] subnets for ap-northeast-1c - public:〜 private:〜
[ℹ] using Kubernetes version 1.14
[ℹ] creating EKS cluster "demo-newsblog" in "ap-northeast-1" region with Fargate profile
[ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=demo-newsblog'
[ℹ] CloudWatch logging will not be enabled for cluster "demo-newsblog" in "ap-northeast-1"
[ℹ] you can enable it with 'eksctl utils update-cluster-logging --region=ap-northeast-1 --cluster=demo-newsblog'
[ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "demo-newsblog" in "ap-northeast-1"
[ℹ] 1 task: { create cluster control plane "demo-newsblog" }
[ℹ] building cluster stack "eksctl-demo-newsblog-cluster"
[ℹ] deploying stack "eksctl-demo-newsblog-cluster"
[✔] all EKS cluster resources for "demo-newsblog" have been created
[✔] saved kubeconfig as "/Users/yumatsud/.kube/config"
[ℹ] creating Fargate profile "fp-default" on EKS cluster "demo-newsblog"
[ℹ] created Fargate profile "fp-default" on EKS cluster "demo-newsblog"
[ℹ] "coredns" is now schedulable onto Fargate
[ℹ] "coredns" is now scheduled onto Fargate
[ℹ] "coredns" pods are now scheduled onto Fargate
[✖] parsing kubectl version string (upstream error: error: EOF
) / "0.0.0": Version string empty
[ℹ] cluster should be functional despite missing (or misconfigured) client binaries
[✔] EKS cluster "demo-newsblog" in "ap-northeast-1" region is ready
ちょっとだけ中身を見てみると、
- 各AZ毎にpublic subnetとprivate subnetが作られる
- SGもコントロールパネルとノードのやりとり用やノード間のやりとり用などが自動で作られる
- IAMロールやCloudWatch Logsなども作られる
とかで自動的に色々と作ってくれるのば便利ですね。上記コマンドだと、
parsing kubectl version string (upstream error: error: EOF) / "0.0.0": Version string empty
ですが、クラスタはちゃんと作られてたっぽいです。念の為下記で確認したところ、
$ kubectl version
Please enter Username:
のように入力を求められてしまうからで、これ自体は こちらの記事 にある通り、kubectlのバージョンが低いと出てしまうとのこと。eksctl
の該当箇所はこちらでした。
Fargate Profile
Fargate Profile
というのが最初はなんのこっちゃ?と思いましたが、Profileの追加画面を見てみると、
とのことで、podをどこでどのように動かすかなどを定義するものらしいです。
ここからroleやsubnetを追加していくのですが、参考にしてた記事によると、
only private subnets are supported for Fargate pods
とあったので、public subnetは除いてみました。
そのあとにpodを動かす namespace
を設定し、確認後に作成する。
これだけで、namespaceに一致するpodがあれば、そこでpodが動くようです。
ちなみに、jsonを定義してコマンドラインから作成することもできるとのこと。
deploy
nginx
のコンテナを動かしてみます。
$ kubectl create deployment demo-app --image=nginx
deployment.apps/demo-app created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-6dbfc49497-frmdq 0/1 ContainerCreating 0 45s
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
fargate-ip-<ip>.ap-northeast-1.compute.internal Ready <none> 160m v1.14.8-eks
fargate-ip-<ip>.ap-northeast-1.compute.internal Ready <none> 160m v1.14.8-eks
fargate-ip-<ip>.ap-northeast-1.compute.internal Ready <none> 5s v1.14.8-eks
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-6dbfc49497-frmdq 1/1 Running 0 3m9s
ここまでで Getting Started with eksctl の実行は終了。。。これだけだと物足りないので、アクセスできるところまでやってみる。
AWS ALB Ingress Controller
Kubernetes Ingress with AWS ALB Ingress Controllerを参考にインターネットからアクセスできるようにしてみようと思います。
ちなみに、実際にALBを作成してアクセスできるようにするには「Amazon EKS on Fargate で ALB Ingress Controller を使用する」が参考になりそうでした。
- クラスターの OIDC プロバイダーをセットアップ
$ eksctl utils associate-iam-oidc-provider --cluster demo-newsblog --approve
[ℹ] eksctl version 0.12.0
[ℹ] using region ap-northeast-1
[ℹ] will create IAM Open ID Connect provider for cluster "demo-newsblog" in "ap-northeast-1"
[✔] created IAM Open ID Connect provider for cluster "demo-newsblog" in "ap-northeast-1"
-
AWS ALB Ingress controller
に必要なRBACの作成
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml
clusterrole.rbac.authorization.k8s.io/alb-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/alb-ingress-controller created
serviceaccount/alb-ingress-controller created
-
ALB Ingress controller
がAWS APIにアクセスするためのIAMポリシーの作成
$ aws iam create-policy \
--policy-name ALBIngressControllerIAMPolicy \
--policy-document https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/iam-policy.json
- Kubernetes用のサービスアカウント作成し、上記で作成したIAMロールを付与
$ eksctl create iamserviceaccount \
> --cluster=demo-newsblog \
> --namespace=kube-system \
> --name=alb-ingress-controller \
> --attach-policy-arn=<上記のarn> \
> --override-existing-serviceaccounts \
> --approve
[ℹ] eksctl version 0.12.0
[ℹ] using region ap-northeast-1
[ℹ] 1 iamserviceaccount (kube-system/alb-ingress-controller) was included (based on the include/exclude rules)
[!] metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set
[ℹ] 1 task: { 2 sequential sub-tasks: { create IAM role for serviceaccount "kube-system/alb-ingress-controller", create serviceaccount "kube-system/alb-ingress-controller" } }
[ℹ] building iamserviceaccount stack "eksctl-demo-newsblog-addon-iamserviceaccount-kube-system-alb-ingress-controller"
[ℹ] deploying stack "eksctl-demo-newsblog-addon-iamserviceaccount-kube-system-alb-ingress-controller"
[ℹ] serviceaccount "kube-system/alb-ingress-controller" already exists
[ℹ] updated serviceaccount "kube-system/alb-ingress-controller"
-
AWS ALB Ingress controller
をdeploy
$ curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml" \
| sed "s/# - --cluster-name=devCluster/- --cluster-name=demo-newsblog/g"
| kubectl apply -f -
deployment.apps/alb-ingress-controller created
$ kubectl logs -n kube-system $(kubectl get po -n kube-system | grep alb-ingress | awk '{print $1}')
W0118 14:31:53.198889 1 client_config.go:549] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
-------------------------------------------------------------------------------
AWS ALB Ingress controller
Release: v1.1.4
Build: git-0db46039
Repository: https://github.com/kubernetes-sigs/aws-alb-ingress-controller.git
-------------------------------------------------------------------------------
- サンプルアプリケーションの 2048 game をデプロイ
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-namespace.yaml
namespace/2048-game created
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-deployment.yaml
deployment.apps/2048-deployment created
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-service.yaml
service/service-2048 created
- Ingressリソースのデプロイ
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-ingress.yaml
ingress.extensions/2048-ingress created
- 下記の
DNS-Name-Of-Your-ALB
で動作確認
$ kubectl get ingress/2048-ingress -n 2048-game
NAME HOSTS ADDRESS PORTS AGE
2048-ingress * <<アクセス先>> 80 3m
感想
eksctlとkubectlを使い分けていく必要があるのがやや面倒ですが、
AWSのリソースとの組み合わせをこのくらいの手順でやれるのは良いかもですね。
あとはproductionに耐えうるものにするにはどうするかを検討していければ実サービスでも使えそうだなと思いました。