特性说明
使用介绍¶
服务端口自动纳管¶
懒加载支持自动监听集群内服务端口信息,并为所有端口启用懒加载,这样就无需手动指定服务端口列表。
在SlimeBoot中配置懒加载相关参数:
general.autoPort:true
,启动端口自动纳管,等于false或者不指定,则手动管理。兼容之前版本
general.wormholePort
中手动指定的端口也会被懒加载纳管。
为了安全,自动纳管时,端口**只会自动增加**。如果需要缩减端口范围,请切换到手动模式,或自动模式下重启懒加载。懒加载遵循Istio对端口协议的判断逻辑(端口名以“HTTP, HTTP2, GRPC, GRPCWeb”开头),只感知HTTP协议的端口变化。
样例:
kind: SlimeBoot
metadata:
name: lazyload
namespace: mesh-operator
spec:
# ...
module:
- name: lazyload
kind: lazyload
enable: true
general:
autoPort: true # 自动纳管服务端口
# ...
具体原理可参考 autoport
基于Accesslog开启懒加载¶
指定SlimeBoot CR资源 spec.module.global.misc.metricSourceType:accesslog
,使用Accesslog获取服务调用关系
或者设置spec.module.global.misc.metricSourceType:prometheus
,使用Prometheus获取服务间调用关系。
使用Accesslog获取服务调用关系的大概过程:
- slime-boot在创建global-sidecar时,发现
metricSourceType: accesslog
,额外生成一个configmap,内容是包含lazyload controller处理accesslog的地址信息的static_resources。再通过一个envoyfilter,将static_resources加入global-sidecar配置中,使得global-sidecar的accesslog会发送到lazyload controller - global-sidecar完成兜底转发时会生成accesslog,包含了调用方和被调用方服务信息。global-sidecar将信息发送给lazyload controller
- lazyload controller分析accesslog,获取到新的服务调用关系
随后的过程,就是修改servicefence和sidecar,和处理prometheus metric的过程一致。
样例
spec:
module:
- name: lazyload # custom value
kind: lazyload # should be "lazyload"
enable: true
general: # replace previous "fence" field
wormholePort: # replace to your application svc ports
- "9080"
global:
misc:
metricSourceType: accesslog
手动或自动为服务启用懒加载¶
支持通过autoFence
参数,指定启用懒加载是手动模式、自动模式。这里的启用懒加载,指的是创建serviceFence资源,从而生成Sidecar CR。
支持通过defaultFence
参数,指定自动模式下,是否全局启用懒加载。
配置方式如下
---
apiVersion: config.netease.com/v1alpha1
kind: SlimeBoot
metadata:
name: lazyload
namespace: mesh-operator
spec:
module:
- name: lazyload
kind: lazyload
enable: true
general:
autoFence: true # true为自动模式,false 为手动模式,默认为手动模式
defaultFence: true # 自动模式下的默认行为,true时,什么都不指定也会生成servicefence,false时只有打上注解的才会开启
# ...
自动模式¶
当autoFence: true
时,进入自动模式。自动模式下,启用懒加载的服务范围,通过三个维度调整。
Service级别 - label slime.io/serviceFenced
false
: 不自动启用-
true
: 自动启用 -
其他值或缺省: 使用Namespace级别配置
Namespace级别 - label slime.io/serviceFenced
false
: 该namespace下的所有服务都不自动启用true
:该namespace下的所有服务都自动启用- 其他值或缺省: 使用全局级别配置
全局级别 - lazyload的defaultFence
参数
false
: 全局不自动启用true
:全局自动启用
优先级:Service级别 > Namespace级别 > 全局级别
注:对于自动生成的ServiceFence资源 ,会通过标准Label app.kubernetes.io/created-by=fence-controller
来记录,实现了状态关联变更。 而不匹配该Label的ServiceFence资源,视为手动配置,不受以上Label影响。
举例
Namespace
testns
下有三个服务:svc1
,svc2
,svc3
- 当
autoFence
为true
且defaultFence
为true
时,自动生成以上三个服务的ServiceFence - 给Namespace testns加上Label
slime.io/serviceFenced: "false"
, 所有testns下的ServiceFence消失 - 给
svc1
打上slime.io/serviceFenced: "true"
label: 服务svc1
的ServiceFence创建 - 删掉Namespace和Service上的label:恢复三个ServiceFence
配置样例
apiVersion: v1
kind: Namespace
metadata:
labels:
istio-injection: enabled
slime.io/serviceFenced: "false"
name: testns
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app: svc1
service: svc1
slime.io/serviceFenced: "true"
name: svc1
namespace: testns
手动模式¶
当autoFence
参数为false
时,启用懒加载为手动模式,需要用户手动创建ServiceFence资源, 手动模块下只支持Service级别。
自定义兜底流量分派¶
lazyload/fence默认会将envoy无法匹配路由(缺省)的流量兜底发送到global sidecar,应对短暂服务数据缺失的问题,这是“懒加载”所必然面对的。 该方案因为技术细节上的局限性,对于目标(如域名)是集群外的流量,无法正常处理,详见 [Configuration Lazy Loading]: Failed to access external service #3。
基于这个背景,设计了本特性,同时也能用于更灵活的业务场景。 大致思路是通过域名匹配的方式将不同的缺省流量分派到不同的目标做正确处理。
配置样例:
module:
- name: lazyload
kind: lazyload
enable: true
general:
wormholePort:
- "80"
- "8080"
dispatches: # new field
- name: 163
domains:
- "www.163.com"
cluster: "outbound|80||egress1.testns.svc.cluster.local" # standard istio cluster format: <direction>|<svcPort>|<subset>|<svcFullName>, normally direction is outbound and subset is empty
- name: baidu
domains:
- "*.baidu.com"
- "baidu.*"
cluster: "{{ (print .Values.foo \".\" .Values.namespace ) }}" # you can use template to construct cluster dynamically
- name: sohu
domains:
- "*.sohu.com"
- "sodu.*"
cluster: "_GLOBAL_SIDECAR" # a special name which will be replaced with actual global sidecar cluster
- name: default
domains:
- "*"
cluster: "PassthroughCluster" # a special istio cluster which will passthrough the traffic according to orgDest info. It's the default behavior of native istio.
在本例中,我们把一部分流量分派给了指定的cluster; 另一部分让它走global sidecar; 然后对其余的流量,让它保持原生istio的行为: passthrough
注意:
- 自定义分派场景,如果希望保持原有逻辑 “其他所有未定义流量走global sidecar” 的话,需要显式配置如上的倒数第二条
添加静态服务依赖关系¶
懒加载除了从slime metric(accesslog/prometheus metric)处根据动态指标更新服务依赖关系,还支持通过serviceFence.spec
添加静态服务依赖关系。支持三种细分场景:依赖某个服务、依赖某个namespace所有服务、依赖具有某个label的所有服务。
依赖某个服务¶
适用于启用懒加载的服务静态依赖另外一个或多个服务的场景,可以在初始化时直接将配置加入sidecar crd。
下面的样例中,为启用懒加载的服务添加对reviews.default
服务的静态依赖关系。
# servicefence
spec:
enable: true
host:
reviews.default.svc.cluster.local: # static dependenct of reviews.default service
stable: {}
# related sidecar
spec:
egress:
- hosts:
- '*/reviews.default.svc.cluster.local'
- istio-system/*
- mesh-operator/*
依赖某个namespace所有服务¶
适用于启用懒加载的服务静态依赖另外一个或多个namespace中所有服务的场景,可以在初始化时直接将配置加入sidecar crd。
下面的样例中,为启用懒加载的服务添加对test
命名空间中所有服务的静态依赖关系。
# servicefence
spec:
enable: true
host:
test/*: {} # static dependency of all services in test namespace
# related sidecar
spec:
egress:
- hosts:
- test/*
- istio-system/*
- mesh-operator/*
依赖具有某个label的所有服务¶
适用于启用懒加载的服务静态依赖具有某个label或多个label的所有服务的场景,可以在初始化时直接将配置加入sidecar crd。
下面的样例中,为启用懒加载的服务添加拥有app=details
的所有服务,以及拥有app=reviews, group=default
的所有服务的静态依赖关系。
# servicefence
spec:
enable: true
labelSelector: # Match service label, multiple selectors are 'or' relationship
- selector:
app: details
- selector: # labels in one selector are 'and' relationship
app: reviews
group: default
# related sidecar
spec:
egress:
- hosts:
- '*/details.default.svc.cluster.local' # with label "app=details"
- '*/details.test.svc.cluster.local' # with label "app=details"
- '*/reviews.default.svc.cluster.local' # with label "app=details" and "group=default"
- istio-system/*
- mesh-operator/*
自定义服务依赖别名¶
在某些场景,我们希望懒加载根据已知的服务依赖,添加一些额外的服务依赖进去。
用户可以通过配置general.domainAliases
,提供自定义的转换关系,实现需求。general.domainAliases
包含多个domainAlias
,每个domainAlias
由匹配规则pattern
和转换规则templates
组成。pattern
只包含一个匹配规则,templates
则可以包含多个转换规则。
举个例子,我们希望添加<svc>.<ns>.svc.cluster.local
时,额外添加<ns>.<svc>.mailsaas
的服务依赖,则可以这么配置
apiVersion: config.netease.com/v1alpha1
kind: SlimeBoot
metadata:
name: lazyload
namespace: mesh-operator
spec:
module:
- name: lazyload-test
kind: lazyload
enable: true
general:
wormholePort: # replace to your application service ports, and extend the list in case of multi ports
- "9080"
domainAliases:
- pattern: '(?P<service>[^\.]+)\.(?P<namespace>[^\.]+)\.svc\.cluster\.local$'
templates:
- "$namespace.$service.mailsaas"
#...
对应的servicefence会这样
apiVersion: microservice.slime.io/v1alpha1
kind: ServiceFence
metadata:
name: ratings
namespace: default
spec:
enable: true
host:
details.default.svc.cluster.local: # static dependent service
stable: {}
status:
domains:
default.details.mailsaas: # static dependent service converted result
hosts:
- default.details.mailsaas
default.productpage.mailsaas: # dynamic dependent service converted result
hosts:
- default.productpage.mailsaas
details.default.svc.cluster.local:
hosts:
- details.default.svc.cluster.local
productpage.default.svc.cluster.local:
hosts:
- productpage.default.svc.cluster.local
metricStatus:
'{destination_service="productpage.default.svc.cluster.local"}': "1" # dynamic dependent service
sidecar则是这样
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: ratings
namespace: default
spec:
egress:
- hosts:
- '*/default.details.mailsaas' # static dependent service converted result
- '*/default.productpage.mailsaas' # dynamic dependent service converted result
- '*/details.default.svc.cluster.local'
- '*/productpage.default.svc.cluster.local'
- istio-system/*
- mesh-operator/*
workloadSelector:
labels:
app: ratings
日志输出到本地并轮转¶
slime的日志默认输出到标准输出,指定SlimeBoot CR资源中spec.module.global.log.logRotate
等于true
会将日志输出到本地并启动日志轮转,不再输出到标准输出。
轮转配置也是可调整的,默认的配置如下,可以通过显示指定logRotateConfig中的各个值进行覆盖。
spec:
module:
- name: lazyload # custom value
kind: lazyload # should be "lazyload"
enable: true
general: # replace previous "fence" field
wormholePort: # replace to your application svc ports
- "9080"
global:
log:
logRotate: true
logRotateConfig:
filePath: "/tmp/log/slime.log"
maxSizeMB: 100
maxBackups: 10
maxAgeDay: 10
compress: true
通常需要配合存储卷使用,在存储卷准备完毕后,指定SlimeBoot CR资源中的spec.volumes
和spec.containers.slime.volumeMounts
来显示将存储卷挂载到日志本地文件所在的路径。
以下是基于minikube kubernetes场景下的完整demo
创建存储卷¶
基于/mnt/data路径创建hostpath类型的存储卷
# hostPath pv for minikube demo
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lazyload-claim
namespace: mesh-operator
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: lazyload-volumn
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
在SlimeBoot中声明挂载信息¶
在SlimeBoot CR资源中指定了存储卷会挂载到pod的"/tmp/log"路径,这样slime的日志会持久化到/mnt/data路径下,并且会自动轮转。
---
apiVersion: config.netease.com/v1alpha1
kind: SlimeBoot
metadata:
name: lazyload
namespace: mesh-operator
spec:
image:
pullPolicy: Always
repository: docker.io/slimeio/slime-lazyload
tag: v0.7.1
module:
- name: lazyload # custom value
kind: lazyload # should be "lazyload"
enable: true
general: # replace previous "fence" field
wormholePort:
- "9080"
global:
log:
logRotate: true
logRotateConfig:
filePath: "/tmp/log/slime.log"
maxSizeMB: 100
maxBackups: 10
maxAgeDay: 10
compress: true
#... skip
volumes:
- name: lazyload-storage
persistentVolumeClaim:
claimName: lazyload-claim
containers:
slime:
volumeMounts:
- mountPath: "/tmp/log"
name: lazyload-storage