Kubernetes

如何創建基於埠將流量路由到不同 Pod 的 Kubernetes 服務?

  • February 22, 2022

我想要一個 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-configmap2. 使用配置中的標誌將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是服務埠。

引用自:https://serverfault.com/questions/1094259