如何設置 Kubernetes 以將主節點上的一組面向外部的埠轉發到集群內部的服務?
我有一個 Kubernetes 集群,我在內部執行 ZeroMQ 代理。我已經設置了一個服務,以便集群上的 pod 可以使用以下 Helm 模板找到該代理:
#values.yaml zmqServiceType: type: ClusterIP zmqPub: port: 31339 zmqSub: port: 31342 zmqWsSub: port: 31343 ----- #service.yaml apiVersion: v1 kind: Service metadata: name: zmq-broker labels: {{ include "zmq-broker.labels" . | indent 4 }} spec: type: {{ .Values.zmqServiceType.type }} ports: - name: zmq-sub port: {{ .Values.zmqSub.port }} protocol: TCP - name: zmq-pub port: {{ .Values.zmqPub.port }} protocol: TCP - name: zmq-ws-sub port: {{ .Values.zmqWsSub.port }} protocol: TCP externalIPs: #Master node IP external address - 10.2.1.100 selector: app.kubernetes.io/name: {{ include "zmq-broker.name" . }} app.kubernetes.io/instance: {{ .Release.Name }}
這在集群中非常有效,Pod 能夠找到與 zmq 端點*“tcp://zmq-broker:"*沒有問題的代理。
但是,我還想公開 zmq-broker,以便可以從集群外部訪問它。
我知道我可以通過執行 kubectl port-forward 非常簡單地做到這一點:
kubectl port-forward <ZMQ_BROKER_POD> 31342:31342 31339:31339 31343:31343
但這有兩個缺點:它需要kubectl port-forward命令一直在執行,並且需要先知道代理在哪個 pod 上執行(加上我的理解,它不適合生產)。
我更喜歡的是一種將向外的埠映射到 pod 而不是服務的方法,這樣無論 pod 名稱是什麼,他們總能找到它。從技術上講,我們將哪個物理節點連接到內部服務並不重要,但我們的偏好是使其成為主節點。我們不需要負載平衡,因為系統中只有一個代理執行。
我以為我需要的只是服務文件中的 externalIPs 部分,但事實並非如此。externalIPs 部分確實在主節點上創建了一個偵聽程序,但它似乎沒有轉發 TCP 流量。
我在這裡嘗試做的事情是否可行,如果可以,怎麼做?
**編輯:**我將外部 IP 移至其中一個工作節點,它工作正常,但無論我在主節點上嘗試什麼 IP,它都不會轉發流量。K8s主節點是不是有什麼特別之處,讓它不轉發外部IP流量?
這原來是由於路由問題。
主節點無法正確路由到工作節點,因為 flannel 使用了錯誤的介面。
編寫的 Helm 圖表是正確的。一旦我們解決了路由問題,一切正常。
如果您發現自己處於主節點不工作但工作節點工作的類似情況,以下可以確認您有同樣的問題:
跑
ip route
在執行一些 pod 的工作節點和主節點上。您應該在頭節點和工作節點上都看到 pod IP 地址(如果使用預設 CIDR,則為 10.244.XX)。在我們的例子中,我們沒有看到主節點上的路由。
通過查看 flannel pod 的日誌,進一步確認 flannel 存在問題:
kubectl logs <Flannel_Pod_Name> --namespace kube-system
這在為頭節點 pod 執行時顯示錯誤,即當它嘗試為 pod 創建路由條目時出現“沒有到主機的路由”錯誤。工作節點日誌顯示 flannel 已成功創建路由。
解決方法是確保您的主節點上的預設路由通過具有與您的工作節點通信的 IP 地址的設備(對我們來說,我們在主節點上的預設路由最初是在 192.X 網路上,但應該一直在 10.X 網路上與工作節點交談)。