V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
guoguobaba
V2EX  ›  Kubernetes

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

  •  
  •   guoguobaba · 235 天前 · 1732 次点击
    这是一个创建于 235 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在每个前端项目,都要弄个 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 之类的特殊处理,是否还有其它方法?

    19 条回复    2024-01-25 11:53:11 +08:00
    1point
        1
    1point  
       235 天前
    写个 error_page 404 /index.html; 就可以了吧
    guoguobaba
        2
    guoguobaba  
    OP
       235 天前
    @1point 不行,这个也是本地规则,是后端返回 404 。
    billzhuang
        3
    billzhuang  
       235 天前   ❤️ 1
    为啥不直接用 oss 静态 site 的功能,套个 cdn 。
    guoguobaba
        4
    guoguobaba  
    OP
       235 天前
    @billzhuang 内网项目
    maocat
        5
    maocat  
       235 天前
    你没有接触过单页前端项目吗

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

    你这需求的话,cdn k8s 都不需要,docker 挂载一下 nginx 的配置文件和 dist 目录,想怎么改怎么更新都行
    guoguobaba
        12
    guoguobaba  
    OP
       234 天前
    @zzl22100048 这个就是实现 s3www 的功能,但是 s3www 没有办法解决我这个问题
    guoguobaba
        13
    guoguobaba  
    OP
       234 天前
    @devopsdogdog 用 nginx+dist 也涉及到前端访问 404 如何 redirect index.html 的问题,ingress+nginx /ingress+oss 问题性质是一样的
    zzl22100048
        14
    zzl22100048  
       234 天前
    @guoguobaba #12 s3www 可以处理 404 ,只不过是每个网站要启动一个 s3www 而已
    aimuz
        15
    aimuz  
       234 天前
    ingress 只是一个路由转发,单页应用需要你的 oss-data 做处理
    aimuz
        16
    aimuz  
       234 天前
    简单点就是把你网站的路由方式改了,改成 #方式
    devopsdogdog
        17
    devopsdogdog  
       234 天前
    @guoguobaba nginx 404 跳转咋会有问题? 冲突的试试 error_page 方式,nginx 规则也是有顺序判断等等的 ,按我理解实现你的需求 完全没问题
    guoguobaba
        18
    guoguobaba  
    OP
       234 天前
    @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
        19
    Anonym0u5  
       114 天前
    我们这前端自己实现静态服务和接口路由规则,用 express+node 镜像打包静态文件。不过最早也是用的 Nginx ,感觉不是很方便。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2267 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 02:51 · PVG 10:51 · LAX 19:51 · JFK 22:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.