AWS Load Balancer Controllerを試してみたメモ。
| コンポーネント | バージョン | 備考 |
|---|---|---|
| eksctl | 0.30.0 | |
| Kubernetes バージョン | 1.18 | |
| プラットフォームのバージョン | eks.1 | |
| aws-load-balancer-controller | 2.0.0 |
参考リンク
- [What's New]Introducing the AWS Load Balancer Controller
- [AWS Blog]Introducing the AWS Load Balancer Controller
- https://github.com/kubernetes-sigs/aws-load-balancer-controller
- https://kubernetes-sigs.github.io/aws-load-balancer-controller/
- https://github.com/aws/eks-charts/tree/master/stable/aws-load-balancer-controller
- Network load balancing on Amazon EKS
- Application load balancing on Amazon EKS
概要
ALB Ingress Controllerを大幅にバージョンアップして名前も変えたもの。主な新機能は3つ。
- NLB IPモードのサポート
- 複数のIngressリソースでALBを共有できる
- TargetGroupBindingカスタムリソース
導入
クラスターを作成する。
eksctl create cluster \ --name=mycluster \ --version 1.18 \ --nodes=2 --managed \ --ssh-access --ssh-public-key=default
OICDプロバイダーを作成する。
eksctl utils associate-iam-oidc-provider \
--region ap-northeast-1 \
--cluster mycluster \
--approve
IAMポリシーを作成する。
curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam-policy.json
IAMロールとServiceAccountを作成する。
eksctl create iamserviceaccount \ --cluster=mycluster \ --namespace=kube-system \ --name=aws-load-balancer-controller \ --attach-policy-arn=arn:aws:iam::XXXXXXXXXXXX:policy/AWSLoadBalancerControllerIAMPolicy \ --override-existing-serviceaccounts \ --approve
CRDを作成する。-kはKustomizeオプション。
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
チャートのリポジトリを追加する。
helm repo add eks https://aws.github.io/eks-charts
既にリポジトリが存在した場合は、チャートを更新する。
helm repo update
チャートを確認する。
$ helm search repo aws-load-balancer NAME CHART VERSION APP VERSION DESCRIPTION eks/aws-load-balancer-controller 1.0.0 v2.0.0 AWS Load Balancer Controller Helm chart for Kub...
インストールする。
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \ --set clusterName=mycluster \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controller \ -n kube-system
以下の様に出力される。
Release "aws-load-balancer-controller" does not exist. Installing it now. NAME: aws-load-balancer-controller LAST DEPLOYED: Tue Oct 27 00:37:31 2020 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: AWS Load Balancer controller installed!
Podが起動していることを確認する。
$ kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE aws-load-balancer-controller-6c4d8d8f64-6gsw7 1/1 Running 0 81s aws-node-chr59 1/1 Running 0 7d8h aws-node-xzsx5 1/1 Running 0 4d12h coredns-86f7d88d77-d4969 1/1 Running 0 7d8h coredns-86f7d88d77-fntwt 1/1 Running 0 7d8h kube-proxy-bmp9g 1/1 Running 0 4d12h kube-proxy-r7hwz 1/1 Running 0 7d8h
カスタムリソースを確認する。
$ kubectl api-resources | grep aws eniconfigs crd.k8s.amazonaws.com false ENIConfig targetgroupbindings elbv2.k8s.aws true TargetGroupBinding securitygrouppolicies sgp vpcresources.k8s.aws true SecurityGroupPolicy
動作確認
NginxのPodを動かしてみる。
Namespaceを作成する。
$ kubectl create ns nginx namespace/nginx created
Deploymentのyamlを用意する。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx
Deploymentを作成する。
$ kubectl apply -f nginx-deployment.yaml -n nginx deployment.apps/nginx created
Podの起動を確認する。
$ kubectl get pod -n nginx NAME READY STATUS RESTARTS AGE nginx-f89759699-f5r8h 1/1 Running 0 8m33s nginx-f89759699-shdlx 1/1 Running 0 8m33s
NLB IPモード
Serviceのyamlを作成する。
apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx annotations: service.beta.kubernetes.io/aws-load-balancer-type: nlb-ip spec: type: LoadBalancer ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx
Serviceを作成する。
$ kubectl apply -f nginx-service-nlb-ip.yaml -n nginx service/nginx created
Serviceを確認する。
$ kubectl get svc -n nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx LoadBalancer 10.100.18.182 k8s-nginx-nginx-3507a5cb51-c613e91128d26166.elb.ap-northeast-1.amazonaws.com 80:30121/TCP 4m37s
TargetGroupBindingを確認する。
$ kubectl get TargetGroupBinding -n nginx
NAME SERVICE-NAME SERVICE-PORT TARGET-TYPE AGE
k8s-nginx-nginx-1800f449e6 nginx 80 ip 6m4s
$ kubectl get TargetGroupBinding -n nginx k8s-nginx-nginx-1800f449e6 -o yaml | kubectl neat
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
labels:
service.k8s.aws/stack-name: nginx
service.k8s.aws/stack-namespace: nginx
name: k8s-nginx-nginx-1800f449e6
namespace: nginx
spec:
networking:
ingress:
- from:
- ipBlock:
cidr: 192.168.0.0/19
- ipBlock:
cidr: 192.168.64.0/19
- ipBlock:
cidr: 192.168.32.0/19
ports:
- port: 80
protocol: TCP
serviceRef:
name: nginx
port: 80
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/k8s-nginx-nginx-1800f449e6/fcdb0e58910f7eb4
targetType: ip
アクセスできることを確認する。
$ curl k8s-nginx-nginx-3507a5cb51-c613e91128d26166.elb.ap-northeast-1.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>
Serviceを削除する。
$ kubectl delete svc nginx -n nginx service "nginx" deleted
TargetGroupBindingも削除される。
$ kubectl get TargetGroupBinding -n nginx No resources found in nginx namespace.
ALB IPモード
ServiceのyamlをClusterIPで作成する。
apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx spec: ports: - port: 80 selector: app: nginx
Serviceを作成する。
$ kubectl apply -f nginx-service.yaml -n nginx service/nginx created
Serviceを確認する。
$ kubectl get svc -n nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.100.55.63 <none> 80/TCP 5m25s
apiVersion: networking.k8s.io/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 alb.ingress.kubernetes.io/group.name: mygroup alb.ingress.kubernetes.io/group.order: "1" spec: rules: - http: paths: - path: /* backend: serviceName: nginx servicePort: 80
Ingressを作成する。
$ kubectl apply -f nginx-ingress.yaml -n nginx ingress.networking.k8s.io/nginx created
Ingressを確認する。
$ kubectl get ing -n nginx NAME CLASS HOSTS ADDRESS PORTS AGE nginx <none> * k8s-nginx-nginx-d736dcdd09-708216381.ap-northeast-1.elb.amazonaws.com 80 84s
TargetGroupBindingを確認する。
$ kubectl get TargetGroupBinding -n nginx
NAME SERVICE-NAME SERVICE-PORT TARGET-TYPE AGE
k8s-nginx-nginx-950afbba61 nginx 80 ip 2m16s
$ kubectl get TargetGroupBinding -n nginx k8s-nginx-nginx-950afbba61 -o yaml | kubectl neat
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
labels:
ingress.k8s.aws/stack-name: nginx
ingress.k8s.aws/stack-namespace: nginx
name: k8s-nginx-nginx-950afbba61
namespace: nginx
spec:
networking:
ingress:
- from:
- securityGroup:
groupID: sg-060f79f358f95e020
ports:
- protocol: TCP
serviceRef:
name: nginx
port: 80
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/k8s-nginx-nginx-950afbba61/f413f7ba74cb55b0
targetType: ip
ALB インスタンスモード
2つめのServiceのyamlをNodePortで作成する。バックエンドは同じにする。
apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx2 spec: type: NodePort ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx
Serviceを作成する。
$ kubectl apply -f nginx2-service.yaml -n nginx service/nginx2 created
Serviceを確認する。
$ kubectl get svc -n nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.100.55.63 <none> 80/TCP 13m nginx2 NodePort 10.100.40.227 <none> 80:31721/TCP 6s
2つめのIngressのyamlをし、同じグループを指定する。ターゲットタイプは指定しない。
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx2 annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/group.name: mygroup alb.ingress.kubernetes.io/group.order: "2" spec: rules: - http: paths: - path: /test backend: serviceName: nginx servicePort: 80
Ingressを作成する。
$ kubectl apply -f nginx2-ingress.yaml -n nginx ingress.networking.k8s.io/nginx2 created
Ingressを確認する。同じアドレスになっていることが確認できる。
$ kubectl get ing -n nginx NAME CLASS HOSTS ADDRESS PORTS AGE nginx <none> * k8s-mygroup-013347b429-1627155524.ap-northeast-1.elb.amazonaws.com 80 13m nginx2 <none> * k8s-mygroup-013347b429-1627155524.ap-northeast-1.elb.amazonaws.com 80 46s
TargetGroupBindingを確認する。
$ kubectl get TargetGroupBinding -n nginx -o wide
NAME SERVICE-NAME SERVICE-PORT TARGET-TYPE ARN AGE
k8s-nginx-nginx-8518c96606 nginx 80 instance arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/k8s-nginx-nginx-8518c96606/eb9c2fa6e1869391 2m11s
k8s-nginx-nginx-d2e1c8852a nginx 80 ip arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/k8s-nginx-nginx-d2e1c8852a/b02b4bd445d1752c 4m5s
$ kubectl get TargetGroupBinding -n nginx k8s-nginx-nginx-8518c96606 -o yaml | kubectl neat
apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
labels:
ingress.k8s.aws/stack: mygroup
name: k8s-nginx-nginx-8518c96606
namespace: nginx
spec:
networking:
ingress:
- from:
- securityGroup:
groupID: sg-07588c5428ac89e2e
ports:
- protocol: TCP
serviceRef:
name: nginx
port: 80
targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:targetgroup/k8s-nginx-nginx-8518c96606/eb9c2fa6e1869391
targetType: instance
マネジメントコンソールを確認する。ALBが1つ作られている。

ターゲットグループは2つ作られている。

リスナールールを確認する。指定した通りルールができている(2つめに到達しないルールになってしまっている)。
