1. K8s vs Istio

k8s_vs_servicemesh

1.1 k8s简介

  • 2014 年,Google 开源了 Kubernetes,随后几年得到迅猛发展,在 2017 年奠定了容器编排调度标准的地位。
  • Kubernetes 作为一种容器编排调度工具,解决了分布式应用程序的部署和调度问题。
  • Kubernetes 本质上是通过声明式配置来实现应用生命周期管理
  • Kubernetes 通过 Service 对象将一个服务的多个实例组合在了一起,统一对外服务。

1.2 k8s无法很好解决Service Mesh的流量需求

  • 服务具有多个版本,需要迭代和上线,在新版发布的时候需要切分流量,实现金丝雀发布;
  • 同时我们应该假定服务是不可靠的,可能因为各种原因导致请求失败,需要面向失败来编程;
  • 如何监控应用程序的指标,了解每个请求的耗时和状态?
  • 如何保障服务的安全性?
  • Kubernetes 在每个 node 中安装了 kube-proxy 组件来转发流量,该组件与 Kubernetes API Server 进行通信,获取集群中的服务信息,然后设置 iptables 规则,将服务请求直接发送到对应的 Endpoint。
  • 但是kube-proxy 组件只能实现最基本的服务发现和转发能力,无法实现这些细粒度的流量需求。

1.3 Istio通过透明代理(sidecar)将流量管理从K8S中解耦

  • Istio 的发起者们就想到了在每个 pod 中注入一个代理,将代理的配置通过一个控制平面集中分发,然后将从 pod 中应用容器发起的每个请求都劫持到 sidecar 代理中,然后转发,这样不就可以完美的解决以上问题了吗?
  • Kubernetes 优秀的架构和可扩展性,可以完美的解决大量 sidecar 的注入和管理问题,在 Kubernetes 的 Pod 中,在原有的应用容器旁边运行一个 Sidecar 容器,可以理解为两个容器共享存储、网络等资源。
  • Istio 不再使用 kube-proxy 组件做流量转发,而是依托在每个 pod 中注入的 sidecar proxy,所有的 proxy 组成了 Istio 的数据平面。从而将流量管理与 Kubernetes 解耦。
  • 在 Istio 之前,人们可以使用 SpringCloud、Netflix OSS 等,通过在应用程序中集成 SDK,编程的方式来管理应用程序中的流量。但是这通常会有编程语言限制,而且在 SDK 升级的时候,需要修改代码并重新上线应用,会增大人力负担。Istio 使得流量管理变得对应用程序透明,使这部分功能从应用程序中转移到了平台层,成为了云原生基础设施。

2. Istio vs Envoy

Envoy 是专为大型现代 SOA(面向服务架构)架构设计的 L7 代理和通信总线。该项目源于以下理念:网络对应用程序来说应该是透明的。当网络和应用程序出现问题时,应该很容易确定问题的根源

2.1 envoy的设计目标

为了做到这一点,Envoy 提供了以下高级功能:

  • 进程外架构:Envoy 是一个独立进程,设计为伴随每个应用程序服务运行。从而Envoy可以透明地在整个基础架构上快速部署和升级。
  • L3/L4 filter 架构:Envoy 的核心是一个 L3/L4 网络代理。可插入 filter 链机制允许开发人员编写 filter 来执行不同的 TCP 代理任务并将其插入到主体服务中。现在已有很多用来支持各种任务的 filter,如原始 TCP 代理、HTTP 代理、TLS 客户端证书认证等。
  • HTTP L7 filter 架构: HTTP 是现代应用程序体系结构的关键组件,Envoy 支持额外的 HTTP L7 filter 层。可以将 HTTP filter 插入执行不同任务的 HTTP 连接管理子系统,例如缓存,速率限制,路由/转发,嗅探 Amazon 的 DynamoDB 等等。
  • 顶级 HTTP/2 支持: 当以 HTTP 模式运行时,Envoy 同时支持 HTTP/1.1 和 HTTP/2。Envoy 可以作为 HTTP/1.1 和 HTTP/2 之间的双向透明代理。这意味着它可以桥接 HTTP/1.1 和 HTTP/2 客户端以及目标服务器的任意组合。
  • HTTP L7 路由:当以 HTTP 模式运行时,Envoy 支持一种路由子系统,能够根据路径、权限、内容类型、运行时及参数值等对请求进行路由和重定向。这项功能在将 Envoy 用作前端/边缘代理时非常有用,同时,在构建服务网格时也会使用此功能。
  • gRPC支持:gRPC 是一个来自 Google 的 RPC 框架,它使用 HTTP/2 作为底层多路复用传输协议。Envoy 支持被 gRPC 请求和响应的作为路由和负载均衡底层的所有 HTTP/2 功能。这两个系统是非常互补的。
  • MongoDB L7 支持:MongoDB 是一种用于现代 Web 应用程序的流行数据库。Envoy 支持对 MongoDB 连接进行 L7 嗅探、统计和日志记录。
  • DynamoDB L7 支持:DynamoDB 是亚马逊的托管键/值 NOSQL 数据存储。Envoy 支持对 DynamoDB 连接进行 L7 嗅探和统计。
  • 服务发现和动态配置/健康检查/高级负载均衡/最佳的可观察性等等…

2.2 Istio使用Envoy作为默认sidecar

Envoy 是 Istio Service Mesh 中默认的 Sidecar,Istio 在 Enovy 的基础上按照 Envoy 的 xDS 协议扩展了其控制平面。
那么Istio 是如何将 Envoy 作为 Sidecar 的方式注入到应用程序 Pod 中,及 Sidecar 是如何做劫持流量的?
在 Sidecar 部署方式中,你会为每个应用的容器部署一个伴生容器。Sidecar 接管进出应用容器的所有流量。在 Kubernetes 的 Pod 中,在原有的应用容器旁边运行一个 Sidecar 容器,可以理解为两个容器共享存储、网络等资源。

istio-proxy作为 Sidecar 的方式和应用运行在同一个 Pod 中,拦截所有进出应用容器的流量

该容器存在的意义就是让 Envoy 代理可以拦截所有的进出 Pod 的流量,即将入站流量重定向到 Sidecar,再拦截应用容器的出站流量经过 Sidecar 处理后再出站。

Init 容器启动时命令行参数中指定了 REDIRECT 模式,因此只创建了 NAT 表规则,接下来我们查看下 NAT 表中创建的规则。

# 查看 NAT 表中规则配置的详细信息
$ iptables -t nat -L -v
# PREROUTING 链:用于目标地址转换(DNAT),将所有入站 TCP 流量跳转到 ISTIO_INBOUND 链上
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    2   120 ISTIO_INBOUND  tcp  --  any    any     anywhere             anywhere

# INPUT 链:处理输入数据包,非 TCP 流量将继续 OUTPUT 链
Chain INPUT (policy ACCEPT 2 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination

# OUTPUT 链:将所有出站数据包跳转到 ISTIO_OUTPUT 链上
Chain OUTPUT (policy ACCEPT 41146 packets, 3845K bytes)
 pkts bytes target     prot opt in     out     source               destination
   93  5580 ISTIO_OUTPUT  tcp  --  any    any     anywhere             anywhere

# POSTROUTING 链:所有数据包流出网卡时都要先进入POSTROUTING 链,内核根据数据包目的地判断是否需要转发出去,我们看到此处未做任何处理
Chain POSTROUTING (policy ACCEPT 41199 packets, 3848K bytes)
 pkts bytes target     prot opt in     out     source               destination

# ISTIO_INBOUND 链:将所有目的地为 9080 端口的入站流量重定向到 ISTIO_IN_REDIRECT 链上
Chain ISTIO_INBOUND (1 references)
 pkts bytes target     prot opt in     out     source               destination
    2   120 ISTIO_IN_REDIRECT  tcp  --  any    any     anywhere             anywhere             tcp dpt:9080

# ISTIO_IN_REDIRECT 链:将所有的入站流量跳转到本地的 15001 端口,至此成功的拦截了流量到 Envoy 
Chain ISTIO_IN_REDIRECT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    2   120 REDIRECT   tcp  --  any    any     anywhere             anywhere             redir ports 15001

# ISTIO_OUTPUT 链:选择需要重定向到 Envoy(即本地) 的出站流量,所有非 localhost 的流量全部转发到 ISTIO_REDIRECT。为了避免流量在该 Pod 中无限循环,所有到 istio-proxy 用户空间的流量都返回到它的调用点中的下一条规则,本例中即 OUTPUT 链,因为跳出 ISTIO_OUTPUT 规则之后就进入下一条链 POSTROUTING。如果目的地非 localhost 就跳转到 ISTIO_REDIRECT;如果流量是来自 istio-proxy 用户空间的,那么就跳出该链,返回它的调用链继续执行下一条规则(OUPT 的下一条规则,无需对流量进行处理);所有的非 istio-proxy 用户空间的目的地是 localhost 的流量就跳转到 ISTIO_REDIRECT
Chain ISTIO_OUTPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ISTIO_REDIRECT  all  --  any    lo      anywhere            !localhost
   40  2400 RETURN     all  --  any    any     anywhere             anywhere             owner UID match istio-proxy
    0     0 RETURN     all  --  any    any     anywhere             anywhere             owner GID match istio-proxy	
    0     0 RETURN     all  --  any    any     anywhere             localhost
   53  3180 ISTIO_REDIRECT  all  --  any    any     anywhere             anywhere

# ISTIO_REDIRECT 链:将所有流量重定向到 Envoy(即本地) 的 15001 端口
Chain ISTIO_REDIRECT (2 references)
 pkts bytes target     prot opt in     out     source               destination
   53  3180 REDIRECT   tcp  --  any    any     anywhere             anywhere             redir ports 15001

ISTIO_OUTPUT 链规则匹配的详细过程如下:

  • 如果目的地非 localhost 就跳转到 ISTIO_REDIRECT 链
  • 所有来自 istio-proxy 用户空间的非 localhost 流量跳转到它的调用点 OUTPUT 继续执行 OUTPUT 链的下一条规则,因为 OUTPUT 链中没有下一条规则了,所以会继续执行 POSTROUTING 链然后跳出 iptables,直接访问目的地
  • 如果流量不是来自 istio-proxy 用户空间,又是对 localhost 的访问,那么就跳出 iptables,直接访问目的地
  • 其它所有情况都跳转到 ISTIO_REDIRECT 链

参考

理解 Istio Service Mesh 中 Envoy 代理 Sidecar 注入及流量劫持
为什么在使用了 Kubernetes 后你可能还需要 Istio?
xds协议
Learn Kubernetes using Interactive Browser-Based Scenarios
Get Started with Istio and Kubernetes
Getting Started with Envoy
MOSN with Istio
Envoy 的架构与基本术语
Envoy 架构与配置结构

更多推荐