写点什么

实践示例:从一个域名跳转到另一个域名,ingress-nginx 经历了什么

  • 2020-05-18
  • 本文字数:2329 字

    阅读完需:约 8 分钟

实践示例:从一个域名跳转到另一个域名,ingress-nginx经历了什么

由于 nginx 的优秀性能表现,所以很多企业在 Kubernetes 中选择 Ingress Controller 的时候依然会选择基于 nginx 的 ingress-nginx。但它的配置比较麻烦,一些复杂的需求需要通过 Ingress 的 annotation 来实现,比如在本文中我们需要实现一个 url rewrite 的功能,简单来说就是我们之前的应用在 todo.qikqiak.com 下面,现在我们需要通过 todo.qikqiak.com/app/ 来进行访问。


本次测试使用的集群为 Kubernetes v1.16.2(Rancher 2.3.3 已默认支持),ingess-nginx 镜像版本为 0.26.1


最原始的 Ingress 对象如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: fe  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"spec:  rules:  - host: todo.qikqiak.com    http:      paths:      - backend:          serviceName: fe          servicePort: 3000        path: /
复制代码


就是一个很常规的 Ingress 对象,部署该对象后,将域名解析后就可以正常访问到应用:



按照需求我们需要对访问的 URL 路径做一个 Rewrite,在 ingress-nginx 官方文档中也给出了说明:


https://kubernetes.github.io/ingress-nginx/examples/rewrite/



按照要求我们需要在 path 中匹配前缀 app,然后通过 rewrite-target 指定目标,修改后的 Ingress 对象如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: fe  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/rewrite-target: /$2spec:  rules:  - host: todo.qikqiak.com    http:      paths:      - backend:          serviceName: fe          servicePort: 3000        path: /app(/|$)(.*)

复制代码


更新后,我们可以遇见到直接访问域名肯定是不行了,因为我们没有匹配 / 的 path 路径:



但是我们带上 app 的前缀再去访问:



我们可以看到已经可以访问到页面内容了,这是因为我们在 path 中通过正则表达式 /app(/|$)(.*) 将匹配的路径设置成了 rewrite-target 的目标路径了,所以我们访问 todo.qikqiak.com/app 的时候实际上相当于访问的就是后端服务的 / 路径,但是我们也可以发现现在页面的样式没有了:



这是因为应用的静态资源路径是在 /stylesheets 路径下面的,现在我们做了 url rewrite 过后,要正常访问也需要带上前缀才可以:http://todo.qikqiak.com/stylesheets/screen.css,对于图片或者其他静态资源也是如此,当然我们去更改页面引入静态资源的方式为相对路径也是可以的,但是毕竟要修改代码,这个时候我们可以借助 ingress-nginx 中的 configuration-snippet 来对静态资源做一次跳转,如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: fe  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/rewrite-target: /$2    nginx.ingress.kubernetes.io/configuration-snippet: |      rewrite ^/stylesheets/(.*)$ /app/stylesheets/$1 redirect;  # 添加 /app 前缀      rewrite ^/images/(.*)$ /app/images/$1 redirect;  # 添加 /app 前缀spec:  rules:  - host: todo.qikqiak.com    http:      paths:      - backend:          serviceName: fe          servicePort: 3000        path: /app(/|$)(.*)
复制代码


更新 Ingress 对象后,这个时候我们刷新页面可以看到已经正常了:



要解决我们访问主域名出现 404 的问题,我们可以给应用设置一个 app-root 的注解,这样当我们访问主域名的时候会自动跳转到我们指定的 app-root 目录下面,如下所示:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: fe  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/app-root: /app/    nginx.ingress.kubernetes.io/rewrite-target: /$2    nginx.ingress.kubernetes.io/configuration-snippet: |      rewrite ^/stylesheets/(.*)$ /app/stylesheets/$1 redirect;  # 添加 /app 前缀      rewrite ^/images/(.*)$ /app/images/$1 redirect;  # 添加 /app 前缀spec:  rules:  - host: todo.qikqiak.com    http:      paths:      - backend:          serviceName: fe          servicePort: 3000        path: /app(/|$)(.*)

复制代码


这个时候我们更新应用后访问主域名 http://todo.qikqiak.com 就会自动跳转到 http://todo.qikqiak.com/app/ 路径下面去了。但是还有一个问题是我们的 path 路径其实也匹配了 /app 这样的路径,可能我们更加希望我们的应用在最后添加一个 / 这样的 slash,同样我们可以通过 configuration-snippet 配置来完成,如下 Ingress 对象:


apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: fe  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"    nginx.ingress.kubernetes.io/app-root: /app/    nginx.ingress.kubernetes.io/rewrite-target: /$2    nginx.ingress.kubernetes.io/configuration-snippet: |      rewrite ^(/app)$ $1/ redirect;      rewrite ^/stylesheets/(.*)$ /app/stylesheets/$1 redirect;      rewrite ^/images/(.*)$ /app/images/$1 redirect;spec:  rules:  - host: todo.qikqiak.com    http:      paths:      - backend:          serviceName: fe          servicePort: 3000        path: /app(/|$)(.*)
复制代码


更新后我们的应用就都会以 / 这样的 slash 结尾了。这样就完成了我们的需求,如果你原本对 nginx 的配置就非常熟悉的话应该可以很快就能理解这种配置方式了,当然如果你还是喜欢更加简单明了的方式的话可以推荐使用 Traefik 。


2020-05-18 18:074031

评论

发布
暂无评论
发现更多内容

YashanDB数据库异步复制机制与容错设计详解

数据库砖家

YashanDB数据库优化数据写入性能的实战技巧

数据库砖家

YashanDB数据库与机器学习平台的融合应用前景分析

数据库砖家

AI智能体 - 目标设定与监控模式

Hernon AI

AI开发 AI智能体 AI开发框架 AI设计模式

小型 DAO 去中心化组织工具开发最低预算需要多少?

西安链酷科技

观测云荣膺亚马逊云科技 2025 年合作伙伴奖项

观测云

可观测性

YashanDB数据库与AI模型训练的结合分析.

数据库砖家

YashanDB数据库与传统数据库的十大战略差异

数据库砖家

关于EDK II固件漏洞修复及版本回退的安全通告

qife122

系统安全 UEFI固件

CAD如何绘制螺旋线

极客天地

YashanDB数据库与企业资源规划系统的整合

数据库砖家

YashanDB数据库与区块链技术的融合探索

数据库砖家

TinyEngine低代码的运行时渲染引擎技术解析

OpenTiny社区

开源 前端 低代码 OpenTiny

写给0-1岁的初创公司合伙人(106):用技术分析思维看产品——如何判断你的产品是否有“相对强度”

Y11

创业 产品 股权 找工作

Android 弹出进度条对话框 避免用户点击界面交互

lichong951

android android-studio

YashanDB数据库优化策略助力提升企业IT系统稳定性

数据库砖家

YashanDB数据库与大数据技术结合的实用方法

数据库砖家

如何和AI协作提高工作效率

Hernon AI

AI 智能体 AI开发框架 AI开发方法论 AI设计模式 AI协作

CAD为什么打印不出图纸并生成了个PLT文件

极客天地

YashanDB数据库与人工智能的结合前景探讨

数据库砖家

人工智能时代,如何打造网络安全“新范式”

光联世纪

SD-WAN

16k数据撬动300亿大模型!我用Qwen3-VL打造了一位“顶尖放射科医生”

LLaMAFactoryOnline

YashanDB数据库异步复制技术应用详解与优化诀窍

数据库砖家

YashanDB数据库优化的10大实用技巧揭秘

数据库砖家

YashanDB数据库与机器学习结合的实践经验

数据库砖家

11 月热搜精选

KaiwuDB

数据库 KaiwuDB 分布式多模数据库 KWDB开源数据库

YashanDB数据库与大数据生态的整合

数据库砖家

YashanDB数据库与区块链技术的交互潜力

数据库砖家

AI 智能体 - 模型上下文协议

Hernon AI

AI智能体 MCP协议 A2A AI开发框架

YashanDB数据库与区块链技术的结合探讨

数据库砖家

YashanDB数据库与人工智能结合的应用新视角

数据库砖家

实践示例:从一个域名跳转到另一个域名,ingress-nginx经历了什么_文化 & 方法_Rancher_InfoQ精选文章