【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"

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/156292.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tmux教学【有图有代码】

Tmux教学【有图有代码】 0、前言1、Tmux基本概念1.1 安装 2、Tmux使用2.1 session操作2.2 window操作2.3 pane操作2.4 其他操作 3、日常中Tmux的工作流 0、前言 想必同学们在跑代码时也许会存在这样一个问题: 本地在连接远程服务器跑代码的时候,本地ssh窗…

分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测

分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单…

Unity编辑器从PC平台切换到Android平台下 Addressable 加载模型出现粉红色,类似于材质丢失的问题

Unity编辑器在PC平台下使用Addressable加载打包好的Cube,运行发现能正常显示。 而在切换到Android平台下,使用Addressable时加载AB包,生成Cube对象时,Cube模型呈现粉红色,出现类似材质丢失的问题。如下图所示。 这是…

【机器学习】决策树原理及scikit-learn使用

文章目录 决策树详解ID3 算法C4.5算法CART 算法 scikit-learn使用分类树剪枝参数重要属性和接口 回归树重要参数,属性及接口交叉验证代码示例 一维回归的图像绘制 决策树详解 决策树(Decision Tree)是一种非参数的有监督学习方法,…

【算法优选】 二分查找专题——贰

文章目录 😎前言🌲[山脉数组的峰顶索引](https://leetcode.cn/problems/peak-index-in-a-mountain-array/)🚩题目描述:🚩算法思路🚩代码实现: 🌴[寻找峰值](https://leetcode.cn/pro…

VUE3基础知识梳理

VUE3基础知识梳理 一、vue了解和环境搭建1.vue是什么:cn.vuejs.org/vuejs.org2.渐进式框架3.vue的版本4.vueAPI的风格5.准备环境5.1.创建vue项目5.2.vue的目录结构 二、vue3语法1.干净的vue项目2.模板语法2.1 文本插值2.2属性绑定2.3条件渲染2.4列表渲染2.5通过key管…

10、SpringBoot_测试用例

四、测试用例 1.准备工作 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>com…

ELK 处理 SpringCloud 日志

在排查线上异常的过程中&#xff0c;查询日志总是必不可缺的一部分。现今大多采用的微服务架构&#xff0c;日志被分散在不同的机器上&#xff0c;使得日志的查询变得异常困难。工欲善其事&#xff0c;必先利其器。如果此时有一个统一的实时日志分析平台&#xff0c;那可谓是雪…

2023年电工(初级)证考试题库及电工(初级)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年电工&#xff08;初级&#xff09;证考试题库及电工&#xff08;初级&#xff09;试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#…

mysql面试题40:列值为null或者空字符串时,查询是否会用到索引?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:列值为null或者空字符串时,查询是否会用到索引? 当列的值为NULL时,查询可能会使用索引,但具体是否使用索引取决于数据库的优化器和查询条件。…

Compose 编译器版本和Kotlin版本对应关系

使用了最新的kotlin版本&#xff0c;compose报错&#xff0c;不兼容&#xff0c;在这里记录一下版本对应关系 值得注意的是Compose Kotlin 编译器扩展 (androidx.compose.compiler) 未关联到 Compose 库版本。相反&#xff0c;它会关联到 Kotlin 编译器插件的版本&#xff0c;…

【SoC FPGA】HPS启动过程

SoC HPS启动流程 Boot ROMPreloaderBoot Loader HPS的启动是一个多阶段的过程&#xff0c;每一个阶段都会完成对应的工作并且将下一个阶段的执行代码引导起来。每个阶段均负责加载下一个阶段。第一个软件阶段是引导 ROM&#xff0c;引导 ROM 代码查找并且执行称为预加载器的第 …

【ArcGIS】NDVI估算植被覆盖度FVC

NDVI计算 植被覆盖度计算 Step1&#xff1a;调出栅格计算器工具 1、首先打开软件&#xff0c;然后在操作页面点击&#xff0c;自定义工具栏中——自定义模式。 2、再点击窗口中的命令选项。 3、在窗口右上角处搜索“栅格计算”。 4、然后&#xff0c;直接将栅格计算器直接…

Linux C select 的学习

一. select 系统调用 1. 函数说明 #include <sys/select.h> #include <sys/time.h>int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);nfds: 是一个整数值&#xff0c;是指集合中所有文件描述符的范围&#…

SpringBoot 接口 字节数组直接显示为图片

源码&#xff1a; import java.io.ByteArrayOutputStream; import javax.imageio.ImageIO; import org.springframework.web.bind.annotation.RequestMapping;/*** 获取二维码图像* 二维码支付** param price 金额* return 二维码图像* throws IOException IOException*/ Requ…

Windows Nginx 服务器部署(保姆级)

大家好 我是寸铁 不知道怎么部署Windows Nginx 服务器看过来 手把手带你部署服务器 将你的本地网页部署到服务器上 话不多说&#xff0c;直接上操作&#xff01;&#xff01;&#xff01; Windows Nginx服务器部署 进入下载地址&#xff1a; http://nginx.org/en/download.h…

stm32学习笔记:中断的应用:对射式红外传感器计次旋转编码器计次

相关API介绍 EXT配置API(stm32f10x exti.h&#xff09; NVIC 配置API (misc.h) 初始化的中断的步骤 第一步&#xff1a;配置RCC时钟&#xff0c;把涉及外设的时钟都打开 第二步&#xff1a;配置GPIO&#xff0c;设置为输入模式 第三步&#xff1a;配置AFIO&#xff0…

VsCode同时编译多个C文件

VsCode默认只能编译单个C文件&#xff0c;想要编译多个文件&#xff0c;需要额外进行配置 第一种方法 ——> 通过手动指定要编译的文件 g -g .\C文件1 .\C文件2 -o 编译后exe名称 例如我将demo.c和extern.c同时编译得到haha.exe g -g .\demo.c .\extern.c -o haha 第二种…

移动应用-Android开发基础\核心知识点

Android开发基础 知识点 1 介绍了解2 系统体系架构3 四大应用组件4 移动操作系统优缺点5 开发工具6 配置工具7 下载相关资源8JDK下载安装流程9配置好SDK和JDK环境10 第一个Hello word11 AS开发前常用设置12模拟器使用运行13 真机调试14 AndroidUI基础布局15 加载展示XML布局16…

dll动态链接库及ocx activex 控件regsvr32注册失败 解决方法(Win10)

一、错误提示说明&#xff1a; 1、regsvr32注册dll或ocx activex控件时提示模块 dll加载失败&#xff0c;请确保该二进制存储在指定的路径中&#xff0c;或者调试它以检查该二进制或相关的.dll文件是否有问题”。 检查了.dll文件路径也没有问题&#xff0c;在开发机器上是可以…