TCP 代理和协议检测
Linkerd
能够代理所有 TCP
流量,包括 TLS
连接、WebSockets
和 HTTP
隧道。
大多数情况下,Linkerd
无需配置即可完成此操作。为此,Linkerd
执行 protocol detection(协议检测) 以确定流量是 HTTP
还是 HTTP/2
(包括 gRPC
)。如果 Linkerd
检测到连接是 HTTP
或 HTTP/2
,Linkerd
将自动提供 HTTP
级别的指标
和路由
。
如果 Linkerd
不能确定连接是使用 HTTP
还是 HTTP/2
,Linkerd
会将连接代理为普通 TCP
连接,应用 mTLS 并像往常一样提供字节级指标
。
(请注意,传入或来自mesh pod
的 HTTPS
调用被视为 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
可以提供 mTLS
、TCP
级别的指标等),但只能用于集群内部的服务。
默认情况下,Linkerd
会自动将某些 server-speaks-first
协议的端口标记为 opaque
。通过默认端口将这些协议传递给集群内部目的地的服务不需要进一步配置。Linkerd
在 2.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 | 端口 4567 和 4568 不在 Linkerd 的默认 opaque 端口集中 |
PostgreSQL | 5432 | |
Redis | 6379 | |
ElasticSearch | 9300 | |
Memcache | 11211 |
如果您正在使用这些协议之一,请按照此决策树来确定您需要应用哪种配置。
将端口标记为 opaque
您可以使用 config.linkerd.io/opaque-ports
annotation 将端口标记为 opaque
。这指示 Linkerd
跳过该端口的协议检测。
可以在 workload
、service
或 namespace
上设置此 annotation。在 workload
上设置它会告诉该 workload
的 mesh
客户端跳过与 workload
建立的连接的协议检测,并告诉 Linkerd
在反向代理传入连接时跳过协议检测。在 service
上设置它会告诉 mesh
客户端在代理连接到 service
时跳过协议检测。
在 namespace
上设置它会将此行为应用于该 namespace
中的所有 service
和 workload
。
由于此
annotation
通知meshed _clients_
的行为,因此它可以应用于unmeshed services
和meshed 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
annotation的 Service resource
。
在这种情况下,您可以在运行 linkerd inject
时使用 --skip-outbound-ports
标志来配置 resource
以在发送到这些端口时完全绕过代理。(类似地,--skip-inbound-ports
标志将配置 resource
以绕过代理以连接到这些端口的传入连接。)
对于这些情况以及诊断问题,跳过代理可能很有用,但除此之外几乎没有必要。
与 opaque
端口一样,可以以逗号分隔的字符串形式提供多个 skip
端口。