What's This
AWSにおいて、k8sでいうIngressはどう作成するのか調査。
ALBを使うのだろうということは想定していたが、どうやって作成するのか気になった。
AWS Load Balancer Controllerを使用して、Ingress を作成したメモです。
あくまでメモなので、参考にされる場合は、公式ドキュメント等の副読的な感じで読まれると幸いです。
概念
大まかな概念
ALBは、Kubernetes Manifestから、ALB Ingress Controllerを使用して作成できる。
このControllerは、元々はAWS ALB Ingress Controllerだったものが、
Rename & Redesignedされて、AWS Load Balancer Controllerに変わったらしい。
(何が変わったのかよくわかっていない)
*元々ALBしか作成できなかったが、ALBとNLBも作成できるようになった、という変更があるらしい。
前者の方はもう開発もされておらず、最新のk8s Versionもサポートしないらしい。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html
https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/expose/expose-intro/
modeについて
Instance mode
クラスター内のノードをALBのターゲットとして登録する。
デフォルトのモード。
サービスの NodePort にルーティングされてから、pods にプロキシされる。
(NodePortはKubernetesのNodeのランダムなポートを使用して外部のサーバーからの疎通性を取ってくれる。)
以下のように、Annotationで明示的に指定することもできる。
alb.ingress.kubernetes.io/target-type: instance
IP mode
Podを ALBのターゲットとして設定する。
ALB に到達するトラフィックは、サービスの pods に直接ルーティングされる。
このトラフィックモードを使用するには、 以下のように、Annotationで指定する。
alb.ingress.kubernetes.io/target-type: ip
イメージ
やってみた
ALB Ingress Controllerを使用して、ALBを作成する。DNS名でアプリを開けるか検証する。
ALB Ingress Controller用にIAMを整える
# Cluster Create
eksctl create cluster --name=`Cluster Name` --nodes=1 --node-type=t3.small --zones=ap-northeast-1a,ap-northeast-1c --without-nodegroup
# eksctl versionが最新であることを確認
$ eksctl version
0.107.0
# OIDC Create
$ eksctl utils associate-iam-oidc-provider --region ap-northeast-1 --cluster `Cluster Name` --approve
# NodeGroup Create
$ eksctl create nodegroup --cluster=`Cluster Name` --region=ap-northeast-1 --name=`NodeGroup Name` --node-type=t3.medium --nodes-min=2 --nodes-max=4 --node-volume-size=20 --ssh-access --managed --asg-access --external-dns-access --full-ecr-access --appmesh-access --alb-ingress-access
$ eksctl get nodegroup --cluster=`Cluster Name`
# Context 設定
$ aws eks --region ap-northeast-1 update-kubeconfig --name `Cluster Name`
# Nodeができていることを確認
$ kubectl get nodes
# AWS Load Balancer ControllerにIAMポリシーを作成し、AWS APIへの呼び出しを代行させる。
$ curl -o iam_policy_latest.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
# Create Policy
$ aws iam create-policy \
> --policy-name AWSLoadBalancerControllerIAMPolicy \
> --policy-document file://iam_policy_latest.json
# Create IAM Role using eksctl
# kube-system名前空間に、作成予定のサービスアカウントがないことを確認。
$ kubectl get sa -n kube-system
$ kubectl get sa aws-load-balancer-controller -n kube-system
Error from server (NotFound): serviceaccounts "aws-load-balancer-controller" not found
$ eksctl create iamserviceaccount \
> --cluster=`Cluster Name` \
> --namespace=kube-system \
> --name=aws-load-balancer-controller \
> --attach-policy-arn=arn:aws:iam::`Account Number`:policy/AWSLoadBalancerControllerIAMPolicy \
> --override-existing-serviceaccounts \
> --approve
$ eksctl get iamserviceaccount --cluster `Cluster Name`
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::
$ kubectl get sa aws-load-balancer-controller -n kube-system
NAME SECRETS AGE
aws-load-balancer-controller 1 7m8s
$ kubectl describe sa aws-load-balancer-controller -n kube-system
Name: aws-load-balancer-controller
Namespace: kube-system
Labels: app.kubernetes.io/managed-by=eksctl
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::
Image pull secrets: <none>
Mountable secrets: aws-load-balancer-controller-token-
Tokens: aws-load-balancer-controller-token-
Events: <none>
Helm & aws-load-balancer-controller Install
# Helm Install
$ brew install helm
$ helm version
$ helm repo update
# ECRについてはコード外の資料を参照
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=`Cluster Name` --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set image.repository=602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon/aws-load-balancer-controller
NAME: aws-load-balancer-controller
LAST DEPLOYED:
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!
$ kubectl -n kube-system get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 36s
coredns 2/2 2 2 60m
$ kubectl -n kube-system describe deployment aws-load-balancer-controller
# Webhook-svcが作成されていることを確認。
$ kubectl -n kube-system get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
aws-load-balancer-webhook-service ClusterIP xx.xxx.xx.x <none> 443/TCP 73s
kube-dns ClusterIP xx.xxx.x.x <none> 53/UDP,53/TCP 60m
$ kubectl -n kube-system describe svc aws-load-balancer-webhook-service
$ kubectl -n kube-system get svc aws-load-balancer-webhook-service -o yaml
$ kubectl -n kube-system get deployment aws-load-balancer-controller -o yaml
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
aws-load-balancer-controller-xxxxxxxxxxxxxxxxx 1/1 Running 0 8m12s
aws-load-balancer-controller-xxxxxxxxxxxxxxxx 1/1 Running 0 8m12s
aws-node-xxxxx 1/1 Running 0 43m
aws-node-xxxxx 1/1 Running 0 43m
coredns-xxxxxxxxxxxxxxxx 1/1 Running 0 67m
coredns-xxxxxxxxxxxxxxxx 1/1 Running 0 67m
kube-proxy-xxxxx 1/1 Running 0 43m
kube-proxy-xxxxx 1/1 Running 0 43m
# Log 確認
$ kubectl -n kube-system logs -f aws-load-balancer-controller-xxxxxxxxxxxxxxxxx
# Secretが作成されていることを確認
$ kubectl -n kube-system get sa aws-load-balancer-controller -o yaml
$ kubectl -n kube-system get secret aws-load-balancer-controller-token-xxxxx -o yaml
$ kubectl -n kube-system get secret aws-load-balancer-controller-token-xxxxx
NAME TYPE DATA AGE
aws-load-balancer-controller-token-xxxxx kubernetes.io/service-account-token 3 28m
$ kubectl -n kube-system get secret aws-load-balancer-controller-token-xxxxx -o yaml
# kube-system内のdeployment確認
$ kubectl get deployment.apps -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 48m
coredns 2/2 2 2 107m
$ kubectl describe deployment.apps/aws-load-balancer-controller -n kube-system
ECRについては以下参照
https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html
Sample Application Deploy
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/examples/2048/2048_full.yaml
namespace/game-2048 created
deployment.apps/deployment-2048 created
service/service-2048 created
ingress.networking.k8s.io/ingress-2048 created
$ kubectl get ingress/ingress-2048 -n game-2048
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-2048 alb * k8s-game2048-ingress2-xxx.ap-northeast-1.elb.amazonaws.com 80 22s
ADDRESSにアクセス。表示されました。
Conclusion
この検証では、バージョン関係でエラーになり、最初からやり直すことが多かったので、
もし試す際には、その辺りを意識されると手戻りが少なく済むかもしれないです。
例
https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/ v2.4.2
/
https://kubernetes-sigs.github.io/aws-load-balancer-controller/ v2.3
/
こんな感じで、kubernetes sigsのリソースを使用する際は、バージョンが最新か確認するといいかもしれないです。
Refference
・https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/alb-ingress.html
・https://www.eksworkshop.com/beginner/130_exposing-service/ingress/
・https://dev.classmethod.jp/articles/eks-aws-alb-ingress-controller/
・https://developer.mamezou-tech.com/containers/k8s/tutorial/ingress/ingress-aws/
・https://github.com/stacksimplify/aws-eks-kubernetes-masterclass/tree/master/08-NEW-ELB-Application-LoadBalancers/08-01-Load-Balancer-Controller-Install
参考にさせていただきました。ありがとうございます。