前言:
三十而立后,琐碎的事情多了起来,不好抽出时间去做技术分享。记得年初那会还说要分享下raft的原理和实践,结果次次爽约。但我的github和技术文章还在持续的更新,我个人感觉专门做PPT讲解要比写文章更要慎重,毕竟一大帮人在现场看你做分享,及给你挑错。😅
这次分享的话题主要围绕微服务service mesh架构的实践,话题也是拆分了三个子topic,分别是微服务的演进史、kubernets、istio。本想做个简单偏科普的介绍,后来发现如单纯只是讲k8s、istio的介绍使用,而不去稍微讲点原理设计,可能会导致ppt的质量显得不高级,所以就又增加了不少原理性的介绍。 😁
该文章后续仍在不断的更新修改中, 请移步到原文地址 http://xiaorui.cc/?p=6051
内容:
ppt已经放到了github上了,这次的分享主要是针对公司内的,由于zoom的配置问题,导致没有做好视频的录像。后面会补充详细的博文及视频的讲解。
下面是pdf的地址,望大家在github上点个star。😁
github pdf: https://github.com/rfyiamcool/share_ppt
pdf 下载: http://xiaorui.cc/static/service_mesh.pdf
问答:
kubernetes是否靠谱? 中小团队,尤其是小团队是否可以hold的住?
个人认为kubernetes在实践中最难的是网络和存储。网络cni推荐大家使用calico,因为calico对比flannel有更好的想能,另外也完美支持bgp路由协议。如果想更加的易用,可以选择基于overlay的flannel插件。至于存储? 不推荐… 意思是说,推荐大家把一些有状态的服务,比如postgres、mysql、elasticsearch,放在k8s的pod之外。为啥? 我问了一圈在各公司搞云平台开发的,他们k8s每次出问题,大概率都是因为存储。 😅 这个很考验基础架构团队的能力。
Istio是否靠谱?
当然,没问题了。不少国外,国内也有不少公司在用了。istio是基于k8s平台做的一层mesh的封装,就算出现了不可控和未知的问题,我们可以把istio的策略都删掉,让pod走原始的k8s service的逻辑。
如何更好的上手kubernetes、istio ?
首先是把官方的文档简略的看一遍,再把组件的原理看一遍。这个实现原理是不能忽视的,不然在实践k8s/istio遇到问题就抓瞎。在了解原理的基础上,可以适当的看他的关键代码实现,像istio的源码还是相对好理解的。
如何减少业务代码嫁接微服务架构的成本?
像我们先前的架构比较复杂,大部分是通过grpc balancer来直接连接的,但还是有部分系统是基于golang nats mq消息总线,主要是使用nats的request/reply的同步语义来实现异步的发布订阅。如果直接把总线改成grpc的方式,代码量其实不小。没有采用grpc直连而总线模式的服务有20来个,怎么用最小的代码来实现?
利用grpc的各种特性来实现的完美兼容,关键词是 grpc.unknownHandler, grpc reflection,静态protobuf描述符。
部分截图:
关键字:
// xiaorui.cc service mesh那些事⼉ kubernetes and istio - xiaorui.cc Kubernetes那些事⼉ - xiaorui.cc istio那些事⼉ - xiaorui.cc 为什么要微服务? 松耦合,代码结构更加清晰 开发者友好,避免⽼代码包袱. 微服务的优点 独⽴发布、快速迭代 故障隔离 增加重⽤, 可组合 针对性横向扩展 服务发现调度的演变 静态配置 中⼼调度 单体结构 构建sdk 消息总线 service mesh 服务发现之静态配置 rpc call s1 s2 s3 s2 get hosts from config.yaml; upstream: s2: - 10.x.x.1 - 10.x.x.2 ??? 频繁上线 ⼿动维护配置 服务发现之负载均衡 static config s1 upstream: s1: - 10.x.x.1 s2: - 10.x.x.2 … s3 API Gateway s2 s4 dynamic config envoy kong openresty upsync 中⼼节点 服务发现之sdk etcd watch发现 s1 sdk consul rpc call client 开发难度不简单 ? 多种语⾔重复性开发 ? 注册上报... s2 s2 s2 s2 s2 消息总线 优点 开发快, 架构易易理理解 nats mq go-micro/go-kit也集成该⽅方案 缺点 req 超时控制 reply topic分区 ? s3 s1 s1 s2 s2 s3 流量量管理理 灰度发布 Service Mesh 指令下发 控制中⼼ 注册发现 consul sidecar sidecar s1 call s2 s1 s1 s2 s2 Service mesh 帮你注册 帮你发现 帮你访问 帮你策略 轻量级代理, 各类决策, 负载调度 应⽤程序⽆感知 解耦应⽤程序的限频, 熔断, 重试/ 超时 灰度上线 … 还存在的问题? 自己开发servcie mesh ? 部署及管理 找一个service mesh ? 大规模部署 Istio 灵活部署 Spring cloud Dubbo 集群式管理 Alipay SofaMesh … … k8s <-> istio what is kubernetes ? 扩展集群 滚动升级回退 基于容器的集群编排引擎 弹性伸缩服务 ⾃动治愈 服务发现 资源配额 灵活扩展API kubernetes 架构 scheduler api server controller node node Master kubelet kubelet container container container container node kubectl kubernetes ha worker node worker node worker node worker node worker node worker node load balancer load balancer api-server api-server api-server scheduler scheduler scheduler controller controller controller kubernetes 架构 maser node api server 总操作⼊⼜ controller 控制中⼼ scheduler pod调度器 kubelet 管理容器的⽣命周期 监控 上报节点状态 kube-proxy 管理service kubernetes notion Pod 最⼩单位 Deployment Service RepliaSet Label Crontab node disktype=ssd Job ConfigMap gpu=true pod app StatefulSet DaemonSet version … cretae deployment process kubectl create deployment controller create replicaSet/pod event list/watch scheduler kubelet bind pod event kube-proxy create pod init service list/watch list/watch list/watch kube-apiserver etcd etcd etcd scheduler predicates 预选过程 node1 node2 过滤掉不满⾜条件的节点 PodFitsResources node3 预选阶段 priorities 优选过程 PodFitsHostPorts PodSelectorMatches CheckNodeDiskPressure CheckNodeMemoryPressure 对节点按照优先级排序 LeastRequestedPriority SelectorSpreadPriority ImageLocalityPriority node1 node2 优选阶段 node1-pri2 node2-pri4 NodeAffinityPriority select max( priority) algorithmprovider 选择优先级最⾼的节点 node3 node1 pod ⼀个pod可以有多个容器 pod之间容器共享⽹络namespace (127.0.0.1) pod之间容器通过Volume来共享⽬录 (emptyDir and hostPath) 127.0.01 container localhost read pod container write volume Service Detail type clusterIP iptables做转发 匹配延迟 nodePort HeadLess clusterIP: None 线性匹配 更新延迟 不能增量 lb … ipvs做转发 算法更灵活 最⼩负载 最少连接 session hash 匹配 可控的更新延迟 kubernetes network Pod 宿主机到pod可以通 pod pod pod pod 宿主机的pod之间可以互通 docker/cni0 ⽹桥 不同node的pod也可以互通 cni 接⼜ Node Node kubernetes cni pod pod container container container container route table veth0 10.1.11.x/24 veth0 10.1.12.x/24 etcd cluster cni0 cni0 flannel.1-tun Node1 flanneld-8285 flanneld-8285 flannel.1-tun udp socket 10.244.0.11 eth0 10.244.0.12 eth0 Packet mac outer-ip udp inner-ip payload Node2 服务发现 环境变量 env Get ClusterIP, Port 使⽤service name 经过coredns解析拿到clusterIP 对于业务来说, 使用 Service Name 就可以了 kubernetes 外部访问 hostNetwork = true hostPort Ingress (nginx, haproxy, traefix, envoy) NodePort (iptables nat) 公有云Load Balancer (aws, azure, gce …) kubernetes 外部访问 NodePort 30000,32767 ingress ingress pod N inside kubernets cluster Node pod A Node Service A pod AA pod pod B pod A Service B pod AA pod pod B ingress design skip kube-proxy direct upstream endpoint hostPort bind node port daemonSet one pod each node Deployment Service Ingress 快速扩容 升级回滚 maxUnavailable: maxSurge: 更新过程中不可⽤的pod数量 default: 25% 更新中pod总数的最⼤值 default: 25% 也可使⽤servcie selector version规避 升级回滚 Deployment Rs (old) app-v1 app-v1 app-v1 Deployment Rs (old) app-v1 app-v1 Deployment Rs (new) app-v2 Rs (old) app-v1 Deployment Rs (new) Rs (new) app-v2 app-v2 app-v1 app-v2 app-v1 为什么还需要istio ? k8s 服务发现 4层负载均衡 滚动升级 … istio 规避长连接的 ”坑” gpc client、net/http 更细致的7层负载均衡 更细致的流量管理 更细致的灰度发布 … istio pilot Mixer citadel 控制⾯板 check & report 数据⾯板 Envoy Envoy Pod servA http1.1, http2.0 grpc/tcp wtih or without mTLS Pod servB istio 组件 Pilot-x 服务发现 jaeger Mixer prometheus istio-policy 检查权限, 配额 istio-telemetry 收集调⽤metrics citadel 证书 galley 校验正确性 ingressgateway ⽹关 zipkin fluented … istio pilot kubectl/istioctl Etcd-Cluster kube-apiserver list/watch Pilot XDS Protocol XDS Pod Pod Pod Envoy Envoy Envoy Service Service Service istio mixer adapter Pod Envoy check / report Service Quota Mixer Mixer Mixer Pod Envoy Service check / report Prometheus fluented adapter istio 流量治理流程 控制⾯板流程 : 管理员通过kubectl/istioctl或者API创建流量规则 Pilot从kubernets apiserver获取数据, 并规则转换为Envoy xds Pilot将xds推送给envoy 数据⾯板流程 : Envoy动态载⼊xds配置, 并初始化新的资源监听 Envoy 拦截 pod上的本地容器的Inbound和Outbound流量 在流量经过Envoy时执⾏对应的流量规则, 执⾏流量治理 kubectl create pod istio inject pilot-proxy auth kube apiserver pilot-agent ⽣成envoy初始化配合 admission mutaing hook 管理envoy的⽣命周期 input envoy sidecar sidecar injector iptables redirect 15001 pilot-init ./prepare_proxy.sh -p 15001 -u 1337 init exit ! ouput Envoy Service only tcp !!! istio crd resource VirtualService 定义路由规则 流量管理 DestinationRule 定义可路由的⽬的服务的⼦集 ⽬的服务的策略 (断路器/负载均衡/TLS …) ServiceEntry 定义⽹格之外的资源 Gateway 为⽹格配置⽹关 Sidecar 服务隔离 EnvoyFilter 集成Lua可⾃定义envoy的过滤链规则 ⼀个实例 rules 重定向 重写 SVC-A 条件: uri, scheme, method, cookie, headers, post, sourceLables, gateways 重试 故障注⼊ 流量镜像 more more more more 规则匹配 SVC-A path: /v1/login header[user]: rui pod pod v1 default pod pod pod v2 规则匹配 权重 SVC-A 90 % pod pod v1 10 % pod pod pod v2 权重 镜像 SVC-A 正式流量 pod pod v1 as goreplay, tcpcopy 镜像流量 pod pod pod test version 镜像 熔断 Closed trip breaks Open > http1MaxPendingRequests > consecutiveErrors reset attempt to reset Half 熔断 other fault inject ratelimit retry delay timeout rewrite abort session affinity redirect … … denier attribute iplist 例⼦ https://github.com/rfyiamcool/istio-http-lb k8s istio 涵盖⼤多数功能测试 平滑迁移 业务只需要更换srvFrame库包即可 !!! ⾃定义grpc编码 grpc.UnknownServiceHandler grpc invoke raw grpc reflect & protobuf reflect control script 通过env和template来⽣成k8s/istio配置 通过namespace来隔离每个developer的环境 可配置服务组启动, 跳过注⼊及启动顺序等 通过control来管理mesh各资源的⽣命周期 gen; start; stop; restart; logs; pods; … https://github.com/rfyiamcool/k8s-istio-control other 分布式链路追踪 opentracing jaeger zipkin design trace ID span ID 分布式⽇志追踪 使⽤trace id追溯上下⽂ “ Q&A ” - xiaorui.cc