はじめに
KubernetesのマネージドサービスであるAmazon EKSを試用します。
ポッドの実行環境としてはEC2とAWS Fargateが選択できますが、EC2インスタンスの管理が不要なFargateを使います。
実行環境
macOS Catalina Version 10.15.5
eksctlでEKSクラスタを作成
以下のリンク先を参考に進めていきます。
Getting started with eksctl - Amazon EKS
前提
❯ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" ❯ sudo installer -pkg AWSCLIV2.pkg -target /
AWS CLIと eksctl
がAWSとやり取りするために必要な設定を行います。
❯ aws configure AWS Access Key ID [None]: <your-access-key> AWS Secret Access Key [None]: <your-secret-access-key> Default region name [None]: <region-code> Default output format [None]: <json>
- eksctl(とkubectl)のインストール
Homebrewで eksctl
をインストールすると kubectl
も一緒にインストールしてくれます。
❯ brew tap weaveworks/tap ❯ brew install weaveworks/tap/eksctl
EKSクラスタの作成
eksctl create cluster
でクラスタを作成します。
バージョンは公式マニュアルに従い 1.18
、リージョンは東京( ap-northeast-1
)を指定しました。
Fargateを使うので --fargate
オプションが必要です。
❯ eksctl create cluster \ --name <your-cluster-name> \ --version 1.18 \ --region ap-northeast-1 \ --fargate ... [✔] EKS cluster "..." in "ap-northeast-1" region is ready
この時点ではCoreDNSのポッド2つのみが存在します。
❯ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-84c76989c7-8s58g 1/1 Running 0 4d8h kube-system coredns-84c76989c7-pb5cb 1/1 Running 0 4d8h
サンプルアプリのデプロイ
続けてサンプルアプリをデプロイします。
Deploy a sample Linux application - Amazon EKS
名前空間は標準で作成される default
を指定しました。
apiVersion: v1 kind: Service metadata: name: my-service namespace: default labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: default labels: app: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 - arm64 containers: - name: nginx image: nginx:1.19.2 ports: - containerPort: 80
作成したマニフェストを指定し、 kubectl apply
でアプリケーションをデプロイします。
❯ kubectl apply -f sample-pod.yml service/my-service created deployment.apps/my-deployment created
kubectl get all
で作成されたリソースを確認します。
Deployment
の spec.replicas
に3を設定したので3つのポッドが作成されました。
❯ kubectl get all NAME READY STATUS RESTARTS AGE pod/my-deployment-68f6fff96f-ccdkn 1/1 Running 0 2m21s pod/my-deployment-68f6fff96f-gdv8t 1/1 Running 0 2m21s pod/my-deployment-68f6fff96f-lxp54 1/1 Running 0 2m21s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 22h service/my-service ClusterIP 10.100.149.193 <none> 80/TCP 2m21s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-deployment 3/3 3 3 2m21s NAME DESIRED CURRENT READY AGE replicaset.apps/my-deployment-68f6fff96f 3 3 3 2m21s
kubectl describe
でリソースの詳細を確認できます。
❯ kubectl -n default describe service my-service Name: my-service Namespace: default Labels: app=my-app ... ❯ kubectl -n default describe pod my-deployment-68f6fff96f-ccdkn Name: my-deployment-68f6fff96f-ccdkn Namespace: default Priority: 2000001000 ...
kubectl exec -it <ポッドの名前> -n <名前空間> -- /bin/bash
でポッド(コンテナ)の中に入れます。
❯ kubectl exec -it my-deployment-68f6fff96f-ccdkn -n default -- /bin/bash root@my-deployment-68f6fff96f-ccdkn:/#
ロードバランサの設定
この時点では外部からアクセスできないので、ALB Ingress ControllerをEKSクラスターにデプロイします。
(EKS on Fargateで使用できるロードバランサはALBのみ。)
ALB Ingress ControllerはIngressリソースの作成を契機にALBを作成してくれます。
ALB Ingress Controller on Amazon EKS - Amazon EKS
IAM OIDCプロバイダーの作成
❯ eksctl utils associate-iam-oidc-provider --region ap-northeast-1 --cluster <your-cluster-name> --approve [ℹ] eksctl version 0.30.0 [ℹ] using region ap-northeast-1 [ℹ] will create IAM Open ID Connect provider for cluster "<your-cluster-name>" in "ap-northeast-1" [✔] created IAM Open ID Connect provider for cluster "<your-cluster-name>" in "ap-northeast-1"
ALB Ingress Controllerポッド用のIAMポリシーを作成
ALB Ingress ControllerがAWSのAPIを呼び出すために必要となるIAMポリシー <ALBIngressControllerIAMPolicy>
を作成します。
ポリシーを作成した際に出力されるARNをメモしておきます。
❯ curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/iam-policy.json ❯ aws iam create-policy --policy-name ALBIngressControllerIAMPolicy --policy-document file://iam-policy.json { "Policy": { "PolicyName": "ALBIngressControllerIAMPolicy", ... } } ❯ rm iam-policy.json
alb-ingress-controllerサービスアカウント、ClusterRole、ClusterRoleBindingの作成
❯ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/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のIAMロールを作成し、ロールをサービスアカウントに割り当て
--attach-policy-arn
にはALB Ingress Controllerポッド用のIAMポリシーを作成で確認したARNを指定します。
❯ eksctl create iamserviceaccount \ --region ap-northeast-1 \ --name alb-ingress-controller \ --namespace kube-system \ --cluster <your-cluster-name> \ --attach-policy-arn arn:aws:iam::<111122223333>:policy/<ALBIngressControllerIAMPolicy> \ --override-existing-serviceaccounts \ --approve [ℹ] eksctl version 0.30.0 [ℹ] using region ap-northeast-1 [ℹ] 2 iamserviceaccounts (kube-system/alb-ingress-controller, kube-system/aws-node) were included (based on the include/exclude rules) ... [ℹ] updated serviceaccount "kube-system/aws-node"
ALB Ingress Controllerをデプロイ
❯ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/alb-ingress-controller.yaml deployment.apps/alb-ingress-controller created
ALB Ingress Controllerデプロイメントのマニフェストを編集
❯ kubectl edit deployment.apps/alb-ingress-controller -n kube-system
spec.containers.args
に --cluster-name
、 --aws-vpc-id
、 --aws-region
を設定します。
spec: containers: - args: - --ingress-class=alb - --cluster-name=<your-cluster-name> - --aws-vpc-id=<your-vpc-id> - --aws-region=ap-northeast-1
ALB Ingress Controllerのポッドを確認
kube-system
に alb-ingress-controller
のポッドが出来上がりました。
❯ kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE alb-ingress-controller-65fcfcd9d4-nzpdr 1/1 Running 1 2m15s coredns-84c76989c7-8s58g 1/1 Running 0 23h coredns-84c76989c7-pb5cb 1/1 Running 0 23h
Ingressリソースを作成
Ingressリソースを作成し、サンプルアプリのService my-service
に接続するALBを用意します。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: "ingress" namespace: "default" annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip labels: app: ingress spec: rules: - http: paths: - path: /* backend: serviceName: my-service servicePort: 80
❯ kubectl apply -f ingress.yaml ingress.extensions/ingress created
動作確認
kubectl get ingress
で取得したアドレスにアクセスできることを確認します。
❯ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress <none> * ... 80 2m6s
後片付け
最後に kubectl delete
でデプロイしたサンプルアプリを削除します。
❯ kubectl delete -f sample-pod.yml service "my-service" deleted deployment.apps "my-deployment" deleted