小弟有一个项目要准备往 Azure 的 k8s 环境上部署,目前在前端服务的部署上碰到了一些困惑,有两种部署方式:
1. 前端 React 使用 nginx 做为基础镜像,打成一个可独立运行的 image ,部署在 k8s ingress 的后面,这样的话相当于有两个 nginx 了,镜像里有一个,然后 ingress 其实也是一个 nginx ,在镜像里和 ingress 上都要配路由规则。
2. 前端只是将静态资源和 js 代码打成 image ,不包含 nginx, 然后部署在 k8s ingress 后面,静态资源和后端服务的路由都在 ingress 里配置。
第一种方式之前实践过,是可行的,但是这样的话环境里相当于有两个 nginx ,感觉怪怪的,第二种方式是我个人想法,还没有测试过,但是从架构上来说相对简洁一些,不知是否可行。本人之前是搞后端的,对前端这块的实践不大了解,问了下 ChatGPT 说推荐用第二种方式,然后 Google 搜了下没找到类似的问题。有没有大佬在 k8s 生产环境上实践过类似的部署?还望不吝赐教。
1
shanch 2023-04-24 17:18:50 +08:00 1
我们目前是第一种
|
2
cydysm 2023-04-24 17:20:13 +08:00 via iPhone 1
第一种不怪
|
3
Judoon 2023-04-24 17:20:37 +08:00 1
ingress 不能直接读取静态文件,只能转发流量到具体服务端口,所以你的方案二还是会需要一个 web server 来提供服务
静态文件不如直接丢 cdn |
4
mypchas6fans 2023-04-24 17:22:03 +08:00 1
印象中第二种没问题的。前司的前端镜像里就是 PM2 start 啥的。但我也不是前端,细节不太清楚了。
|
6
killva4624 2023-04-24 17:32:38 +08:00 1
第二种没有 web server ,无法响应 HTTP 请求。
第二种是通常的做法,不算奇怪:前面一个是 Ingress 负责流量入口,后面一个作为你的前端“服务”。 |
7
StoneHuLu 2023-04-24 17:43:17 +08:00 1
op 想的太洁癖了,以.net core 项目举例,项目本身是自带一个 Kestrel 做 Webserver 的,java 不了解是不是也自带一个,印象中 spring 好像有,这个 Kestrel 本质上就是个超轻量级的 webserver ,所以说你前端项目放个 nginx 完全正常,因为后端项目实际上也有 webserver 的,只是它不是 nginx ,所以你就无视了
|
8
anonydmer 2023-04-24 18:21:21 +08:00 2
第一种方法没有什么怪得,不要从技术栈的角度看问题; web 容器里的 nginx 只是为了伺服静态文件,你完全可以用其他的,caddy ,甚至在需要 ssr 的时候用 node ; k8s 的 ingress 是为了处理流量和路由,没有说一定要用 nginx ,各种 ingress 实现多了去了,Azure 上的 ingress 实现还真不一定是 nginx 吧。 不过这样建议楼主你说的 web 容器里的 nginx 还有负责路由,这个可以去掉。
|
9
IvanLi127 2023-04-24 18:23:33 +08:00 via Android
第一种,都用容器了,可以不用在意多一个 nginx 。实在在意的话。。。换成 serve 作为 web 服务,看起来会不会舒服很多🤣
|
10
bogun 2023-04-24 18:27:31 +08:00 1
第二种的话,前端的 pod 负责 build 静态文件,并将静态文件映射出去,ingress 挂载该目录,在 ingress 的配置文件里面配置该目录即可。
|
11
perfectlife 2023-04-24 18:27:33 +08:00
不用 ingress 的话,前端服务的 svc 用 loadblance 也可以
|
12
FrankAdler 2023-04-24 18:27:48 +08:00 1
@killva4624
@nerocho 类似对象存储这种,是可以直接不经过所谓的 web server 直接响应请求的,输出 html 内容后,再请求后端就可以了,也可以用上 cdn ,现公司前公司都是这么干的,前端 build 完直接推送 oss |
13
SKYNE 2023-04-24 18:31:04 +08:00 1
也可以将 index.html 放入 nginx 镜像,其他都自动上传到 oss ,然后用域名加资源路径来加载静态文件。
|
15
knightgao2 2023-04-24 19:48:27 +08:00
1 个 pod 里打 2 个容器,一份放文件 一份放服务
|
16
realpg 2023-04-24 20:02:46 +08:00 1
|
17
chendy 2023-04-24 20:14:25 +08:00 2
小东西直接扔 nginx
大项目 oss cdn 除非是 ssr ,否则纯静态的东西放 k8s 实在想不出有啥优势 |
18
xiaoxiongwu 2023-04-24 20:18:11 +08:00
@shanch 的
|
19
ll0504 2023-04-24 20:56:49 +08:00 1
ingress 是做路由转发的,这个一般是针对整个服务集群匹配路由到哪个具体服务,类似于你去 ktv 消费,有迎宾给你引导到某个包房,这个 ingress 就是个迎宾。nginx 是做静态服务的,相当于你点的公主或者牛郎,在包厢里陪你唱歌喝酒。整个 ktv 就像个 k8s 集群,迎宾跟公主角色要分离开,各自负责好自己的职责,共同为这个 ktv 高效运转提供服务,这叫高内聚低耦合。当然迎宾按理说也很漂亮,也可以直接提供服务满足客户需求,但是迎宾都去满足客户了,谁来把大堂里的客户接待了
|
21
SanjinGG 2023-04-24 21:51:30 +08:00 1
容器用的 docker ,走自动化,用的第一种,容器里的 nginx 跑不掉的,你的接口也要做反代,必须有 nginx ,宿主机只要配一个子域名的反代就行,这样也便于维护
|
22
leokun 2023-04-24 22:06:54 +08:00 1
我司用的第一种,nginx 配置文件随项目分支更新,有时候会写一些 njs 脚本(处理 oauth 授权),这些都放到项目里面维护,打成一个包比较合理
|
23
dayeye2006199 2023-04-25 04:03:28 +08:00 via Android 1
第一个没啥怪的。就和上面说的,nginx 不光是个反代,也是静态资源服务器。
你那个 Pod 里面的静态资源服务器可以替换成 caddy ,apache 等各种选择。 Ingress controller 的实现也不光是 nginx ,好多都是云厂商自己的私有 gateway 。这两个东西配合使用非常合理。 |
24
killva4624 2023-04-25 07:51:48 +08:00 via iPhone
@FrankAdler 存储对象是可以啊,但 OP 问的是在 K8S 里部署。
|
25
eryajf 2023-04-25 08:09:55 +08:00 1
推荐一个方案:结合 http-server 来玩,前端项目仍旧打成静态文件,然后基于 http-server 监听,接下来 ingress 该咋配咋配。
http-server 是个神器,平时本地调试也经常能用上。 关于 http-server 的介绍,可见: https://wiki.eryajf.net/pages/7edb58/ |
26
rocmax 2023-04-25 08:37:33 +08:00 via Android
csr 说到底就是存个文件而已,为什么要部署到 k8s ? aws 的话直接存 s3 前面套 cloudfront ,azure 也应该有对应的服务。
|
27
cheng6563 2023-04-25 08:55:49 +08:00
我们是 2
|
29
genffy 2023-04-25 11:16:28 +08:00
如果只是纯静态资源,其实没多大必要。。。
|
30
nerocho 2023-04-25 11:32:04 +08:00
@FrankAdler index.html 放到 pod 里面是为了自己管理版本( cdn 缓存生效问题),如果前端版本不敏感,那 cdn 肯定更好。
|
31
nerocho 2023-04-25 11:39:07 +08:00
@nerocho index.html 放 cdn 我猜肯定没经历,cdn 节点缓存更新不及时的痛(当然多及时,取决于自己业务),自己控制缓存策略稳一些
|
32
vmlinz 2023-06-25 15:16:01 +08:00 via iPhone 1
前端如果没有 ssr 要求,不需要放到 k8s 。纯静态 spa 这类使用 s3 加 cdn 才是最优的,因为可以充分利用 cdn edge 服务。或者使用其他前端 paas 平台,比如 vercel ,cloudflare pages 。
如果非要部署到 k8s ,cdn 回源都需要到 k8s ,建议使用 nginx 加上静态资源打包镜像,这样前后端架构保持一致,而且需要 ssr 的情况也可以应对。最好不要用 ingress 去服务静态资源,它的设计不是做这个的。 |