Istio 授权策略,您是否还在“启用”它? (ft. 只有我们不知道的真相) 😲

大家好!如果您是在MSA(微服务架构)环境中开发和运营服务的人,那么您一定曾被“安全”这座巨大的山所困扰。特别是当服务间的通信变得复杂交织时,您是否也曾有过“这个请求真的安全吗?🤨”或者“我们能否只让授权服务之间进行通信?”这样的担忧呢?

此时,许多人会想到服务网格的代表——Istio。因为Istio提供了强大的流量控制、可观测性以及“安全”功能。其中,允许或阻止特定服务之间通信的授权(Authorization)功能尤其吸引人。

然而,许多人在这里犯了一个关键的错误。那就是…

“如何‘启用’Istio的授权功能?”这个问题。

简单来说,根本不需要!🤯


💡 真相:Istio 授权不是一个需要“开启”的功能

许多人在安装Istio时,会尝试修改IstioOperator资源,或者寻找诸如values.pilot.authorization.enabled=true之类的安装选项。就好像要额外安装一个新功能一样。

然而,Istio的授权功能无需单独启用,它在Istio安装的那一刻就已经存在于我们身边了。它就在那里,只是因为我们没有调用它,所以一直保持沉默。

打个比方,我们家里已经安装了“门锁”。我们只需要决定给谁“钥匙”让他们开门,或者不给钥匙让他们无法进入。

  • Istio 授权功能:已安装的门锁 🚪
  • AuthorizationPolicy 资源:决定给谁钥匙的规则(策略)🔑

也就是说,授权功能本身就内置在Istio的核心组件Envoy代理中,并始终处于待命状态。当我们创建AuthorizationPolicy策略资源并将其应用到集群时,这个锁机制就会根据策略开始运作。


🧐 那么它实际上是如何工作的呢?(全面了解整个过程)

了解单个策略固然重要,但理解整体流程会更容易。

  1. Istio 安装和 Sidecar 注入 🚀
  • 在 Kubernetes 集群中安装 Istio。
  • 将 Istio 的 Envoy 代理(Sidecar)注入到我们想要保护的服务(Pod)中。现在,所有流量都将通过这个代理。
  1. 策略未应用状态(默认:全部允许) ✅
  • 如果没有创建任何 AuthorizationPolicy,Istio 将允许网格内部的所有流量(ALLOW)。它有安全功能,但没有规则,所以会放行所有通信。
  1. AuthorizationPolicy 创建和应用 📝
  • 我们用 YAML 文件编写诸如“服务 A 只允许向服务 B 发送 GET 请求”之类的规则。这就是 AuthorizationPolicy。
  • 使用 kubectl apply 命令将此策略应用到集群。
  1. Istiod 的作用(策略传播) 📡
  • 控制平面 Istiod 会检测到此 AuthorizationPolicy 的创建。
  • Istiod 会解析此策略,并将新规则传播给受该策略影响的 Envoy 代理。
  1. Envoy 代理的作用(策略强制执行) 👮
  • 收到策略后,Envoy 代理会从那时起检查所有进出流量。
  • 与策略中明确规定的规则匹配的流量将被允许(ALLOW),不匹配的流量将被拒绝(DENY)。

理解这个流程后,我们就会知道,我们所要做的仅仅是“很好地创建并应用所需的规则”。


🛠️ 通过实际示例理解:保护 reviews 服务

光说不练假把式,对吧?让我们通过实际代码来创建一个策略,以控制进入 reviews 服务的请求。

场景: 只允许 product-api 服务向 reviews:v1 服务的 /reviews/{id} 路径发送 GET 请求。除此之外的所有请求都将被阻止。

1. 定义 AuthorizationPolicy (allow-product-to-reviews.yaml)

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-product-to-reviews
  namespace: default
spec:
  # 选择要应用此策略的工作负载。
  # 适用于带有 app: reviews, version: v1 标签的 Pod。
  selector:
    matchLabels:
      app: reviews
      version: v1
  # 此策略的默认操作是“ALLOW”。
  # 这意味着将允许符合以下“rules”的请求。
  action: ALLOW
  # 定义要允许的请求的详细规则。
  rules:
  - from:
    # 允许来自哪个“源”的请求?
    - source:
        # 指定发送请求的工作负载的服务帐户。
        # 这是最安全和推荐的方法。
        principals: ["cluster.local/ns/default/sa/product-api"]
    to:
    # 允许发往哪个“目标”的请求?
    - operation:
        # 指定允许的 HTTP 方法。
        methods: ["GET"]
        # 指定允许的路径。
        paths: ["/reviews/*"]

2. 应用策略

在终端中执行以下命令,将策略应用到集群。

kubectl apply -f allow-product-to-reviews.yaml

3. 结果确认

现在会发生什么呢?

  • 允许的请求 👍
  • 由 product-api 服务帐户运行的 Pod 向 reviews:v1 Pod 的 /reviews/123 发送的 GET 请求
  • 拒绝的请求 👎
  • product-api 向 reviews:v1 发送的 POST 请求(方法不同,因此被拒绝)
  • unknown-service 向 reviews:v1 发送的 GET 请求(服务帐户不同,因此被拒绝)
  • product-api 向 reviews:v2 发送的 GET 请求(策略的 selector 中指定了 version: v1,因此策略不适用于 v2。如果没有其他 DENY 策略,此请求默认将被允许)

⚠️ 重要:只要应用了一个 action: ALLOW 策略,那么与该 selector 匹配的工作负载将默认进入“隐式 DENY”状态。也就是说,所有未在 ALLOW 规则中明确列出的请求都将自动被拒绝。这是 Istio 强大零信任安全模型的开端。


😫 常见误解,为什么是错的?

  • “需要通过 IstioOperator 或 Helm 值来启用授权功能。”
  • 为什么不对? 如上所述,授权功能是 Envoy 代理的核心功能,是不可分割的一部分。它是一个内置功能,不需要单独的安装或激活过程。控制平面(Istiod)只是将我们创建的策略传递给代理。
  • “安装了 Istio,我的服务就安全了。”
  • 为什么不对? 仅仅安装 Istio 意味着您具备了“应用安全的能力”,而不是“安全已应用的状态”。在应用 AuthorizationPolicy 之前,所有流量都是允许的,因此您必须通过明确的策略来直接设置所需的安全级别。

✨ 结论:改变思维方式,Istio 安全变得更简单

Istio 授权策略不是“启用”它,而是“应用并执行策略”。

只要记住这个简单的道理,处理 Istio 安全的方式就会变得清晰得多。您不再需要寻找不存在的配置值,现在就可以定义并应用您的服务所需的访问规则(AuthorizationPolicy)。一个虽小但功能强大的 YAML 文件将使您的 MSA 环境更加安全。



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注