ALB Ingress Controllerを試してみたメモ。
参考リンク
環境
コンポーネント | バージョン | 備考 |
---|---|---|
eksctl | 0.13.0 | |
Kubernetes バージョン | 1.14 | |
プラットフォームのバージョン | eks.7 | |
aws-alb-ingress-controller | v1.1.4 |
注意点
- ALB Ingress Controllerで管理してもらうためには、Ingressのアノテーションで
kubernetes.io/ingress.class: alb
を指定する - トラフィックモードが2種類あり、
alb.ingress.kubernetes.io/target-type
で指定する- 「インスタンス」の場合、NodePort経由でPodにルーティングされるので、Serviceは
NodePort
で公開する必要がある - 「IP」の場合、PodのIPに直接ルーティングされる
- 「インスタンス」の場合、NodePort経由でPodにルーティングされるので、Serviceは
クラスターの作成
クラスターを作成する。
eksctl create cluster --name=mycluster --nodes=3 --managed --ssh-access --ssh-public-key=sotosugi
ALB Ingress Controlerに必要なRoleはWorkerノードのインスタンスに付与してもよいし、よりセキュアな方法としてIAM Roles for ServiceAccount(IRSA)でPodに付与することもできる。
eksctl
でのクラスターの作成時に--alb-ingress-access
のフラグをつけることで、WorkerノードにIAMロールを付与できるが、今回はマニュアルの記載にしたがってIRSAを使う。
サブネットにタグ付けが必要だが、eksctlで作っていればタグ付けされている。
全てのサブネットに以下が必要。
キー | 値 |
---|---|
kubernetes.io/cluster/<cluster-name> |
shared |
パブリックサブネットに以下を必要。
キー | 値 |
---|---|
kubernetes.io/role/elb |
1 |
プライベートサブネットに以下をが必要。
キー | 値 |
---|---|
kubernetes.io/role/internal-elb |
1 |
ALB Ingress Controllerのデプロイ
ALB Ingress Controllerをデプロイする。
IRSAの設定
IAM OIDC プロバイダーを作成し、クラスターに関連づける。eksctl
がやってくれる。
eksctl utils associate-iam-oidc-provider \ --cluster mycluster \ --approve
AWS CLIでやることも可能だが、サムプリントの取得がやや面倒。
aws iam create-open-id-connect-provider
- Kubernetes サービスアカウントに対するきめ細やかな IAM ロール割り当ての紹介
- OpenID Connect ID プロバイダーのルート CA サムプリントの取得
作成されたOIDCプロバイダーを確認する。
aws iam list-open-id-connect-providers
ALB Ingress ControllerのPodに割り当てるためのIAMポリシーを作成する。
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/iam-policy.json aws iam create-policy \ --policy-name ALBIngressControllerIAMPolicy \ --policy-document file://iam-policy.json
出力されるこのポリシーのARNが後で必要になるのでメモしておく。
alb-ingress-controller
という名前のServiceAccount、ClusterRole、ClusterRoleBindingを作成する。
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml
ALB Ingress Controller用のIAMロールを作成し、このロールに前のステップで作成したServiceAccountをアタッチし、作成済みのIAMポリシーをアタッチする。eksctl
を使うとまとめてやってくれる。
eksctl create iamserviceaccount \ --name alb-ingress-controller \ --namespace kube-system \ --cluster mycluster \ --attach-policy-arn <ALBIngressControllerIAMPolicyのARN> \ --override-existing-serviceaccounts \ --approve
ServiceAccountへのアノテーションの付与もやってくれている。
$ kubectl get sa -n kube-system alb-ingress-controller -o yaml apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXXX:role/eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J creationTimestamp: "2020-02-26T13:29:55Z" name: alb-ingress-controller namespace: kube-system resourceVersion: "5890" selfLink: /api/v1/namespaces/kube-system/serviceaccounts/alb-ingress-controller uid: 1359da05-589c-11ea-8f07-0a9b53daa8b6 secrets: - name: alb-ingress-controller-token-q6qlt $
IAMロールを確認する。信頼関係の部分が独特。
$ aws iam get-role --role-name eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J { "Role": { "Path": "/", "RoleName": "eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J", "RoleId": "AROAYXO4ULJGYQS6MY7J3", "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J", "CreateDate": "2020-02-26T13:29:24+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::XXXXXXXXXXXX:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/ABBA5808E08E5733D7FEF998BD06C077" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.ap-northeast-1.amazonaws.com/id/ABBA5808E08E5733D7FEF998BD06C077:sub": "system:serviceaccount:kube-system:alb-ingress-controller", "oidc.eks.ap-northeast-1.amazonaws.com/id/ABBA5808E08E5733D7FEF998BD06C077:aud": "sts.amazonaws.com" } } } ] }, "Description": "", "MaxSessionDuration": 3600, "Tags": [ { "Key": "alpha.eksctl.io/cluster-name", "Value": "mycluster" }, { "Key": "eksctl.cluster.k8s.io/v1alpha1/cluster-name", "Value": "mycluster" }, { "Key": "alpha.eksctl.io/iamserviceaccount-name", "Value": "kube-system/alb-ingress-controller" } ], "RoleLastUsed": {} } }
$ aws iam list-attached-role-policies --role-name eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J { "AttachedPolicies": [ { "PolicyName": "ALBIngressControllerIAMPolicy", "PolicyArn": "arn:aws:iam::XXXXXXXXXXXX:policy/ALBIngressControllerIAMPolicy" } ] }
$ aws iam list-role-policies --role-name eksctl-mycluster-addon-iamserviceaccount-kub-Role1-V4WM5Y6XVY6J { "PolicyNames": [] }
AWS CLIでも可能だが面倒で、以下の手順とアノテーション設定が必要。
ALB Ingress Controllerのデプロイ
ALB Ingress ControllerをDeploymentを作成する。
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml
Deployment定義の一部を編集する。
kubectl edit deployment.apps/alb-ingress-controller -n kube-system
spec:
containers:
- args:
- --ingress-class=alb
+ - --cluster-name=mycluster
image: docker.io/amazon/aws-alb-ingress-controller:v1.1.4
imagePullPolicy: IfNotPresent
name: alb-ingress-controller
稼働を確認する。
$ kubectl get po -n kube-system -l app.kubernetes.io/name=alb-ingress-controller NAME READY STATUS RESTARTS AGE alb-ingress-controller-577cb9c49b-rvk7b 1/1 Running 0 76s
稼働確認
Deploymentを作成する。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
kubectl apply -f nginx-deployment.yaml
Serviceを作成する。
apiVersion: v1 kind: Service metadata: name: nginx spec: type: ClusterIP selector: app: nginx ports: - port: 80 targetPort: 80
kubectl apply -f nginx-service.yaml
Ingressを作成する。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - http: paths: - path: /* backend: serviceName: nginx servicePort: 80
kubectl apply -f nginx-ingress.yaml
作成したリソースを確認する。
$ kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nginx 2/2 2 2 4m57s $ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 81m nginx ClusterIP 10.100.155.164 <none> 80/TCP 2m55s $ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE nginx * 80934e0c-default-nginx-ef8b-1267588155.ap-northeast-1.elb.amazonaws.com 80 25m
作成されたALBを確認する。
aws elbv2 describe-load-balancers
URLにアクセスして確認。
$ curl 80934e0c-default-nginx-ef8b-1267588155.ap-northeast-1.elb.amazonaws.com <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>