这是一篇关于服务网格技术Istio的速览,包括概念、作用、架构、组件的简介,及安装使用的关键步骤示例,非常适合想要快速掌握它的人。
服务网格(Service Mesh)
服务网格用来描述微服务之间的网络和交互。随着服务网格的规模和复杂性的增加,可能变得难以理解和管理,越来越需要服务发现、负载平衡、故障恢复、度量和监控这些能力。针对服务网格,通常还具有更复杂的要求,例如 A/B 测试、金丝雀发布、速率限制、访问控制和端到端身份验证等。
Istio 和 Kubernetes
Kubernetes 管理着工作节点的可用性和资源使用,并依据 pod 自动伸缩器的需求而相应地添加或减少 pod。Istio 是一个可配置的开源服务网格(Service Mesh)层,用于连接和监控 Kubernetes 集群中的容器,并可为其提供安全性。Istio 通过将额外的容器注入到 pod 中来为其赋予安全性、管理能力和监控能力。Istio 运行于 Kubernetes 之上,添加了对开发人员和集群管理员基本上不可见的容器,这是一些被称为边车(Sidecar)容器,它们充当着“中间人”角色,引导流量并监控组件之间的交互。最终,Istio和Kubernetes 以配置、监控和管理这三种方式协同工作。
为什么使用Istio
- 使用 TLS 加密、基于身份的身份验证和授权来保护集群中的服务间通信
- HTTP、gRPC、WebSocket 和 TCP 流量的自动负载平衡
- 通过丰富的路由规则、重试策略、故障转移和故障注入对流量行为进行精细控制
- 作为可插拔策略层,提供配置API以支持访问控制、速率限制和配额管理
- 为集群内部和集群出入口提供自动化的指标、日志和跟踪
架构
- Proxy/Envoy
作为容器运行于 pod 中,以每个微服务的边车代理,来处理每个 pod 的出入流量。
- Mixer
通过创建策略或前置条件来执行对流量的检查和遥测,实现安全、指标等功能。
- Pilot
将控制流量治理和安全规则转换和下发给Envoy。
- Citadel
作为服务间访问身份认证的证书颁发机构。
术语
- Gateway 网关
为 http/tcp 流量配置负载均衡器,使入口流量进入服务网格。
- Virtual Service 虚拟服务
定义控制服务请求如何在服务网格中路由的规则。
- Destination Rule 目的地规则
配置在虚拟服务发生后应用于请求的策略集。
- Service Version (Subset) 服务版本(子集)
允许根据标签(Label)选择 pod 的子集。
- Service Entry 服务入口
提供对网格外服务的受控访问。
安装并试用
# 1.访问istio发布地址,并下载安装文件
curl -L https://istio.io/downloadIstio | sh -
# 2.进入安装目录
cd istio-1.10.0
# 3.将istioctl命令添加到PATH
export PATH=$PWD/bin:$PATH
# 4.将 istio 安装到 kubernetes 集群
istioctl install --set profile=demo -y
# 5. 为命名空间添加 label,以指示 istio 为其注入 Envoy
kubectl create namespace testing
kubectl label namespace testing istio-injection=enabled
kubectl describe namespace testing
# 6. 从istio示例中部署bookinfo
kubectl apply -n testing -f samples/bookinfo/platform/kube/bookinfo.yaml
# 7. 执行以下命令可以看到envoy已被注入(Ready数为2)
kubectl get pods -n testing
8. 现在就可以将流量路由到我们的服务和pod。
首先建一个gateway.xml文件。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: sampleapp-gateway
spec:
selector:
istio: ingressgateway # istio 默认的 controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
再使用kubectl apply命令将其部署到kubernetes,这将允许流量进入服务网格。
kubectl apply -f gateway.yml -n testing
9. 现在开始创建Virtual Service,来控制请求如何被路由到服务。
先通过yaml文件virtual-service.yml来定义虚拟服务。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- sampleapp-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
再将定义应用到kubernetes集群。
kubectl apply -f virtual-service.yml -n testing
然后就可以通过如下命令测试访问该地址。
$ IP_LB=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.clusterIP}')
$ curl -H "Host: xyz.com" $IP_LB/productpage
我们可以再来建立一些路由规则。
virtual-service-all.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
retries: # 配置在发生 gateway-error,connect-failure,refused-stream 时重试2次,并设置重试的超时时间
attempts: 2
perTryTimeout: 1s
retryOn: gateway-error,connect-failure,refused-stream
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
user-agent:
regex: ".*Chrome.*"
#cookie:
# regex: "^(.*?;)?(user=packtpub)(;.*)?#34;
route:
- destination:
host: reviews
subset: v2
timeout: 2s
- route:
- destination:
host: reviews
subset: v1
#weight: 100
mirror: # 转发到测试子集
host: reviews
subset: v3
mirror_percent: 100
timeout: 2s
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
kubectl apply -f virtual-service-all.yml -n testing
以上配置表示如下规则:
- istio在访问productpage服务时,如果遇到 gateway-error,connect-failure,refused-stream 这些错误,就会尝试重新连接该服务。
- 而当http头中的username值为jason,并且user-agent包含“Chrome”时,流量将被转发到v2子集。
- Mirrors部分展示了在投入生产之前将实时流量转移到某个子集进行测试。
- weight用来设置流量权重
10.现在定义一些Destination Rule来配置经Virtual Service路由之后需要被应用的策略。
首先建立destination-rule-all.yaml文件。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
trafficPolicy:
connectionPool:
tcp:
maxConnections: 50
connectTimeout: 1s
tcpKeepalive:
time: 3600s
interval: 60s
http:
maxRetries: 3
maxRequestsPerConnection: 50
idleTimeout: 60s
http1MaxPendingRequests: 25
http2MaxRequests: 5
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
spec:
host: ratings
trafficPolicy:
outlierDetection:
consecutiveErrors: 5 # 5 upstream errors (502,503,504)
interval: 30s # Sliding window of 30s
baseEjectionTime: 1m # eject upstream for 1 min
maxEjectionPercent: 50 # max 50% of upstream hosts ejected
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
spec:
host: details
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
应用到kubernetes集群。
kubectl apply -f destination-rule-all.yaml -n testing
11.再来设置一些TLS规则,让Pod之间使用加密通信
建立文件enable-strict-mode.yml。
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
将其应用到kubernetes集群。
kubectl apply -f enable-strict-mode.yml -n testing
12.我们可以使用Kiali这个Dashboard让流量可视化。
kubectl apply -f istio-1.10.0/samples/addons/kiali.yaml
kubectl apply -f istio-1.10.0/samples/addons/prometheus.yaml
kubectl apply -f istio-1.10.0/samples/addons/extras/zipkin.yaml
kubectl apply -f istio-1.10.0/samples/addons/extras/prometheus-operator.yaml