nginx-ingress controller简单实现基于http header、cookie、arg的灰度发布
前面讲了一篇使用nginx流量切分的文章做A/B测试,今天讲一下怎么简单使用nginx实现基于http header、cookie、arg实现简单的灰度发布。
总的来说实现非常简单,只是在nginx配置里的location块里加入相应的配置即可。假设有个应用的两个版本,分别为old和new,如下面所示:
使用$http_ 获取http请求的header,根据配置中是否为完整或者正则匹配,匹配foo的值
location / { .... if ($http_foo = "bar") { //完全匹配 #if ($http_foo ~ "bar") { //正则匹配 proxy_pass http://default-new-nginx-80; break; } proxy_pass http://default-old-nginx-80; .... }
使用$cookie_获取http请求的cookie,根据配置中是否为完整或者正则匹配,匹配foo的值
location / { .... if ($cookie_foo ~ "^bar") { //正则匹配 #if ($cookie_foo = "bar") { //完全匹配 proxy_pass http://default-new-nginx-80; break; } proxy_pass http://default-old-nginx-80; ...
使用$arg_获取http的请求参数,根据配置中是否为完整或者正则匹配,匹配foo的值
location / { .... if ($arg_foo ~ "^bar") { //正则匹配 #if ($arg_foo = "bar") { //完全匹配 proxy_pass http://default-new-nginx-80; break; } proxy_pass http://default-old-nginx-80; ...
在nginx中配置很简单,但是我的集群环境是k8s,我使用的是nginx-ingress-controller暴露内网应用,因此我考虑的是怎么将这个配置以ingress的形式发布到k8s集群中,nginx-ingress-controller能够感知并将配置正确的写入nginx并reload。
举个栗子
假设有old版本的nginx,以域名形式访问old版本会返回old内容,访问new版本会返回new内容,deployment和service yaml文件如下
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: old-nginx spec: replicas: 2 selector: matchLabels: run: old-nginx template: metadata: labels: run: old-nginx spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx imagePullPolicy: Always name: old-nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: old-nginx spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: old-nginx sessionAffinity: None type: NodePort
再生成新的版本的应用,即我们准备灰度的版本
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: new-nginx spec: replicas: 1 selector: matchLabels: run: new-nginx template: metadata: labels: run: new-nginx spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx imagePullPolicy: Always name: new-nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: new-nginx spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: new-nginx sessionAffinity: None type: NodePort
应用部署完毕后,我们看要怎么配置ingress才能够正确的刷新到ngixn.conf,在nginx-ingress-controller中,它支持 nginx.ingress.kubernetes.io/configuration-snippet 这样一个注解允许我们在location里配置自定义需求。同时结合nginx-ingress-controller的upstream命名方式namespace-serviceName-port的方式配置注解信息。如下ingress yaml所示
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/configuration-snippet: | if ($http_foo ~ "^.*bar$") { proxy_pass http://default-new-nginx-80; break; } name: gray-release namespace: default spec: rules: - host: www.example.com http: paths: - backend: serviceName: old-nginx servicePort: 80 path: / - backend: serviceName: new-nginx servicePort: 80 path: /
生成之后,我们去nginx-ingress-controller镜像里查看nginx.conf,会发现和我们在上述nginx的配置一样,这里我们请求访问下看是否和配置那样符合我们的逾期。
curl -H "Host: www.example.com" http://172.16.0.9 old curl -H "Host: www.example.com" http://172.16.0.9 old curl -H "Host: www.example.com" http://172.16.0.9 old curl -H "Host: www.example.com" -H "foo: bar" http://172.16.0.9 new curl -H "Host: www.example.com" -H "foo: bar" http://172.16.0.9 new curl -H "Host: www.example.com" -H "foo: bar" http://172.16.0.9 new
同理如果我们要想设置cookie,arg都可以以header的类似方式配置,nginx-ingress-controller会帮我们把配置刷新到nginx以完成我们的灰度需求。
阅读更多- 灰度发布-基于nginx的cookie实现
- 基于cookie在nginx实现业务灰度发布 推荐
- Nginx之一:实现简单HTTP模块helloworld
- 基于TCP和HTTP协议的RPC简单实现
- 使用 ngx_http_upstream_session_sticky_module 实现基于cookie的负载均衡
- java最简单的方式实现http get请求 gbk转utf8 javaweb发布到服务器
- Nginx之一:实现简单HTTP模块helloworld
- WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)
- nginx服务器的简单实现和 http 跳转至 https
- 基于 Java NIO 实现简单的 HTTP 服务器
- 基于nginx-rtmp-module模块实现的基于HTTP协议的FLV直播模块(nginx-http-flv-module)
- Nginx之一:实现简单HTTP模块helloworld
- 基于Java实现简单Http服务器之一
- Nginx之一:实现简单HTTP模块helloworld
- ffmpeg+nginx搭建HLS服务器及基于ARM实现的简单hls解决方案
- 基于TCP和HTTP协议的RPC简单实现
- 【Nginx】初识nginx---实现一个简单的http模块
- 基于RFC6265 (HTTP状态管理协议)实现简单的登录系统
- 基于SpringBoot简单实现SpringAop+Redis+cookie 单点登录 和 用户登录检测
- 基于ASP.NET的comet简单实现 http长连接,IAsyncResult