最近半年一直在用Istio做服务网格的落地,从最开始的调研到后来的生产环境部署,踩了不少坑,也积累了一些配置经验。
Istio作为目前最主流的Service Mesh实现,功能很强大,但是配置也比较复杂,很多人刚接触的时候会觉得无从下手。今天这篇文章就来详细讲解Istio的实战配置,从基础到高级,一步步带你掌握Istio的核心配置。
内容包括流量管理、安全策略、可观测性、故障注入、流量镜像等核心功能的配置方法,以及一些生产环境的最佳实践和踩坑经验。希望能给正在学习或者使用Istio的朋友一些参考。
一、先说说Istio是什么
在讲配置之前,先简单说说Istio是什么,以及它的核心架构。
Istio是一个开源的服务网格(Service Mesh)框架,由Google、IBM、Lyft等公司联合开发。它的核心思想是把服务间的通信、安全、监控等功能从业务代码中抽离出来,放到一个独立的基础设施层来处理,这样业务代码就不需要关心这些非业务功能了,只需要关注业务逻辑本身。
Istio的架构分为数据平面和控制平面两部分。
数据平面由一系列的Sidecar代理组成,每个服务实例旁边都会部署一个Envoy代理作为Sidecar,所有的入站和出站流量都会经过这个Sidecar代理。Sidecar代理负责处理服务间的通信、负载均衡、熔断、限流、安全认证、监控数据采集等功能。
控制平面负责管理和配置数据平面的Sidecar代理。Istio 1.5版本之前控制平面由Pilot、Mixer、Citadel、Galley等多个组件组成,1.5版本之后合并成了一个单一的istiod组件,简化了部署和运维。
Istio的核心功能包括:
- 流量管理:动态路由、负载均衡、熔断、限流、重试、超时、故障注入、流量镜像等
- 安全:服务间的TLS加密、身份认证、授权策略等
- 可观测性:分布式追踪、指标采集、访问日志等
了解了架构之后,我们来看具体的配置。
二、基础配置:部署Istio和注入Sidecar
首先是基础配置,包括部署Istio和给服务注入Sidecar。
部署Istio最简单的方式是用istioctl命令行工具。先下载对应版本的istioctl,然后执行安装命令:
istioctl manifest apply --set profile=defaultprofile是安装配置的预设,常用的有default、demo、minimal等。default是默认配置,适合生产环境;demo是演示配置,开启了所有功能,适合学习和测试;minimal是最小配置,只安装核心组件。
安装完成之后,可以用下面的命令查看Istio的组件是否正常运行:
kubectl get pods -n istio-system接下来是给服务注入Sidecar。Istio支持两种注入方式:手动注入和自动注入。
手动注入是用istioctl命令给已经部署的服务注入Sidecar:
istioctl kube-inject -f deployment.yaml | kubectl apply -f -自动注入更方便,只需要给命名空间打上标签,这个命名空间下新创建的Pod就会自动注入Sidecar:
kubectl label namespace default istio-injection=enabled打上标签之后,新创建的Pod会自动注入Sidecar,已经存在的Pod需要重启才会注入。
注入完成之后,可以用下面的命令查看Pod是否有Sidecar容器:
kubectl get pods正常情况下,每个Pod应该有两个容器,一个是业务容器,一个是istio-proxy容器。
三、流量管理:VirtualService和DestinationRule
流量管理是Istio最核心也是最常用的功能,主要通过VirtualService和DestinationRule两个资源来配置。
VirtualService用来定义流量的路由规则,比如根据请求的路径、域名、Header等把流量路由到不同的服务或者不同的版本。
DestinationRule用来定义目标服务的配置,比如负载均衡策略、连接池配置、熔断配置、版本定义等。
先看一个简单的VirtualService例子,把流量按比例分配到两个版本:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- route:
- destination:
host: my-service
subset: v1
weight: 80
- destination:
host: my-service
subset: v2
weight: 20这个配置把80%的流量路由到v1版本,20%的流量路由到v2版本。这里的subset需要在DestinationRule中定义。
对应的DestinationRule配置:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-service
spec:
host: my-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: RANDOM
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 100
maxRequestsPerConnection: 10
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30s这个配置定义了两个subset,分别对应version标签为v1和v2的Pod。同时配置了负载均衡策略为随机,连接池大小,以及异常检测(熔断)配置。
异常检测的意思是,如果某个实例连续5次请求失败,就把它从负载均衡池中剔除30秒,30秒之后再尝试恢复。这样可以避免故障实例影响整体服务的可用性。
VirtualService还支持更复杂的路由规则,比如根据Header路由:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- match:
- headers:
user-agent:
regex: ".*Chrome.*"
route:
- destination:
host: my-service
subset: v2
- route:
- destination:
host: my-service
subset: v1这个配置把使用Chrome浏览器的请求路由到v2版本,其他请求路由到v1版本。这种方式常用于灰度发布或者A/B测试。
还可以根据请求路径路由:
http:
- match:
- uri:
prefix: /api/v1
route:
- destination:
host: service-v1
- match:
- uri:
prefix: /api/v2
route:
- destination:
host: service-v2VirtualService还支持超时、重试等配置:
http:
- route:
- destination:
host: my-service
timeout: 5s
retries:
attempts: 3
perTryTimeout: 2s这个配置设置了请求超时时间为5秒,失败后最多重试3次,每次重试的超时时间为2秒。
四、高级流量管理:故障注入和流量镜像
除了基础的路由功能,Istio还支持一些高级的流量管理功能,比如故障注入和流量镜像。
故障注入是指在系统中主动注入一些故障,比如延迟、错误等,用来测试系统的容错能力和弹性。这在微服务架构中非常重要,因为服务之间的依赖关系很复杂,需要确保某个服务出现故障的时候不会导致整个系统崩溃。
Istio支持两种故障注入:延迟注入和错误注入。
延迟注入的配置:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- fault:
delay:
percentage:
value: 10
fixedDelay: 3s
route:
- destination:
host: my-service这个配置给10%的请求注入3秒的延迟,用来测试系统在高延迟情况下的表现。
错误注入的配置:
http:
- fault:
abort:
percentage:
value: 5
httpStatus: 500
route:
- destination:
host: my-service这个配置给5%的请求返回500错误,用来测试系统在服务出错情况下的容错能力。
故障注入是混沌工程的重要手段,通过主动注入故障来发现系统的薄弱环节,提高系统的可靠性。
流量镜像是指把生产环境的流量复制一份发送到另一个服务,而不影响原来的服务。这样可以在不影响生产环境的情况下测试新版本的服务,或者进行数据分析、监控等。
流量镜像的配置:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- route:
- destination:
host: my-service
subset: v1
weight: 100
mirror:
host: my-service
subset: v2
mirrorPercentage:
value: 100这个配置把所有发送到v1版本的流量镜像一份发送到v2版本。镜像的流量是"即发即忘"的,v2版本的响应会被忽略,不会影响原来的请求。
流量镜像非常适合用来做新版本的验证,在不影响生产环境的情况下,把生产流量复制到新版本,观察新版本的表现,确认没问题之后再切流量。
五、安全配置:认证和授权
Istio的安全功能也是非常强大的,主要包括身份认证、TLS加密和授权策略。
Istio默认支持服务间的mTLS(双向TLS)加密,也就是说服务之间的通信会自动加密,而且服务之间会互相验证身份。这样即使网络被监听,攻击者也无法窃取或者篡改服务间的通信内容。
开启mTLS的配置很简单,只需要创建一个PeerAuthentication资源:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT这个配置在整个网格范围内开启严格的mTLS模式,所有服务之间的通信都必须使用mTLS加密。
mode有三个选项:
- STRICT:严格模式,必须使用mTLS
- PERMISSIVE:宽容模式,既接受mTLS也接受明文流量,适合迁移过程中使用
- DISABLE:关闭mTLS
除了mTLS,Istio还支持请求级别的认证和授权。
请求认证(RequestAuthentication)用来验证请求的身份,通常是验证JWT token:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: my-jwt-auth
spec:
selector:
matchLabels:
app: my-service
jwtRules:
- issuer: "https://auth.example.com"
jwksUri: "https://auth.example.com/.well-known/jwks.json"这个配置给带有app: my-service标签的服务启用JWT认证,验证来自指定issuer的JWT token。
授权策略(AuthorizationPolicy)用来控制谁可以访问服务:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: my-service-authz
spec:
selector:
matchLabels:
app: my-service
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/other-service"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]这个配置只允许other-service服务访问my-service的/api/*路径,而且只允许GET和POST方法。
授权策略支持非常灵活的规则配置,可以根据来源服务、请求方法、请求路径、请求Header、JWT claims等进行授权控制。
六、可观测性:追踪、指标和日志
Istio的可观测性功能也很完善,支持分布式追踪、指标采集和访问日志。
分布式追踪方面,Istio默认集成了Jaeger、Zipkin等追踪系统。因为所有的流量都经过Sidecar代理,所以Istio可以自动采集服务间的调用链数据,不需要修改业务代码。
只需要在安装Istio的时候开启追踪功能,然后配置采样率:
apiVersion: networking.istio.io/v1alpha3
kind: MeshConfig
metadata:
name: istio
namespace: istio-system
spec:
enableTracing: true
defaultConfig:
tracing:
sampling: 10这个配置开启了分布式追踪,采样率为10%,也就是10%的请求会被追踪。
需要注意的是,虽然Istio可以自动采集追踪数据,但是业务服务需要把请求中的追踪Header(比如x-request-id、x-b3-traceid等)传递下去,这样才能把同一个请求的多个服务调用关联起来。
指标采集方面,Istio默认会采集很多服务间通信的指标,比如请求量、延迟、错误率等,并且集成了Prometheus和Grafana。可以通过Grafana仪表盘直观地查看服务的性能指标。
访问日志方面,Istio的Sidecar代理会记录所有经过的请求的访问日志,包括请求时间、来源、目标、方法、路径、状态码、延迟等信息。可以通过配置来控制访问日志的格式和输出位置。
这些可观测性功能对于微服务架构的运维非常重要,能够帮助我们快速定位问题、分析性能瓶颈、了解系统的运行状态。
七、生产环境最佳实践和踩坑经验
最后分享一些生产环境的最佳实践和踩坑经验。
第一,渐进式开启mTLS。不要一开始就开启STRICT模式,建议先用PERMISSIVE模式运行一段时间,确保所有服务都已经注入Sidecar并且支持mTLS,然后再切换到STRICT模式。不然可能会导致有些服务无法通信。
第二,合理配置资源。Istio的Sidecar代理会占用一定的CPU和内存资源,生产环境要根据服务的流量情况合理配置Sidecar的资源请求和限制。一般来说,每个Sidecar至少要请求0.1核和128MB内存,流量大的服务需要更多。
第三,控制Sidecar的配置大小。如果服务网格很大,服务很多,Sidecar需要同步的配置就会很多,会导致Sidecar占用内存过大,而且配置同步慢。可以通过Sidecar资源来限制每个Sidecar需要同步的配置范围,只同步相关命名空间的配置:
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default
namespace: default
spec:
egress:
- hosts:
- "default/*"
- "istio-system/*"这个配置限制default命名空间的Sidecar只同步default和istio-system命名空间的配置。
第四,注意版本兼容性。Istio的版本更新比较快,不同版本之间的API可能会有变化,升级的时候要注意兼容性。建议在测试环境充分测试之后再升级生产环境,而且不要跨太多版本升级。
第五,做好监控和告警。要监控Istio控制平面和数据平面的运行状态,比如istiod的健康状态、Sidecar的配置同步状态、代理的资源使用情况等。发现异常要及时告警和处理。
第六,灰度发布Istio本身。升级Istio版本的时候,建议用灰度的方式,先升级一部分Sidecar,观察没问题之后再全部升级,避免一次性升级导致全量故障。
踩过的坑:
- 最开始开启STRICT模式的时候,有几个服务没有注入Sidecar,导致这些服务无法和其他服务通信,排查了很久才发现。所以一定要先确认所有服务都注入了Sidecar再开启STRICT模式。
- Sidecar的资源限制设置得太小,导致流量大的时候Sidecar被OOM杀掉,服务不可用。后来把资源限制调大就好了。
- 服务网格太大的时候,Sidecar同步配置很慢,新创建的服务要等很久才能正常通信。后来用Sidecar资源限制了配置范围就解决了。
- 故障注入配置忘记删除,导致线上服务一直有错误,排查了很久才发现是故障注入的问题。所以故障注入用完之后一定要记得删除。
八、写在最后
Istio是一个非常强大的服务网格框架,功能很完善,但是学习曲线也比较陡,配置比较复杂。不过只要掌握了核心的配置方法,理解了它的工作原理,用起来还是很方便的。
这篇文章介绍了Istio的核心配置,包括基础部署、流量管理、安全配置、可观测性等,还有一些生产环境的最佳实践和踩坑经验。希望能给正在学习或者使用Istio的朋友一些参考。
当然Istio的功能远不止这些,还有很多高级功能和细节,需要在实际使用中慢慢学习和体会。建议大家多动手实践,搭一个测试环境多试试,这样才能真正掌握。
服务网格是云原生领域的一个重要方向,Istio作为目前最主流的实现,值得每一个做微服务和云原生的开发者学习和掌握。希望这篇文章能帮到大家,也欢迎大家在评论区交流讨论自己使用Istio的经验和问题。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录