技术分享之service mesh (k8s&istio)的那些事儿

前言:

三十而立后,琐碎的事情多了起来,不好抽出时间去做技术分享。记得年初那会还说要分享下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描述符。

部分截图:

service mesh
go nats service mesh
go nats mesh
service mesh
service mesh 轻量级代理
kubernetes 架构
kubernetes 高可用架构
kubernets创建pod过程
k8s 调度器
kubernetes scheduler
k8s pod
k8s pod
kubernetes flannel cni
k8s cni flannel
kubernets service discovery
kubernetes ingress nodeport hostport
kubernets ingress 原理
istio kubernetes
istio
istio
istio pilot
istio pilot
istio mixer
istio rules
istio weight
istio mirror 镜像
istio mixer 熔断
istio 重试 注入
k8s 自动化管理脚本
kubernetes 管理脚本

关键字:


// 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


对Golang感兴趣的朋友可以加群: 278517979 !!!
另外如果大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码, 感谢!
另外再次标注博客原地址  xiaorui.cc