Kubernetes Ingress 可將集群內部的 Service 通過 HTTP/HTTPS 的方式暴露供外部訪問,并通過路徑匹配規則定義服務的路由,但是 Ingress 對 TCP/UDP 的服務卻支持的不那么好,如果我們服務中有使用 Websocket 或 Socket, 需要暴露給外部訪問,在 Kubernetes 中該如何配置呢?
大致有兩種方式[見參考檔案1]:
- 使用 NodePort, 使用節點 IP 與 NodePort 暴露的埠訪問
- 使用 ClusterIp + Ingress + ConfigMap
使用 NodePort 將埠直接暴露,需要節點有外網 IP,且該方式可能繞過現有的 TLS, 存在安全性的問題,
ClusterIp 只能在集群內部訪問,由 Ingress 進行代理對外暴露,但對于 TCP/UDP, Ingress 不支持直接代理, 需要借助 ConfigMap 進行映射,
NodePort 的方式比較簡單, 本文介紹 ClusterIp + Ingress + ConfigMap 的方式,
創建 ClusterIp 服務
假設有一個 Websocket/Socket 服務,暴露埠 8828, 針對該服務定義 ClusterIp 配置如下(不宣告 type, 默認即為 ClusterIp),
apiVersion: v1
kind: Service
metadata:
name: my-websocket-svc
namespace: develop
spec:
ports:
- name: socket
port: 8828
targetPort: 8828
protocol: TCP
selector:
app: my-websocket
創建 ClusterIp,
[root@kmaster k8s-deploy]# kubectl apply -f my-websocket-svc.yaml
創建 ConfigMap
在 ingress-nginx-controller 所在的 namespace 下創建 ConfigMap(如果已經有 ConfigMap 了, 則可在已有 ConfigMap 的 data 部分添加下面配置中的 data 條目)
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
8828: "develop/my-websocket-svc:8828"
data 部分的格式為: <namespace/service name>:<service port>:[PROXY]:[PROXY], [PROXY]:[PROXY] 部分為可選, 上述配置表示將宿主機的 8828 埠 映射到 develop namespace 下 my-websocket-svc 服務的 8828 埠上,
創建 ConfigMap,
[root@kmaster k8s-deploy]# kubectl apply -f tcp-service-configmap.yaml
配置 ingress-nginx-controller
修改 ingress-nginx-controller 的配置,
[root@kmaster ~]# kubectl edit deploy ingress-nginx-controller -n ingress-nginx
在 .spec.template.spec.containers[].args[] 部分添加 --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services (或針對 UDP, --udp-services-configmap=$(POD_NAMESPACE)/udp-services), 如下圖所示

在.spec.template.spec.containers[].ports[] 部分添加 port 映射,如圖

經驗證,不加該部分 port 映射配置也沒問題
保存,應用配置更新,nginx-ingress-controller 將會自動重啟 Pod,使配置生效,
驗證
在 nginx-ingress-controller Pod 所在節點上執行如下命令查看是否監聽了 TCP 埠,

如上,8828 埠已被 nginx-ingress 監聽,
對于 Websocket 應用, 可使用 wscat 進行除錯
C:\Users\Administrator>wscat -c ws://域名:8828
Connected (press CTRL+C to quit)
>
wscat 安裝:
npm install -g wscat
其它
- 注意 ConfigMap 的 namesapce 與 nginx-ingress-controller 一致,否則將
--tcp-services-configmap=$(POD_NAMESPACE)/tcp-services中的$(POD_NAMESPACE)改為 ConfigMap 具體的 namesapce - 如果將 nginx-ingress-controller 系結了節點,則重啟可能導致失敗(因為埠分配沖突),可先洗掉(
kubectl delete deploy ingress-nginx-controller -n ingress-nginx),再新建(kubectl apply -f nginx-ingress.yaml),該操作會影響服務可用性,生產環境需慎重 - 如果配置后未生效,可通過查看 nginx-ingress-controller Pod 的日志定位原因
kubectl logs ingress-nginx-controller-58fdbbc68d-wqtlr -n ingress-nginx
參考檔案:
- https://www.ibm.com/support/knowledgecenter/en/SSSHTQ/omnibus/helms/all_helms/wip/reference/hlm_expose_probe.html
- https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/exposing-tcp-udp-services.md
[轉載請注明出處]
作者:雨歌
歡迎關注作者公眾號:半路雨歌,查看更多技術干貨文章

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/222071.html
標籤:其他
上一篇:在 Kubernetes Ingress 中支持 Websocket/Socket 服務
下一篇:安裝MySQL5.7
