在 k8s 里利用 oss 部署静态网站的问题

225 天前
 guoguobaba

现在每个前端项目,都要弄个 nginx 容器,把 dist 放进去,我想到一个用 oss 部署静态网站的方案

1 、k8s 创建一个 Service ,类型为 ExternalName ,把 oss-data 指向 oss 的地址,我用的是腾讯 cos ,地址就是 nginx-static-xxxx.cos.ap-shanghai.myqcloud.com ,这个 bucket 设置为公有读私有写

2 、把 dist 目录上传到 nginx-static-xxxx/test/目录下

3 、创建一个 ingress 规则,把 oss-data 的 80 端口映射为一个域名 test.mydomain.com ,如下

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite ^/$  /index.html redirect;
    nginx.ingress.kubernetes.io/rewrite-target: /test/$1
    nginx.ingress.kubernetes.io/upstream-vhost: nginx-static-xxxx.cos.ap-shanghai.myqcloud.com

  name: www
  namespace: test
spec:
  ingressClassName: nginx
  rules:
    - host: test.mydomain.com
      http:
        paths:
          - backend:
              service:
                name: oss-data
                port:
                  number: 80
            path: /(.*)
            pathType: Prefix

就是用户访问 test.domain.com/index.html ,会转发到后端的 oss-data/test/index.html ,传给 cos 的则是 nginx-static-xxxx.cos.ap-shanghai.myqcloud.com/test/index.html rewrite /$ 是为了保证访问 test.domain.com 的时候 cos 不会报告 404 错误

这样,以后,每次发布新项目,只需要把 dist 目录同步到 cos 这个 bucket 的某个目录中,然后创建一个 ingress 规则映射到新域名即可。

如果是全静态网站这种方案没有问题。但是对于 vue 的路由就有点问题,比如 url 里的路由信息,比如/login?...,在 vue 里会跳转,但是 ingress 把这个请求转到 cos 上,就会出现 404 。在 nginx 里,是使用 try_files 来保证直接/login 跳转到 index.html 的 。

但是在 ingress 里,try_files 和 rewrite 规则有些冲突,try_files 是查找本地文件,rewrite-target 是把数据传到后端服务,类似于(proxy_pass)的规则。

所以除了把/login 之类的特殊处理,是否还有其它方法?

1715 次点击
所在节点    Kubernetes
19 条回复
1point
225 天前
写个 error_page 404 /index.html; 就可以了吧
guoguobaba
225 天前
@1point 不行,这个也是本地规则,是后端返回 404 。
billzhuang
225 天前
为啥不直接用 oss 静态 site 的功能,套个 cdn 。
guoguobaba
225 天前
@billzhuang 内网项目
maocat
225 天前
你没有接触过单页前端项目吗

后端代理前端项目,后端要路由通配,所有的非后端 api url 都转发到前端上面并且 code 是 200 ,或者前端给你对应页面的路由,后端进行同一个配置替换
liuhai233
225 天前
感觉你要做一个 vercel 或者 cloudflare pages ,不错
mightybruce
225 天前
不建议这么做吧, 有些 OSS 支持静态存储卷,比这样做好太多了。
nulIptr
225 天前
感觉这么搞还不如把 oss 挂成 pv 然后起个 nginx 转发…
Jat001
225 天前
你这个内网是没法访问互联网的环境还是只是说这个项目不能在公网出现?
如果是后者,COS + CDN 完全能满足,COS 设私有,CDN 源站选 COS ,开启私有 COS 自动鉴权。
如果是固定公网 IP ,只需要 CDN 上加白名单就行。如果是动态 IP ,URL 鉴权也能用,只不过这样每个请求都要带上鉴权参数,可能更麻烦。
zzl22100048
225 天前
有个东西叫 s3www
devopsdogdog
225 天前
现在每个前端项目,都要弄个 nginx 容器,把 dist 放进去,我想到一个用 oss 部署静态网站的方案

你这需求的话,cdn k8s 都不需要,docker 挂载一下 nginx 的配置文件和 dist 目录,想怎么改怎么更新都行
guoguobaba
225 天前
@zzl22100048 这个就是实现 s3www 的功能,但是 s3www 没有办法解决我这个问题
guoguobaba
225 天前
@devopsdogdog 用 nginx+dist 也涉及到前端访问 404 如何 redirect index.html 的问题,ingress+nginx /ingress+oss 问题性质是一样的
zzl22100048
225 天前
@guoguobaba #12 s3www 可以处理 404 ,只不过是每个网站要启动一个 s3www 而已
aimuz
224 天前
ingress 只是一个路由转发,单页应用需要你的 oss-data 做处理
aimuz
224 天前
简单点就是把你网站的路由方式改了,改成 #方式
devopsdogdog
224 天前
@guoguobaba nginx 404 跳转咋会有问题? 冲突的试试 error_page 方式,nginx 规则也是有顺序判断等等的 ,按我理解实现你的需求 完全没问题
guoguobaba
224 天前
@devopsdogdog 这种方法,多了 nginx 和 pv csi 的两层 overhead ,性能上不是很好。当然,我测试实现了这个功能,只不过 nginx 配置需要调整一下。
```
server {
listen 80;
server_name localhost;

#charset koi8-r;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;

location ~ ^/(?<project>[^/]+)/ {
root /usr/share/nginx/html;
try_files $uri $uri/ /$project/index.html;
index index.html index.htm;
}

}

```

每个 project 需要 try_files 的位置会有区别。

当然能在 oss 里解决是最好的。实际上相当于 如果 nginx 有个 proxy_pass ,如何在返回 404 的情况下,rewrite 到一个新的后端地址
Anonym0u5
105 天前
我们这前端自己实现静态服务和接口路由规则,用 express+node 镜像打包静态文件。不过最早也是用的 Nginx ,感觉不是很方便。

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

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

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

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

© 2021 V2EX