如何創建基於埠將流量路由到不同 Pod 的 Kubernetes 服務?
我想要一個 LoadBalancer 類型的服務,它指向埠 80 上的 nginx,並指向埠 22 的單獨 sshd pod。但是我無法使用單個選擇器基於埠進行路由。
我要使用的案例類似於 github.com,它接受 github.com 的 80 埠流量和 22 埠的 ssh 流量。因此,在這種情況下,DNS 將指向一組 k8s 負載均衡器,我假設它們將路由到每個埠的適當 pod。因此,如果我以錯誤的方式進行操作,請讓我知道。我對其他解決方案持開放態度。
我想避免做的是設置一個單獨的 pod,比如 HAProxy,它按埠路由。
我研究過使用 Ingress,但這僅適用於 HTTP 流量。
Ingress 不會暴露任意埠或協議。向 Internet 公開 HTTP 和 HTTPS 以外的服務通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 類型的服務。
https://kubernetes.io/docs/concepts/services-networking/ingress/
感謝@Ivan M. 為我指明了正確的方向,我只想在此處添加解決方案的程式碼範例:
首先,令人困惑的是,kubernetes 文件讓我誤以為您不能將入口用於非 http 流量。您必須知道的是,您可以使用不同的入口控制器。使用 nginx 入口控制器,您可以代理任意 tcp 甚至 udp 流量。
第二個障礙是 nginx 入口有兩個單獨的儲存庫。那些是:
我最終使用了 kubernetes/ingress-nginx 控制器。
nginx-values.yaml
controller: service: enableHttp: true tcp: "22": "other-namespace/service-name:22"
然後我們有 helm install
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm -n nginx -f nginx-values.yaml install ingress-nginx ingress-nginx/ingress-nginx
然後我將 Ingress 安裝到 k8s 中。注意
ingressClassName
入口.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: nginx spec: ingressClassName: nginx defaultBackend: service: name: my-http-service port: number: 80
然後你kubectl那個壞男孩
kubectl apply -f ingress.yaml
我想避免做的是設置一個單獨的 pod,比如 HAProxy,它按埠路由。
你不需要設置這樣單獨的 Pod。
Kubernetes Ingress 預設不支持 TCP 或 UDP 服務。但是例如,
ingress-nginx
控制器提供了一種機制來支持不同埠上的 TCP 或 UDP。您可以通過修改 ConfigMap 來暴露 TCP 或 UDP 埠。出於這個原因,這個 Ingress 控制器使用標誌“–tcp-services-configmap”和“–udp-services-configmap”來指向一個現有的配置映射,其中鍵是要使用的外部埠,值表示使用以下格式公開的服務:
<namespace/service name>:<service port>:[PROXY]:[PROXY]
在此處查看其他資訊。
在部署 Ingress Controller之前,此類 ConfigMap 應該已經可用。
所以,嘗試:
1. 使用以下 TCP 服務配置創建一個 ConfigMap。
$ cat ingress-nginx-tcp.yml apiVersion: v1 kind: ConfigMap metadata: name: ingress-nginx-tcp namespace: default data: "22": targetnamespace/target-service:22
--tcp-services-configmap
2. 使用配置中的標誌將Ingress 控制器指向此 ConfigMap,如下所示:$ kubectl get deployment ingress-nginx-controller -o yaml apiVersion: apps/v1 kind: Deployment metadata: name: ingress-nginx-controller namespace: default spec: ... template: ... spec: containers: - args: - /nginx-ingress-controller - --tcp-services-configmap=$(POD_NAMESPACE)/ingress-nginx-tcp ...
3. 在為 Ingress 定義的 Service 中公開埠 22,如下所示:
$ kubectl get svc ingress-nginx-controller -o yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx-controller namespace: default spec: ports: - name: tcp-22 nodePort: 30957 port: 22 protocol: TCP targetPort: 22 ... type: LoadBalancer ...
您可以使用此方法定義可以公開的任意數量的埠。
對於那些使用ingress-nginx helm chart的人來說,還有另一種選擇。大部分配置已經完成,您只需要在tcp部分指定您的埠,如下所示:
tcp: 2222: "default/example-tcp-svc:22"
其中
2222
是暴露埠,22
是服務埠。