FAQ

在您搜索有关 Istio 和服务网格技术的信息时,我们希望此常见问题解答对您有所帮助

常见问题

Istio 是什么?

Istio 是一个开放的、与平台无关的服务网格,提供了流量管理,策略下发,和遥测收集能力。

开放:Istio 是作为一个开源软件来开发和管理的,我们鼓励社区各界来贡献和反馈。

平台无关:Istio 不是针对某一个特定的部署环境的。在初始开发阶段, Istio 将会支持基于 Kubernetes 部署。但是,Istio 将会建设成可以快速方便的适应其它环境。

服务网格:Istio 的设计目标是管理微服务间和应用程序间的通信问题, 而不用修改底层服务。Istio 针对所有服务之间的通信提供了自动的基线流量弹性、 服务指标收集、分布式追踪、流量加密、协议升级和高级路由功能。

更多介绍,请参阅 Istio 是什么

为什么我想用 Istio?

按照传统做法,Istio 处理的大多数逻辑都是直接构建到应用程序中的。 在一组服务中,要管理更新这块通信逻辑是一个繁重的任务。 Istio 提供了一个基础架构级的方案来解决管理服务通信问题。

应用开发者:利用 Istio 管理服务间的流量,开发者就可以专注于业务逻辑开发和快速迭代新特性。

服务运维者:Istio 可以从一个中心控制点进行策略控制和网格监控,而不依赖应用程序的发展。 因此,运维者可以通过简化的管理平面确保持续的策略控制。

我如何开始使用 Istio?

我们建议您按照入门上的说明进行操作, Istio 的主要示例应用程序 Bookinfo 应用示范了安装配置。 您可以使用此设置来浏览各种 Istio 指南, 该指南中的案例包括了智能路由、策略执行、安全、遥测等。

要在现有 Kubernetes 上部署和使用 Istio, 请参阅我们的安装说明文档。

Istio 的许可证是什么?

Istio 使用了 Apache License 2.0

Istio 是如何诞生的?

Istio 项目由 Google 和 IBM 的团队与 Lyft 的 Envoy 团队合作发起, 它已经完全在 GitHub 上公开开发。

目前支持哪些部署环境?

Istio 被设计和构建为平台无关的。对于 1.25 版本, Istio 支持运行容器编排的平台环境,比如 Kubernetes(1.28, 1.29, 1.30, 1.31)。

我该如何参与贡献?

非常欢迎任何贡献,我们期待社区的反馈,补充和错误报告。

代码托管在 GitHub 中, 请阅读贡献指南学习如何为社区做出贡献。

除了代码之外,还有其他为 Istio 社区做出贡献的方式, 包括我们的讨论论坛SlackStack Overflow

文档在哪里?

在 istio.io 查看文档。 文档包括概念概述任务指南指南、 和完整的参考文档

详细的开发人员级别文档保留在我们的 Wiki 中。

Istio 不工作了应该怎么做?

查看操作指南寻找解决方案或者通过错误报告页面提交错误信息。

Istio 的路线图是什么?

查看我们的功能状态页面新闻获取最新动态。

“Istio” 这个词是什么意思?

它是希腊语中的 “sail(帆)”。

如何加入 Istio Slack 工作区?

如果您想与我们社区的成员进行实时互动,可以加入 Istio Slack 工作区

安装

我应该使用哪种方式安装 Istio?

除了简单地入门评估版安装之外, 还有其它几种不同的方式安装 Istio,您应该根据您的生产要求来选择安装方式。 下面列出了每种安装方式的优缺点:

  1. 使用 istioctl 安装

    具有高安全性的简单、合格的安装和管理方法,这也是社区推荐的安装方法。

    优点:

    • 完整的配置和运行状态的验证。
    • 使用提供了扩展的配置、自定义选项的 IstioOperator API。

    缺点:

    • 需要维护多个 Istio 次要版本的二进制文件。
    • istioctl 命令可能根据您的运行环境自动设置相关值,从而能够在不同的 Kubernetes 环境中进行不同的安装。
  2. 使用 Helm 进行安装

    允许轻松与基于 Helm 的工作流程集成并在升级期间自动进行资源修剪。

    优点:

    • 使用行业标准工具的熟悉方法。
    • Helm 原生发布和升级管理。

    缺点:

    • istioctl install 相比,检查和验证更少。
    • 某些管理任务需要更多步骤并且复杂性更高。
  3. 应用生成的 Kubernetes 清单

    此方法适用于需要严格审核或扩充输出清单,或存在第三方工具限制的情况。

    优点:

    • 更容易与未使用 helmistioctl 的工具集成。
    • 除了 kubectl 之外,不需要其他安装工具。

    缺点:

    • 不执行上述任一方法支持的安装时检查、环境检测或验证。
    • 不支持安装管理或升级功能。
    • 用户体验不够精简。
    • 安装过程中的错误报告不够完善。

这些安装方式的安装向导在 Istio 安装页面中。

Kubernetes - 我该如何调试 Sidecar 自动注入的问题?

为了支持 Sidecar 自动注入,请确保你的集群符合此 前提条件。 如果您的微服务是部署在 kube-systemkube-public 或者 istio-system 这些命名空间,那么就会被免除 Sidecar 自动注入,请使用其他命名空间替代。

Ambient 模式

ztunnel 存在单点故障吗?

Istio 的 ztunnel 不会将单点故障(SPOF)引入 Kubernetes 集群。 ztunnel 的故障仅限于单个节点,该节点被视为集群中的易出错组件。 它的行为与每个集群上运行的其他节点关键基础设施(如 Linux 内核、容器运行时等)相同。 在设计合理的系统中,节点中断不会导致集群中断。了解更多

安全

在 Istio 安装完成之后,我应该如何开启/关闭双向 TLS?

您可以随时使用认证策略目标规则来为您的服务设置双向 TLS 认证。请参阅任务以获取更多细节。

在同一集群中,我可以为部分服务开启 TLS 双向认证,并为其它服务禁用 TLS 双向认证吗?

认证策略可以配置为 网格范围(影响网络中的所有服务)、命名空间范围(命名空间中的所有服务)或某个特定服务。 您可以根据需要对集群中的服务配置一种或多种 TLS 双向认证策略。

如何验证流量是否使用双向 TLS 加密?

如果您使用 values.global.proxy.privileged=true 参数安装 Istio, 您可以使用 tcpdump 来确定加密状态。同样在 Kubernetes 1.23 及以后的版本中, 作为将 Istio 安装为特权用户的另一种选择,您可以使用 kubectl debug临时容器(Ephemeral Container) 中运行 tcpdump。有关说明,请参见 Istio 双向 TLS 迁移

如果全局启用 TLS 双向认证,那么非 Istio 服务还可以访问 Istio 服务吗?

启用 STRICT 双向 TLS 时,非 Istio 工作负载无法与 Istio 服务通信, 因为它们没有有效的 Istio 客户端证书。

如果需要允许这些客户端,可以将双向 TLS 模式配置为 PERMISSIVE,允许明文和双向 TLS。 这可以针对单个工作负载或整个网格来完成。

有关更多详细信息,请参阅身份验证策略

启用双向 TLS 认证时应该如何使用 Kubernetes liveness 和 readiness 对服务进行健康检查?

如果启用了双向 TLS 认证,则来自 kubelet 的 HTTP 和 TCP 健康检查将不能正常工作,因为 kubelet 没有 Istio 颁发的证书。

有几种选择:

  1. 使用 probe rewrite 将 liveness 和 readiness 的请求直接重定向到工作负载。 有关更多信息,请参阅 Probe Rewrite

  2. 使用单独的端口进行健康检查,并且仅在常规服务端口上启用双向 TLS。 有关更多信息,请参阅 Istio 服务的运行状况检查

  3. 如果对 Istio 服务使用 PERMISSIVE 模式, 那么他们可以接受 HTTP 和双向 TLS 流量。请记住,由于其他人可以通过 HTTP 流量与该服务进行通信, 因此不强制执行双向 TLS。

如何配置 Istio 证书的生命周期?

对于在 Kubernetes 中运行的工作负载,其 Istio 证书的生命周期默认为 24 小时。

可以通过自定义代理配置proxyMetadata 字段来覆盖此配置。例如:

proxyMetadata:
  SECRET_TTL: 48h
Auto 双向 TLS 是否会排除使用 "excludeInboundPorts" 注释设置的端口?

不排除,当 traffic.sidecar.istio.io/excludeInboundPorts 用于服务器工作负载时, Istio 仍然默认配置客户端 Envoy 以发送双向 TLS 请求。要改变这一点,您需要配置一个目标规则, 将双向 TLS 模式设置为 DISABLE,用以让客户端发送纯文本到这些端口。

MySQL 连接故障排除

安装 Istio 后,您可能会发现 MySQL 无法连接。这是因为 MySQL 是服务器优先协议, 这会干扰 Istio 的协议检测。特别是,使用 PERMISSIVE mTLS 模式可能会导致问题。 您可能会看到诸如 ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0 这样的错误。

这可以通过使用 STRICTDISABLE 模式或配置所有客户端来发送 mTLS。 有关详细信息,请参阅服务器优先协议

Istio 是否支持授权?

支持。Istio 对网格中的 HTTP 服务和普通 TCP 服务提供授权特性支持, 了解更多

Istio 中如何配置 Ingress 使其仅处理 TLS 连接?

依照安全入口流量任务中的描述进行配置, 可以确保 Istio Ingress 只处理 TLS 连接。

我可以为 HTTPS 服务安装 Istio Sidecar 吗?

可以,并且启用或禁用双向 TLS 都可以。

指标和日志

可以通过 REST 接口访问 Istio 指标吗?

您可以使用 Prometheus 收集有关 Istio 的遥测数据。 然后,使用 Prometheus 的 HTTP API 来查询该数据。

代理内遥测(v2)和基于 Mixer 的遥测(v1)报告的遥测有什么区别?

与基于 Mixer 的遥测(v1)方法相比,代理内遥测(v2)降低了资源成本并提高了代理性能, 是 Istio 中呈现遥测的首选机制。 但是,v1 和 v2 之间报告的遥测数据区别不大,如下所列:

  • 网格外流量缺少标签

    代理内遥测依赖于 Envoy 代理之间的元数据交换来收集对​​等工作负载名称、命名空间和标签等信息。 在基于 Mixer 的遥测中,此功能由 Mixer 执行,作为将请求属性与平台数据组合的一部分。 此元数据交换由 Envoy 代理通过为 HTTP 协议添加特定 HTTP 标头或为 TCP 协议增加 ALPN 协议来执行, 如此处所述。 这需要在客户端和服务器工作负载中注入 Envoy 代理,这意味着当一个对等点不在网格中时报告的遥测数据将缺少如工作负载名称、命名空间和标签等对等点属性。 但是,如果两个对等点都注入了代理,则此处提到的所有标签都可以在生成的指标中使用。 当服务器工作负载脱离网格时,服务器工作负载元数据仍被分发到客户端边车,导致客户端指标填充了服务器工作负载元数据标签。

  • TCP 元数据交换需要 mTLS

    TCP 元数据交换依赖于 Istio ALPN 协议, 该协议需要启用双向 TLS (mTLS) 以便 Envoy 代理能够成功交换元数据。 这意味着如果您的集群中未启用 mTLS,则 TCP 协议的遥测将不包括工作负载名称、命名空间和标签等对等信息。

  • 没有为直方图指标配置自定义存储桶的机制

    基于 Mixer 的遥测支持为直方图类型指标(如请求持续时间和 TCP 字节大小)自定义存储桶。 代理内遥测没有这样的可用机制。此外,与基于 Mixer 的遥测中的秒数相比,代理内遥测中可用于延迟指标的存储桶以毫秒为单位。 但是,默认情况下,代理内遥测中有更多存储桶可用于较低延迟级别的延迟指标。

  • 短期指标没有指标过期

    基于 Mixer 的遥测支持指标过期,即在可配置的时间量内未生成的指标将被取消注册以供 Prometheus 采集。 这在生成短期指标的场景(例如一次性作业)中很有用。取消注册指标可防止报告将来不再更改的指标, 从而减少 Prometheus 中的网络流量和存储。这个过期机制在代理内遥测中不可用。 可以在此处找到解决此问题的方法。

如何管理短期指标?

短期指标可能会阻碍 Prometheus 的性能,因为它们通常是标签基数的重要来源。 基数是标签唯一值数量的度量。要管理短期指标对 Prometheus 的影响, 您必须首先确定高基数指标和标签。Prometheus 在其 /status 页面上提供基数信息。 可以通过 PromQL 检索其他信息。有几种方法可以减少 Istio 指标的基数:

  • 禁用主机报头回退。 destination_service 标签是高基数的一个潜在来源。 如果 Istio 代理无法从其他请求元数据中确定目标服务,则 destination_service 的值默认出现在主机报头中。 如果客户端使用各种主机报头,这可能会导致 destination_service 产生的大量值。 在这种情况下,请按照指标自定义指南禁用主机报头回退网格范围。 要禁用特定工作负载或命名空间的主机头回退,您需要复制统计 EnvoyFilter 配置,更新它以禁用主机报头回退,并应用一个更具体的选择器。 这个问题有更多关于如何实现这一点的细节。
  • 从集合中删除不必要的标签。如果不需要具有高基数的标签,您可以使用 tags_to_remove 通过指标自定义将其从指标集合中删除。
  • 通过联合或分类规范化标签值。如果需要标签提供的信息, 您可以使用 Prometheus 联邦请求分类来规范化标签。

如何迁移现有的 Mixer 功能?

Mixer 在 Istio 1.8 版本中被移除。 如果您仍然依赖于 Mixer 的内置适配器或任何进程外的适配器进行网格扩展,则需要迁移。

对于内置适配器,提供了几种替代方案:

对于自定义进程外适配器,强烈建议迁移到基于 Wasm 的扩展。请参阅有关 Wasm 模块开发扩展分发的指南。 作为临时解决方案,您可以在 Mixer 中启用 Envoy ext-authz 和 gRPC 访问日志 API 支持, 这允许您将 Istio 升级到发布 1.7 版本,同时仍然使用 1.7 Mixer 的进程外适配器。 这将使您有更多时间迁移到基于 Wasm 的扩展。请注意,此临时解决方案未经实战测试, 不太可能得到补丁修复,因为它只在 Istio 1.7 分支上可用,这是在 2021 年 2 月 之后的支持窗口之外的。

Prometheus 适配器能在非 Kubernetes 环境下使用吗?

您可以使用 docker-compose 来安装 Prometheus。

怎样查看 Istio 的请求都发生了什么?

您可以启用链路追踪 以确定 Istio 中的请求是怎样流动的。

另外,您还可以使用如下命令以了解网格中的更多状态信息:

  • istioctl proxy-config: 获取 Kubernetes 运行期间的代理配置信息:

    # 在指定的 Pod 中 Envoy 实例的启动(bootstrap)配置信息。
    $ istioctl proxy-config bootstrap productpage-v1-bb8d5cbc7-k7qbm
    

    在指定的 Pod 中 Envoy 实例的集群(cluster)配置信息。

    $ istioctl proxy-config cluster productpage-v1-bb8d5cbc7-k7qbm

    在指定的 Pod 中 Envoy 实例的监听器(listener)配置信息。

    $ istioctl proxy-config listener productpage-v1-bb8d5cbc7-k7qbm

    在指定的 Pod 中 Envoy 实例的路由(route)配置信息。

    $ istioctl proxy-config route productpage-v1-bb8d5cbc7-k7qbm

    在指定的 Pod 中 Envoy 实例的端点(endpoint)配置信息。

    $ istioctl proxy-config endpoints productpage-v1-bb8d5cbc7-k7qbm

    查看更多 proxy-config 的用法可用如下命令

    $ istioctl proxy-config –help

  • kubectl get:通过路由配置获取网格中不同资源的信息:

    # 列出所有的 VirtualService
    $ kubectl get virtualservices
我可以使用 Prometheus 配合 Istio 抓取应用程序指标吗?

是的。Prometheus 是一款开源监控系统和时间序列数据库。 您可以将 Prometheus 与 Istio 结合使用来记录跟踪 Istio 和服务网格内应用程序运行状况的指标。 您可以使用 GrafanaKiali 等工具对指标进行可视化。 请参阅 Prometheus 配置以了解如何启用指标收集。

一些注意事项:

  • 如果 Prometheus Pod 在 istiod Pod 生成所需证书并将其分发给 Prometheus 之前启动, 则 Prometheus pod 需要重启以便收集双向 TLS 保护的目标信息。
  • 如果您的应用程序在专用端口上公开了 Prometheus 指标,则应将该端口添加到 Service 和 Deployment 规范中。

分布式追踪

如何使用 Istio 实现分布式追踪?

Istio 使用 Envoy的分布式追踪系统集成。 由应用程序负责为后续传出请求转发追踪的 header 信息

您可以在分布式链路追踪概述Envoy 链路追踪文档中找到更多信息。

使用 Istio 进行分布式追踪需要什么?

Istio 允许报告服务网格中工作负载到工作负载间通信的追踪 Span。 然而,为了将各种追踪 Span 整合在一起以获得完整的流量图,应用程序必须在传入和传出请求之间传播追踪上下文信息。

具体来说,Istio 依靠应用程序来转发 Envoy 生成的请求 ID 和标准标头。这些标头包括:

  • x-request-id
  • traceparent
  • tracestate

Zipkin 用户必须确保他们传播 B3 链路追踪标头

  • x-b3-traceid
  • x-b3-spanId
  • x-b3-parentspanid
  • x-b3-sampled
  • x-b3-flags
  • b3

标头传播可通过客户端库完成,例如 OpenTelemetry。 它也可手动完成,如分布式链路追踪任务中所述。

基于 Envoy 的跟踪如何工作?

对于基于 Envoy 的跟踪集成,Envoy(Sidecar 代理)代表所代理的应用程序将跟踪信息直接发送到跟踪后端。

Envoy:

  • 在请求代理时为请求生成请求 ID 和跟踪标头(例如 X-B3-TraceId
  • 根据请求和响应元数据(即响应时间)为每个请求生成跟踪范围
  • 将生成的跟踪范围发送到跟踪后端
  • 将跟踪头转发到代理的应用程序

Istio 支持 OpenTelemetry 和兼容的后端,包括 Jaeger。 其他支持的平台包括 ZipkinApache SkyWalking

什么生成了初始链路头?

如果请求中未提供初始标头, 则 Istio 网关或 Sidecar 代理 (Envoy) 会生成初始标头

为什么 Istio 不能代替应用程序传播标头?

尽管 Istio Sidecar 将处理关联应用程序实例的入站和出站请求, 它没有将出站请求与导致它们的入站请求相关联的隐式方法。可以实现这种关联的唯一方法是通过应用程序传播相关信息 (例如标头)从入站请求到出站请求。头传播可以通过客户端库或手动完成。 提供了进一步的讨论使用 Istio 进行分布式跟踪需要什么?

为什么我的请求没有被追踪?

default 配置文件中, 链路追踪的采样率被设置为 1%。这意味着 Istio 捕获的 100 个链路实例中只有 1 个会报告给跟踪后端。 demo 配置文件中的采样率设置为 100%。有关如何设置采样率的信息, 请参阅本节

如果您仍然没有看到任何追踪数据,请确认您的端口是否符合 Istio 端口命名规范, 并公开适当的容器端口(例如,通过 pod spec)来启用 sidecar 代理(Envoy)能够对流量进行捕获。

如果您只看到与出口代理相关的链路数据,而没有看到入口代理, 则可能仍与 Istio 端口命名约定有关。

如何控制追踪数量?

Istio 通过 Envoy,目前支持基于百分比的采样策略来生成追踪信息。 有关如何设置此采样率的更多信息,请参阅本节

Istio 支持请求跟踪 vert.x 事件总线消息吗?

目前 Istio 不提供对发布/订阅和事件总线协议的支持。这些技术都遵循 best-effort 网络模型,网络传输容易遭到破坏。

流量管理

怎样查看在 Istio 中已配置的当前路由规则?

可以使用这个命令查看 kubectl get virtualservice -o yaml

Sidecar 代理在哪些端口上截获入站流量?

Istio 默认截获所有端口的入站流量, 您可以通过 traffic.sidecar.istio.io/includeInboundPorts 这个 Pod 注解指定一组端口来截获流量,或通过 traffic.sidecar.istio.io/excludeOutboundPorts 指定一组端口来放行流量,以更改这种默认行为。

MUTUAL 和 ISTIO_MUTUAL TLS 模式有什么区别?

两个 DestinationRule 设置都会发送双向的 TLS 流量。 使用 ISTIO_MUTUAL 时,将会自动使用 Istio 证书。 对于 MUTUAL,必须配置密钥、证书和可信任的 CA。 允许与非 non-Istio 应用启动双向的 TLS。

Istio 可以与 StatefulSet 和 Headless Service 一起使用吗?

是的,从 Istio 1.10, Istio 已完全支持这些工作负载。

为什么我的 CORS(跨源资源共享)配置不起作用?

当应用了 CORS(跨源资源共享)配置后, 您可能会发现看似什么也没发生,并想知道哪里出了问题。 CORS 是一个经常被误解的 HTTP 概念,在配置时经常会导致混淆。

要弄明白这个问题,有必要退后一步,看看 CORS 是什么, 以及何时应该使用它。默认情况下,浏览器对脚本发起的 “cross origin” 请求有限制。 例如,这可以防止网站 attack.example.combank.example.com 发出 JavaScript 请求, 从而窃取用户的敏感信息。

为了允许这个请求,bank.example.com 必须允许 attack.example.com 执行跨域请求, 这就是 CORS 的作用所在。如果我们想在一个启用了 Istio 的集群内提供 bank.example.com 服务,我们可以通过配置一个 corsPolicy 来允许这样做:

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: bank
spec:
  hosts:
  - bank.example.com
  http:
  - corsPolicy:
      allowOrigins:
      - exact: https://attack.example.com
...

在这种情况下,我们明确地允许一个单一的起源;通配符通常用于不敏感的页面。

一旦我们这样做了,一个常见的错误就是发送一个请求,比如 curl bank.example.com -H "Origin: https://attack.example.com", 然后期望这个请求被拒绝。 但是,curl 和许多其他客户端不会看到被拒绝的请求,因为 CORS 是一个浏览器约束。 CORS 配置只是在响应中添加 Access-Control-* 头;如果响应不令人满意, 则由客户端(浏览器)来拒绝请求。在浏览器中, 这是通过预检请求来完成的。

我可以不配置任何路由规则,使用 Ingress 的标准配置吗?

简单的 Ingress 规范开箱即用,通过 HostTLS 以及基本 Path 精确匹配就可以使用,无需配置路由规则。请注意 Path 在使用 Ingress 资源时不应该有任何 . 字符。

比如,下面 Ingress 的资源匹配 Hostexample.com 以及 URL/helloworld 的请求。

$ kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-ingress
  annotations:
    kubernetes.io/ingress.class: istio
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /helloworld
        pathType: Prefix
        backend:
          service:
            name: myservice
            port:
              number: 8000
EOF

然而,这下面的规则将不工作,因为它们在 Path 中使用了正则表达式,并且添加了 ingress.kubernetes.io 注解。

$ kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: this-will-not-work
  annotations:
    kubernetes.io/ingress.class: istio
    # 除入口类之外的其他入口注解将不被接受
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /hello(.*?)world/
        pathType: Prefix
        backend:
          service:
            name: myservice
            port:
              number: 8000
EOF

Istio 支持哪些协议?

目前,Istio 支持基于 TCP 的协议。此外,Istio 还为其他协议(如 httpmysql) 提供路由和指标等功能。

对于所有协议列表以及协议配置信息, 请查看文档协议选择