什么是
Istio ? 这就是所谓的服务网格,一种在网络上添加抽象层的技术。 我们拦截集群中的全部或部分流量,并对其执行一组特定的操作。 哪一个 例如,我们进行智能路由,或者实施断路器方法,我们可以组织“ canary部署”,将流量部分切换到该服务的新版本,并且可以限制外部交互并控制从群集到外部网络的所有行程。 可以设置策略规则来控制不同微服务之间的活动。 最后,我们可以获取整个网络上的交互图,并使统一的度量标准集合对应用程序完全透明。
关于工作机制的信息可以在
官方文档中找到。 Istio是一个非常强大的工具,可以解决许多问题。 在本文中,我想回答在开始使用Istio时通常会出现的基本问题。 这将帮助您更快地处理它。

工作原理
Istio由两个主要区域组成-控制平面和数据平面。 控制平面包含确保其余组件正确操作的主要组件。 在当前版本(1.0)中,控制平面具有三个主要组件:先导,混合器,城堡。 我们不会考虑使用Citadel,而是需要生成证书以确保服务之间的相互TLS。 让我们仔细看一下Pilot and Mixer的设备和用途。

Pilot是主要的控制组件,可传播有关集群中所有内容的所有信息-服务,其端点和路由规则(例如,Canary部署规则或断路器规则)。
混合器-控制平面的可选组件,它提供了收集指标,日志和有关网络交互的任何信息的功能。 他还监视对策略规则的遵守情况以及对速率限制的遵守情况。
数据平面是使用Sidecar代理容器实现的。 默认情况下,使用功能强大的
特使代理服务器 。 可以用其他实现方式代替它,例如nginx(nginmesh)。
为了使Istio对应用程序完全透明地工作,有一个自动注入系统。 最新的实现适用于Kubernetes 1.9+版本(变异录入Webhook)。 对于Kubernetes 1.7、1.8版本,可以使用Initializer。
Sidecar容器通过GRPC协议连接到Pilot,该协议允许优化推送集群中发生的更改的模型。 GRPC从1.6版开始在Envoy中使用,在Istio中从0.8版开始使用,并且是一个试验性代理-golang over envoy的包装,用于配置启动参数。
Pilot和Mixer是完全无状态的组件,所有状态都保存在内存中。 它们的配置指定为Kubernetes自定义资源,保存在etcd中。
Istio-agent接收领航地址,并向其打开GRPC流。
正如我所说,Istio实现了对应用程序完全透明的所有功能。 让我们弄清楚如何。 算法如下:
- 部署服务的新版本。
- 根据注入边车容器的方法,在配置应用阶段添加istio-init容器和istio-agent容器(使节),或者可以将它们手动插入Kubernetes实体的Pod描述中。
- istio-init容器是一个为炉膛应用iptables规则的脚本。 在istio-agent容器中设置流量包装有两个选项:使用redirect iptables规则或TPROXY 。 在撰写本文时,将使用带有重定向规则的默认方法。 在istio-init中,可以配置需要拦截哪些流量并将其路由到istio-agent。 例如,为了拦截所有传入和传出流量,您需要将
-i
和-b
参数设置为*
。 您可以指定要拦截的特定端口。 为了不拦截特定子网,可以使用-x
标志指定它。 - 执行init容器后,将启动主要容器,包括领航员(特使)。 它通过GRPC连接到已经部署的Pilot,并接收有关集群中所有现有服务和路由策略的信息。 根据收到的数据,他配置了集群,并直接为它们分配了Kubernetes集群中应用程序的端点。 还要注意一个重要的点:特使动态地设置它开始监听的监听器(IP,端口对)。 因此,当请求进入Pod时,将使用Sidecar中的重定向iptables规则对请求进行重定向,使节已经可以成功处理这些连接并了解在何处进一步代理流量。 同样在此阶段,信息被发送到混音器,稍后我们将进行讨论,并发送跟踪范围。
结果,我们得到了一个完整的特使代理服务器网络,可以从一个点(飞行员)进行配置。 所有入站和出站请求都通过特使。 此外,仅TCP通信被拦截。 这意味着Kubernetes服务IP可以通过UDP使用kube-dns进行解析,而无需更改。 然后,在解决之后,传出请求将截获并处理传出的请求,使者已经确定了将请求发送到哪个端点(在访问策略或触发断路器算法的情况下则不是)。
整理好Pilot之后,现在您需要了解Mixer的工作原理以及为什么需要它。 您可以在
此处阅读官方文档。
当前形式的混合器由两个部分组成:组织遥测,组织策略(在版本0.8之前,它是组织混合器的一个组成部分)。 它们都是混音器,它们各自负责其任务。 Istio遥测通过GRPC从Sidecar Report容器接收有关谁去哪里以及使用哪些参数的信息。 Istio-policy接受检查请求,以检查是否满足策略规则。 当然,并非针对每个请求都执行政策检查,但是会在客户端(在小汽车中)缓存一定时间。 报告检查是通过批处理请求发送的。 稍后我们将看到如何配置以及需要发送哪些参数。
Mixer被认为是一个高度可用的组件,可以为遥测数据的收集和处理提供不间断的工作。 系统原来是一个多级缓冲区。 最初,数据在容器的边车侧被缓冲,然后在混合器侧被缓冲,然后被发送到所谓的混合器后端。 结果,如果任何系统组件发生故障,则缓冲区将增长并在系统恢复后崩溃。 混合器后端是用于发送遥测数据的端点:statsd,newrelic等。 您可以编写自己的后端,这非常简单,我们将看到如何做。

总而言之,采用容积遥测的工作方案如下。
- 服务1向服务2发送请求。
- 离开服务1时,请求将包装在自己的小车中。
- 边车特使监视服务请求2如何通过并准备必要的信息。
- 然后使用“报告”请求将其发送到遥测。
- 等距遥测技术确定是否将此报告发送到后端,向哪个数据发送以及向哪个数据发送。
- 等速遥测在必要时将报告数据发送到后端。
现在,让我们看看如何在仅由主要组件(飞行员和边车特使)组成的Istio系统中进行部署。
首先,让我们看一下Pilot读取的主要配置(网格):
apiVersion: v1 kind: ConfigMap metadata: name: istio namespace: istio-system labels: app: istio service: istio data: mesh: |- # tracing (pilot envoy' , ) enableTracing: false # mixer endpoint', sidecar #mixerCheckServer: istio-policy.istio-system:15004 #mixerReportServer: istio-telemetry.istio-system:15004 # , envoy Pilot ( envoy proxy) rdsRefreshDelay: 5s # default envoy sidecar defaultConfig: # rdsRefreshDelay discoveryRefreshDelay: 5s # ( envoy) configPath: "/etc/istio/proxy" binaryPath: "/usr/local/bin/envoy" # sidecar (, , tracing span') serviceCluster: istio-proxy # , envoy , drainDuration: 45s parentShutdownDuration: 1m0s # REDIRECT iptables. TPROXY. #interceptionMode: REDIRECT # , admin sidecar (envoy) proxyAdminPort: 15000 # , trace' zipkin ( , ) zipkinAddress: tracing-collector.tracing:9411 # statsd envoy () # statsdUdpAddress: aggregator:8126 # Mutual TLS controlPlaneAuthPolicy: NONE # , istio-pilot , service discovery sidecar discoveryAddress: istio-pilot.istio-system:15007
所有主要的控制平面组件都位于Kubernetes的名称空间istio-system中。
最低限度我们只需要部署飞行员。 为此,我们将使用
此配置。并手动配置容器的注入侧车。
初始化容器:
initContainers: - name: istio-init args: - -p - "15001" - -u - "1337" - -m - REDIRECT - -i - '*' - -b - '*' - -d - "" image: istio/proxy_init:1.0.0 imagePullPolicy: IfNotPresent resources: limits: memory: 128Mi securityContext: capabilities: add: - NET_ADMIN
和边车:
name: istio-proxy args: - "bash" - "-c" - | exec /usr/local/bin/pilot-agent proxy sidecar \ --configPath \ /etc/istio/proxy \ --binaryPath \ /usr/local/bin/envoy \ --serviceCluster \ service-name \ --drainDuration \ 45s \ --parentShutdownDuration \ 1m0s \ --discoveryAddress \ istio-pilot.istio-system:15007 \ --discoveryRefreshDelay \ 1s \ --connectTimeout \ 10s \ --proxyAdminPort \ "15000" \ --controlPlaneAuthPolicy \ NONE env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: INSTANCE_IP valueFrom: fieldRef: fieldPath: status.podIP - name: ISTIO_META_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: ISTIO_META_INTERCEPTION_MODE value: REDIRECT image: istio/proxyv2:1.0.0 imagePullPolicy: IfNotPresent resources: requests: cpu: 100m memory: 128Mi limits: memory: 2048Mi securityContext: privileged: false readOnlyRootFilesystem: true runAsUser: 1337 volumeMounts: - mountPath: /etc/istio/proxy name: istio-envoy
为了使一切成功启动,您需要获取ServiceAccount,ClusterRole,ClusterRoleBinding,Pilot CRD for Pilot,可以在
此处找到其说明。
结果,我们向特使注入边车的服务应该成功启动,从飞行员那里得到所有发现并处理请求。
重要的是要了解控制平面的所有组件都是无状态应用程序,并且可以在没有任何问题的情况下进行水平缩放。 所有数据都在etcd中作为Kubernetes资源的自定义描述。
Istio(到目前为止,还处于实验阶段)还具有在集群外部运行的能力,以及监视和摸索多个Kubernetes集群之间的服务发现的能力。 您可以
在此处了解更多信息。
对于多群集安装,应考虑以下限制:
- Pod CIDR和Service CIDR在所有群集中必须是唯一的,并且不应重叠。
- 群集之间的任何Pod CIDR必须都可以使用所有Pod CIDR。
- 所有Kubernetes API服务器都必须可以彼此访问。
这是帮助您开始使用Istio的初始信息。 但是,仍然存在许多陷阱。 例如,路由外部流量(到群集外部)的功能,调试边车的方法,性能分析,设置混合器和编写自定义混合器后端,使用envoy设置跟踪机制及其操作。
我们将在以下出版物中讨论所有这些问题。 提出您的问题,我将尽力解决。