协议检测(Protocol detection),顾名思义,允许 Linkerd 自动检测 TCP 连接中使用的协议。 Linkerd 的设计原则之一是“just work”,协议检测是 Linkerd 如何实现这一目标的重要组成部分。

什么是协议检测?

简而言之,协议检测是通过检查连接上的流量来确定 TCP 连接上使用的协议的能力。

Linkerd 使用 Protocol detection 来避免要求用户指定协议。 Linkered 的代理不需要用户配置每个端口使用的协议,而是简单地执行协议检测来回答问题。

LinkerdProtocol detection 通过查看客户端连接的前几个字节来获取有关流量的信息来工作。 这种实现有一些后果,我们将在下面介绍。

但首先,让我们首先回答为什么 Linkerd 关心任何协议的问题。

可观察性、可靠性和安全性

我们通常将 Linkerd 的广泛功能分为三类:可观察性(Observability)、可靠性(reliability)和安全性(security)。 了解连接(connection)上使用的协议是每个类别的基础。

可观察性

Linkerd 可观察性功能的核心是流量检测。 这种仪器需要了解正在使用的协议,因为协议的知识可以提供丰富的指标。 例如,知道连接正在使用 HTTPLinkerd 就可以解析请求、响应和响应代码,并报告响应延迟、请求量和错误率等指标。 这些指标非常有价值,以至于它们成为谷歌 SRE 书中所谓的“黄金信号”的一部分。 另一方面,如果 Linkerd 只知道连接是 TCP,则它仅限于记录非常基本的信息,例如读取和写入的字节数——无法进一步解释字节。

Linkerd 可观察特性的核心是流量的测量。这种检测需要理解正在使用的协议,因为对协议的了解可以提供丰富的度量。例如,知道一个连接正在使用 HTTP,就允许 Linkerd 解析请求、响应和响应代码,并报告响应延迟、请求量和错误率等指标。这些指标非常有价值,它们是谷歌的 SRE 书中所谓的“黄金信号”的一部分。另一方面,如果 Linkerd 只知道一个连接是 TCP,那么它只能记录非常基本的信息,比如读取和写入的字节数——没有进一步解释字节的能力。

安全

双向 TLS (mTLS)Linkerd 的核心功能。从 Linkerd 2.9 开始,网状端点(meshed endpoints)之间的所有 TCP 流量默认由 Linkerd 代理进行 mTLS。 (有一些警告 - 请参阅下面有关 skip-ports 的部分。)

在这里,再次了解连接的协议至关重要。例如,如果连接已经是 TLS 的(例如,通过应用程序),则没有理由重新 TLS。(严格来说,TLS 是一种传输层协议,而不是像 HTTP 那样的应用层协议,但就本文而言,两者之间的区别并不重要。)

可靠性

最后,了解底层连接的协议允许 Linkerd 提供复杂的可靠性功能。 这里的一个例子是负载平衡。 在不知道连接协议的情况下,Linkerd 仅限于平衡连接(balancing connections):一旦与服务器建立了 TCP 连接,它就无法进一步操作该连接。

但是,如果 Linkerd 知道连接是 HTTP,它可以从连接平衡(connection balancing)转移到请求平衡(request balancing)。Linkerd 将建立一个跨端点的连接池,并平衡这个池中的请求。 由于它现在可以访问 requestsresponsesLinkerd 在平衡请求方面可以非常复杂; 事实上,它根据每个可能端点的最近性能(使用称为“指数加权移动平均(exponentially weighted moving average)”或 EWMA 的指标)来平衡请求,以避免从慢速端点引起尾部延迟(tail latency)。

( Linkerd 也是 Kubernetes 中负载平衡 gRPC 连接的一个简单解决方案。)

当协议检测失败时

虽然协议检测旨在允许 Linkerd “just work”,但在某些情况下它不能:臭名昭著的服务器优先协议(server-speaks-first)。 这些协议(包括 MySQLSMTP)通过让客户端建立连接然后等待服务器响应来工作。从 TCP 的角度来看,这是一种完全合法的行为,但这意味着 Linkerd 无法检测到协议,因为相关信息来自服务器,而不是客户端。

(为什么不简单地使用服务器的字节来检测协议?因为在检测协议的时候,Linkerd 甚至还没有建立到服务器的连接。选择与哪个服务器对话是负载均衡器的一个功能,而使用哪个负载均衡器是协议的一个功能。这是一个 delicious、带有 TCP-flavored 的“先有鸡还是先有蛋(chicken-and-egg)”问题。)

为了避免这种情况,Linkerd 引入了 skip-inbound-portsskip-outbound-ports 配置选项。 这些选项指示 Linkerd 通过修改 Linkerd 用于通过其 sidecar 代理连接 podiptables 规则来完全绕过某些端口的代理。例如,将 annotation config.linkerd.io/skip-outbound-ports: 3306 添加到工作负载的 PodSpec 指示 Linkerd 创建一个 iptables 规则,以确保 Linkerd 代理永远不会处理到端口 3306MySQL 端口)的任何流量 . 同样,annotation config.linkerd.io/skip-inbound-ports: 3306 将编写一个 iptables 规则,以便代理永远不会处理发送给它的 MySQL 流量。

Skip Ports 配置

这些选项为 protocol detection 无法处理 server-speaks-first 协议提供了一种解决方法。 然而,它们有一个明显的缺点:因为它们完全绕过 Linkerd 代理,Linkerd 无法应用 mTLS 或捕获这些端口的任何指标。

Linkerd 2.10 中的不透明端口和改进的协议检测

为了解决 skip-ports 的不足,在 2.10 版本中,Linkerd 将添加不透明端口(opaque ports)的概念(以及相应的 opaque-ports annotation)。不透明端口就是 Linkerd 将代理而不执行协议检测的端口。虽然这种方法仍然需要配置,但将端口标记为不透明允许 Linkerd 应用 mTLS 并报告 TCP-level metrics —— 这比完全跳过它是一个很大的改进。

Opaque Ports 配置

Linkerd 2.10 还将通过使其“fail open”来改进协议检测的工作方式:如果协议检测代码在 10 秒后没有看到客户端字节,它会将连接视为 TCP 连接并继续,而不是像 2.9 那样失败 . 这意味着不使用 opaque-ports(或 skip-ports)annotating server-speaks-first 端口的最坏情况行为是 10 秒的连接时间延迟,而不是连接失败。

总结

Protocol detectionLinkerd 最强大的功能之一,也是 Linkerd “just works” 原则的基础。虽然协议检测不是万灵药,但 Linkerd 2.10 中引入的 opaque-ports 应该解决早期 skip-ports 特性的大部分缺点,并允许 Linkerd 使用者在整个 Kubernetes 环境中扩展 mTLS,而不管协议是什么。

我是为少
微信:uuhells123
公众号:黑客下午茶
加我微信(互相学习交流),关注公众号(获取更多学习资料~)

Server-Speaks-First 有点坑,Linkerd 2.10 中的协议检测和不透明端口的更多相关文章

  1. windows 10中使用命令行关掉占用指定端口的程序

    通过netstat -ano与findstr命令结合查询到带有9080端口的监听信息,图中最后一列为监听程序的PID 通过tasklist命令与findstr命令结合查询到指定PID对应的应用程序 使 ...

  2. SQL SERVER 2012/2014 链接到 SQL SERVER 2000的各种坑

    本文总结一下SQL SERVER 2012/2014链接到SQL SERVER 2000的各种坑,都是在实际应用中遇到的疑难杂症.可能会有人说怎么还在用SQL SERVER 2000,为什么不升级呢? ...

  3. Linkerd 2.10(Step by Step)—使用 Kustomize 自定义 Linkerd 的配置

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  4. Linkerd 2.10(Step by Step)—多集群通信

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  5. Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  6. Linkerd 2.10(Step by Step)—使用 Debug Sidecar,注入调试容器来捕获网络数据包

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 部署 ...

  7. Linkerd 2.10(Step by Step)—3. 自动轮换控制平面 TLS &Webhook TLS 凭证

    Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ...

  8. 升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了Failed to locate Homebrew!

    升级10.11.6后CocoaPods的坑,之前10.11.4已经安装好的,居然没了,用命令 sudo gem install cocoapod 装不上,换 sudo gem install -n/u ...

  9. ubuntu下搭建node server的几个坑

    [ubuntu下搭建node server的几个坑] 1.环境变量 process.env.PORT需要使用 export PORT=80设置 windows下是set PORT=80 2.命令连结 ...

随机推荐

  1. Spring Boot Docker

    1.  IDEA中配置Docker Docker默认只接受本地客户端的请求,为了能够远程访问它,首先要开放Docker的监听端口,运行外部应用可以访问 修改 /lib/systemd/system/d ...

  2. idea debug无法启动 Error running 'Tomcat8': Unable to open debugger port (127.0.0.1:50168): java.net.SocketException "socket closed

    在日志里显示在 event log 里的 Error running 'server_web': Address localhost:1099 is already in use 显示1099单口已被 ...

  3. Python 类与对象 __init__()参数

    创建类Person 1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 pas ...

  4. 23 shell 进程替换

    0.shell进程替换的用法 1.使用进程替换的必要性 2.进程替换的本质 进程替换和命令替换非常相似.命令替换是把一个命令的输出结果赋值给另一个变量,例如dir_files=`ls -l`或date ...

  5. 解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题

    解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题 最近有个问题非常讨厌,我们的工程中使用自己的连接池连接mysql数据库,可mysql数据库每隔8小时就会自动断开所有链接, ...

  6. 深度解析HashMap底层实现架构

    摘要:分析Map接口的详细使用以及HashMap的底层是如何实现的? 本文分享自华为云社区<[图文并茂]深度解析HashMap高频面试及底层实现结构![奔跑吧!JAVA]>,原文作者:灰小 ...

  7. Lua控制语句

    目录 1. 控制结构 if-else 单个 if 分支 型 两个分支: if-else 型 多个分支: if-elseif-else型 2. while 型控制结构 3. repeat控制结构 4. ...

  8. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

  9. 使用.net Core 3.1 多线程读取数据库

    第一步:先创建一个DBhepler类,作为连接数据库中心,这个不过多说明,单纯作为数据库的连接........... 1 public static string Constr = "数据库 ...

  10. EditPlus运行java时如何从键盘输入数据

    在练习Java的Scanner时,EditPlus如何读取从键盘输入的数呢? 例如如下程序,编译通过,运行时却输入不了数据: 1 package myP101; 2 3 import java.uti ...