前言
在使用 EKS 的情況下,基本上都會有為 Pod 建立 Ingress / Service 來讓服務可以被存取的需求。在 EKS 的場景中,通常都會透過 aws-load-balancer-controller
[1](這也是 AWS 官方建議的方式)來建立 ALB / NLB。然而,在預設的情況下,一個 Ingress 會對應到一個 ALB。一個 Service 會對應到一個 NLB。但是很多時候會為了節省成本(或是業務確實沒有那麼大流量的需求)來減少 ALB / NLB 的數量。這邊介紹一些可以共用 ALB / NLB 的方式。
ALB
在使用 aws-load-balancer-controller
的情況下,可以透過 IngressGroup[2] 這個功能來達成共用 ALB 的需求。具體做法是透過為 Ingress 資源添加 alb.ingress.kubernetes.io/group.name
annotations。以下為範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: orange-purple-ingress namespace: orange-purple-ns labels: app: color-2 annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/group.name: app-color-lb spec: ingressClassName: alb rules: - http: paths: - path: /orange pathType: Prefix backend: service: name: orange-service port: number: 80
|
NLB
在使用 aws-load-balancer-controller
的情況下,官方目前並沒有一個推薦的方式可以做到這件事情。以下提供一些做法:
- 自行建立 NLB / Listener / Targetgroup 等資源,並在 EKS 叢集當中建立 TargetGroupBinding[3] 資源,讓叢集當中多個 Service 可以共用同一個 NLB。以下為範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: elbv2.k8s.aws/v1beta1 kind: TargetGroupBinding metadata: name: red-tgb namespace: red-ns spec: serviceRef: name: red-service port: 80 targetGroupARN: <target-group-arn> networking: ingress: - from: - ipBlock: cidr: "0.0.0.0/0" ports: - port: 80
|
- 上面的方式雖然可行,但是 NLB 就會脫離 EKS 叢集的掌控。如果想要讓 NLB 也可以被叢集管理,可以透過為 Service 建立不同的 port,並且讓不同的 port 對應到不同的 Deployment[4]。值得注意的是,這個方式似乎一定要使用 named ports。以下為範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: app: exampleapp role: fe template: metadata: labels: app: exampleapp role: fe spec: containers: - name: nginx image: patientplatypus/kubeplayfrontend ports: - name: frontend containerPort: 3000 --- apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 1 selector: matchLabels: app: exampleapp role: be template: metadata: labels: app: exampleapp role: be spec: containers: - name: nginx image: patientplatypus/kubeplaybackend ports: - name: backend containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: entrypt spec: type: LoadBalancer ports: - name: backend port: 8080 targetPort: backend - name: frontend port: 8081 targetPort: frontend selector: app: exampleapp
|
參考
[1] https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/
[2] https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/ingress/annotations/#ingressgroup
[3] https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/guide/targetgroupbinding/targetgroupbinding/#targetgroupbinding
[4] https://github.com/kubernetes/kubernetes/issues/24875#issuecomment-794596576