当前位置: 首页 > news >正文

【k8s】ingress-nginx通过header路由到不同后端

K8S中ingress-nginx通过header路由到不同后端

背景
  • 公司使用ingress-nginx作为网关的项目,需要在相同域名、uri,根据header将请求转发到不同的后端中
  • 在稳定发布的情况下,ingress-nginx是没有语法直接支持根据header做转发的。但是这个可以利用灰度发布的特性实现header路由功能
准备
  • 准备两个后端,后端代码如下,路由均为 /app
    • main.go
package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default()r.GET("/app", func(context *gin.Context) {context.JSON(200, gin.H{"message": "app1"})})r.Run(":8080")
}
  • 使用Dockerfile构建镜像
    • 这里构建 goapp1:v1,goapp2:v1两个镜像(goapp2请将main.go修改 “message”: “app2”)
FROM golang:1.17.13
RUN mkdir -p /go/app/; \cd /go/app/; \go mod init app1;\GOPROXY="https://goproxy.cn,direct" go get github.com/gin-gonic/gin@v1.6.3
WORKDIR /go/app/
COPY main.go /go/app
EXPOSE 8080
CMD go run main.go
使用灰度发布的特性进行header的路由
  • 此解决方案参考:https://v2-1.docs.kubesphere.io/docs/zh-CN/quick-start/ingress-canary/
  • 注:本人使用低版本ingress-nginx,高版本的请大家自行修改不同之处
  • 首先部署goapp1:v1 和 goapp2:v1 的deployment和service
    • 此为goapp1。goapp2请自行修改
apiVersion: apps/v1
kind: Deployment
metadata:name: goapp1namespace: default
spec:replicas: 1selector:matchLabels:app: goapp1template:metadata:labels:app: goapp1spec:containers:- image: goapp1:v1imagePullPolicy: IfNotPresentname: goapp1ports:- containerPort: 80protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: goapp1namespace: default
spec:ports:- port: 8080protocol: TCPtargetPort: 8080selector:app: goapp1
  • 部署稳定发布版本的ingress,路由至goapp1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: goapp1 namespace: defaultannotations:kubernetes.io/ingress.class: nginx
spec:rules:- host: test.comhttp:paths:- path: /app pathType: Prefixbackend:service:name: goapp1port: number: 8080
  • 部署canary版本的ingress,路由至goapp2
    • 这里可见 域名都是 test.com,uri都是 /app
    • 注解:
      • nginx.ingress.kubernetes.io/canary: “true” # 启用canary灰度发布特性
      • nginx.ingress.kubernetes.io/canary-by-header: canary # 通过header可选择是否转发至canary版本的后端
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: goapp2namespace: defaultannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-header: canary
spec:rules:- host: test.comhttp:paths:- path: /app pathType: Prefixbackend:service:name: goapp2port: number: 8080
  • 进行测试
for i in {1..20};# ingress-nginx的NodePort请自行查看,替换下面的端口do curl test.com:31132/app -H "canary: never"; # 路由至稳定版本的goapp1echo -e "";
done
for i in {1..20};do curl test.com:31132/app -H "canary: always"; # 路由至canary版本的goapp2echo -e "";
done
  • 效果如下,可以看到可以通过header控制发送请求到不同后端,能够满足需求
    在这里插入图片描述
通过nginx进行转发
  • 第二种方法可通过在k8s集群部署一个nginx, 通过nginx进行分流
    • 流量路径如下: ingress-nginx --> nginx --> goapp1或goapp2
  • 这里nginx写法有比较多,我选择最简单的通过if判断$http_my_header
  • 在使用$http_my_header之前,需要对ingress-nginx和nginx添加参数,允许header中存在下划线
    • ingress-nginx
kubectl edit cm ingress-nginx-controller
------------------
apiVersion: v1
data:allow-snippet-annotations: "true"# 添加下面这两个参数enable-underscores-in-headers: "true"ignore-invalid-headers: "false"
kind: ConfigMap
  • 部署nginx,nginx中开启允许header下划线的参数:underscores_in_headers on;
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxnamespace: default
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.24.0ports:- containerPort: 80volumeMounts:- name: nginxmountPath: /etc/nginx/nginx.confsubPath: nginx.confvolumes:- name: nginxconfigMap:name: nginxitems:- key: nginx.confpath: nginx.conf
---
apiVersion: v1
kind: Service
metadata:name: nginxnamespace: default
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80
---
apiVersion: v1
data:nginx.conf: |user  nginx;worker_processes  auto;error_log  /var/log/nginx/error.log notice;pid        /var/run/nginx.pid;events {worker_connections  1024;}http {upstream upstream_server1 {server goapp1:8080;}upstream upstream_server2 {server goapp2:8080;}include       /etc/nginx/mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" "$http_my_header"';access_log  /var/log/nginx/access.log  main;sendfile        on;keepalive_timeout  65;server {underscores_in_headers on; listen 80;server_name test.com;location /app {if ($http_my_header = "value1") {proxy_pass http://upstream_server1;}if ($http_my_header = "value2") {proxy_pass http://upstream_server2;}}}}kind: ConfigMap
metadata:name: nginxnamespace: default
  • 上面的配置判断 $http_my_header是 value1 还是 value2,再转发到不同的upstream
  • 测试
curl test.com/app -H "my_header:value1"
curl test.com/app -H "my_header:value2"

在这里插入图片描述

相关文章:

【k8s】ingress-nginx通过header路由到不同后端

K8S中ingress-nginx通过header路由到不同后端 背景 公司使用ingress-nginx作为网关的项目,需要在相同域名、uri,根据header将请求转发到不同的后端中在稳定发布的情况下,ingress-nginx是没有语法直接支持根据header做转发的。但是这个可以利…...

LuatOS-SOC接口文档(air780E)-- httpsrv - http服务端

httpsrv.start(port, func)# 启动并监听一个http端口 参数 传入值类型 解释 int 端口号 function 回调函数 返回值 返回值类型 解释 bool 成功返回true, 否则返回false 例子 -- 监听80端口 httpsrv.start(80, function(client, method, uri, headers, body)-- m…...

Android Studio: unrecognized Attribute name MODULE

错误完整代码: ������ (1.8.0_291) �г����쳣������&#xff…...

云服务器带宽对上传下载速度的影响

简单来说就是 云服务器收到数据代表入&#xff0c;带宽大小 < 10时&#xff0c;入带宽大小10 带宽大小 > 10时&#xff0c;出入带宽上限 等于实际购买时候的大小...

2023/9/28 -- ARM

【内存读写指令】 int *p0X12345678 *p100;//向内存中写入数据 int a *p;//从内存读取 1.单寄存器内存读写指令 1.1 指令码以及功能 向内存中写&#xff1a; str:向内存中写一个字(4字节)的数据 strh:向内存写半个字&#xff08;2字节&#xff09;的数据 strb:向内存写一个字…...

vue原生实现element上传多张图片浏览删除

vue原生实现element上传多张图片浏览删除 <div class"updata-component" style"width:100%;"><div class"demo-upload-box clearfix"><div class"demo-upload-image-box" v-if"imageUrlArr && imageUrlAr…...

黑群晖video station评级问题

黑群晖video station评级问题 环境 群晖Version: 6.2.3-25423video station 2.4.10方法1,py文件 登录ssh,获取sudo权限 cd /var/packages/VideoStation/target/plugins/syno_themoviedbsudo vim search.py替换movie_data[vote_average] 替换为 round(movie_data[vote_avera…...

Godot快速精通-从看懂英文文档开始-翻译插件

视频教程地址&#xff1a;https://www.bilibili.com/video/BV1t8411q7hw/ 大家好&#xff0c;我今天要和大家分享的是如何快速精通Godot&#xff0c;众所周知&#xff0c;一般一个开源项目都会有一个文档&#xff0c;对于有一定基础或者是理解能力强的同学&#xff0c;看文档比…...

vue项目的学习周报03

学习周报 日期范围&#xff1a;2023年9月25日~2023年10月1日 学习目标&#xff1a;本周的学习目标是学习vue的基础知识 学习成果&#xff1a;在本周我完成以下任务和学习活动&#xff1a; 1.我完成了对vue.js的基础认识&#xff1b; 2.学习了通过index.js导入新的组件&#…...

ES中个别字段属性说明

DEFAULT_NO_CFS_RATIO ​ DEFAULT_NO_CFS_RATIO这个用于判断生成新段的时候&#xff0c;是否使用复合文件&#xff0c; 复合文件&#xff08;Compound File&#xff09;是将多个索引文件合并为一个单一的文件组合&#xff0c;以减少文件数量和提高性能。 ​ 在 Lucene 中&…...

Web前端-Vue2+Vue3基础入门到实战项目-Day3(生命周期, 案例-小黑记账清单, 工程化开发入门)

Web前端-Vue2Vue3基础入门到实战项目-Day3 生命周期生命周期 & 生命周期四个阶段生命周期钩子生命周期案例created应用mounted应用 案例 - 小黑记账清单工程化开发入门工程化开发和脚手架项目运行流程index.htmlmain.js 组件化组件注册局部注册全局注册 来源 生命周期 生命…...

如何在小程序首页设置标题栏文字

小程序的首页标题栏是用户进入小程序时首先看到的部分&#xff0c;因此设置一个适合文字对于树立品牌非常有作用。以下是一些简单的步骤&#xff0c;教你如何在小程序的首页设置标题栏文字&#xff08;如下图&#xff0c;白色的“商城”文字&#xff09;。 1. 在小程序管理员后…...

CPU性能分析--火焰图使用

记录工具使用说明&#xff0c;火焰图原理网上分析很多。主要用来分析函数调用栈占用的cpu利用率&#xff0c;分析函数性能。 perf安装&#xff1a; sudo apt-get install linux-tools-common sudo apt-get install linux-tools-"(uname -r)" sudo apt-get install …...

微服务10-Sentinel中的隔离和降级

文章目录 降级和隔离1.Feign整合Sentinel来完成降级1.2总结 2.线程隔离两种实现方式的区别3.线程隔离中的舱壁模式3.2总结 4.熔断降级5.熔断策略&#xff08;根据异常比例或者异常数&#xff09; 回顾 我们的限流——>目的&#xff1a;在并发请求的情况下服务出现故障&…...

python实现UI自动化配置谷歌浏览器驱动

web端UI自动化执行在哪个浏览器&#xff0c;需要对应哪个浏览器的驱动。以谷歌浏览器为例&#xff0c;进行配置。一、查看谷歌浏览器版本 如下截图&#xff1a;我的谷歌浏览器版本是&#xff1a; 117.0.5938.150 二、下载对应版本谷歌浏览器驱动 首先可以从其他版本驱动地址中…...

AI如何帮助Salesforce从业者找工作?

在当今竞争激烈的就业市场中&#xff0c;找到满意的工作是一项艰巨的任务。成千上万的候选人竞争一个岗位&#xff0c;你需要利用一切优势从求职大军中脱颖而出。 这就是AI的用武之地&#xff0c;特别是像ChatGPT这样的人工智能工具&#xff0c;可以成为你的秘密武器。本篇文章…...

【Vue面试题十七】、你知道vue中key的原理吗?说说你对它的理解

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;你知道vue中key的原理吗…...

【数据结构】二叉树--堆排序

目录 一 降序(建小堆) 二 升序 (建大堆) ​三 优化(以升序为例) 四 TOP-K问题 一 降序(建小堆) void Swap(int* x, int* y) {int tmp *x;*x *y;*y tmp; }//降序 建小堆 void AdjustUp(int* a, int child) {int parent (child - 1) / 2;while (child > 0){if (a[chil…...

项目log日志mysql记录,熟悉python的orm框架

直接在项目里面创建一个class&#xff0c;这个类对应着mysql里面的表 我们运行项目&#xff0c;可以自动建立表 在.env中找到mysql的配置信息&#xff0c;这个是在NB服务器上运行的mysql&#xff0c;localhost需要变成NB服务器的ipv4地址 使用Mysql工具连接查看&#xff0c;连…...

【数据结构-字符串 四】【字符串识别】字符串转为整数、比较版本号

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【字符串转换】&#xff0c;使用【字符串】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...