在 GKE 上为边车设置授权政策

本页面介绍了如何在 GKE 上的 Cloud Service Mesh 边车上设置不同类型的授权政策。

准备工作

您应该熟悉 Gateway API 和授权扩展。

在创建授权政策之前,您必须执行以下步骤:

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Enable the Network Security, Network Services APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

命名空间级 AuthzPolicy

如果您想拒绝整个命名空间的预期流量模式,请配置授权政策,以拒绝对命名空间中所有工作负载的任何传入 HTTP 请求:

cat >ns-authz-policy-deny.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/bad_token"
  action: DENY
  enforcementLevel: L7
EOF
kubectl apply -f ns-authz-policy-deny.yaml

空的 selector: {} 会定位命名空间中的所有 Pod。

如果您希望允许整个命名空间的预期流量模式,请配置授权政策,以允许对命名空间中所有工作负载的任何传入 HTTP 请求:

cat >ns-authz-policy-allow.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/headers"
        methods: ["GET"]
  action: ALLOW
  enforcementLevel: L7
EOF
kubectl apply -f ns-authz-policy-allow.yaml

空的 selector: {} 会定位命名空间中的所有 Pod。

拒绝针对工作负载的入站请求

如果您的工作负载应该仅进行出站调用(例如 Cron 作业),请配置授权政策来拒绝对工作负载的任何传入 HTTP 请求:

cat >deny-path-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector:
      matchLabels:
        app: EXAMPLE_APP
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/deny_path"
  action: DENY
  enforcementLevel: L7
EOF
kubectl apply -f deny-path-authz-policy.yaml

输出类似于以下内容:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

应用此政策后,对与 app: EXAMPLE_APP 匹配的 Pod 上的路径 /deny_path 的任何传入 HTTP 请求都将被拒绝,并且调用方将收到 HTTP 403 Forbidden 响应代码。

允许向工作负载发送特定入站请求

您还可以配置 ALLOW 政策,以仅允许符合特定条件的请求,同时拒绝其余请求。

以下示例在 example-app 部署上配置了授权政策,以仅允许来自身份为 spiffe://cluster.local/NAMESPACE/pod1 的 Pod 的 mTLS 请求。

cat >allow-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector:
      matchLabels:
        app: EXAMPLE_APP
  rules:
  - from:
      sources:
      - principals:
        - principal:
            type: Exact
            value: "spiffe://cluster.local/NAMESPACE/pod1"
  action: ALLOW
  enforcementLevel: L7
EOF
kubectl apply -f allow-authz-policy.yaml

输出类似于以下内容:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

只有使用 mTLS 进行身份验证且提供确切 SPIFFE 身份 spiffe://cluster.local/NAMESPACE/pod1 的传入请求才会收到 HTTP 200 OK。任何其他请求都将被代理拒绝,并返回 HTTP 403 Forbidden。

委托给外部授权引擎

您可以自带授权引擎,并配置 Cloud Service Mesh,将工作负载的所有授权决策委托给配置的引擎。

  1. 安装 GCPAuthzExtension CRD(如果尚未安装):

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/main/config/crd/networking.gke.io_gcpauthzextensions.yaml
    
  2. 在支持 ext_proc gRPC 协议的 Kubernetes 中部署基于标注的授权扩展工作负载,并配置授权扩展资源:

    cat >authz-extension.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzExtension
    metadata:
      name: my-authz-ext
      namespace: NAMESPACE
    spec:
      backendRef:
        group: ""
        kind: Service
        name: authz-service
        port: PORT
      authority: "authz-service.NAMESPACE.svc.cluster.local"
      forwardHeaders:
      - Authorization
      failOpen: false
      timeout: "100ms"
      wireFormat: ExtProcGRPC
    EOF
    kubectl apply -f authz-extension.yaml
    

    替换以下内容:

    • NAMESPACE:authz-service Service 和工作负载的命名空间。
    • PORT:提供 ext_proc gRPC API 的 authz-service 服务的端口。

    此命令会创建一个基于标注的授权扩展,该扩展作为 Kubernetes 服务 authz-service 运行。

    输出类似于以下内容:

    gcpauthzextension.networking.gke.io/my-authz-ext created
    
  3. 设置授权政策,将工作负载的授权决策委托给之前配置的授权扩展程序:

    cat >authz-policy.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: my-workload-authz
      namespace: NAMESPACE
    spec:
      targetRefs:
      - group: ""
        kind: Pod
        selector:
          matchLabels:
            app: EXAMPLE_APP
      rules:
      - from:
          sources:
          - principals:
            - principal:
                type: Exact
                value: "spiffe://cluster.local/NAMESPACE/pod1"
        to:
          operations:
          - paths:
            - type: Exact
              value: "/api/payments-schedule"
      action: CUSTOM
      enforcementLevel: L7
      customProviders:
        extensionRefs:
        - group: networking.gke.io
          kind: GCPAuthzExtension
          name: my-authz-ext
    EOF
    kubectl apply -f authz-policy.yaml
    

    输出类似于以下内容:

    gcpauthzpolicy.networking.gke.io/my-workload-authz created
    

    代理会等待授权扩展程序做出响应,然后再将请求转发到应用。如果扩展程序通过以错误结束调用来拒绝请求,或者如果调用在 failOpen 为 false 时失败或超时,则调用方会收到 HTTP 500 响应。如果扩展程序发送即时响应,则调用方会收到该响应的状态代码。