在生产中运行kubernetes上的Istio

19-01-21 banq
         

什么是Istio?Istio是一种服务网格技术,为网络添加了一个抽象层。它拦截k8s集群中的全部或部分流量,并对其执行一组操作。支持哪些操作?例如,设置智能路由或实施断路器方法,设置“金丝雀部署”。此外,Istio可以对外部交互施加限制并控制集群与外部网络之间的所有路由。此外,它还支持设置策略规则,以控制不同微服务之间的活动。最后,我们可以生成一个完整的网络交互图,并使统一的度量集合对应用程序完全透明。

在这里,我想介绍基于Istio的微服务交互背后的基本原理,我将尝试证明Istio是一个解决各种问题的强大工具。在这篇文章中,我将尝试回答Istio初学者通常拥有的问题。这些是允许您更有效地使用Istio的东西。

但在安装之前,我想介绍一些中心概念,并看一下Istio的组件和它们之间的交互原理。

工作原理

Istio由两个主要部分组成 - 控制平面和数据平面。控制平面包含确保其他组件之间正确交互的基本组件。在当前版本1.0中,控制平面有三个主要组件:Pilot,Mixer,Citadel。Citadel将不在这里讨论,因为它需要为服务之间的相互TLS生成证书。让我们来看看Pilot和Mixer的设计和目的。

Pilot是主要控制组件,它分发有关我们保留在集群内部的所有信息 - 服务,端点和路由规则(例如,金丝雀部署规则或断路器规则)。

Mixer是一个可选的控制平面组件,可以收集指标,日志和有关网络交互的任何信息。它还监控政策规则的遵守情况以及对速率限制的遵守情况。

使用边车Sidecar代理容器实现数据平面组件。默认情况下,边车Sidecar代理使用的是强大的Envoy。为了确保Istio对应用程序完全透明,有一个自动注射系统。最新的实现支持kubernetes版本1.9和更新(。对于kubernetes版本1.7,1.8,您可以使用初始化程序。

边车Sidecar容器通过GRPC协议连接到Pilot,优化了集群内部变化的下推模型。自1.6版以来,GRPC已在Envoy中使用; 在Istio中,它已经从0.8版开始实现,并且是一个试验代理 - 一个配置启动参数的Go over envoy的包装器。

Pilot和Mixer是完全无状态的组件,所有状态都保存在应用程序的内存中。它们的配置在存储在etcd中的kubernetes Custom Resources中指定。Istio-agent获取Pilot地址并打开GRPC流。

正如我所说,Istio实现了对应用程序完全透明的所有功能。我们来看看其算法的工作原理如下:

  1. 部署了某个微服务的新版本。
  2. 根据边车容器注入类型,在配置阶段添加istio-init容器和istio-agent容器(envoy),或者可以将它们手动插入kubernetes实体的pod描述中。
  3. istio-init容器是一个应用pod的iptables规则的脚本。有两种方法可以将流量重定向到istio-agent容器:使用重定向iptables规则或TPROXY。目前默认使用重定向规则。在istio-init中,可以配置哪些流量将被拦截并发送到istio-agent。例如,为了拦截所有传入和传出的所有流量,您需要设置的参数-i和-b为*。您可以指定要拦截的特定端口。为避免拦截某个子网,可以使用该-x标志指定它。
  4. 初始化执行后,将启动容器,包括pilot-agent(envoy)。它通过GRPC连接到已部署的Pilot,并获取有关群集中所有现有服务和路由策略的信息。根据收到的数据,它配置集群并将这些映射直接映射到k8s集群中的应用程序端点。有一个重要时刻:envoy都是在开始侦听时动态配置侦听器(IP,端口对)。因此,当请求进入pod并使用iptables规则重定向到边车时,envoy准备处理这些连接并了解转发代理流量的位置。在此步骤中,信息将发送到Mixer,我们将在下面介绍。

最后,我们得到了一个完整的Envoy代理服务器网络,可以从一个点(Pilot)进行配置。因此,所有入站和出站请求都通过Envoy。此外,只拦截TCP流量。这意味着kubernetes服务IP通过UDP上的kube-dns解析而无需修改。然后,在解析器之后,envoy拦截并处理出站请求,决定请求应该发送到哪个端点(或者在有访问策略的情况下或会触发断路器算法)。

现在我们已经熟悉了Pilot,我们将了解Mixer的工作原理以及我们需要它的原因。

Mixer有两个组成部分:istio-telemetry,istio-policy(最高版本0.8,它曾经是一个单独的组件istio-mixer)。两者都是Mixer。Istio遥测技术从边车容器接收GRPC并报告有关服务交互和参数的信息。Istio-policy接受检查请求以验证是否符合策略规则。这些策略检查缓存在客户端(在边车上)一段时间。报告检查以批处理请求发送。我们将看看如何配置它以及稍后需要设置哪些参数。

Mixer应该是一个高度可用的组件,可以不间断地组装和处理遥测数据。该系统是一个多级缓冲区。最初,数据在容器的边车侧缓冲,然后在Mixer侧缓冲,最后发送到所谓的Mixer后端。因此,如果任何系统组件发生故障,缓冲区将会增长,并且在系统恢复后,将刷新缓冲区。Mixer后端是发送遥测数据的端点:statsd,newrelic等。编写自定义后端很容易,稍后我将展示如何。

综上所述,使用istio-telemetry的工作流程如下:

  1. 有两个服务,服务1向服务2发送请求。
  2. 当请求离开服务1后,将在其边车中被重定向。
  3. 边车Envoy监控服务处理请求2并准备必要的信息。
  4. 然后它使用监控报告Report请求将其发送到istio-telemetry。
  5. Istio-telemetry确定是否将此报告发送到后端,发送请求和请求内容的位置。

使用Pilot和Envoy

现在让我们看看如何使用Pilot和边车Envoy这两个基本组件来设置Istio系统。让我们回顾一下Pilot读取的基本配置(网格):

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio
  namespace: istio-system
  labels:
    app: istio
    service: istio
data:
  mesh: |-
# disable tracing mechanism for now
    enableTracing: false
# do not specify mixer endpoints, so that sidecar containers do not send the information
    #mixerCheckServer: istio-policy.istio-system:15004
    #mixerReportServer: istio-telemetry.istio-system:15004
# interval for envoy to check Pilot
    rdsRefreshDelay: 5s
# default config for envoy sidecar
    defaultConfig:
      # like rdsRefreshDelay
      discoveryRefreshDelay: 5s
# path to envoy executable
      configPath: "/etc/istio/proxy"
      binaryPath: "/usr/local/bin/envoy"
# default name for sidecar container
      serviceCluster: istio-proxy
# time for envoy to wait before it shuts down all existing connections
      drainDuration: 45s
      parentShutdownDuration: 1m0s
# by default, REDIRECT rule for iptables is used. TPROXY can be used as well.
      #interceptionMode: REDIRECT
# port for sidecar container admin panel
      proxyAdminPort: 15000
# address for sending traces using zipkin protocol (not used as turned off in enableTracing option)
      zipkinAddress: tracing-collector.tracing:9411
# statsd address for envoy containers metrics
      # statsdUdpAddress: aggregator:8126
# turn off Mutual TLS
      controlPlaneAuthPolicy: NONE
# istio-pilot listen port to report service discovery information to sidecars
      discoveryAddress: istio-pilot.istio-system:15007

让我们将所有主要控制组件(控制平面)放在名称空间istio-system中的kubernetes中。

最低配置仅需要Pilot部署。这里我们使用以下配置。我们将手动配置边车容器的注入。

Init容器配置:

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
         command:
         - "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

要成功部署,您需要为Pilot创建ServiceAccount,ClusterRole,ClusterRoleBinding和CRD; 有关这些的更多信息,请点击此处。结果,带有注入的边车envoy的服务将启动,从pilot检索所有发现数据,并处理请求。

关键是所有控制平面组件都是无状态应用程序,并且可以轻松地水平扩展。所有数据都存储在etcd中,作为kubernetes资源的自定义描述。

此外,可以在集群外部运行Istio(实验性地)并监视和共享几个kubernetes集群之间的服务发现。有关此信息,请访问此处。在多集群安装中,请考虑以下限制:

  1. CIDR Pod和服务CIDR在所有群集中必须是唯一的,并且不得重叠。
  2. 必须可以从群集之间的任何Pod CIDR访问所有CIDR Pod。
  3. 所有Kubernetes API服务器必须可以相互访问。