基于ambassador实现K8S灰度发布
为什么需要灰度发布
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。
总结下一些应用场景:
- 微服务依赖很多组件,需要在实际环境验证
- 部署新功能有风险,然后可以通过导流一小部分用户实际使用,来减小风险
- 让特定的用户访问新版本,比如部署一个版本,只让测试使用
- A/B Testing,部署两个版本,进行版本对比,比如验证两个推荐服务的推荐效果
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
ambassador介绍
ambassador[æmˈbæsədər],是Kubernetes微服务 API gateway,基于Envoy Proxy。
Open Source Kubernetes-Native API Gateway built on the Envoy Proxy
官方地址:
部署ambassador
按官网提示部署ambassador
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: Service
metadata:
labels:
service: ambassador-admin
name: ambassador-admin
spec:
type: NodePort
ports:
- name: ambassador-admin
port: 8877
targetPort: 8877
selector:
service: ambassador
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: ambassador
rules:
- apiGroups: [""]
resources: [ "endpoints", "namespaces", "secrets", "services" ]
verbs: ["get", "list", "watch"]
- apiGroups: [ "getambassador.io" ]
resources: [ "*" ]
verbs: ["get", "list", "watch"]
- apiGroups: [ "apiextensions.k8s.io" ]
resources: [ "customresourcedefinitions" ]
verbs: ["get", "list", "watch"]
- apiGroups: [ "networking.internal.knative.dev" ]
resources: [ "clusteringresses", "ingresses" ]
verbs: ["get", "list", "watch"]
- apiGroups: [ "networking.internal.knative.dev" ]
resources: [ "ingresses/status", "clusteringresses/status" ]
verbs: ["update"]
- apiGroups: [ "extensions" ]
resources: [ "ingresses" ]
verbs: ["get", "list", "watch"]
- apiGroups: [ "extensions" ]
resources: [ "ingresses/status" ]
verbs: ["update"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: ambassador
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ambassador
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ambassador
subjects:
- kind: ServiceAccount
name: ambassador
namespace: kube-system
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: authservices.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: authservices
singular: authservice
kind: AuthService
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: consulresolvers.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: consulresolvers
singular: consulresolver
kind: ConsulResolver
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: kubernetesendpointresolvers.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: kubernetesendpointresolvers
singular: kubernetesendpointresolver
kind: KubernetesEndpointResolver
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: kubernetesserviceresolvers.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: kubernetesserviceresolvers
singular: kubernetesserviceresolver
kind: KubernetesServiceResolver
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: mappings.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: mappings
singular: mapping
kind: Mapping
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: modules.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: modules
singular: module
kind: Module
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ratelimitservices.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: ratelimitservices
singular: ratelimitservice
kind: RateLimitService
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tcpmappings.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: tcpmappings
singular: tcpmapping
kind: TCPMapping
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlscontexts.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: tlscontexts
singular: tlscontext
kind: TLSContext
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tracingservices.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: tracingservices
singular: tracingservice
kind: TracingService
categories:
- ambassador-crds
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: logservices.getambassador.io
spec:
group: getambassador.io
version: v1
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: logservices
singular: logservice
kind: LogService
categories:
- ambassador-crds
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ambassador
spec:
replicas: 3
selector:
matchLabels:
service: ambassador
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
"consul.hashicorp.com/connect-inject": "false"
labels:
service: ambassador
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
service: ambassador
topologyKey: kubernetes.io/hostname
serviceAccountName: ambassador
containers:
- name: ambassador
image: quay.azk8s.cn/datawire/ambassador:0.86.1
resources:
limits:
cpu: 1
memory: 400Mi
requests:
cpu: 200m
memory: 100Mi
env:
- name: AMBASSADOR_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
- name: admin
containerPort: 8877
livenessProbe:
httpGet:
path: /ambassador/v0/check_alive
port: 8877
initialDelaySeconds: 30
periodSeconds: 3
readinessProbe:
httpGet:
path: /ambassador/v0/check_ready
port: 8877
initialDelaySeconds: 30
periodSeconds: 3
volumeMounts:
- name: ambassador-pod-info
mountPath: /tmp/ambassador-pod-info
volumes:
- name: ambassador-pod-info
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
restartPolicy: Always
securityContext:
runAsUser: 8888
---
apiVersion: v1
kind: Service
metadata:
name: ambassador
spec:
type: NodePort
externalTrafficPolicy: Local
ports:
- port: 80
targetPort: 8080
selector:
service: ambassador
EOF
为了方便访问网关,生成一个ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
kubernetes.io/tls-acme: 'true'
name: ambassador
spec:
rules:
- host: ambassador.iflyresearch.com
http:
paths:
- backend:
serviceName: ambassador
servicePort: 80
path: /
ambassador 配置
ambassador 使用envoy来实现相关的负载,而envoy类似nginx。ambassador的原理大概是读取service里的配置,然后自动生成envoy的配置,当service变更时,动态更新envoy的配置并重启,所以ambassador需要可以访问服务API。
ambassador 的配置是放到metadata的annotations,以getambassador.io/config开头:
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Mapping
name: {{ .Values.service.name }}_mapping
prefix: /{{ .Values.service.prefix }}
service: {{ .Values.service.name }}.{{ .Release.Namespace }}
profix指定如何访问服务,service指定指向那个服务。注意,需要加上namespace名称,否则容易报找不到后端。
ambassador 灰度
ambassador实现灰度可以根据weight权重,或者指定匹配特定的header来实现。
根据weight进行灰度
用法:
部署一个新版本的service,prefix和之前老服务保持一致,但是配置weight,比如20,这样20%的流量会流转到新服务,这样实现A/B Test
---
apiVersion: v1
kind: Service
metadata:
name: svc-gray
namespace: default
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Mapping
name: svc1_mapping
prefix: /svc/
service: service-gray
weight: 20
spec:
selector:
app: testservice
ports:
- port: 8080
name: service-gray
targetPort: http-api
根据请求头 header 进行灰度 (regex_headers 正则匹配)
部署一个新版本,只需要特定的用户才能访问,可以通过该方案来实现。
例如:
---
apiVersion: v1
kind: Service
metadata:
name: svc-gray
namespace: default
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Mapping
name: svc1_mapping
prefix: /svc/
service: service-gray
headers:
gray: true
spec:
selector:
app: testservice
ports:
- port: 8080
name: service-gray
targetPort: http-api
访问时,当指定gray: true时,访问灰度版本,可以用postman来测试:

作者:Jadepeng
出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
基于ambassador实现K8S灰度发布的更多相关文章
- ASP.NET Core on K8S学习之旅(14)Ingress灰度发布
本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 之前一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和 ...
- K8S基于ingress-nginx实现灰度发布
之前介绍过使用ambassador实现灰度发布,今天介绍如何使用ingre-nginx实现. 介绍 Ingress-Nginx 是一个K8S ingress工具,支持配置 Ingress Annota ...
- K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布)
K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布) 环境 软件 版本 kubernetes v1.18.6 nginx-ingress-controller 0.32 ...
- Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布
Istio是什么? Istio是Google继Kubernetes之后的又一开源力作,主要参与的公司包括Google,IBM,Lyft等公司.它提供了完整的非侵入式的微服务治理解决方案,包含微服务的管 ...
- Knativa 基于流量的灰度发布和自动弹性实践
作者 | 李鹏(元毅) 来源 | Serverless 公众号 一.Knative Knative 提供了基于流量的自动扩缩容能力,可以根据应用的请求量,在高峰时自动扩容实例数:当请求量减少以后,自动 ...
- k8s+istio:流量控制之灰度发布
通过Kubernetes+Istio的流量控制实现灰度发布,主要演示通过流量权重实现蓝绿,通过http自定义头实现金丝雀 准备环境 k8s和istio不想自己装的话可以在云上买个按量付费集群,用完即删 ...
- Istio 太复杂?KubeSphere基于Ingress-Nginx实现灰度发布
在 Bookinfo 微服务的灰度发布示例 中,KubeSphere 基于 Istio 对 Bookinfo 微服务示例应用实现了灰度发布.有用户表示自己的项目还没有上 Istio,要如何实现灰度发布 ...
- k8s实现灰度发布
灰度发布在实际生产部署中是经常被使用的方式,常规的方法是手动从前端LB(负载均衡)上将后端服务器摘掉,然后,停服务,最后上传代码,完成软连接更新.在使用CI/CD工具时,这个过程变得自动化了,我们只需 ...
- 基于 Istio 与 Kubernetes 对应用进行灰度发布与 Tracing
灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式.通俗来说,即让产品的迭代能够按照不同的灰度策略对新版本进行线上环境的测试,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以对新版本进行测试 ...
随机推荐
- 阿里云POLARDB如何助力轻松筹打造5亿用户信赖的大病筹款平台?
轻松筹首创了“大病救助”模式,帮助了众多病患在第一时间解決了医疗资金等问题,为了从源头解决了医疗资金问题.而在轻松筹这样全球5.5亿用户信赖的大病筹款平台的背后,是日益增长的各种数据.面对这样数据量所 ...
- Flask学习之三 web表单
本部分Miguel Grinberg教程的翻译地址:http://www.pythondoc.com/flask-mega-tutorial/webforms.html 开源中国的:http://ww ...
- 《C语言深度解剖》学习笔记之函数
第6章 函数 1.编码风格 [规则6-1]每一个函数都必须有注释 [规则6-2]每个函数定义之后以及每个文件结束之后都要加若干个空行 [规则6-3]在一个函数体内,变量定义与函数语句之间要加空行 [规 ...
- Jmeter监控
https://www.cnblogs.com/saryli/p/6596647.html JMeter是一款压力测试工具,我们也可以用它来监控服务器资源使用情况. JMeter正常自带可以通过Tom ...
- Bert源码阅读
前言 对Google开源出来的bert代码,来阅读下.不纠结于代码组织形式,而只是梳理下其训练集的生成,训练的self-attention和multi-head的具体实现. 训练集的生成 主要实现在c ...
- hdu 1277 全文检索 (直接映射查找 || 自动机)
Problem - 1277 无聊做水题的时候发现的一道题目.这道题第一反应可以用自动机来解决.当然,条件是各种限制,从而导致可以用直接映射标记的方法来搜索.具体的做法就像RK算法一样,将字符串has ...
- 推荐几个web前端比较实用的网站
第一次写博客,说实在的有点紧张和兴奋,哈哈哈哈,本人工作了有两年的时间,平时也有做笔记的习惯,但是都做得乱七八糟的,所以就想通过写博客来记录.好了,废话不多说了,先来几个觉得在工作中使用到的,还不错的 ...
- php Restful设计
1.restful是基于资源的,面向资源架构风格(一个链接,一张图.一个文本等等) 2.restful的http协议 2.1 url: 2.1.1 port 服务端口,默认为80 2.1.2 path ...
- Python--day21--包
包: 包是一种通过使用‘.模块名’来组织python模块名称空间的方式. 1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高 ...
- Springboot 2.x下多数据源配置
本文同样适用于2.x版本下Mybatis的多数据源配置 项目中经常会遇到一个项目需要访问多个数据源的情况,多数情况下可以参考这个教程进行配置. 不过该教程适合springboot1.x版本,由于2.x ...