应用程序要求

Istio 为应用程序提供了大量的功能,而对应用程序代码本身几乎没有影响。 许多 Kubernetes 应用程序可以部署在启用 Istio 的集群中,而不需要对应用程序做任何修改。 然而,在部署启用 Istio 的应用程序时,需要特别注意 Istio Sidecar 模型造成的影响。 本文介绍了针对这些应用程序的注意事项以及启用 Istio 的具体要求。

Pod 要求

作为 Istio 服务网格中的一部分,Kubernetes 集群中的 Pod 和 Service 必须满足以下要求:

  • 应用 UID:确保您的 Pod 不会被 ID(UID)为 1337 的用户运行应用,因为 1337 是为 Sidecar 代理保留的。

  • NET_ADMINNET_RAW 能力:除非使用 Istio CNI 插件, 否则 istio-init 容器需要 NET_ADMINNET_RAW 权限来配置 iptables 流量重定向。 该命名空间必须使用 privileged 级别的 Pod 安全准入(Pod Security Admission)策略; baselinerestricted 级别都会禁止这些权限,从而导致 istio-init 容器无法运行。

    要检查命名空间上的 pod-security.kubernetes.io/enforce 标签:

    $ kubectl get namespace <your namespace> --show-labels
    NAME       STATUS   AGE   LABELS
    myapp      Active   3d    pod-security.kubernetes.io/enforce=privileged,...

    要将命名空间设置为 privileged 强制:

    $ kubectl label namespace <your namespace> pod-security.kubernetes.io/enforce=privileged --overwrite

    如果您的安全策略不允许在命名空间上执行 privileged, 请改用 Istio CNI 插件, 它可以处理流量重定向,而无需在 Pod 中提升功能。

  • Pod 标签(label):我们建议使用 Pod 标签显式声明带有应用程序标识符和版本的 Pod。 这些标签将上下文信息添加到 Istio 收集的指标和遥测数据中。 每个值都是从多个标签中读取的,按优先级从最高到最低的顺序排列:

    • 应用程序名称:service.istio.io/canonical-nameapp.kubernetes.io/nameapp
    • 应用程序版本:service.istio.io/canonical-revisionapp.kubernetes.io/versionversion
  • 已命名 Service 端口:可以选择已命名 Service 端口用于显式指定协议。 更多详细信息请参见协议选择。 如果一个 Pod 属于多个 Kubernetes Service, 这些 Service 不能对不同的协议(例如 HTTP 和 TCP)使用相同的端口号。

Istio 使用的端口

Istio Sidecar 代理(Envoy)使用以下端口和协议。

端口协议描述仅限 Pod 内部
15000TCPEnvoy 管理端口(命令/诊断)
15001TCPEnvoy 出站
15002TCP故障检测侦听端口
15004HTTP调试端口
15006TCPEnvoy 入站
15008H2HBONE mTLS 隧道端口
15020HTTP从 Istio 代理、Envoy 和应用程序合并的 Prometheus 遥测
15021HTTP健康检查
15053DNSDNS 端口,如果启用了捕获
15090HTTPEnvoy Prometheus 遥测

Istio 控制平面(istiod)使用以下端口和协议。

端口协议描述仅限本地主机
443HTTPSWebhook 服务端口
8080HTTP调试接口(已弃用,仅限容器端口)
15010GRPCXDS 和 CA 服务(纯文本,仅用于安全网络)
15012GRPCXDS 和 CA 服务(TLS 和 mTLS,推荐用于生产)
15014HTTP控制平面监控
15017HTTPSWebhook 容器端口,从 443 转发

服务器优先协议

一些协议是 “服务器优先” 协议,这意味着服务器将发送第一个字节。这可能会对 PERMISSIVE mTLS 和自动协议选择产生影响。

这两个功能都通过检查连接的初始字节来确定协议,这与服务器优先协议不兼容。

为了支持这些情况, 请按照显式协议选择步骤将应用程序的协议声明为 TCP

已知以下端口通常承载服务器优先协议,并自动假定为 TCP

协议端口
SMTP25
DNS53
MySQL3306
MongoDB27017

因为 TLS 通信不是服务器优先的,所以 TLS 加密的服务器优先流量将与自动协议检测一起使用,只要您确保所有经过 TLS 嗅探的流量都已加密:

  1. 将服务器的 mTLS 模式设置为 STRICT。这将对所有请求强制执行 TLS 加密。
  2. 将服务器的 mTLS 模式设置为 DISABLE。这将禁用 TLS 嗅探,允许使用服务器优先协议。
  3. 配置所有客户端发送 TLS 流量,通常通过 DestinationRule 或依赖自动 mTLS。
  4. 将您的应用程序配置为直接发送 TLS 流量。

出站流量

为了支持 Istio 的流量路由功能,离开 Pod 的流量可能与未部署 Sidecar 时的流量不同。

对基于 HTTP 的流量,流量根据 Host 标头进行路由。如果目标 IP 和 Host 标头未对齐,这可能会导致意外行为。例如,curl 1.2.3.4 -H "Host: httpbin.default" 请求将被路由到 httpbin 服务,而不是 1.2.3.4

对不基于 HTTP 的流量(包括 HTTPS),Istio 无法访问 Host 标头, 因此路由决策基于服务 IP 地址。

这意味着直接调用 Pod(例如,curl <POD_IP>),而不匹配 Service。 虽然流量可以通过, 但它不会获得 mTLS 加密、流量路由和遥测等完整的 Istio 功能。

相关的更多信息,请参阅流量路由页面。

这些信息有用吗?
您是否有更多建议和改进意见?

感谢您的反馈!