K8s nginx-ingress 如何配置二级目录转发远程静态服务器基于Vue路由history模式打包的应用程序

K8s nginx-ingress 如何配置二级目录转发远程静态服务器基于Vue路由history模式打包的应用程序

背景

首先这标题有点绕,我先解释下:

  1. 首先我们有静态服务器,上面某个目录有Vue路由history模式打包的应用程序(也就是build后的产物);
  2. 但是静态服务器一般不做对外域名用的,我们需要在k8s nginx-ingress上做下域名二级目录代理,转发到该静态目录;

这就是本文的背景,相信也是很多开发/运维同学的需求;

由上:

#我们静态服务目录是,/cso/ https://static.chinacloudapi.cn/cso/  #静态服务下文件的url是 https://static.chinacloudapi.cn/cso/static/js/manifest.967d8a794130980087be.js 

然后:

#我们部署的域名是: http://test.mysite.com/cso/  #同样,对应以上静态服务文件的url是: http://test.mysite.com/cso/static/js/manifest.967d8a794130980087be.js 

好了需求清楚了, 我们转发二级目录就是 /cso/,我们一一来看怎么实现。

先配置好Vue

1、在入口文件index.html文件中添加

<meta base="/xxx/"> 

2、配置Vue History的路由模式(我这里还是vue2.x)

export default new Router({   mode: 'history',   base: '/cso/',   routes: [     ... 

3、在config/index.js文件修改build属性下面的assetsPublicPath: '/xxx/'(用Cli3搭建的项目,应该是在vue.config.js文件修改publicPath: '/xxx/');

...   build: {     index: path.resolve(__dirname, '../dist/index.html'),     assetsRoot: path.resolve(__dirname, '../dist'),     assetsSubDirectory: 'static',          // assetsPublicPath: '/', //默认的     assetsPublicPath: '/cso/', //改为  ... 

4、访问验证:

K8s nginx-ingress 如何配置二级目录转发远程静态服务器基于Vue路由history模式打包的应用程序

成功;

原生Nginx转发配置

部署Nginx本机

location ~* /cso {     root  html/cso;     index index.html index.htm;     try_files $uri $uri/ /index.html;    } 

这就是大家比较熟悉的history模式必配的try_files,原理是:

  • 像html/js/css等静态资源请求,能本地能找到物理文件的,直接返回;
  • 访问vue里面的路由时,没有对应的物理问题的,请求转回到index.html由vue处理渲染;

部署到远程静态服务或OSS

转发静态assets

location ~* /cso.*.(gif|jpg|jpeg|png|bmp|swf|css|js|eot|svg|ttf|woff|woff2|properties|json)$ {     proxy_http_version 1.1;      proxy_pass https://static.chinacloudapi.cn;   } 

转发document

location ~* /cso {     proxy_http_version 1.1;       add_header Cache-Control 'no-store, no-cache';     rewrite ^ /cso/index.html break;     proxy_pass https://static.chinacloudapi.cn; } 

这里配置两个功能location,其实是参考try_files的原理实现的;

同时,这种配置方式也适用于解决很多想把第三方程序的UI(Hangfire等)挂载到二级域名时,静态文件404的问题;

K8s nginx-ingrss转发配置

说真的,用惯nginx原生配置后,在nginx-ingress稍微配置有一点点难度的规则我就想哭(主要确实不太熟);

configuration-snippet方式:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata:     name: my-custom-snippet   namespace: cso-site   annotations:       nginx.ingress.kubernetes.io/configuration-snippet: |          location ~* /cso.*.(gif|jpg|jpeg|png|bmp|swf|css|js|eot|svg|ttf|woff|woff2|properties|json)$ {             proxy_http_version 1.1;              proxy_pass https://static.chinacloudapi.cn;           }         location ~* /cso {             proxy_http_version 1.1;               add_header Cache-Control 'no-store, no-cache';             rewrite ^ /cso/index.html break;             proxy_pass https://static.chinacloudapi.cn;         }         spec:   ingressClassName: nginx   rules:   - host: test.mysite.com   defaultBackend:     service:       name: cso-site-svc       port:         number: 80   tls:   - hosts:     - test.mysite.com     secretName: tls-secret 

这种方式就比较简单了,就直接配置支持nginx原生语法,但它也是有限制的具体参考文档;

原生ingress写法

apiVersion: networking.k8s.io/v1 kind: Ingress metadata:   annotations:     kubernetes.io/ingress.class: nginx     nginx.ingress.kubernetes.io/upstream-vhost: "static.chinacloudapi.cn"     nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"     nginx.ingress.kubernetes.io/rewrite-target: /cso/index.html     name: slz-cso-ui-doc   namespace: cso-site spec:   rules:   - host: test.mysite.com     http:       paths:       - path: /cso/(.*)         pathType: Prefix         backend:           service:             name: cso-site             port:                number: 443    defaultBackend:     service:       name: cso-site       port:          number: 80   tls:   - hosts:     - test.mysite.com     secretName: tls-secret --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata:   annotations:     kubernetes.io/ingress.class: nginx         nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"      nginx.ingress.kubernetes.io/upstream-vhost: "static.chinacloudapi.cn"     nginx.ingress.kubernetes.io/rewrite-target: /cso/$1$2$3       nginx.ingress.kubernetes.io/use-regex: "true"   name: slz-cso-ui-static   namespace: cso-site spec:   rules:   - host: test.mysite.com     http:       paths:       - path: /cso/(.*)(.)(gif|jpg|jpeg|png|bmp|swf|css|js|eot|svg|ttf|woff|woff2|properties|json)$         pathType: Prefix         backend:           service:             name: cso-site             port:                number: 443   defaultBackend:     service:       name: cso-site       port:          number: 80   tls:   - hosts:     - test.mysite.com     secretName: tls-secret 

我们来看看生成的nginx规则:

K8s nginx-ingress 如何配置二级目录转发远程静态服务器基于Vue路由history模式打包的应用程序

这是我抽取核心部分的规则,可以看到翻译成原生写法是规则生成正确的;

总结

k8s nginx-ingress配置稍微复杂点的规则真的很痛苦;

配置ingress时在不是特别熟的情况下跟我一样先写原生nginx,再翻译成ingress是个不错的方法;

水完, 欢迎讨论。

发表评论

评论已关闭。

相关文章