为网关配置 Cloud CDN

本文档介绍了如何使用 Google Kubernetes Engine (GKE) Gateway 控制器配置 Cloud CDN。您可以在 Cloud CDN 文档中找到有关 Cloud CDN 概念、最佳实践和问题排查的详细信息。

Cloud CDN 可将内容缓存到更靠近用户的位置,从而有助于缩短最终用户延迟时间并减少源站负载。您可以使用 GCPHTTPFilter CustomResourceDefinition 启用 Cloud CDN 缓存功能。

本文档适用于为组织设计和架构网络的应用程序开发者、云架构师和网络专家。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

概览

GKE 网关与 Cloud CDN 的集成可让您使用 Kubernetes 原生资源来管理边缘缓存。借助 GCPHTTPFilter 资源,您可以针对不同的流量切片微调缓存模式和存留时间 (TTL) 等配置。

您可以通过创建 GCPHTTPFilter 对象并在 HTTPRoute 规则中引用该对象来启用 Cloud CDN。您可以创建多个 GCPHTTPFilter 对象,以便为不同类型的流量定义不同的缓存行为。 例如,您可以创建一个用于静态图片的过滤条件,并创建另一个使用 Cloud CDN 建议的默认值的默认政策。

通过 GCPHTTPFilter 资源,您可以配置以下内容:

  • 缓存模式:控制 Cloud CDN 如何缓存来自源站的响应。
  • 存留时间 (TTL) 配置:配置对象在缓存中保留的时间。
  • 缓存键:定义请求的哪些元素(标头、Cookie、查询字符串)用于生成缓存键。
  • 负缓存:缓存常见错误响应或重定向,以减少故障期间的来源负载。
  • 缓存政策:控制 Cloud CDN 处理可缓存请求的方式。例如,您可以启用 Cloud CDN 以执行以下操作:
    • 即使后端服务不可用,也能继续提供缓存内容,从而保持高可用性。
    • 定义绕过缓存以直接从后端提取数据的特定请求标头。
    • 将对同一资源的多个并发请求合并为一个请求,以减少后端负载。

GCPHTTPFilter 资源必须与所附加的 HTTPRoute 资源位于同一命名空间中。配置 GCPHTTPFilter 后,该过滤器会合并到相应路由的过滤器链中。

下图演示了如何使用 GCPHTTPFilter 将不同的缓存配置应用于 HTTPRoute 中的特定流量切片:

图 1. 在 HTTPRoute 中使用 GCPHTTPFilter 进行不同的缓存配置。
图 1:HTTPRoute 中的缓存配置。

此架构可让您配置精细的自动化边缘缓存管理。 HTTPRoute 通过根据请求路径等属性匹配传入流量,来配置如何处理传入请求。如需为特定路由启用缓存,请将 GCPHTTPFilter 附加到 HTTPRoute 中的规则。每个 GCPHTTPFilter 都可以为图片、Web 资源和其他内容指定不同的缓存逻辑。然后,Cloud CDN 会强制执行此缓存逻辑,并将缓存的内容传送给客户端。

要求和限制

  • 您的集群必须为 GKE 1.35.2-gke.1751000 或更高版本。
  • 您必须使用 gke-l7-global-external-managedgke-l7-global-external-managed-mc GatewayClass 配置全球级外部网关
  • 您必须已配置 HTTPRoute 资源
  • 您不能在同一网关上同时启用 Identity-Aware Proxy (IAP) 和 Cloud CDN。如果需要 IAP,您必须先移除 GCPHTTPFilter 对象,然后才能启用 GCPBackendPolicy。
  • 您只能将一个 GCPHTTPFilter 对象附加到 HTTPRoute 中的特定路径规则。

价格

启用缓存后,您需要按 Cloud CDN 价格付费。如需了解详情,请参阅 Cloud CDN 价格

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行 gcloud components update 命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。

角色与权限

  1. 如需查看已配置的 Google Cloud 资源,请确保您拥有roles/compute.networkViewer IAM 角色

  2. 确保您有权访问 GKE 集群,并且有权执行必要的操作。以下代码段显示了所需的最低 RBAC 权限:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: gateway-caching-admin
    rules:
    # 1. Full access to manage HTTPRoutes
    - apiGroups: ["gateway.networking.k8s.io"]
      resources: ["httproutes"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    # 2. Read-only access to view the Gateway
    - apiGroups: ["gateway.networking.k8s.io"]
      resources: ["gateways"]
      verbs: ["get", "list", "watch"]
    # 3. Full access to manage caching filters
    - apiGroups: ["networking.gke.io"]
      resources: ["gcphttpfilters"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    

如需详细了解如何使用 RBAC 和 IAM,请参阅与 Identity and Access Management 的交互

使用 GCPHTTPFilter 配置缓存

如需启用和配置 Cloud CDN,您需要创建一个或多个 GCPHTTPFilter 资源,然后在 HTTPRoute 对象中引用这些资源。

创建 GCPHTTPFilter

GCPHTTPFilter 资源用于定义缓存政策。在以下示例中,您将创建三个 GCPHTTPFilters

  • 第一个过滤器会缓存静态图片,以便更快地向最终用户交付图片。
  • 第二个过滤器会缓存 CSS 文件等 Web 资源。
  • 第三个过滤条件用作剩余流量的“全方位”过滤条件。
  1. 通过将以下清单保存为 store-caching-images-filter.yaml 来创建第一个过滤条件:

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-images-filter
    spec:
      cachePolicy:
        cacheKeyPolicy:
          includeQueryString: false
        cacheMode: CACHE_ALL_STATIC
        defaultTTL: 12h
    

    在此清单中,适用以下规则:

    • includeQueryString:指示 Cloud CDN 忽略缓存键中的查询参数。这有助于确保针对同一图片的不同用户请求收到相同的缓存副本。
    • cacheMode:设置为 CACHE_ALL_STATIC,可自动缓存图片等静态内容。
    • defaultTTL:指示 Cloud CDN 将图片缓存 12 小时。 您可以指定时间,以小时 (h)、分钟 (m) 或秒 (s) 为单位。
  2. 创建第二个过滤条件。将以下清单保存为 store-caching-webassets-filter.yaml

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-webassets-filter
    spec:
      cachePolicy:
        cacheKeyPolicy:
          includeQueryString: false
        serveWhileStale: 24h
        cacheMode: CACHE_ALL_STATIC
        defaultTTL: 24h
    

    此清单与第一个过滤器的设置大致相同,但存在以下差异:

    • serveWhileStale:设置为 24 小时。如果 Web 资源(例如 CSS 文件)在 defaultTTL 后过期,Cloud CDN 会继续从缓存中传送该过期的资源,最长可达 24 小时,并在后台重新验证相应内容。
    • defaultTTL:设置为更长的时长,即 24 小时。
  3. 创建第三个过滤器,以定义不带任何参数的默认缓存政策。将以下清单保存为 store-caching-default-filter.yaml

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-default-filter
    spec:
      cachePolicy: {}
    

    如果您未在 GCPHTTPFilter 资源中指定任何参数,GKE 会使用缓存的默认值

  4. 将过滤条件应用到集群:

    kubectl apply -f store-caching-images-filter.yaml
    kubectl apply -f store-caching-webassets-filter.yaml
    kubectl apply -f store-caching-default-filter.yaml
    

将过滤条件附加到 HTTPRoute

如需应用缓存政策,请更新现有 HTTPRoute 清单以引用过滤条件。

您可以在同一 HTTPRoute 对象中引用不同的过滤条件,以应用一致的缓存规则。您还可以在不同规则中重复使用同一过滤器,例如在逐步推出期间,您可以在不同后端版本之间拆分流量。

  1. 修改现有 HTTPRoute 清单(例如 store-route-external.yaml),以在路由规则中包含 filters 部分:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # RULE 1: Default /img/ traffic to store-v1
      - matches:
        - path:
            value: /img/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-images-filter
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 2: Default /web/ traffic to store-v1
      - matches:
        - path:
            value: /web/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-webassets-filter
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 3: Canary /img/ traffic (header + path match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /img/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-images-filter
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 4: Canary /web/ traffic (header + path match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /web/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-webassets-filter
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 5: Default (catch-all) traffic to store-v1
      - backendRefs:
        - name: store-v1
          port: 8080
        # If you need caching for default traffic, it can be enabled by placing
        # filters directly under backendRefs
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-default-filter
    
  2. 将更新后的 HTTPRoute 配置应用到集群:

    kubectl apply -f store-route-external.yaml
    
  3. 验证 HTTPRoute 和网关已部署:

    kubectl describe httproute store-external
    kubectl describe gateway external-http
    

    输出显示,已为 HTTPRoute 资源启用 Cloud CDN。Cloud CDN 会将配置的缓存政策应用于您的流量,并加快静态图片、Web 资产和其他流量的传送速度。

使缓存内容失效

如需从缓存中清除过期内容,您必须提交失效请求。如需详细了解失效操作的运作方式,请参阅 Cloud CDN 文档中的使缓存内容失效

  1. 查找与网关关联的网址映射:

    kubectl describe gateway external-http
    

    查找 networking.gke.io/url-maps 注解。例如:

    Name: external-http
    Namespace: foo
    API Version: gateway.networking.k8s.io
    Kind: Gateway
    Annotations: networking.gke.io/backend-services: gkegw-service1
                 networking.gke.io/firewalls: gkegw-l7-fw
                 networking.gke.io/forwarding-rules: gkegw-fr1
                 networking.gke.io/health-checks: gkegw-hc1
                 networking.gke.io/ssl-certificates:
                 networking.gke.io/target-proxies: gkegw-tp1
                 networking.gke.io/url-maps: gkegw-url-map1
    
  2. 您可以使用多种失效匹配器(包括主机、路径、缓存标记、响应状态代码、MIME 类型和后端)使内容失效。例如,如需使用主机和状态代码匹配器提交失效请求,请运行以下命令:

    gcloud compute url-maps invalidate-cdn-cache URL_MAP_NAME
        --host="store.example.com" 
        --status=404
    

    URL_MAP_NAME 替换为上一步中确定的名称,例如 gkegw-url-map1

监控 Cloud CDN 性能

您可以使用 Cloud Logging 和 Cloud Monitoring 来跟踪缓存命中率和性能。

Cloud CDN 日志与由 GKE Gateway Controller 预配的负载均衡器相关联。日志按负载平衡器的转发规则和网址映射编入索引。如需检索最近的日志,请运行以下命令:

gcloud logging read 'resource.type="http_load_balancer" AND 
    resource.labels.url_map_name="URL_MAP_NAME" AND 
    logName="projects/PROJECT_ID/logs/cloudcdn_googleapis_com%2Frequests"' 
    --project PROJECT_ID --limit 100 --format json

Cloud CDN 会将指标导出到 Cloud Monitoring。您可以在监控查询中使用 matched_url_path_rule 过滤条件,将指标范围缩小到特定 HTTPRoute。

如需详细了解如何查看 Cloud CDN 的日志和监控信息,请参阅缓存的日志和指标

停用 Cloud CDN

如需停用缓存,请从 HTTPRoute 中移除 GCPHTTPFilter 引用。

  1. 修改 HTTPRoute 清单,并移除引用 GCPHTTPFilter 的 filters 块。以下示例展示了移除了过滤器的 HTTPRoute 清单:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # RULE 1: Default /img/ traffic to store-v1
      - matches:
        - path:
            value: /img/
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 2: Canary /img/ traffic (header match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /img/
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 3: Default (catch-all) traffic to store-v1
      - backendRefs:
        - name: store-v1
          port: 8080
    
  2. 将更新后的 HTTPRoute 清单应用于集群:

    kubectl apply -f store-route-external.yaml
    

后续步骤