将 Istio 1.4 Alpha 之前的安全策略迁移到当前 API

本教程旨在帮助客户将已弃用的 v1alpha1 安全策略迁移到受支持的 v1beta1 版本。

2021年3月3日 | 作者:朱阳敏 - Google,Craig Box - Google

在 Istio 1.4 之前的版本中,安全策略是使用 v1alpha1 API(MeshPolicyPolicyClusterRbacConfigServiceRoleServiceRoleBinding)配置的。在咨询了我们的早期用户后,我们对策略系统进行了重大改进,并在 Istio 1.4 之后发布了 v1beta1 API。这些更新后的 API(PeerAuthenticationRequestAuthenticationAuthorizationPolicy)帮助我们标准化了在 Istio 中定义策略目标的方式,帮助用户了解策略的应用位置,并减少了所需的配置对象数量。

旧的 API 在 Istio 1.4 中已弃用。在引入 v1beta1 API 两个版本之后,Istio 1.6 移除了对 v1alpha1 API 的支持。

如果您使用的是 Istio 1.6 之前的版本,并且想要升级,则必须将您的 alpha 安全策略对象迁移到 beta API。本教程将帮助您完成此迁移。

概述

您的控制平面必须首先升级到支持 v1beta1 安全策略的版本。

建议首先升级到 Istio 1.5 作为过渡版本,因为它是唯一支持 v1alpha1v1beta1 安全策略的版本。您将在 Istio 1.5 中完成安全策略迁移,移除 v1alpha1 安全策略,然后继续升级到更高版本的 Istio。对于给定的工作负载,v1beta1 版本将优先于 v1alpha1 版本。

或者,如果您想从 Istio 1.4 直接跳级升级到 1.6 或更高版本,则应使用金丝雀升级方法安装新版本的 Istio 作为单独的控制平面,并逐渐将您的工作负载迁移到新的控制平面,同时完成安全策略迁移。

无论哪种情况,都建议使用命名空间粒度进行迁移:对于每个命名空间,查找所有对命名空间中的工作负载有影响的 v1alpha1 策略,并同时将所有策略迁移到 v1beta1。这可以实现更安全的迁移,因为您可以确保一切按预期工作,然后继续迁移下一个命名空间。

主要差异

在开始迁移之前,请通读 v1beta1身份验证授权文档,以了解 v1beta1 策略。

您应该检查所有现有的 v1alpha1 安全策略,找出使用了哪些字段以及哪些策略需要迁移,将发现的结果与下面列出的主要差异进行比较,并确认没有阻止问题(例如,使用在 beta 版本中不再支持的 alpha 功能)

主要差异v1alpha1v1beta1
API 稳定性不向后兼容向后兼容
mTLSMeshPolicyPolicyPeerAuthentication
JWTMeshPolicyPolicyRequestAuthentication
授权ClusterRbacConfigServiceRoleServiceRoleBindingAuthorizationPolicy
策略目标基于服务名称基于工作负载选择器
端口号服务端口工作负载端口

尽管 v1beta1 安全策略中的 RequestAuthenticationv1alpha1 JWT 策略类似,但存在明显的语义更改。v1alpha1 JWT 策略需要迁移到两个 v1beta1 资源:RequestAuthenticationAuthorizationPolicy。这将由于使用 AuthorizationPolicy 而更改 JWT 拒绝消息。在 alpha 版本中,HTTP 代码 401 与主体 Origin authentication failed 一起返回。在 beta 版本中,HTTP 代码 403 与主体 RBAC: access denied 一起返回。

v1alpha1 JWT 策略的triggerRule 字段AuthorizationPolicy 替换,唯一的例外是regex 字段不再受支持。

迁移流程

本节详细介绍如何迁移 v1alpha1 安全策略。

对于每个命名空间,查找所有对命名空间中的工作负载有影响的 v1alpha1 安全策略。结果可能包括

步骤 2:将服务名称转换为工作负载选择器

v1alpha1 策略使用其服务名称选择目标。您应该参考相应的服务定义来确定应在 v1beta1 策略中使用的工作负载选择器。

单个 v1alpha1 策略可能包含多个服务。它需要迁移到多个 v1beta1 策略,因为 v1beta1 策略当前每个策略最多只支持一个工作负载选择器。

另请注意,v1alpha1 策略使用服务端口,但 v1beta1 策略使用工作负载端口。这意味着迁移后的 v1beta1 策略中的端口号可能不同。

步骤 3:迁移身份验证策略

对于每个 v1alpha1 身份验证策略,请使用以下规则进行迁移

  1. 如果整个命名空间启用了 mTLS 或 JWT,请为整个命名空间创建不带工作负载选择器的 PeerAuthenticationRequestAuthenticationAuthorizationPolicy。根据命名空间对应 MeshPolicyPolicy 的语义填写策略。

  2. 如果工作负载启用了 mTLS 或 JWT,请为工作负载创建带相应工作负载选择器的 PeerAuthenticationRequestAuthenticationAuthorizationPolicy。根据工作负载对应 MeshPolicyPolicy 的语义填写策略。

  3. 对于与 mTLS 相关的配置,如果 alpha 策略使用 STRICT,则使用 STRICT 模式,否则在所有其他情况下使用 PERMISSIVE

  4. 对于与 JWT 相关的配置,请参阅最终用户身份验证文档,了解如何迁移到 RequestAuthenticationAuthorizationPolicy

提供了一个安全策略迁移工具来自动迁移身份验证策略。请参阅该工具的自述文件以了解其用法。

步骤 4:迁移 RBAC 策略

对于每个 v1alpha1 RBAC 策略,请使用以下规则进行迁移

  1. 如果整个命名空间启用了 RBAC,请为整个命名空间创建一个不带工作负载选择器的 AuthorizationPolicy。添加一个空规则,以便默认情况下拒绝对命名空间的所有请求。

  2. 如果工作负载启用了 RBAC,请为工作负载创建一个带相应工作负载选择器的 AuthorizationPolicy。根据工作负载对应 ServiceRoleServiceRoleBinding 的语义添加规则。

步骤 5:验证迁移后的策略

  1. 仔细检查迁移后的 v1beta1 策略:确保没有名称重复的策略,命名空间指定正确,并且给定命名空间的所有 v1alpha1 策略都已迁移。

  2. 使用命令 kubectl apply --dry-run=server -f beta-policy.yamlv1beta1 策略进行试运行,以确保其有效。

  3. v1beta1 策略应用于给定命名空间并密切监视效果。如果使用了 JWT 或授权,请确保测试允许和拒绝场景。

  4. 迁移下一个命名空间。仅在成功完成所有命名空间的迁移后才删除 v1alpha1 策略。

示例

v1alpha1 策略

本节提供了一个完整的示例,展示了命名空间 foo 的迁移。假设命名空间 foo 具有以下影响其工作负载的 v1alpha1 策略

# A MeshPolicy that enables mTLS globally, including the whole foo namespace
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
  name: "default"
spec:
  peers:
  - mtls: {}
---
# A Policy that enables mTLS permissive mode and enables JWT for the httpbin service on port 8000
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: httpbin
  namespace: foo
spec:
  targets:
  - name: httpbin
    ports:
    - number: 8000
  peers:
  - mtls:
      mode: PERMISSIVE
  origins:
  - jwt:
      issuer: testing@example.com
      jwksUri: https://www.example.com/jwks.json
      triggerRules:
      - includedPaths:
        - prefix: /admin/
        excludedPaths:
        - exact: /admin/status
  principalBinding: USE_ORIGIN
---
# A ClusterRbacConfig that enables RBAC globally, including the foo namespace
apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: 'ON'
---
# A ServiceRole that enables RBAC for the httpbin service
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: httpbin
  namespace: foo
spec:
  rules:
  - services: ["httpbin.foo.svc.cluster.local"]
    methods: ["GET"]
---
# A ServiceRoleBinding for the above ServiceRole
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: httpbin
  namespace: foo
spec:
  subjects:
  - user: cluster.local/ns/foo/sa/sleep
    roleRef:
      kind: ServiceRole
      name: httpbin

httpbin 服务

httpbin 服务具有以下定义

apiVersion: v1
kind: Service
metadata:
  name: httpbin
  namespace: foo
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin

这意味着服务名称 httpbin 应替换为工作负载选择器 app: httpbin,服务端口 8000 应替换为工作负载端口 80。

v1beta1 身份验证策略

下面列出了 foo 命名空间中 v1alpha1 身份验证策略的迁移后的 v1beta1 策略

# A PeerAuthentication that enables mTLS for the foo namespace, migrated from the MeshPolicy
# Alternatively the MeshPolicy could also be migrated to a PeerAuthentication at mesh level
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: foo
spec:
  mtls:
    mode: STRICT
---
# A PeerAuthentication that enables mTLS for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  # port level mtls set for the workload port 80 corresponding to the service port 8000
  portLevelMtls:
    80:
      mode: PERMISSIVE
--
# A RequestAuthentication that enables JWT for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: testing@example.com
    jwksUri: https://www.example.com/jwks.json
---
# An AuthorizationPolicy that enforces to require JWT validation for the httpbin workload, migrated from the Policy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin-jwt
  namespace: foo
spec:
  # Use DENY action to explicitly deny requests without JWT token
  action: DENY
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        # This makes sure requests without JWT token will be denied
        notRequestPrincipals: ["*"]
    to:
    - operation:
        # This should be the workload port 80, not the service port 8000
        ports: ["80"]
        # The path and notPath is converted from the trigger rule in the Policy
        paths: ["/admin/*"]
        notPaths: ["/admin/status"]

v1beta1 授权策略

下面列出了 foo 命名空间中 v1alpha1 RBAC 策略的迁移后的 v1beta1 策略

# An AuthorizationPolicy that denies by default, migrated from the ClusterRbacConfig
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: default
  namespace: foo
spec:
  # An empty rule that allows nothing
  {}
---
# An AuthorizationPolicy that enforces to authorization for the httpbin workload, migrated from the ServiceRole and ServiceRoleBinding
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
      version: v1
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/foo/sa/sleep"]
    to:
    - operation:
        methods: ["GET"]

完成升级

恭喜;到达此点后,您应该只有 v1beta1 策略对象,并且您将能够继续将 Istio 升级到 1.6 及更高版本。

分享此文章