Kubernetesで複数のTCP接続をNGINXを使って1つのLBにまとめる
Kubernetes の Ingress は、外部のトラフィックを受けるのはHTTPのみでTCPやUDPにはまだ対応していません。
現状では、それらのトラフィックを受けるには Service の type を loadBalancer
に設定することでTCPなどの接続を受けることができるようになります。
1 Service = 1 LB
ただ、Service の場合、Ingress のように条件に応じて振り分けるようなことができないため、1つの Service で1つのPodに割り振るような設定しかできません。
EKS (Amazon Elastic Kubernetes Service) の場合、Service に LoadBalancer を設定すると CLB (Classic Load Balancer) か NLB (Network Load Balancer) が1つ割り当てられます。
CLBやNLBは稼働させるだけなら1台あたり2,000円/月くらいなのですが、開発環境などで複数環境が必要になってくると、それなりの数のServiceを稼働させることになるので、お値段も気にしなるところです。
複数のServiceを1つのLBにまとめたい
NGINX では http 以外にも stream{}
ブロックを記載することで、TCP や UDP もロードバランシングすることができます。今回の要件では、この機能を使って実現したいと思います。
NGINX Docs | TCP and UDP Load Balancing
今回は下記の図のように開発環境でTCP接続が必要なアプリが複数ある場合に、1つのLBで複数のポートを開けて、NGINXで複数のServiceに振り分ける方法でやっていきます。
NGINX Ingress Controller でも同様の機能があるのですが、Ingressの機能などは不要なのと、特に設定も難しくないため1からNGINXを設定して対応します。
Exposing TCP and UDP services - NGINX Ingress Controller
設定してみる
まずは外部のトラフィックを受ける Service です。受信するポートは 4000
と 4001
に設定。
external-dns も動いているので、 annotations でドメインの設定も行行います。
---
apiVersion: v1
kind: Service
metadata:
name: nginx-sv
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-xxxxxx"
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "3600"
external-dns.alpha.kubernetes.io/hostname: "proxy.example.com"
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 4000
targetPort: 4000
name: app0
protocol: TCP
- port: 4001
targetPort: 4001
name: app1
protocol: TCP
NGINX の設定ファイルを ConfigMap に記載する
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx-stream.conf: |
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
stream {
resolver kube-dns.kube-system.svc.cluster.local valid=5s;
proxy_timeout 60m;
proxy_socket_keepalive on;
server {
listen 4000;
proxy_pass app0.default.svc.cluster.local:6000;
}
server {
listen 4001;
proxy_pass app1.default.svc.cluster.local:6000;
}
}
NGINXではDNSのTTLを無視して独自にキャッシュを持つため、下記のように短めに設定しなおします。
resolver kube-dns.kube-system.svc.cluster.local valid=5s;
NGINX の Deployment では上記のConfigMapをVolumeMountして読み込ませる
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dp
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.17
name: nginx
resources:
limits:
cpu: 500m
memory: 250Mi
ports:
- containerPort: 4000
name: app0
- containerPort: 4001
name: app1
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
name: nginx-conf
volumes:
- configMap:
name: nginx-conf
items:
- key: nginx-stream.conf
path: nginx.conf
name: nginx-conf
アプリ側のService(Deploymentなどは省略)
---
apiVersion: v1
kind: Service
metadata:
name: app0
spec:
ports:
- port: 4000
---
apiVersion: v1
kind: Service
metadata:
name: app1
spec:
ports:
- port: 4001
これで proxy.example.com
の 4000 ポートにアクセスすると app0
に、4001 ポートにアクセスすると app1
に到達するようになりました。
まとめ
NGINXを使うことで、ロードバランサーを集約することができました。
EKS の場合、Service の type が LoadBalancer の場合、デフォルトでは CLB になりますが、annotations に以下のように設定することで NLBを使うこともできます。
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
Network Load Balancer Support in Kubernetes 1.9 | AWS Open Source Blog
CLB と NLB では AWS のドキュメントにあるように機能差があります。パフォーマンスについても NLB の方が優れているようです。
特徴 - Elastic Load Balancing | AWS
また、上記には記載がありませんが、設定できるリスナーの上限は NLB は 50 で CLB は 100 になります。
Network Load Balancer のクォータ - Elastic Load Balancing
Classic Load Balancer のクォータ - Elastic Load Balancing
今回は開発環境ということでパフォーマンスはそれほど重視していないのと、アクセス制限を Security Group で行いたかったので CLB を使うことにしました。
現状では NLB は Security Group に対応していませんが、最近、TLS ターミネーションに対応したので、近い将来 Serucity Group にも対応してくれるかもしれません。
Author And Source
この問題について(Kubernetesで複数のTCP接続をNGINXを使って1つのLBにまとめる), 我々は、より多くの情報をここで見つけました https://qiita.com/SNakano/items/0770b4db0504bdd281b1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .