网站页面架构,成都官网优化推广,广州贝勤网络科技有限公司,建行源宝导读#xff1a;明源云客的终端用户越来越多#xff0c;也涌现出线上流量活动的场景#xff0c;大量的访问和接口请求导致服务器出现较高负载。本文将介绍云客团队为了缓解服务器压力#xff0c;通过K8S进行分流与资源隔离的实践过程。一、背景PaaS和B2C的主要客户云客… 源宝导读明源云客的终端用户越来越多也涌现出线上流量活动的场景大量的访问和接口请求导致服务器出现较高负载。本文将介绍云客团队为了缓解服务器压力通过K8S进行分流与资源隔离的实践过程。一、背景 PaaS和B2C的主要客户云客的终端用户越来越多也开始有流量活动的需求。 近期云客需要开始一个流量活动B2C配合对特定接口做了压测并且对系统容量进行了调整。当时的压测结果是200并发300ms完成基本符合云客的要求。可是活动开始后事情跟我们预想的是不一样的压测只测试了注册接口但是实际登陆接口也会有巨大的请求量。由于登陆接口有比较多的调用第三方所以在请求量大的是对服务器的CPU带来较高的负载。在这个情况下我们不断的对服务进行扩容。可是扩到190个核心服务服务依然是没法正常。 由于当时部署的是整个服务组统一给所有用户提供服务如下图 按照这个情况只要一个租户的流量特别大给集群带来压力就会导致整个服务异常所有人都无法正常访问。出于将影响范围缩小的考虑我们需要将活动的流量分流并保障即便活动的客户出现问题也只是影响活动租户不会影响到其他租户。二、分流 在思考如何分流时第一个想到的是之前已经在云链和云空间落地的利用openresty识别url参数headercookie中的特征信息然后进行路由这个方案。但是由于paas和B2C部署是基于k8s这个方案就变的不那么好了。 使用openresty就需要在集群之外架设将流量分配到两个集群那么会遇到这些问题分流集群通常不是常驻有需要的时候才会部署这样每次需要分流前都要去维护分流策略。为了保障openresty的可用性可能需要在集群外部部署多个openresty服务。那么流量的路径会变的很复杂且冗长这会让排查问题变的困难同时会影响访问速度。需要时间完成分流策略的代码并且要进行一定的压力测试才能够正式上线接管流量。会需要很比较多的时间。 由于这些问题考虑从k8s的ingress来进行分流。有了下图的设想 ingress-controller的选择 我们使用的ingress-controller是nginx-ingressnginx-ingress自带一个分流功能定义上也十分符合k8s和helm的的管理方式。查阅官方文档后发现目前nginx-ingress只支持headercookie进行分流可是现状是现有项目分流的特征信息在url的query才有。只能再去寻找其他ingress-controller。 查找并对比了traefikambassadorhaproxyalibaba-ingress这几个ingress-controller。traefik在功能上是满足的且有很多新的功能十分值得尝试并且解决了nginx令人诟病的静态配置问题。但是不支持tcp协议路由需要k8s版本高于1.14。由于一个网络插件升级的问题我们的k8s集群一直还在1.12版本所以这次用不上了。ambassador。如果严格遵循k8s的定义ambassador其实不算一个ingress-controller。它并不是通过ingress去定义路由规则而是直接在service上加上注解定义路由规则更像一个api网关。这样的话我们需要改动的点就比较多了。haproxy的优势在负载均衡算法在七层协议的路由能力不能满足需求。passalibaba-ingress阿里云基于nginx-ingress进行了一些定制开发和优化的ingress-controller。基本是与我们现在用的nginx-ingress一致在分流的规则定义上有一些差异。nginx的分流是分别在两个namespace定义两条ingress规则注解有差异通过注解匹配请求alibaba的则是在同一个ingress规则定义2个后端服务再通过注解匹配请求。alibaba-ingress的分流规则支持基于query的匹配是符合我们需求的但是两年没有更新版本并且官方不提供helm部署方式。 基于符合需求且影响点最小化的思路选用了alibaba-ingress来作为这次分流的ingress-controller。三、部署 在选定了分流的方案之后如何高效稳定的部署两组服务成为第二个需要解决的问题。 目前我们的部署方式将一组服务打包成一个产品进行部署。 如何部署分流的服务组有两个方案将分流的服务一个个加入产品里面进行部署。将现有产品在其他namespace再部署一份。方案1所有服务都在一个namespace中ingress规则很好配ingress规则不能路由到不同namespace的service但是会让服务管理变的十分复杂并且需要修改应用配置。放弃。方案2两组服务分别 部署在两个namespace需要解决跨namespace配置ingress规则的问题但是管理上简单也不需要对应用做任何改动。 改变部署存在的影响点太多时间紧迫必须选择影响点最少的办法。所以方案2是首选。 如何让ingress规则跨namespace 既然ingress的规则不能跨namespace路由那就想办法把其他namespace的service弄到当前namespace。在k8s中有一种ExternalName类型的service提供了映射外部服务的能力其实就是一个类似cname解析的功能。 部署示意 分两个命名空间部署两组一模一样的服务在常驻服务的命名空间中用ExternalName类型的service将分流服务命名空间内的服务映射过来。ingress在同一个命名空间下进行流量分配。四、资源隔离 在分流和部署的方案都确定以后需要考虑最后一个问题。如何保障正常用户不被活动的用户影响。根据我们的现状之所以正常用户会被影响的主要原因就是资源被活动用户消耗殆尽导致整个系统的崩溃基于这个情况为了保护正常用户的访问只需要将正常用户和活动用户使用的资源进行隔离即可。 K8S提供了几种管理容器调度到节点的功能节点选择器nodeSelector非常简单的方法来将 pod 约束到具有特定标签的节点上节点亲和nodeAffinity节点亲和分为硬和软两种“硬”类似节点选择器只是可以用更复杂的约束规则“软”则是尽可能运行到符合条件的节点上。节点瑕疵和容忍度Taint和Toleration为特定节点打上瑕疵标签只有能够容忍该瑕疵的pod才能运行到这类节点上。 实现隔离 利用1和3的功能就能够实现我们期望的效果。为活动的租户新增一批节点给这些节点打上瑕疵标签。保持正常业务的容器无法被调度到这些节点。按照之前部署中介绍的方案为活动租户新部署一套服务。新增的一组服务配置节点选择器约束到特定节点配置节点容忍新增节点的瑕疵标签。 经过上述步骤就能够将两组服务的资源很好的隔离开。五、快速配置 完成了功能性的诉求最后就是需要在使用上变得便利。因为之前选择方案都会考虑配置和部署的便利性所以最终只需要对现有的chart部署模版进行一些小小的调整就能实现快速配置分流以及隔离。 新增节点 通过阿里云新增节点之后通过下面命令对节点打标签和瑕疵kubectl label node cn-hangzhou.i-bp1faickzmmuat2f09dr b2ccanary
kubectl taint node cn-hangzhou.i-bp1faickzmmuat2f09dr b2ccanary:NoSchedule部署分流服务 我们使用helm部署只需要复制常驻服务的values文件新增几个字段并关闭ingress配置然后用helm部署到新的namespace即可。 以一个服务的values举例复制内容如下b2c-nginx-proxy:replicaCount: 5image:tag: 20190920env:enabled: true ingress:enabled: trueannotations: kubernetes.io/ingress.class: nginxhosts:- example.mypaas.com.cntls: - secretName: example.com.cnhosts:- example.mypaas.com.cn
修改后内容如下b2c-nginx-proxy:replicaCount: 5image:tag: 20190920env:enabled: true ingress:enabled: falseannotations: kubernetes.io/ingress.class: nginxhosts:- example.mypaas.com.cntls: - secretName: example.com.cnhosts:- example.mypaas.com.cntolerations:- key: b2coperator: Equalvalue: canaryeffect: NoSchedule nodeSelector:b2c: canary常驻服务开启分流配置 常驻服务的values文件新增几行即可实现分流以一个服务的values举例b2c-nginx-proxy:replicaCount: 3image:tag: 20190920env:enabled: true ingress:enabled: truecanary:enable: true #开启分流annotations: kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/service-match: | #分流规则配置b2c-nginx-proxy-canary: query(tenant_code, /.*zhaosadmin.*/) hosts:- example.mypaas.com.cntls: - secretName: example.com.cnhosts:- example.mypaas.com.cn简单的三步即可完成租户分流并且隔离。六、应用 当所有验证ok后立马将这套方案在生产上线将当时活动的租户分流并隔离。同时开始缩减集群规模把为正常租户提供服务的服务组节点数量恢复成常驻节点数量保留四个节点继续为活动租户提供服务。 到目前为止正常租户的服务没有受到过影响。七、云擎的灰度策略 灰度发布的技术本质跟这个分流并没有太大的区别。只是使用场景上的差异所以这套方案可以放到云擎直接实现灰度发布。简单介绍一下将来各团队接入使用时也能提前准备。 支持的路由规则 云擎支持的ingress-controller只会是nginx-ingress因为alibaba-ingress几年没有更新不敢在生产环节长期使用。所以云擎只能支持根据header和cookie进行路由。如果各团队希望能够灰度发布需要在请求头中加入特定标识。 数据库的灰度没有租户库的团队需要保持灰度的两个版本在数据结构上是兼容的有租户库的团队选择租户的范围进行数据升级 产品内部的服务调用 需要使用灰度发布必须保持各个服务间的调用都要走内网调用。不能通过公网域名调用这样会导致调用关系混乱。 支持的特性 由于是利用nginx-ingress实现的所以还是会遵循一些nginx本身的限制。只能创建一条灰度规则一条规则内可以同时定义headercookie权重。优先级关系header - cookie - 权重。header支持自定义值并且值可以用正则匹配cookie只支持固定值always或never分流规则所有配置遵循原有的所有配置如最大传输大小是否强制https超时时间等八、未来 现阶段利用nginx-ingress云擎能够以极低的成本提供灰度发布的能力但是nginx-ingress整体来看功能还是有欠缺。不过在这次事件中为了找方案了解了其他优秀的ingress-controller。后续应该会把所有的ingress-controller替换成traefik来实现更多功能。------ END ------作者简介尹同学 运维负责人目前在云技术创新中心负责技术运维工作。也许您还想看天眼系统对应用页面首次有效渲染的数据采集云客大数据管理保障体系浅谈Readiness和Liveness在云客的应用基于Go的微服务运行情况监控实践