应用需求

Istio 为应用程序提供了大量功能,而对应用程序代码本身的影响微乎其微。许多 Kubernetes 应用程序可以在启用了 Istio 的集群中部署,而无需进行任何更改。但是,Istio 的 sidecar 模型会带来一些影响,在部署启用了 Istio 的应用程序时可能需要特别考虑。本文档介绍了这些应用程序注意事项以及启用 Istio 的具体要求。

Pod 需求

要成为网格的一部分,Kubernetes Pod 必须满足以下要求

  • 应用程序 UID:确保您的 Pod **不**以用户 ID (UID) 值为 1337 的用户运行应用程序,因为 1337 保留给 sidecar 代理。

  • NET_ADMINNET_RAW 功能:如果您的集群中 Pod 安全策略 已强制执行,并且除非您使用 Istio CNI 插件,否则您的 Pod 必须允许 NET_ADMINNET_RAW 功能。Envoy 代理的初始化容器需要这些功能。

    要检查您的 Pod 是否允许使用 NET_ADMINNET_RAW 权限,您需要检查其 服务账户 是否可以使用允许 NET_ADMINNET_RAW 权限的 Pod 安全策略。如果您没有在 Pod 的部署中指定服务账户,则 Pod 将使用其部署命名空间中的 default 服务账户运行。

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

    $ 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 服务账户,请运行以下命令:

    $ 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 初始化容器的权限。否则,您需要 授予权限

  • Pod 标签:我们建议使用 Pod 标签显式声明具有应用程序标识符和版本的 Pod。这些标签为 Istio 收集的指标和遥测添加了上下文信息。这些值中的每一个都从多个标签中读取,按优先级从高到低排序。

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

Istio 使用的端口

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

端口协议描述仅 Pod 内部
15000TCPEnvoy 管理端口(命令/诊断)
15001TCPEnvoy 出站
15004HTTP调试端口
15006TCPEnvoy 入站
15008HTTP2HBONE 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 的流量的路由方式可能与未部署侧车时的路由方式不同。

对于基于 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>)而不是服务的直接调用将不匹配。虽然流量可能会 通过,但它不会获得完整的 Istio 功能,包括 mTLS 加密、流量路由和遥测。

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

这些信息是否有用?
您是否有任何改进建议?

感谢您的反馈!