中间件访问服务与性能优化 主讲人:罗丹网易数帆资深中间件运维架构师 CONTENT 1 云原生中的service 2 service底层实现简介 3 service在轻舟中间件的应用 4 性能优化思路 数字化基础软件自主创新分享周 1 云原生中的service 数字化基础软件自主创新分享周 DIGITALSAIL 中间件访问服务与性能优化 云原生中的service Q:你的应用程序A想要访问其他服务B时,是怎么配置的? 直接配置服务B所在运行的机器的IP地址 服务B换部署节点后IP改变 配置服务B的前置代理nginx/haproxy的地址 服务B后端变更时需额外手工调整nginx/haproxy 配置服务B的域名+dns解析、注册中心、服务发现 数字化基础软件自主创新分享周 云原生中的service Service介绍 k8S内部 通过service的请求 标签选择器 service 应用的访问入口 按规则获取ep中的其中一个地址 动态监测pod 将pod的访问地址维护 到 真实请求 endpoint endpoint列表中 Pod 最小调度单元 Pod 最小调度单元 Pod 最小调度单元 数字化基础软件自主创新分享周 云原生中的service Service介绍 apiVersion:v1#版本kind:Service#类型metadata:#元数据 name:#资源名称 namespace:#命名空间 spec: selector:#标签选择器,用于确定当前Service代理哪些Pod,对应pod上的label字段 #没有selector字段,service被创建时 #endpointcontroller不会自动创建endpoint app:nginx type:NodePort#Service的类型,指定Service的访问方式clusterIP:#虚拟服务的IP地址 sessionAffinity:#session亲和性,支持ClientIP、None两个选项,默认值为Noneports:#端口信息 -port:8080#Service端口protocol:TCP#协议targetPort:#Pod端口nodePort:#主机端口 数字化基础软件自主创新分享周 云原生中的service Service的主要类型 01 ClusterIP K8S集群内访问,默认类型,K8S系统自动分配的虚拟ip,无ip地址的又称为headless 02 NodePort K8S集群外访问,在node上开放端口暴露给外部 03 LoadBalancer K8S集群外访问,需要外部云环境支持 04 ExternalName 特例,没有选择器selector,将服务映射到DNS域名可以把集群外部的服务引入集群内部直接使用 https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/ 数字化基础软件自主创新分享周 2 service底层实现简介 数字化基础软件自主创新分享周 NETEASEDIGITALSAIL 中间件访问服务与性能优化 service底层实现简介 kube-proxy:负责service的实现 userspace模式 最早的负载均衡方案,它在用户空间监听一个端口,所有服务通过iptables转发到这个端口,然后在其内部负载均衡到实际的Pod iptables模式 目前推荐的方案,完全以iptables规则的方式来实现service负载均衡 ipvs模式 v1.11新增了ipvs模式(v1.8开始支持测试版,并在v1.11GA), 采用增量式更新,并可以保证service更新期间连接保持不断开 数字化基础软件自主创新分享周 iptables代理模式 https://kubernetes.io/zh-cn/docs/concepts/services-networking/service service底层实现简介 kube-proxy:iptables模式 iptables是基于内核netfilter实现的, netfilter提供了一整套的钩子(hook)函数管理机制 链:系统预定义链、自定义链;自定义链要通过其他链跳转执行表:关注nat表,用于修改数据包的源地址和目的地址 kube-proxy:如何动态刷新iptables? kube-proxy的pod监听集群中service和endpoints资源的变化刷新节点上的iptables规则, 从而实现访问serviceVIP代理到后端pod的功能 数字化基础软件自主创新分享周 预定义链对应netfilterIP层面的5个钩子 service底层实现简介 我有一个clusterip类型的service 我直接在node上访问了一下它的80端口,该关注前面那张图的哪一步? 数字化基础软件自主创新分享周 service底层实现简介 在node上telnet10.178.86.3880 tcp协议,来源ip任意,目的ip是10.178.86.38,匹配到KUBE-SVC-EN2DPUE2MJ52PPBT这条子链 DNAT是一个最终处理动作,将目的ip和port换成10.178.174.238:8010.178.174.238是谁?service指向的后端pod 数字化基础软件自主创新分享周 3 service在轻舟中间件的应用 数字化基础软件自主创新分享周 NETEASEDIGITALSAIL 中间件访问服务与性能优化 service在轻舟中间件的应用 01 ClusterIP K8S集群内访问,默认类型,K8S系统自动分配的虚拟ip,无ip地址的又称为headless 02 NodePort K8S集群外访问,在node上开放端口暴露给k8s外部 03 LoadBalancer K8S集群外访问,需要外部云环境支持 均有提供,适用于不同的网络访问场景,可视化页面配置 数字化基础软件自主创新分享周 service在轻舟中间件的应用 物理机集群原有云平台 服务器 Node 应用 Subnet1 虚拟机 容器 业务 容器 业务 Headless/Clusterip 容器 中间件 Subnet2 K8SMaster 虚拟机×3 容器 中间件 容器 中间件 容器 中间件 应用 容器 Node 虚拟机 LB NodePort NodePort 服务器 ×3 KubernetesMaster •容器内部访问支持 Headleass以及ClusterIP方式 •集群间访问支持NodePort方式 •跨云访问支持LB方式 LB LB •业务方可以实现平滑迁移上云 数字化基础软件自主创新分享周 service在轻舟中间件的应用 cluster-ipservice访问流程 有一个clusterip类型的service,后端指向了Node2上的podB 在Node1上的podA发起请求,目标为[clusterip]:port 数字化基础软件自主创新分享周图片来自:calico service在轻舟中间件的应用 node-portservice访问流程: 有一个nodeport类型的service,后端指向了Node2上的podB 在k8s集群外部的一台机器上(可以连通Node1)发起请求,目标为[Node1ip]:port 数字化基础软件自主创新分享周图片来自:calico 4 性能优化思路 数字化基础软件自主创新分享周 NETEASEDIGITALSAIL 中间件访问服务与性能优化 性能优化思路 客户端感觉: •响应慢! •TPS低! 服务端感觉: •怎么带不动? •错在哪儿? 数字化基础软件自主创新分享周 https://brendangregg.com/linuxperf.html 性能优化思路 1、完善系统可观测性,通过监控、告警,系统水位定位瓶颈点 Prometheus搭配自研的skiff-nms服务,对pod、container、实例业务数据进行采样和告警自研Log-agent采集组件、Log-seer查询组件监控实例日志输出 Redis 核心监控指标 used_memory避免写⼊失败 user_memory_rss避免oom 主从状态、集群状态 客户端数量、⼤key列表防⽌不合理使⽤影响集群稳定性和性能 内存碎⽚率避免oom 慢⽇志防⽌不合理使⽤影响性能 数字化基础软件自主创新分享周 性能优化思路 2、网络优化 轻舟SR-IOV容器网络,支持SR-IOV的网卡可以将VF口直通给业务pod-利用硬件特性,高QPS低延时 3、最佳实践配置业务使用 Redis只保存热数据,低频访问数据使⽤MySQL等持久化存储-发挥内存价值 按数据类型进行合理压缩,减少内存占⽤ 避免使用大key、避免集合对象元素过多、将热点打散到多个key主动key过期-避免key设置相同过期时间 关闭操作系统透明⼤⻚ 除非有必要,禁用swap避免额外io 数字化基础软件自主创新分享周 性能优化思路 CPU/内存/存储/网络等基础设施条件之外的实践举例 1、将集群node按业务/部署服务的场景进行划分,使用nodeSelector将pod调度到特定节点上2、某重点业务和普通业务都使用了kafka,但是两个kafka实例混布在同一个k8s集群里, 使用了同node上的一个物理盘导致io繁忙 -自研的存储的provisioner,通过不同的sc隔离不同物理盘 -让重点kafka实例使用单独的io隔离的独占存储,普通业务使用公共存储 3、对于业务混合部署场景,通过memcg的优先级和后台回收,优先保证高优先级容器的业务性能 -减缓内存回收对在线业务容器的影响 数字化基础软件自主创新分享周 THANKS 感谢观看