应用程序要求

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

Pod 要求

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

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

  • NET_ADMINNET_RAW 权限:如果您的集群强制执行Pod 安全策略, 必须给 Pod 配置 NET_ADMINNET_RAW 权限。如果您使用 Istio CNI 插件,可以不配置。

    要检查您的 Pod 是否有 NET_ADMINNET_RAW 权限,您需要检查这些 Pod 的服务账户是否有 NET_ADMINNET_RAW 权限的 Pod 安全策略。如果您没有在 Pod 部署中指定服务账户, Pod 会使用其命名空间中的默认服务账户运行。

    要列出服务账户的权限,请在下面的命令中用您的值替换 <your namespace><your service account>

    1. $ for psp in $(kubectl get psp -o jsonpath="{range .items[*]}{@.metadata.name}{'\n'}{end}"); do if [ $(kubectl auth can-i use psp/$psp --as=system:serviceaccount:<your namespace>:<your service account>) = yes ]; then kubectl get psp/$psp --no-headers -o=custom-columns=NAME:.metadata.name,CAPS:.spec.allowedCapabilities; fi; done

    例如,要检查 default 命名空间中的 default 服务账户,运行以下命令:

    1. $ for psp in $(kubectl get psp -o jsonpath="{range .items[*]}{@.metadata.name}{'\n'}{end}"); do if [ $(kubectl auth can-i use psp/$psp --as=system:serviceaccount:default:default) = yes ]; then kubectl get psp/$psp --no-headers -o=custom-columns=NAME:.metadata.name,CAPS:.spec.allowedCapabilities; fi; done

    如果您在服务账户的允许策略的功能列表中看到 NET_ADMINNET_RAW*, 则您的 Pod 有权限运行 Istio Init 容器。否则, 您将需要提供权限

  • 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)使用以下端口和协议。

为避免与 Sidecar 发生端口冲突,应用程序不应使用 Envoy 所使用的任何端口。

端口协议描述仅限 Pod 内部
15000TCPEnvoy 管理端口(命令/诊断)
15001TCPEnvoy 出站
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 功能。

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