TCP 代理和协议检测

TCP 代理和协议检测

Linkerd 能够代理所有 TCP 流量,包括 TLS 连接、WebSocketsHTTP 隧道。

大多数情况下,Linkerd 无需配置即可完成此操作。为此,Linkerd 执行 protocol detection(协议检测) 以确定流量是 HTTP 还是 HTTP/2(包括 gRPC)。如果 Linkerd 检测到连接是 HTTPHTTP/2Linkerd 将自动提供 HTTP 级别的指标路由

如果 Linkerd 不能确定连接是使用 HTTP 还是 HTTP/2Linkerd 会将连接代理为普通 TCP 连接,应用 mTLS 并像往常一样提供字节级指标

(请注意,传入或来自mesh podHTTPS 调用被视为 TCP,而不是 HTTP。由于客户端启动 TLS 连接,Linkerd 无法解密连接以观察 HTTP 事务。)

配置协议检测

如果您在建立连接时遇到 10 秒的延迟,您可能会遇到协议检测超时。本节将帮助您了解如何解决此问题。

在某些情况下,Linkerd协议检测会超时,因为它看不到来自客户端的任何字节。当使用服务器先发送数据的“服务器优先(server-speaks-first)”协议(例如 SMTP)或主动建立连接而不发送数据的协议(例如 Memcache)时,通常会遇到这种情况。在这种情况下,连接将在 10 秒的协议检测延迟后作为 TCP 连接进行。

为了避免这种延迟,您需要为 Linkerd 提供一些配置。配置协议检测有两种基本机制:_不透明端口(opaque ports)和_跳过端口(skip ports_)。将端口标记为 opaque 会指示 Linkerd 跳过协议检测并立即将连接代理为 TCP 流;将端口标记为 skip port 会完全绕过代理。不透明端口通常是首选(因为 Linkerd 可以提供 mTLSTCP 级别的指标等),但只能用于集群内部的服务。

默认情况下,Linkerd 会自动将某些 server-speaks-first 协议的端口标记为 opaque。通过默认端口将这些协议传递给集群内部目的地的服务不需要进一步配置。Linkerd2.11 版本中默认的不透明端口列表是 25(SMTP)587(SMTP)3306(MySQL)4444(Galera)5432(Postgres)6379(Redis)9300(ElasticSearch)11211(Memcache)。请注意,这可能会在未来版本中发生变化。

下表包含可能需要配置的常见协议。

协议 默认端口 注意
SMTP 25, 587
MySQL 3306
MySQL with Galera 3306, 4444, 4567, 4568 端口 45674568 不在 Linkerd 的默认 opaque 端口集中
PostgreSQL 5432
Redis 6379
ElasticSearch 9300
Memcache 11211

如果您正在使用这些协议之一,请按照此决策树来确定您需要应用哪种配置。

Decision tree

将端口标记为 opaque

您可以使用 config.linkerd.io/opaque-ports annotation 将端口标记为 opaque。这指示 Linkerd 跳过该端口的协议检测

可以在 workloadservicenamespace 上设置此 annotation。在 workload 上设置它会告诉该 workloadmesh 客户端跳过与 workload 建立的连接的协议检测,并告诉 Linkerd反向代理传入连接时跳过协议检测。在 service 上设置它会告诉 mesh 客户端在代理连接到 service 时跳过协议检测
namespace 上设置它会将此行为应用于该 namespace 中的所有 serviceworkload

由于此 annotation 通知 meshed _clients_ 的行为,因此它可以应用于 unmeshed servicesmeshed services

设置 opaque-ports annotation 可以通过在运行 linkerd inject 时使用 --opaque-ports 标志来完成。例如,对于运行在集群上的 MySQL 数据库使用非标准端口 4406,您可以使用以下命令:

linkerd inject mysql-deployment.yml --opaque-ports=4406 \
  | kubectl apply -f -
 linkerd inject mysql-service.yml --opaque-ports=4406 \
  | kubectl apply -f -

可以以逗号分隔的字符串形式提供多个端口。您提供的值将替换而不是增加 opaque 端口的默认列表。

将端口标记为 skip

有时需要完全绕过代理。例如,当连接到集群外的 server-speaks-first 目的地时,没有可以设置 config.linkerd.io/opaque-ports annotationService resource

在这种情况下,您可以在运行 linkerd inject 时使用 --skip-outbound-ports 标志来配置 resource 以在发送到这些端口时完全绕过代理。(类似地,--skip-inbound-ports 标志将配置 resource 以绕过代理以连接到这些端口的传入连接。)

对于这些情况以及诊断问题,跳过代理可能很有用,但除此之外几乎没有必要。

opaque 端口一样,可以以逗号分隔的字符串形式提供多个 skip 端口。