为 GKE 配置 Cloud Storage FUSE CSI 驱动程序边车容器

本指南将介绍如何为 Cloud Storage FUSE CSI 驱动程序边车容器配置资源,包括设置私有映像、自定义写入缓冲区和自定义读取缓存卷。通常,您无需更改这些设置。

Cloud Storage FUSE CSI 驱动程序使用可自定义的边车容器来高效地装载和访问 Cloud Storage 存储桶。通过配置边车,您可以微调应用性能和资源使用情况,从而加快数据访问速度、缩短处理时间,并可能降低应用的总体资源消耗量。

本指南适用于希望优化与 GKE 互动的应用的性能、安全性和效率的开发者、管理员和架构师。

在阅读本页面内容之前,请确保您熟悉 Cloud Storage、Kubernetes 和容器化概念的基础知识。

边车容器的运作方式

Cloud Storage FUSE CSI 驱动程序使用边车容器来装载 Cloud Storage 存储桶,以便 Kubernetes 应用可以将其作为本地文件系统进行访问。此边车容器名为 gke-gcsfuse-sidecar,与工作负载容器一起在同一 Pod 中运行。当驱动程序在 Pod 规范中检测到 gke-gcsfuse/volumes: "true" 注解时,会自动注入边车容器。这种边车容器方法有助于确保安全并有效管理资源。

边车容器可处理装载 Cloud Storage 存储桶的复杂性,并为应用提供文件系统访问权限,而无需您直接管理 Cloud Storage FUSE 运行时。您可以使用 gke-gcsfuse/cpu-limitgke-gcsfuse/memory-limit 等注解为边车容器配置资源限制。边车容器模型还可确保 Cloud Storage FUSE 实例与工作负载生命周期相关联,从而防止其不必要地消耗资源。这意味着,在工作负载容器退出时,边车容器会自动终止,尤其是在 Job 工作负载或 RestartPolicyNever 的 Pod 中。

Cloud Service Mesh 和 OSS Istio 兼容性

Cloud Storage FUSE CSI 驱动程序的边车容器和 Istio 可以在 Pod 中共存和并发运行。 不过,在 GKE 1.29 版及更高版本中,如果 Cloud Storage FUSE 在 Istio 代理准备就绪之前尝试连接到元数据服务器,您可能会遇到身份验证失败的情况。如果您遇到这些身份验证失败问题,可以在 Pod 规范中将 traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32 添加到 metadata.annotations,从而解决此问题。此注解用于配置 Istio 或 Cloud Service Mesh,以将 GKE 元数据服务器的 IP 地址从重定向中排除。

配置自定义写入缓冲区

Cloud Storage FUSE 会在本地目录中暂存写入的文件,然后在 closefsync 操作中将其上传到 Cloud Storage。

本部分介绍如何为 Cloud Storage FUSE 写入缓冲配置自定义缓冲区卷。如果您需要替换默认 emptyDir 卷以供 Cloud Storage FUSE 在写入操作中暂存文件,则此场景可能适用。如果您需要在 Autopilot 集群上写入大于 10 GiB 的文件,此操作会非常有用。

您可以指定 Cloud Storage FUSE CSI 驱动程序支持的任何类型的存储空间进行文件缓存,例如本地 SSD、基于 Persistent Disk 的存储空间和 RAM 磁盘(内存)。GKE 会使用指定的卷进行文件写入缓冲。如需详细了解这些选项,请参阅选择为文件缓存提供支持的存储空间

如需使用由 Persistent Disk 支持的自定义缓冲区卷,您必须在 Pod 的 securityContext 中指定非零 fsGroup。此步骤会为非 root 边车容器授予卷所需的读取或写入权限。如果您的 PVC 通过使用 Cloud Storage FUSE CSI 驱动程序将 Cloud Storage 存储分区装载为持久卷,则无需进行此设置。

以下示例展示了如何将预定义的 PersistentVolumeClaim 用作缓冲区卷:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
spec:
  securityContext:
    fsGroup: FS_GROUP
  containers:
  ...
  volumes:
  - name: gke-gcsfuse-buffer
    persistentVolumeClaim:
      claimName: BUFFER_VOLUME_PVC

替换以下内容:

  • FS_GROUP:fsGroup ID。
  • BUFFER_VOLUME_PVC:预定义的 PVC 的名称。

配置自定义读取缓存卷

本部分介绍如何为 Cloud Storage FUSE 读取缓存配置自定义缓存卷。

如果您需要替换默认 emptyDir 卷以供 Cloud Storage FUSE 在读取操作中缓存文件,则此场景可能适用。您可以指定 GKE 支持的任何类型的存储空间(例如 PersistentVolumeClaim),GKE 会使用指定的卷进行文件缓存。如果您需要在 Autopilot 集群上缓存大于 10 GiB 的文件,此操作会非常有用。

如需使用由 Persistent Disk 支持的自定义缓存卷,您必须在 Pod 的 securityContext 中指定非零 fsGroup。此步骤会为非 root 边车容器授予卷所需的读取或写入权限。如果您的 PVC 使用 Cloud Storage FUSE CSI 驱动程序将 Cloud Storage 存储分区装载为持久卷,则无需进行此设置。

以下示例展示了如何将预定义的 PersistentVolumeClaim 用作缓存卷:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"
spec:
  securityContext:
    fsGroup: FS_GROUP
  containers:
  ...
  volumes:
  - name: gke-gcsfuse-cache
    persistentVolumeClaim:
      claimName: CACHE_VOLUME_PVC

替换以下内容:

  • FS_GROUPfsGroup ID。
  • CACHE_VOLUME_PVC:预定义的 PersistentVolumeClaim 名称。

为边车容器配置私有映像

本部分介绍在您将边车容器映像托管在私有容器仓库中的情况下如何使用边车容器映像。如果您出于安全目的需要使用专用节点,则此场景可能适用。

如需配置和使用私有边车容器映像,请按照以下步骤操作:

  1. 参阅 GKE 兼容性表,查找兼容的公共边车容器映像。
  2. 将该映像拉取到本地环境,并推送到您的私有容器注册表。
  3. 在清单中,指定一个名为 gke-gcsfuse-sidecar 的容器,并使其仅有映像字段。GKE 会使用指定的边车容器映像来准备边车容器注入。

    示例如下:

    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      containers:
      - name: gke-gcsfuse-sidecar
        image: PRIVATE_REGISTRY/gcs-fuse-csi-driver-sidecar-mounter:PRIVATE_IMAGE_TAG
      - name: main # your main workload container.
    

    替换以下内容:

    • PRIVATE_REGISTRY:您的私有容器仓库。 例如 us-central1-docker.pkg.dev/my-project/my-registry
    • PRIVATE_IMAGE_TAG:您的私有边车容器映像标记。 例如 v1.17.1-gke.1

配置边车容器资源

默认情况下,针对 Standard 集群和 Autopilot 集群,gke-gcsfuse-sidecar 容器配置了以下资源请求和限制:

请求

  • 250m CPU
  • 256 MiB 内存
  • 5 GiB 临时存储

限制(GKE 1.29.1-gke.1670000 及更高版本):

  • 无限 CPU
  • 无限内存
  • 无限临时存储空间

限制(低于 GKE 1.29.1-gke.1670000 版本):

  • 250m CPU
  • 256 MiB 内存
  • 5 GiB 临时存储

默认情况下,针对 Standard 集群和 Autopilot 集群,gke-gcsfuse-metadata-prefetch 容器配置了以下资源请求和限制:

请求

  • 10m CPU
  • 10 MiB 内存
  • 10 MiB 临时存储空间

此政策具有以下限制:

  • 50m CPU
  • 250 MiB 内存
  • 无限临时存储空间

在 Standard 集群和 Autopilot 集群中,您可以覆盖默认值。GKE 处理容器资源的方式取决于集群的运维模式:

  • Standard 集群:如果请求或限制中的一个已设置,而另一个未设置,则 Pod 的资源限制和请求将设置为相同的值。如果同时设置了请求和限制,Pod 会完全使用您指定的资源请求和限制。如果您未设置任何值,系统会直接应用默认资源(如上所述)。
  • Autopilot 集群:如果请求或限制中的一个已设置,而另一个未设置,则 Pod 的资源限制和请求将设置为相同的值。请参阅在 Autopilot 中设置资源替换,了解资源替换和设置的默认资源值将如何影响 Pod 行为。

如需覆盖 gke-gcsfuse-sidecar 容器的默认值,您可以选择指定注解 gke-gcsfuse/[cpu-limit|memory-limit|ephemeral-storage-limit|cpu-request|memory-request|ephemeral-storage-request],如以下示例所示:

如需覆盖 gke-gcsfuse-metadata-prefetch 容器的默认值(从 GKE 版本 1.32.3-gke.1717000 及更高版本开始),您可以选择指定注解 gke-gcsfuse/[metadata-prefetch-cpu-limit|metadata-prefetch-memory-limit|metadata-prefetch-ephemeral-storage-limit|metadata-prefetch-cpu-request|metadata-prefetch-memory-request|metadata-prefetch-ephemeral-storage-request],如以下示例所示:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    gke-gcsfuse/volumes: "true"

    # gke-gcsfuse-sidecar overrides
    gke-gcsfuse/cpu-limit: "10"
    gke-gcsfuse/memory-limit: 10Gi
    gke-gcsfuse/ephemeral-storage-limit: 1Ti
    gke-gcsfuse/cpu-request: 500m
    gke-gcsfuse/memory-request: 1Gi
    gke-gcsfuse/ephemeral-storage-request: 50Gi

    # gke-gcsfuse-metadata-prefetch overrides
    gke-gcsfuse/metadata-prefetch-cpu-limit: "10"
    gke-gcsfuse/metadata-prefetch-memory-limit: 10Gi
    gke-gcsfuse/metadata-prefetch-ephemeral-storage-limit: 1Ti
    gke-gcsfuse/metadata-prefetch-cpu-request: 500m
    gke-gcsfuse/metadata-prefetch-memory-request: 1Gi
    gke-gcsfuse/metadata-prefetch-ephemeral-storage-request: 50Gi

您可以使用值 "0" 取消设置任何资源限制或请求,但请注意,gke-gcsfuse-sidecar 容器已取消设置所有限制(cpu-limitmemory-limitephemeral-storage-limit),而 gke-gcsfuse-metadata-prefetch 容器已取消设置 ephemeral-storage-limit,因此在 GKE 版本为 1.32.3-gke.1717000 或更高版本的集群上将这些限制设置为 "0" 将会是无效操作。

例如,设置 gke-gcsfuse/metadata-prefetch-memory-limit: "0" 表示您希望取消设置 gke-gcsfuse-metadata-prefetch 容器内存限制。如果您无法确定元数据预提取功能为支持您的工作负载而需要的资源量,并且希望允许元数据预提取使用节点上的所有可用资源,这将非常有用。

(可选)使用 Cloud Profiler 分析性能

您可以使用 Cloud Profiler 持续、精细地了解存储密集型应用的资源消耗情况。借助这些精细数据,您可以主动监控 Cloud Storage FUSE CSI 驱动程序及其边车容器中的 CPU 和内存使用情况。通过 Cloud Profiler 数据获得的分析洞见可帮助您识别低效的代码路径、优化资源分配,以及在内存泄漏或意外的内存不足 (OOM) 事件影响服务稳定性之前对其进行问题排查。

使用 Cloud Profiler 是可选操作,专为需要详细性能诊断的管理员而设计。默认情况下,Cloud Profiler 会为节点驱动程序启用。对于边车容器,这是一项可以选择启用的功能,您可以手动启用。

启用 Cloud Profiler 之前

如需将 Cloud Profiler 与 Cloud Storage FUSE CSI 驱动程序搭配使用,请确保您使用的是 GKE 版本 1.36.0-gke.2403000 或更高版本。在生成剖析文件之前,您必须启用 Cloud Profiler API,并为要剖析的组件配置适当的 IAM 权限。

启用 API

启用 Cloud Profiler API

向节点驱动程序授予权限

如需将分析数据发送到 Cloud Profiler,节点驱动程序需要 IAM 权限。由于节点驱动程序默认在宿主网络上运行,因此它会使用与 GKE 节点关联的 IAM 服务账号进行身份验证,而不是使用 Workload Identity Federation for GKE。

roles/cloudprofiler.agent 角色授予节点的相应服务账号:

gcloud projects add-iam-policy-binding PROJECT_ID \
    --role=roles/cloudprofiler.agent \
    --member=serviceAccount:NODE_SERVICE_ACCOUNT

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • NODE_SERVICE_ACCOUNT:GKE 节点使用的 IAM 服务账号。除非您的节点配置为使用其他服务账号,否则这通常是默认的 Compute Engine 服务账号,例如 PROJECT_NUMBER-compute@

向边车容器授予权限

如需将性能分析数据发送到 Cloud Profiler,边车容器和 gcsfuse 进程需要 IAM 权限。这些组件使用 Workload Identity Federation for GKE 进行身份验证,该功能使用与您的工作负载 Pod 关联的 Kubernetes 服务账号 (KSA)。

向您的 Pod 使用的 KSA 授予 roles/cloudprofiler.agent 角色:

gcloud projects add-iam-policy-binding projects/PROJECT_ID \
    --role=roles/cloudprofiler.agent \
    --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA_NAME \
    --condition=None

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • PROJECT_NUMBER:您的 Google Cloud 项目的项目编号。
  • NAMESPACE:Kubernetes 命名空间的名称。
  • KSA_NAME:您的 Kubernetes 服务账号的名称。

为边车工作负载启用 Cloud Profiler

如需为边车装载程序和底层 gcsfuse 进程生成配置文件,请在工作负载规范中将 enableCloudProfilerForSidecar 卷属性设置为 "true"。为边车容器启用 Cloud Profiler 也会自动为底层 gcsfuse 进程启用该功能。

BUCKET_NAME 替换为您的 Cloud Storage 存储桶的名称:

volumes:
  - name: gcs-fuse-csi-ephemeral
    csi:
      driver: gcsfuse.csi.storage.gke.io
      volumeAttributes:
        bucketName: BUCKET_NAME
        enableCloudProfilerForSidecar: "true"

查看性能分析数据

如需查看分析数据,请前往 Google Cloud 控制台中的 Cloud Profiler 页面。使用服务名称过滤条件(如下所示)分析您正在调查的组件:

组件 服务名称过滤条件
节点驱动程序 gcs-fuse-csi-driver
Sidecar 装载器 gke-gcsfuse-sidecar
GCSFuse gcsfuse

Cloud Profiler 使用 POD_NAME_POD_UID 格式标识每个实例。这样可确保即使 Pod 重启,每个实例也能获得唯一标识符。

(可选)停用 GCSFuse 性能剖析

默认情况下,为边车容器启用性能剖析功能也会对底层 gcsfuse 进程进行性能剖析。您可能需要停用 gcsfuse 分析,以减少资源开销或仅专注于分析边车容器的性能。

如需停用 gcsfuse 性能剖析,同时保持 Sidecar 性能剖析处于启用状态,请将 enable-cloud-profiler=false 添加到卷规范中的 mountOptions 属性。

BUCKET_NAME 替换为您的 Cloud Storage 存储桶的名称:

volumes:
  - name: gcs-fuse-csi-ephemeral
    csi:
      driver: gcsfuse.csi.storage.gke.io
      volumeAttributes:
        bucketName: BUCKET_NAME
        enableCloudProfilerForSidecar: "true"
        mountOptions: "enable-cloud-profiler=false"

配置日志记录详细程度

默认情况下,gke-gcsfuse-sidecar 容器会生成 infoerror 级别的日志。不过,为了进行调试或更详细的分析,您可能需要调整日志记录详细程度。本部分概述了如何提高或降低日志记录级别。

您可以使用装载选项来配置日志记录详细程度,也可以使用 CSI 驱动程序的功能将卷属性值转换为必要的 gcsfuse 配置设置。

在目标 Pod 清单中,添加以下配置:

      volumeAttributes:
        bucketName: BUCKET_NAME
        mountOptions: "implicit-dirs"
        gcsfuseLoggingSeverity:  LOGGING_SEVERITY

如需使用装载选项,请在目标 Pod 清单中添加以下配置:

  mountOptions: "logging:severity:LOGGING_SEVERITY"

替换以下内容:

  • BUCKET_NAME:您的 Cloud Storage 存储桶名称。
  • LOGGING_SEVERITY:以下值之一,具体要求取决于您的要求:
    • trace
    • debug
    • info
    • warning
    • error

部署 Pod 后,CSI 驱动程序会使用新配置的日志记录级别启动 gcsfuse。

您可以使用以下过滤条件来验证是否应用了日志记录严重级别:

resource.labels.container_name="gke-gcsfuse-sidecar"
resource.type="k8s_container"
resource.labels.pod_name="POD_NAME"
"severity:"

问题排查

如需详细了解如何排查 Cloud Storage FUSE CSI 驱动程序的问题,请参阅 GitHub 项目文档中的问题排查指南

后续步骤