在 Kubernetes Ingress 中支持 Websocket/Socket 服务
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
[转载请注明出处]
作者:雨歌
欢迎关注作者公众号:半路雨歌,查看更多技术干货文章

在 Kubernetes Ingress 中支持 Websocket/Socket 服务的更多相关文章
- ASP.NET Core 中的 WebSocket 支持(转自MSDN)
本文介绍 ASP.NET Core 中 WebSocket 的入门方法. WebSocket (RFC 6455) 是一个协议,支持通过 TCP 连接建立持久的双向信道. 它用于从快速实时通信中获益的 ...
- 如何在 Knative 中部署 WebSocket 和 gRPC 服务?
作者 | 冬岛 阿里云容器平台工程师 导读:虽然说 Knative 默认就支持 WebSocket 和 gRPC,但在使用中会发现,有时想要把自己的 WebSocket 或 gRPC 部署到 Kna ...
- 把H2数据库从jar包部署到Kubernetes,并解决Ingress不支持TCP的问题
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! H2 Database是一个优秀的数据库,又小又方便,支持内存和文件形式,经常会在测试.POC(proof of conce ...
- AutoCAD.net支持后台线程-Socket服务端
最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket ...
- node.js中ws模块创建服务端和客户端,网页WebSocket客户端
首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...
- Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架
一.基本介绍 WebSocket是HTML5的一种新通信协议,它实现了浏览器与服务器之间的双向通讯.而Socket.IO是一个完全由JavaScript实现.基于Node.js.支持WebSocket ...
- 在python中编写socket服务端模块(二):使用poll或epoll
在linux上编写socket服务端程序一般可以用select.poll.epoll三种方式,本文主要介绍使用poll和epoll编写socket服务端模块. 使用poll方式的服务器端程序代码: i ...
- 在Ngnix中配置支持Websocket
使用SignalR实现Websocket实时数据传输时,前后端各自实现编码后,无法将Websocket调试通过.沮丧之时,负责配置网络代理的同事说,网络访问这块使用了Ngnix代理设置,可能是造成We ...
- Kubernetes中使用ClusterDNS进行服务发现
在k8s集群中,服务是运行在Pod中的,Pod的发现和副本间负载均衡是我们面临的问题.我们使用Service解决了负载均衡的问题,但是集群环境中,service经常伴随着ip的变动而变动,得益于kub ...
随机推荐
- 多测师讲解html _链接标签004_高级讲师肖sir
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>链 ...
- Cypress系列(65)- 测试运行失败自动重试
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 重试的介绍 学习前的三问 什么是重试测试 ...
- Python错误:AssertionError: group argument must be None for now
运行多线程出现的错误 调试了很久,最后发先 __init__ 写错了,修改后后,运行正确.
- MySQL数据库规范 (设计规范+设计规范+操作规范)
I 文档定义 1.1 编写目的 为了在软件生命周期内规范数据库相关的需求分析.设计.开发.测试.运维工作,便于不同团队之间的沟通协调,以及在相关规范上达成共识,提升相关环节的工作效率和系统的可维护性. ...
- "计算机科学"与"软件工程"有什么区别?哪个专业更适合你?
"计算机科学和软件工程专业有什么不同?" 以及- "如果我想成为软件工程师,我应该选择计算机科学还是软件工程专业?" 在这篇文章中,我会回答这个问题,并分享一些 ...
- linux(centos8):jmeter5.3并发测试实例(参数在范围内随机取值)
一,测试的url地址说明: 1,这是一个秒杀功能的url: http://127.0.0.1:8080/second/skusecond?actid=2020&skuid=cpugreen&a ...
- centos8平台使用parted管理分区
一,parted的用途 parted是GNU发布的强大的分区工具, parted命令可以划分单个分区大于2T的GPT格式的分区,也可以划分普通的MBR分区. 因为fdisk命令对于大于2T的分区无法划 ...
- selenium基础--五种定位方式
find_element_by_name find_element_by_id find_element_by_xpath find_element_by_link_text find_element ...
- 给萌新HTML5 入门指南
本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. HTML5的发展改变了互联网技术趋势,前端热度依旧不减,所以对于应用开发人员 ...
- C语言积累一点点
778. 水位上升的泳池中游泳https://leetcode-cn.com/problems/swim-in-rising-water/ 839. 相似字符串组 https://leetco ...