LoginSignup
16
11

More than 3 years have passed since last update.

aws EKS で いろいろなロードバランサー構成を試してみた

Posted at

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)構成

一番シンプルに構築できるロードバランサー構成

image.png

  • 良い点

    • 管理する対象が一つで済むので、他の構成より障害のリスクが小さくなる
    • IPモードにすると、Podへ直接ロードバランシングしてくれるのでオーバーヘッドを少なくできる
    • AWSのセキュリティグループが使える
  • 懸念事項

    • 異なるNamespaceのService(Podも含む)を混在出来ないので、ALBをNamespace毎に作成する必要がある(費用が増える)
    • rewrite-targetが使えない
Deployment+Service(app-a).yaml
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
ALB.yaml
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がカバーする構成
image.png

  • 良い点

    • 異なるNamespaceのService(Podも含む)を混在させることが可能。AWS上で作成するLBの数を減らすことができる
    • rewrite-targetが使える
    • AWSのセキュリティグループが使える
  • 懸念事項

    • NGINX Ingress ControllerのPodの可用性を考える必要がある
ALB.yaml
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
Deployment+Service(app-a).yaml
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
NGINX_Ingress(app-a).yaml
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
Deployment+Service(app-b).yaml
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
NGINX_Ingress(app-b).yaml
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の方が関連記事も多く、事例が多い感じです。

image.png

  • 良い点

    • 外部LBのIPアドレスを固定にできるので、IPを制限してセキュリティを向上させることがやりやすい
    • 異なるNamespaceのService(Podも含む)を混在させることが可能。AWS上で作成するLBの数を減らすことができる
    • rewrite-targetが使える
  • 懸念事項

    • NGINX Ingress ControllerのPodの可用性を考える必要がある
    • AWSのセキュリティグループが使えない
NLB.yaml
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
Deployment+Service(app-a).yaml
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
NGINX_Ingress(app-a).yaml
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
Deployment+Service(app-b).yaml
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
NGINX_Ingress(app-b).yaml

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/

16
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11