存储、配置与密钥

共 19 题
📑 题目列表 19 题
#
★★★

1. CSI 的 Identity/Controller/Node 三组 gRPC 服务如何划分职责?

CSI 的 Identity/Controller/Node 三组 gRPC 服务如何划分职责?

  • Identity 服务
  • Controller 服务
  • Node 服务

CSI(Container Storage Interface)定义三组 gRPC 服务。Identity 服务:提供插件信息(名称、版本、能力),如 GetPluginInfo、Probe,用于 controller 与 node 组件确认插件。Controller 服务:在控制平面(与存储系统交互)执行卷的管理操作,如 CreateVolume、DeleteVolume、PublishVolume(挂载)、ControllerExpandVolume,由 CSI 的 controller 插件(外部 provisioner 等 sidecar)调用。Node 服务:在节点上执行本地卷操作,如 NodePublishVolume(把卷挂载到具体 Pod 的目标路径)、NodeUnpublishVolume、NodeGetVolumeStats,由 kubelet 调用。职责划分:Controller 管"卷的创建/控制面",Node 管"节点上的实际挂载/数据面"。

核心是"Controller 管控制面卷操作,Node 管节点挂载,Identity 管插件信息"。三者分离实现插件可插拔。

#
★★★

2. CSI 的 NodePublishVolume 如何将卷挂载进容器(目标挂载点与 bind mount)?

CSI 的 NodePublishVolume 如何将卷挂载进容器(目标挂载点与 bind mount)?

  • NodePublishVolume 调用时机
  • 目标挂载点
  • bind mount

NodePublishVolume 由 kubelet 在 Pod 调度到某节点、卷需要挂载时调用 CSI 节点插件。它接收 target_path(Pod 内卷在节点上的挂载目标目录,即 Pod 的 volumeMounts 路径对应的节点路径)与 volume_context、staging_target_path。CSI 插件将卷挂载到 staging 路径后,再通过 bind mount 把卷绑定挂载到 target_path,使 Pod 容器内的挂载点可见(bind mount 是同一文件系统的多个挂载点)。卸载时调用 NodeUnpublishVolume。目标路径由 kubelet 根据 Pod 的 volumeMounts 计算。

核心是"先 stage 再 bind mount 到 target_path"。bind mount 让卷在容器内可见。

#
★★★

3. Kubernetes 的 CSI migration 机制如何让 in-tree 插件无缝切换到 CSI 驱动?

Kubernetes 的 CSI migration 机制如何让 in-tree 插件无缝切换到 CSI 驱动?

  • in-tree 插件与 CSI 的关系
  • CSI migration 原理
  • feature gate 与迁移

CSI migration 让 Kubernetes 把对 in-tree 存储插件(如 aws-ebs、gce-pd、azure-disk、cinder)的调用自动翻译为对应 CSI 驱动的调用,从而无需修改 PVC/PV 配置即可迁移到 CSI。原理:Kubernetes 内置 migration 逻辑,当检测到 in-tree 存储类时,通过 feature gate(如 CSIMigrationAWS)启用,把卷操作转发给同名的 CSI 驱动。迁移过程:安装 CSI 驱动,启用 feature gate,原有 in-tree 资源无缝对接 CSI,之后可移除 in-tree 代码。目的:逐步移除 in-tree 插件,统一到 CSI 生态。

核心是"in-tree 到 CSI 的透明翻译 + feature gate 控制迁移"。无需改资源即可迁移。

#
★★★

4. PV 的 reclaimPolicy(Retain/Recycle/Delete)在 PVC 释放后如何处理存储?

PV 的 reclaimPolicy(Retain/Recycle/Delete)在 PVC 释放后如何处理存储?

  • 三种回收策略
  • Retain 的数据保留
  • Delete 的自动删除

PV 的 reclaimPolicy 决定 PVC 释放(删除)后 PV 如何处理。Retain:保留 PV 与底层存储数据,管理员手动清理后可重新复用(PV 状态变为 Released,需手动删除后重建)。Delete:删除 PV 时自动删除底层存储(云盘),动态供给常用。Recycle:自动清理数据后复用(已废弃,deprecated)。静态 PV 常用 Retain 保护数据,动态 PV 默认 Delete。Retain 适合数据需保留的场景,Delete 适合临时存储。

核心是"数据保留 vs 自动删除"。Retain 保护数据,Delete 自动清理。

#
★★★

5. PV/PVC 的 volumeMode(Filesystem/Block)如何决定卷挂载方式?

PV/PVC 的 volumeMode(Filesystem/Block)如何决定卷挂载方式?

  • Filesystem 模式
  • Block 模式
  • 挂载方式差异

volumeMode 决定卷以文件系统还是块设备方式挂载。Filesystem(默认):卷格式化为文件系统并挂载到 Pod 的路径,容器内看到文件系统;Block:卷以原始块设备(raw block device)暴露,容器内以 /dev/xxx 设备路径访问,不格式化,适合需要直接访问块设备的应用(如数据库、专用工具)。Block 模式需在 volumeDevices 中声明 devicePath,而非 volumeMounts。调度与挂载路径不同。

核心是"文件系统 vs 原始块设备"。Block 适合数据库等高性能存储。

apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: block-pvc }
spec:
  accessModes: [ReadWriteOnce]
  volumeMode: Block
  storageClassName: fast
#
★★★

6. StorageClass 如何通过注解设为默认类并提供动态供给?

StorageClass 如何通过注解设为默认类并提供动态供给?

  • 默认 StorageClass 注解
  • 动态供给
  • 无默认类的行为

StorageClass 通过注解 storageclass.kubernetes.io/is-default-class: "true" 设为默认类。当 PVC 未指定 storageClassName 时,使用默认类进行动态供给:provisioner 根据 PVC 自动创建底层存储并生成 PV。若存在多个默认类,PVC 会失败(需指定 class)。动态供给的 StorageClass 定义 provisioner(如 standard.csi...)、parameters、reclaimPolicy、volumeBindingMode 等。无默认类时,PVC 未指定类则一直 Pending。

核心是"默认类注解 + 动态供给"。未指定类时用默认 class。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: disk.csi.azure.com
parameters: { skuname: Premium_LRS }
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
#
★★★

7. StorageClass 的 parameters 如何映射到存储后端的供给参数?

StorageClass 的 parameters 如何映射到存储后端的供给参数?

  • parameters 含义
  • 映射到后端
  • 常见参数

StorageClass 的 parameters 是传给 provisioner 的键值对,用于指定底层存储的供给参数。不同 provisioner 有不同参数,如 云盘 CSI 的 type/sku(磁盘类型)、replication、zone;NFS 的 server/path;local-path 的节点目录。provisioner 读取这些参数创建对应底层存储(如创建云盘、FPE 等)。parameters 是 provisioner 特定的,不能跨厂商通用。它是动态供给如何创建存储的关键配置。

核心是"parameters 是 provisioner 特定的供给参数"。它决定底层存储的规格。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: { name: fast }
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
  encrypted: "true"
#
★★★

8. in-tree 存储插件迁移到 CSI 的规划中驱动部署、feature gate 与兼容验证?

in-tree 存储插件迁移到 CSI 的规划:驱动部署、feature gate 与兼容验证如何做?

  • in-tree 到 CSI 迁移
  • 驱动部署
  • feature gate

迁移规划:1)部署目标 CSI 驱动(如 ebs.csi.aws.com、azuredisk.csi.driver)到集群;2)确认集群版本支持 CSI migration(启用对应 feature gate,如 CSIMigrationAWS/CSIMigrationAzureDisk);3)验证现有 PVC/PV 与 CSI 驱动兼容(迁移后 in-tree 资源自动翻译为 CSI 调用);4)创建新 PVC 用 CSI StorageClass,逐步迁移存量工作负载;5)监控 CSI 驱动日志与指标,验证读写正常;6)确认后移除 in-tree 依赖。目的是未来移除 in-tree 插件代码。

核心是"先部署 CSI 驱动,再启用 feature gate 做透明迁移,最后验证"。迁移靠 CSI migration 自动翻译。

#
★★★

9. local PV 的使用限制与调度约束

local PV 的使用限制与调度约束是什么?

  • local PV 的节点绑定
  • WaitForFirstConsumer 延迟绑定
  • 限制(单节点、无复制)

local PV 使用节点本地存储(目录或块设备),PV 通过 nodeAffinity 绑定到具体节点,Pod 只能调度到该节点。调度约束:local PV 必须用 volumeBindingMode: WaitForFirstConsumer(延迟绑定),让 Pod 先调度再绑定 PV,避免 Pod 调度到无数据的节点。限制:数据只在单节点,无跨节点复制、无高可用;节点故障数据丢失;Pod 无法跨节点迁移;需要手动管理节点拓扑与容量。适合对数据本地性要求高、可容忍单节点故障的场景。

核心是"节点绑定 + 延迟绑定 + 单节点限制"。local PV 高性能但无高可用。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: { name: local }
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
#
★★

10. CSI 存储拓扑(topology)与 zone/region 感知调度

CSI 存储拓扑(topology)与 zone/region 感知调度如何工作?

  • CSI topology 概念
  • 拓扑感知调度
  • 可用区/区域约束

CSI 存储拓扑让存储感知节点的物理位置(zone/region)。CSI 驱动通过 topology 声明卷可用的位置(如某 zone 的存储)。当 StorageClass 带 topology 约束时,调度器会考虑节点与存储的拓扑匹配:使用 WaitForFirstConsumer 延迟绑定,等 Pod 调度到某 zone 后,provisioner 在该 zone 创建卷,使 Pod 与卷在同一区域,避免跨 zone 访问(降低延迟、满足合规)。这样实现"卷与工作负载同区域"的拓扑感知调度。

核心是"存储与节点拓扑匹配 + 延迟绑定"。保证卷与 Pod 同 zone。

#
★★

11. ConfigMap/Secret 热更新与 Pod 内文件同步的延迟问题

ConfigMap/Secret 热更新与 Pod 内文件同步的延迟问题如何处理?

  • 挂载文件的更新机制
  • 同步延迟
  • 环境变量不更新

ConfigMap/Secret 作为卷挂载时,kubelet 会定期(默认约 1 分钟,可通过 kubelet config 的 configMapAndSecretChangeDetectionInterval 调整)同步更新卷内文件,Pod 内文件随之变化,但已有进程不自动读取新值(需应用自行 watch 文件或重启)。作为环境变量注入时,更新不会同步到已运行容器(环境变量只在启动时读取)。因此热更新只对挂载文件生效且存在延迟,应用需自行处理重载。若需即时更新,可配置 short 间隔或重启应用。

核心是"挂载文件有同步延迟,环境变量不更新"。应用需 watch 文件或重启。

#
★★

12. K8s PVC 在线扩容的完整流程(StorageClass 支持/文件系统扩容/验证)如何做,失败如何回退?

K8s PVC 在线扩容的完整流程(StorageClass 支持/文件系统扩容/验证)如何做,失败如何回退?

  • 扩容条件(StorageClass allowVolumeExpansion)
  • 修改 PVC 容量
  • 文件系统扩容

在线扩容流程:1)确认 StorageClass 启用了 allowVolumeExpansion: true;2)编辑 PVC 增大 spec.resources.requests.storage;3)CSI 控制器执行 ControllerExpandVolume 扩容底层存储;4)kubelet 在节点上执行 NodeExpandVolume 扩容文件系统(需 Pod 挂载卷);5)验证 kubectl get pvc 状态与 df 输出。只有底层存储支持并可扩容时才能在线扩容。失败回退:若扩容失败,PVC 状态变为异常,需检查驱动日志;部分操作不可回退(已扩容的底层存储一般不能缩小),需谨慎并备份。

核心是"allowVolumeExpansion + 修改容量 + 底层/文件系统扩容"。扩容通常不可缩回,需备份。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: { name: expandable }
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true
kubectl edit pvc mypvc
# 增大 spec.resources.requests.storage 到更大的值
#
★★

13. K8s 中如何使用 NFS 提供 PV(静态供给、挂载参数与故障处理)?

K8s 中如何使用 NFS 提供 PV(静态供给、挂载参数与故障处理)?

  • 静态 PV 供给
  • NFS 挂载参数
  • 故障处理

NFS 需静态供给 PV:管理员创建 PV,spec.nfs.server 指向 NFS 服务器、path 指向导出目录,并声明 accessModes(ReadWriteMany)与 capacity。PVC 绑定该 PV,Pod 挂载。NFS 支持多读多写(ReadWriteMany),适合共享存储。挂载参数(如 nfsvers、mountOptions)可在 PV 的 mountOptions 配置。故障处理:NFS 服务器故障会导致所有挂载 Pod 的 I/O 卡住(挂载为硬挂接),需监控 NFS 可用性;NFS 本身无高可用(除非用 NFS+HA/DRBD),需冗余。

核心是"静态 PV + NFS server/path + ReadWriteMany"。NFS 故障会导致挂载 I/O 停滞。

apiVersion: v1
kind: PersistentVolume
metadata: { name: nfs-pv }
spec:
  accessModes: [ReadWriteMany]
  capacity: { storage: 100Gi }
  nfs:
    server: 10.0.0.10
    path: /exports/data
  mountOptions: [vers=4, hard, nolock]
#
★★

14. Velero 备份恢复与 restic 集成

Velero 备份恢复与 restic 集成如何工作?

  • Velero 备份机制
  • restic 卷备份
  • 恢复流程

Velero 是 Kubernetes 备份/恢复工具,备份集群资源(对象)与持久卷数据。对象备份通过 API 导出资源;卷数据备份通过 restic(或 FileSystem Backup)集成,将 PVC 中的数据备份到对象存储(如 S3、Azure Blob)。restic 以 DaemonSet 方式运行在各节点,对 Pod 的卷做文件级别备份。恢复:用 velero restore 从备份恢复资源与卷,可指定 namespace 映射、label 过滤。备份计划用 Schedule 定期执行。

核心是"对象+卷数据备份、restic 卷级备份、对象存储暂存"。用于灾备与迁移。

velero backup create my-backup --include-namespaces app
velero schedule create daily --schedule="0 2 * * *"
velero restore create --from-backup my-backup
#
★★

15. dockerconfigjson 类型 Secret 如何用于私有仓库镜像拉取认证?

dockerconfigjson 类型 Secret 如何用于私有仓库镜像拉取认证?

  • dockerconfigjson 类型
  • 创建方式
  • imagePullSecrets

dockerconfigjson 类型 Secret 保存 Docker 的认证配置(~/.docker/config.json 内容),用于私有仓库镜像拉取。创建:kubectl create secret docker-registry(自动生成 .dockerconfigjson 字段)。使用:在 Pod 或 ServiceAccount 的 imagePullSecrets 指定该 Secret,kubelet 拉取镜像时用它认证。也可把 Secret 关联到 ServiceAccount,使该 SA 创建的 Pod 自动使用。它包含仓库地址、用户名、密码(base64 加密)。

核心是"保存 docker 认证并用于镜像拉取"。常用 create secret docker-registry 创建。

kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=user --docker-password=pass
apiVersion: v1
kind: Pod
metadata: { name: app }
spec:
  imagePullSecrets:
    - name: regcred
  containers: [{ name: c, image: registry.example.com/app:latest }]
#
★★

16. emptyDir 卷如何在 Pod 内容器间共享数据及其生命周期限制?

emptyDir 卷如何在 Pod 内容器间共享数据及其生命周期限制?

  • emptyDir 的共享
  • 生命周期(随 Pod)
  • 与宿主存储

emptyDir 是 Pod 内的临时空卷,Pod 内多个容器可同时挂载同一 emptyDir 卷,实现容器间数据共享(如 sidecar 共享日志、缓存)。它的生命周期与 Pod 相同:Pod 创建时空卷,Pod 删除(无论原因)时清空。emptyDir 默认存于节点临时存储(可配置 medium=Memory 用 tmpfs 内存)。用途:容器间通信、临时缓存、日志中转。限制:数据不持久,Pod 重建丢失;不适合持久数据。

核心是"容器间共享 + 随 Pod 生命周期"。数据不持久。

apiVersion: v1
kind: Pod
metadata: { name: app }
spec:
  containers:
    - name: writer
      image: writer
      volumeMounts: [{ name: shared, mountPath: /data }]
    - name: reader
      image: reader
      volumeMounts: [{ name: shared, mountPath: /read }]
  volumes:
    - name: shared
      emptyDir: {}
#

17. External Secrets Operator 如何从 Azure Key Vault 拉取密钥并同步为 Secret?

External Secrets Operator 如何从 Azure Key Vault 拉取密钥并同步为 Secret?

  • External Secrets Operator 原理
  • SecretStore 配置
  • 同步为 Secret

External Secrets Operator(ESO)通过 SecretStore 定义外部密钥源(如 Azure Key Vault),自动把外部密钥拉取并同步为 Kubernetes Secret。配置:1)创建 SecretStore 指定 provider 为 azure(含 vault 的 tenantId、clientId、client secret 或身份认证);2)创建 ExternalSecret 声明要从 Key Vault 拉取的密钥(target 指定生成的 Secret 名称),ESO 拉取并创建/更新对应 Secret。支持自动轮换(轮询更新 Secret)。Secret 内容在 Secret 中 base64 存储。

核心是"SecretStore 定义源 + ExternalSecret 声明拉取"。实现外部密钥集中管理。

apiVersion: external-secrets.io/v1
kind: SecretStore
metadata: { name: vault }
spec:
  provider:
    azure:
      tenantId: "<tenant>"
      vaultUrl: "https://myvault.vault.azure.net"
      authSecretRef: { clientId: { name: azure-creds, key: clientId }, clientSecret: { name: azure-creds, key: clientSecret } }
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata: { name: db-secret }
spec:
  secretStoreRef: { name: vault, kind: SecretStore }
  target: { name: app-db-secret }
  data:
    - secretKey: db_password
      remoteRef: { key: db/password }
#

18. External Secrets Operator 如何对接 GCP Secret Manager 同步密钥?

External Secrets Operator 如何对接 GCP Secret Manager 同步密钥?

  • GCP Secret Manager provider
  • SecretStore 配置
  • 同步为 Secret

ESO 对接 GCP Secret Manager:SecretStore 的 provider 设为 gcp,指定 projectID 与认证(workload identity 或 service account key)。ExternalSecret 声明从 Secret Manager 拉取密钥(remoteRef 的 key 为 Secret Manager 的 secret 名与版本),ESO 拉取并同步为 Kubernetes Secret。支持按版本拉取、自动轮换。GCP 认证推荐用 Workload Identity 免钥。

核心是"gcp provider + workload identity + ExternalSecret"。集中管理 GCP 密钥。

apiVersion: external-secrets.io/v1
kind: SecretStore
metadata: { name: gcp-store }
spec:
  provider:
    gcp:
      projectID: my-project
      auth: { workloadIdentity: { clusterLocation: us-central1, clusterName: my-cluster, serviceAccountRef: { name: sa } } }
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata: { name: gcp-secret }
spec:
  secretStoreRef: { name: gcp-store, kind: SecretStore }
  target: { name: app-secret }
  data:
    - secretKey: api_key
      remoteRef: { key: my-secret, version: "1" }
#

19. SOPS 如何加密 Git 中的敏感配置并与 GitOps 工作流集成?

SOPS 如何加密 Git 中的敏感配置并与 GitOps 工作流集成?

  • SOPS 加密原理
  • 加密解密流程
  • 与 GitOps 集成

SOPS(Secrets OPerationS)加密文件中的敏感内容:YAML/JSON 格式对值逐项加密,INI/ENV 等格式则加密整个文件。它用 KMS 密钥(GCP/AWS/Azure)或 age/PGP 加密。加密后文件可安全提交 Git,解密需密钥。支持多种格式(YAML/JSON/INI/ENV)。与 GitOps 集成:在 CI/CD 中解密并渲染(如 Helm 插件 helm-secretssops 解密后 apply),或在 Argo CD 中用插件/AOT 解密。保证 Git 中不存明文密钥,密钥由 KMS 管理。

核心是"文件级加密 + KMS 密钥 + GitOps 解密渲染"。Git 中只存密文。

# 加密文件
sops -e secret.yaml > secret.enc.yaml
# 解密
sops -d secret.enc.yaml
# .sops.yaml 规则指定加密字段