更多相关文章

个人博客 :pyenv.cc

ServiceMesh基本概念

手把手教你部署istio控制平面

四个案例让你掌握istio网格功能

VirtualService实现Istio高级流量治理

DestinationRule实现Istio集群高级配置

一、Istio环境中运行Pod的要求

  • Service association (服务关联)
  • Pod 必须从属于某个Service,哪怕Pod不需要暴露任何端口,否则此Pod就是一个无Service的Pod,会导致网格内部无法于相关的Sidecar进行关联;
  • 同时从属于多个Service时,这些Service不能为该类Pod的同一个端口标识使用不同的协议;
  • Application UIDs
  • UID 1337 预留给了Sidecar Proxy 使用,业务应用不能以这一 UID 运行;
  • NET_ADMIN and NET_RAW capabilities
  • 强制启用了PSP(Pod Security Policy)的Kubernetes环境中,必须允许在网格内的Pod上使用NET_ADMIN和 NET_RAW这两个Capability,以确保Sidecar Envoy依赖的初始化Pod能够正常运行;
  • 未启用PSP,或者启用了PSP但使用了专用的Istio CNI Plugin的场景,可以不用;
  • Pods with app and version labels (部署在网格内的每一个应用程序都需要明确使用以下两个标签)
  • 显式地为 Pod使用app和version标签;
  • app标签用于为分布式追踪生成context,而label则用于指示应用的版本化;
  • Named Service Ports (为网格内的每一个Service的端口定义一个名称及明确其协议)
  • Service Port 应该明确指定使用的协议;
  • 命名格式 :
    • [-] 如 http-8080
    • Kubernetes v1.18 及之后的版本中,可以直接使用 appProtocol 字段进行标识;
# 网格会依赖对应方式指定的协议标识作为协议,即应用程序对外提供服务协议的特定标识;这也是Envoy在代理应用程序基于的协议类型;1、<protocol>[-<suffix>] 格式
apiVersion: v1
kind: Service
metadata:name: demoappv10
spec:ports:- name: http-8080port: 8080protocol: TCPtargetPort: 8080selector:app: demoappversion: v1.0type: ClusterIP2、Kubernetes v1.18 及之后的版本中,可以直接使用 appProtocol 字段进行标识
apiVersion: v1
kind: Service
metadata:name: demoappv10
spec:appProtocol: httpports:- name: httpport: 8080protocol: TCPtargetPort: 8080selector:app: demoappversion: v1.0type: ClusterIP

二、协议选择 (Protocol Selection)

  • Istio 支持代理的协议

    • 支持代理任何类型的TCP流量,包括HTTP、HTTPS、gRPC及原始TCP(raw tcp) 协议;
    • 但为了提供额外的能力,比如路由和更加丰富的指标,Istio需要确定更加具体的协议( 应用层协议) ;
    • Istio不会代理任何UDP协议;
  • 协议选择
    • istio 能够自动检测并识别 HTTP和HTTP/2 的流量,未检测出的协议类型将一律视为普通的TCP流量;
    • 也支持由用户手动指定;
  • 手动指定协议
    • Service Port 应该明确指定使用的协议;
    • 命名格式 :
      • [-]
      • Kubernetes v1.18 及之后的版本中,可以直接使用 appProtocol 字段进行标识;
  • Istio支持的协议类型如下 :

https://istio.io/latest/docs/ops/configuration/traffic-management/protocol-selection/

三、Sidecar代理方式简介

  • Kubernetes平台上,Envoy Sidecar容器与application容器于同一个Pod中共存,它们共享 NETWORK、UTS和IPC等名称空间,因此也共用同一个网络协议栈;

    • Envoy Sidecar 基于 init 容器 (需要使用 NET_ADMIN 和 NET_RAW Capability 于 Pod启动时设置的 iptables规则以实现流量拦截)

      • 入站流量由iptables拦截后转发给Envoy;
      • Envoy根据配置完成入栈流量代理;
      • 后端应用程序生成的出站流量依然由iptables拦截并转发给Envoy;
      • Envoy 根据配置完成出站流量代理;
  • 流量拦截模式
    • REDIRECT : 重定向模式
    • TPROXY : 透明代理模式
      • 具体操作参考 : https://github.com/istio/istio/blob/master/tools/packaging/common/istio-start.sh

四、Sidecar Envoy 流量劫持

  • 流量的透明劫持

    • 流量的透明劫持,用于确保让应用无需事先改造即可获得服务治理和观测能力;
    • 开启透明劫持功能后,出入应用的业务流量将会被Sidecar Envoy自动拦截;

五、Istio注入的Envoy Sidecar

  • Istio 基于 Kubernetes Admission Controller Webhook 完成sidecar自动注入,它会为每个微服务分别添加两个相关的容器;

    • istio-init : 隶属于 Init Containers ,即初始化容器,负责在微服务相关的Pod中 生成iptables规则 以进行流量拦截并向Envoy Proxy进行转发,运行完成后退出;
    • istio-proxy : 隶属于Contianers, 即Pod中的正常容器,程序为 Envoy Proxy;
# 查看每个Pod上是如何指定注入的 istio init container
# Init Containers 生成流量劫持规则
Init Containers:istio-init:Container ID:  docker://943e9512f4e3ec0f64b25b26ac334c70800169416389abc58b723413481c787fImage:         docker.io/istio/proxyv2:1.12.1Image ID:      docker-pullable://istio/proxyv2@sha256:4704f04f399ae24d99e65170d1846dc83d7973f186656a03ba70d47bd1aba88fPort:          <none>Host Port:     <none>Args:istio-iptables# 入向流量生成规则的重定向端口-p15001# 出向流量端口-z15006# 使用用户UID-u1337-mREDIRECT-i*-x-b*-d15090,15021,15020
...
Containers:demoapp:Container ID:   docker://563a48b833baf3ab46ef35f147012e124ba3c114323377c261f2cb5c8729a34fImage:          ikubernetes/demoapp:v1.0Image ID:       docker-pullable://ikubernetes/demoapp@sha256:6698b205eb18fb0171398927f3a35fe27676c6bf5757ef57a35a4b055badf2c3Port:           <none>Host Port:      <none>
...
# istio-proxy: 真正意义上流量治理 sidecar envoyistio-proxy:Container ID:  docker://bab78cd8993123c8a24a236a02a0b572a3acbc0e013559a24dd57959d9c7430cImage:         docker.io/istio/proxyv2:1.12.1Image ID:      docker-pullable://istio/proxyv2@sha256:4704f04f399ae24d99e65170d1846dc83d7973f186656a03ba70d47bd1aba88fPort:          15090/TCPHost Port:     0/TCPArgs:proxysidecar   # sidecar 模式运行--domain$(POD_NAMESPACE).svc.cluster.local--proxyLogLevel=warning--proxyComponentLogLevel=misc:error--log_output_level=default:info--concurrency2

5.1、istio-init初始化容器

  • istio-init初始化容器基于 istio/proxyv2 镜像启动,它运行 istio-iptables 程序以生成流量拦截规则

    • 拦截的流量将转发至两个相关的端口

      • 15006 :由 -z 选项定义,指定用于接收拦截所有发往当前Pod/VM的入栈流量的目标端口,该配置仅用于 REDIRECT 转发模式;
      • 15001 :由 -p 选项定义,指定用于接收拦截的所有TCP流量的目标端口;
    • 流量拦截模式由 -m 选项指定,目前支持 REDIRECT 和 TPROXY 两种模式;
    • 流量拦截时要包含的目标端口列表使用 -b 选项指定,而要排除的目标端口列表则使用 -d 选项指定;
    • 流量拦截时要包含的目标 CIDR 地址列表可使用 -i 选项指定,而要排除的目标 CIDR 格式的地址列表则使用 -x 选项指定;

5.1.1、istio中用于流量拦截的iptables规则

  • nsenter 命令于宿主机上可直接于目标容器的网络名称空间中运行 iptables 命令,例如,假设 productpage 相关的 Pod被调度运行于 k8s-node02 节点之上,且其内部的 envoy 进程的 pid在宿主机为 5607 ;
# 对应运行envoy sidecar 节点上运行命令
root@native:~# ps aux | grep envoy | grep 1337
root@native:~# nsenter -t 8134 -n iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N ISTIO_INBOUND
-N ISTIO_IN_REDIRECT
-N ISTIO_OUTPUT
-N ISTIO_REDIRECT
-A PREROUTING -p tcp -j ISTIO_INBOUND
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_INBOUND -p tcp -m tcp --dport 15008 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 22 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15090 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15021 -j RETURN
-A ISTIO_INBOUND -p tcp -m tcp --dport 15020 -j RETURN
-A ISTIO_INBOUND -p tcp -j ISTIO_IN_REDIRECT
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
-A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT
-A ISTIO_OUTPUT -o lo -m owner ! --uid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --gid-owner 1337 -j ISTIO_IN_REDIRECT
-A ISTIO_OUTPUT -o lo -m owner ! --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN
-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001

5.1.2、流量拦截的处理机制

  • 入向流量拦截 : PREROUTING -> ISTIO_INBOUND

    • RETURN

      • 目标端口为 TCP 协议的 22、15020、15021、15008、15090 时将报文返回至上级 PREROUTING 链,即不予拦截;
    • ISTIO_IN_REDIRECT : 其它目标端口的请求报文则由该自定链中的规则 (-A ISTIO_IN_REDIRECT -p tcp -j RESIRECT --to-ports 15006) 将请求重定向至 15006 端口;
      • 15006 端口时为 envoy 的 VirtualInboundListener 绑定的端口,于是请求则转交由Envoy处理;
      • Envoy 根据报文目标地址匹配入向 (Inbound) 方向的Listener,若存在,则根据该 Listener的配置决定如何将请求转发至 Envoy后端的应用程序;

  • 出向流量拦截 : OUTPUT -> ISTIO_OUTPUT

    • RETURN

      • 从 LO 接口流出,且源地址为 127.0.0.6/32 的出向流量
      • UID Owner 为 1337 的出向流量
      • GID Owner 为 1337 的出向流量
      • 从 LO 接口流出,且UID Owner 非为 1337 的出向流量
      • 从 LO 接口流出,且GID Owner 非为 1337 的出向流量
      • 目标地址是 127.0.0.1/32 的出向流量
    • ISTIO_IN_REDIRECT : Sidecar Envoy 同其反向代理的本地后端应用程序间的通信
      • 从 LO 接口流出,目标地址非为 127.0.0.1/32,且UID Owner 为 1337 的出向流量
      • 从 LO 接口流出,目标地址非为 127.0.0.1/32,且GID Owner 为 1337 的出向流量
  • ISTIO_REDIRECT:其它报文则由该自定义链中的规则(-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001)重定向至15001端口;
    • Envoy根据报文目标地址匹配出向(Outbound)方向的Listener,若存在,则 根据该Listener的配置决定如何将报文向外转发;

5.2、istio-proxy 容器

  • istio-proxy即所谓的sidecar容器,它运行两个进程:

    • pilot-agent
    • 基于k8s api server 为 envoy 初始化出可用的 bootstrap 配置文件并启动envoy;
    • 监控并管理envoy的运行状态,包括envoy出错时重启envoy,以及envoy配置变更后将其重载等;
    • envoy
    • envoy 由pilot-agent 进程基于生成bootstrap 配置进行启动,而后根据配置中指定的 pilot 地址,通过xDS API获取动态配置信息;
    • Sidecar形式的Envoy通过流量拦截机制为应用程序实现入站和出站代理功能;
# kubectl exec demoappv10-6ff964cbff-84kqr -it -c istio-proxy -- ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
istio-p+     1  0.1  0.4 747732 47700 ?        Ssl  Feb19   0:50 /usr/local/bin/pilot-agent proxy sidecar --domain default.svc.cluster.local --proxyLogLevel=
istio-p+    28  0.4  0.5 185544 58488 ?        Sl   Feb19   3:16 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45
istio-p+    42  0.0  0.0   5900  2804 pts/0    Rs+  03:45   0:00 ps aux

5.2.1、istio-proxy 容器及其Listener

  • Envoy 的bootstrap 配合文件由pilot-agent 负责生成,而生效的大多配置则定义了dynamic resources ,并通过xDS静态集群指向的Plot 获取;

    • 而这些配置则来自于 VirtaulService、DestinationRule、Gateway和ServiceEntry资源对象等提供的配置;
  • 由Pilot基于Kubernetes发现的网格内的各Service均会被自动转换为下发给各Sidecar实例的Listener、Route、Cluster和Endpoint的相关配置;
    • 为了能够让Sidecar Envoy代理网格内进出各Service的流量,所以需要进行流量劫持,而后由Envoy根据请求特征,将流量派发至合适的Listener,进而完成后续的流量路由、负载均衡等;

5.2.2、istio-proxy Listener (几个重要侦听器的作用)

  • Envoy Listener 支持绑定于 IP Socket 或 Unix Domain Socket 之上,也可以不予绑定,而是接收由其他的Listener转发来的数据;

    • VirtualOutboundListener
    • 通过一个端口接收所有的出口流量,而后再按照请求的端口分别转发给相应的 Listener进行处理;
    • VirtualInboundListner
    • 功能相似,但主要用于处理入向流量;

VirtualOutboundListener(不过多展开)

  • iptables 将其所在的Pod中的外发流量拦截后转发至监听于15001的Listener,而该Listener通过在配置中将 use_origin_dest 参数设置为true,从而实现将接收到的请求转发给同请求原目标地址关联的Listener之上;
  • 若不存在可接收转发报文的Listener,则Envoy将根据Istio的全局配置选项 outboundTrafficPolicy 参数的值决定如何进行处理 :
    • ALLOW_ANY :
    • 允许外发至任何服务的请求,无论目标服务是否存在于Pilot的注册表中;此时,没有匹配的目标Listener的流量将由该侦听器上 tcp_proxy 过滤器指向的 Passthrouh Cluster 进行透传;
    • REGISTRY_ONLY :
    • 仅允许外发请求至注册与Polit 中的服务;此时,没有匹配的目标Listener的流量将由该侦听器上 tcp_proxy 过滤器指向的 BlackHoleCluster 将流量直接丢弃;
  • 出向流量劫持方式总结 :
    • 所有应用的出向流量会被重定向给 Envoy Sidecar 的 15001 侦听器,而后 15001 侦听器将流量根据其请求的原有的目标IP和目标端口来在Envoy中找出真正于该流量相关的出站侦听器,再把其请求转交至其真正相关的出站侦听器;若其没有找到对应条件的出站侦听器则根据出站流量策略 outboundTrafficPolicy 确定是交给 Passthrouh Cluster 进行透传还是 BlackHoleCluster 进行丢弃;

VirtualInbound Listener(不过多展开)

  • 入向流量劫持

    • 较早版本的 Istio 基于同一个 VirtualListener 在 15001 端口上同时处理入站和出站流量;
    • 自 1.4 版本起,Istio引入了 REDIRECT 代理模式,它通过监听于 15006 端口 的专用 VirtualInboundListener 处理入向流量代理以避免潜在的死循环问题;
  • 入向流量处理
    • 对于进入到 侦听器 “0.0.0.0:15006” 的流量,VirtaulInboundListener 会在 filterChains 中,通过一系列的 filter_chain_match 对流量进行匹配检测,以确定应该由哪个或哪些过滤器进行流量处理;
  • 入向流量劫持方式总结
    • istio proxy 对所有相关入向流量的处理方式是所有请求的无论目标 APP服务监听的端口,Envoy 都不会为其在前端创建入站侦听器而是所有流量交给 15006 ,在15006入站侦听器内部 都会通过 filter_chain_match 进行处理,然后通过其内部 filterChainMatch 进行匹配,而后又经过filter进行流量转发;

5.3、istio-proxy Clusters

  • Istio 网格中的Cluster分别由 static_resources 提供的静态配置集群以及 dynamic_resources 提供的动态配置集群组成;

    • 静态集群由 envoy_rev0.json 的初始化配置中的 prometheus_stats 、xDS server 和zipkin server等组成;
    • 动态集群则是由通过xDS API 从Pilot获取的配置信息生成;
  • 对于网格内的一个特定Pod来说,其集群可主要分为两类 :
    • inbound : 该Pod内的Sidecar Envoy直接代理的服务;
    • outbound : 网格内的所有服务;
  • 动态集群类型
    • Inbound Cluster :Sidecar Envoy直接代理的应用,同一Pod中,由Sidecar Envoy反向代理的应用容器;
    • Outbound Cluster :网格中的所有服务,包括当前Sidecar Envoy直接代理的服务,该类Cluster占了Envoy可用集 群中的绝大多数;
    • PassthroughCluster和InboundPassthroughClusterIpv4 :发往此类集群的请求报文会被直接透传至其请求中的原 始目标地址,Envoy不会进行重新路由;
    • BlackHoleCluster :Envoy的一个特殊集群,它没有任何可用的endpoint,接收到的请求会被直接丢弃;未能正 确匹配到目标服务的请求通常会被发往此Cluster;

Sidecar及流量拦截机制-上相关推荐

  1. Sidecar及流量拦截机制-下

    更多相关文章 个人博客 :pyenv.cc ServiceMesh基本概念 手把手教你部署istio控制平面 四个案例让你掌握istio网格功能 VirtualService实现Istio高级流量治理 ...

  2. Attribute在拦截机制上的应用

    http://blog.csdn.net/niuyongjie/article/details/1295842 从这一节开始我们讨论Attribute的高级应用,为此我准备了一个实际的例子:我们有一个 ...

  3. Nginx流量拦截算法

    0x00.About 电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单.信誉分析,进而根据用户ip信誉权重做相应的流量拦截.限制流量. Nginx自身有的请求限制模 ...

  4. 千亿流量拦截控制处理技术-Nginx(安装 命令 路由匹配 负载均衡 常用配置)

    千亿流量拦截控制处理技术-Nginx Nginx使用与配置 1 什么是nginx 1.1 可大量并行处理 1.2 与 Apache 相比 1.2.1 Apache VS Nginx 1.2.2 常用w ...

  5. Nginx流量拦截算法 1

    0x00.About 电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单.信誉分析,进而根据用户ip信誉权重做相应的流量拦截.限制流量. Nginx自身有的请求限制模 ...

  6. Nginx + LUA下流量拦截算法

    前言 电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单.信誉分析,进而根据用户ip信誉权重做相应的流量拦截.限制流量. Nginx自身有的请求限制模块ngx_htt ...

  7. 如何绕过chrome的弹窗拦截机制

    如何绕过chrome的弹窗拦截机制 在chrome的安全机制里面,非用户触发的window.open方法,是会被拦截的.举个例子: var btn = $('#btn'); btn.click(fun ...

  8. 反思|Android 事件拦截机制的设计与实现,android组件化开发

    最顶层View直接持有最下层某个View的引用合理吗?答案是否定的.首先,这导致View层级依赖之间的混乱:其次,顶层View本身持有了最下层某个View的引用,则这之间若干个层级的View的targ ...

  9. Android短信拦截机制适配的坑(下)--4.4以上系统,主要是6.0

    前一篇文章,Android短信拦截机制适配的坑(上)--4.4以下系统 介绍了广播接收的顺序,但是我明确说明在4.4以下系统,那么4.4及以上系统会遇到说明问题呢? 首先我们要来了解4.4系统短信的机 ...

最新文章

  1. 树莓派视觉小车 -- 物体跟踪(OpenCV)
  2. vue 取数组第一个值_vue遍历对象中的数组取值示例
  3. BugKuCTF WEB web基础$_GET
  4. 在利用计算机生成,计算机生成人像,从而使人脸的模糊变为现实
  5. php cli 判断,php cli 命令行详解【转】
  6. python 抓包基于pypcap
  7. python 统计单词个数---从文件读取版本---不去重
  8. Android 仿美团网,大众点评购买框悬浮效果之修改版
  9. 对R语言发展与历史的一个初步认识
  10. [python] 字典 pop(key)函数:删除字典中key及其值,并返回该值
  11. Linux多线程服务端编程学习(四)finger服务的实现
  12. 【POJ】2676-Sudoku 【51Nod】1211-数独(DFS)
  13. Android malware样本SLocker Mobile Ransomware
  14. javascript-ECMAScript
  15. 中国中试工厂市场现状研究分析与发展前景预测报告
  16. 【315】备份全盘和备份C盘的区别
  17. python计算协方差_在Python中计算协方差
  18. 什么是promise,promise的使用及实现
  19. 年前找Java实习面试经历
  20. Hive案例之股票分析

热门文章

  1. 家中这些地方保持干净,财神进来不再走!
  2. C#编写MySQL报错信息
  3. virtualbox rc=-101 问题解决
  4. 普通运动控制卡在LabVIEW平台上的…
  5. jdbc连接mysql工具类_jdbc之工具类DBUtil的使用
  6. DS1302异常 秒数超过60 走时过快问题
  7. DHCP客户端获取IP地址的过程
  8. Emacs 24.3 使用 w3m访问网页
  9. word设置默认字体_如何在Word中设置默认字体
  10. 升级IPv6新路由器购买与老路由器巧妙利用