AWS EKSで使えるロードバランサーには複数の種類があって、どう構成するべきか悩みどころなので色々試してみました。
今回使ったKubernetesのロードバランサーの種類
今回は以下の3種類をつかって、ロードバランサーの構成パターンを試してみました。
これ以外の種類もあります。
ロードバランサー | 種類 | 導入するController |
---|---|---|
aws ALB (Application Load Balancer) | Ingress(L7) | AWS ALB Ingress Controller |
aws NLB (Network Load Balancer) | Service(L4) | 不要 |
NGINX Ingress Controller | Ingress(L7) | NGINX Ingress Controller |
aws ALB(L7)構成
一番シンプルに構築できるロードバランサー構成
-
良い点
- 管理する対象が一つで済むので、他の構成より障害のリスクが小さくなる
- IPモードにすると、Podへ直接ロードバランシングしてくれるのでオーバーヘッドを少なくできる
- AWSのセキュリティグループが使える
-
懸念事項
- 異なるNamespaceのService(Podも含む)を混在出来ないので、ALBをNamespace毎に作成する必要がある(費用が増える)
- rewrite-targetが使えない
apiVersion: v1
kind: Namespace
metadata:
name: app-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
replicas: 3
selector:
matchLabels:
run: app-a
template:
metadata:
labels:
run: app-a
spec:
containers:
- image: nginx
name: app-a
---
apiVersion: v1
kind: Service
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
type: NodePort
selector:
run: app-a
ports:
- port: 80
protocol: TCP
targetPort: 80
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: app-a
name: alb-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: app-a
servicePort: 80
aws ALB(L7) + Nginx Ingress(L7)構成
aws ALBの良いところを活かしつつ、ALBの懸念事項をNginx Ingress Controllerがカバーする構成
-
良い点
- 異なるNamespaceのService(Podも含む)を混在させることが可能。AWS上で作成するLBの数を減らすことができる
- rewrite-targetが使える
- AWSのセキュリティグループが使える
-
懸念事項
- NGINX Ingress ControllerのPodの可用性を考える必要がある
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: kube-system
name: alb-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
rules:
- http:
paths:
- backend:
serviceName: (NGINX Ingress Controllerのサービス名)
servicePort: 80
apiVersion: v1
kind: Namespace
metadata:
name: app-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
replicas: 3
selector:
matchLabels:
run: app-a
template:
metadata:
labels:
run: app-a
spec:
containers:
- image: nginx
name: app-a
---
apiVersion: v1
kind: Service
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
type: ClusterIP
selector:
run: app-a
ports:
- port: 80
protocol: TCP
targetPort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: app-a
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: (ALBのDNS名)
http:
paths:
- path: /app-a(/|$)(.*)
backend:
serviceName: app-a
servicePort: 80
apiVersion: v1
kind: Namespace
metadata:
name: app-b
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app-b
name: app-b
labels:
run: app-b
spec:
replicas: 3
selector:
matchLabels:
run: app-b
template:
metadata:
labels:
run: app-b
spec:
containers:
- image: nginx
name: app-b
---
apiVersion: v1
kind: Service
metadata:
namespace: app-b
name: app-b
labels:
run: app-b
spec:
type: ClusterIP
selector:
run: app-b
ports:
- port: 80
protocol: TCP
targetPort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: app-b
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: (ALBのDNS名)
http:
paths:
- path: /app-b(/|$)(.*)
backend:
serviceName: app-b
servicePort: 80
aws NLB(L4) + Nginx Ingress(L7)構成
aws ALB + Nginx Ingressとよく似ている。細かい点で一長一短あるものの、Google検索してみるとALBの方が関連記事も多く、事例が多い感じです。
-
良い点
- 外部LBのIPアドレスを固定にできるので、IPを制限してセキュリティを向上させることがやりやすい
- 異なるNamespaceのService(Podも含む)を混在させることが可能。AWS上で作成するLBの数を減らすことができる
- rewrite-targetが使える
-
懸念事項
- NGINX Ingress ControllerのPodの可用性を考える必要がある
- AWSのセキュリティグループが使えない
apiVersion: v1
kind: Service
metadata:
namespace: kube-system
name: nlb-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
release: nginx-ingress-controller
ports:
- name: http
port: 80
protocol: TCP
apiVersion: v1
kind: Namespace
metadata:
name: app-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
replicas: 3
selector:
matchLabels:
run: app-a
template:
metadata:
labels:
run: app-a
spec:
containers:
- image: nginx
name: app-a
---
apiVersion: v1
kind: Service
metadata:
namespace: app-a
name: app-a
labels:
run: app-a
spec:
type: ClusterIP
selector:
run: app-a
ports:
- port: 80
protocol: TCP
targetPort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: app-a
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: (NLBのDNS名)
http:
paths:
- path: /app-a(/|$)(.*)
backend:
serviceName: app-a
servicePort: 80
apiVersion: v1
kind: Namespace
metadata:
name: app-b
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: app-b
name: app-b
labels:
run: app-b
spec:
replicas: 3
selector:
matchLabels:
run: app-b
template:
metadata:
labels:
run: app-b
spec:
containers:
- image: nginx
name: app-b
---
apiVersion: v1
kind: Service
metadata:
namespace: app-b
name: app-b
labels:
run: app-b
spec:
type: ClusterIP
selector:
run: app-b
ports:
- port: 80
protocol: TCP
targetPort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: app-b
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: (NLBのDNS名)
http:
paths:
- path: /app-b(/|$)(.*)
backend:
serviceName: app-b
servicePort: 80
感想
個人的な感想としては、なるべくシンプルな構成で作成するLBの数を減らすことが出来てセキュリティグループも使える「aws ALB + Nginx Ingress構成」が使いやすいのかとは思います。
ただ、スロットリングなどを実装しようとすると、また色々考えなければならないなと思います。AWS側で制御させるのであればAPI Gatewayを組み合わせるなどのパターンもありかもしれません。
参考
Amazon EKSでIngress Controllerに何を採用するか検討した
https://tech.recruit-mp.co.jp/infrastructure/post-19310/
Namespaceの異なるIngressリソースを1つのALBで対応する
https://qiita.com/samskeyti/items/4b5b25f92f66bbaa9a36
API Gateway as an Ingress Controller for Amazon EKS
https://aws.amazon.com/jp/blogs/opensource/network-load-balancer-nginx-ingress-controller-eks/