请教一个 k8s 动态端口映射的问题

2021-04-26 22:09:58 +08:00
 LotteWong

小白刚入门 k8s,想请教一下 v 友们怎么处理以下问题比较好呢——

已知A 服务接收客户端的请求,负责向数据库写入端口信息;B 服务负责从数据库读出端口信息;并监听这些端口来提供服务。所以可理解为,A 服务的端口是固定的(配置文件指定),B 服务的端口是动态的(数据库中读取)。

问题:现在如果要使用 k8s 部署这两个服务,A 服务的端口映射可以直接指定,B 服务的端口映射应该如何优雅地处理呢?

PS: 如果是 A/B 服务的设计不合理也很欢迎大家提出建议:D 非常感谢大家~

2287 次点击
所在节点    Kubernetes
19 条回复
napsterwu
2021-04-26 23:04:30 +08:00
动态的只能用 ingress 了呗
liuhan907
2021-04-27 01:50:55 +08:00
最符合 k8s 风格的是创建 crd 然后写个 operator 监视并动态创建 deploy 。然后不要写数据库直接操作 crd
CivAx
2021-04-27 01:54:36 +08:00
无论动态不动态,最终体现在 service 上 NAT 出来的都是同一个固定的端口,但是怎么在容器启动前后去获取这个 dynamic 端口并据此进行 service 创建确实想不到办法…
wd
2021-04-27 07:06:15 +08:00
那客户是怎么访问到你的服务的呢? ingress 还是其他的?
joesonw
2021-04-27 09:05:45 +08:00
这不就是 CNI 一部分的工作嘛
thet
2021-04-27 09:28:09 +08:00
动态改 service 的 targetPort 不知道可不可行
CivAx
2021-04-27 10:50:41 +08:00
@thet #6 sidecar 一个 kubectl 容器动态请求说不定可以
Judoon
2021-04-27 11:40:03 +08:00
你这两个 AB 服务怎么感觉像是一种独立的服务注册发现机制啊?

想了解一下 B 服务提供的端口原先是怎么被调用的呢? 比如是 C 服务去读数据库,然后再调用 B 的某些端口?
eric96
2021-04-27 11:52:48 +08:00
突然想到,我们公司的注册端口是固定在配置文件的,所以当时迁移到 k8s 的时候没遇到题主的这个问题
LotteWong
2021-04-27 14:16:42 +08:00
@wd 原来是进程部署的,没有容器端口映射这一层的问题
LotteWong
2021-04-27 14:19:50 +08:00
@Judoon 可以将 A+B 理解成一个网关,A 服务是用户在上面注册服务信息,B 服务是真正做代理转发的
mritd
2021-04-27 14:20:42 +08:00
根据楼主需求,目前来说有两种参考方案: 第一种 operator 外部介入,这种方式下强调了使用 k8s 服务发现方式,即流量经过 svc 负载,pod 变动体现在 svc 后端上,此时核心问题在于如何然后应用未启动之前确定端口号,此时 operator 可以自己读取数据库,或者让 B 应用暴露固定提供动态端口的接口信息,总之就是让 operator 动态改变 svc spec,这会有一定延迟和流量损失
LotteWong
2021-04-27 14:22:15 +08:00
@liuhan907 这种方法估计需要改动源码还要学习一下 crd 的内容,感谢大佬解答,我去研究一下(
mritd
2021-04-27 14:22:30 +08:00
第二种,考虑通过 svc 的无头模式,让他返回后段 pod 的真实 ip,然后 A 服务自己实现负载,此时跟传统架构保持一致,但是 svc 域名查询是否在 A 服务协议层支持暂不确定
LotteWong
2021-04-27 14:24:00 +08:00
@eric96 主要是端口不是固定的,是用户输入的,所以没办法直接固定写到配置文件哈哈
LotteWong
2021-04-27 14:35:11 +08:00
@mritd 两种方法刚刚去看了一下,很有启发,感谢大佬的解答~
mritd
2021-04-27 14:38:44 +08:00
@LotteWong 其实 operator 介入也会有点尴尬,因为单个 service 的后端 target port 是一样的,如果你的 B 应用不同实例启动会 listen 不同的端口那么没法过 svc,所以这种情况你还得考虑让它 IP 直连
LotteWong
2021-04-27 14:48:40 +08:00
@mritd B 应用的不同实例监听的端口应该会是一样的(都是同样的数据库内容),感觉第一种做法有性能损耗,第二种做法没有负载均衡要自己再搞个,需要在两者之间取舍一下😂
wd
2021-04-27 22:15:46 +08:00
@LotteWong 那你要不看看 service 的 node Port 类型,可以在 node 直接绑定端口,并且可定制。 你只需要在 pod 那维护自己的 service 就可以 expose 端口

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/773460

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX