在 Kubernetes Ingress 中支持 Websocket/Socket 服務

Kubernetes Ingress 可將集羣內部的 Service 經過 HTTP/HTTPS 的方式暴露供外部訪問,並經過路徑匹配規則定義服務的路由。可是 Ingress 對 TCP/UDP 的服務卻支持的不那麼好。若是咱們服務中有使用 Websocket 或 Socket, 須要暴露給外部訪問,在 Kubernetes 中該如何配置呢?html

大體有兩種方式[見參考文檔1]:nginx

  1. 使用 NodePort, 使用節點 IP 與 NodePort 暴露的端口訪問
  2. 使用 ClusterIp + Ingress + ConfigMap

使用 NodePort 將端口直接暴露,須要節點有外網 IP,且該方式可能繞過現有的 TLS, 存在安全性的問題。git

ClusterIp 只能在集羣內部訪問,由 Ingress 進行代理對外暴露,但對於 TCP/UDP, Ingress 不支持直接代理, 須要藉助 ConfigMap 進行映射。github

NodePort 的方式比較簡單, 本文介紹 ClusterIp + Ingress + ConfigMap 的方式。web

建立 ClusterIp 服務

假設有一個 Websocket/Socket 服務,暴露端口 8828, 針對該服務定義 ClusterIp 配置以下(不聲明 type, 默認即爲 ClusterIp),shell

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,npm

[root@kmaster k8s-deploy]# kubectl apply -f my-websocket-svc.yaml

建立 ConfigMap

在 ingress-nginx-controller 所在的 namespace 下建立 ConfigMap(若是已經有 ConfigMap 了, 則可在已有 ConfigMap 的 data 部分添加下面配置中的 data 條目)api

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,websocket

[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), 以下圖所示

ingress-tcp

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

ingress-tcp-port

經驗證,不加該部分 port 映射配置也沒問題

保存,應用配置更新,nginx-ingress-controller 將會自動重啓 Pod,使配置生效。

驗證

在 nginx-ingress-controller Pod 所在節點上執行以下命令查看是否監聽了 TCP 端口,

ingress-tcp-check

如上,8828 端口已被 nginx-ingress 監聽。

對於 Websocket 應用, 可以使用 wscat 進行調試

C:\Users\Administrator>wscat -c ws://域名:8828
Connected (press CTRL+C to quit)
>

wscat 安裝: npm install -g wscat

其它

  1. 注意 ConfigMap 的 namesapce 與 nginx-ingress-controller 一致,不然將 --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services 中的 $(POD_NAMESPACE) 改成 ConfigMap 具體的 namesapce
  2. 若是將 nginx-ingress-controller 綁定了節點,則重啓可能致使失敗(由於端口分配衝突),可先刪除(kubectl delete deploy ingress-nginx-controller -n ingress-nginx),再新建(kubectl apply -f nginx-ingress.yaml),該操做會影響服務可用性,生產環境需慎重
  3. 若是配置後未生效,可經過查看 nginx-ingress-controller Pod 的日誌定位緣由 kubectl logs ingress-nginx-controller-58fdbbc68d-wqtlr -n ingress-nginx

參考文檔:

  1. https://www.ibm.com/support/knowledgecenter/en/SSSHTQ/omnibus/helms/all_helms/wip/reference/hlm_expose_probe.html
  2. https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/exposing-tcp-udp-services.md

[轉載請註明出處]
做者:雨歌
歡迎關注做者公衆號:半路雨歌,查看更多技術乾貨文章
qrcode

相關文章
相關標籤/搜索