本篇面向已经会使用 kubectl 部署应用的人。这里只讲“应用怎么从 Configra 取配置”;部署 Configra 自身是另一件事。第一次试用不需要 Kubernetes,先看本地体验。
先选读取方式
| 方式 | 数据放在哪里 | 更新方式 | 适用情况 |
|---|---|---|---|
| CSI provider | Pod 的临时 CSI 文件卷 | 驱动轮换,应用重读文件 | 希望不创建原生配置对象 |
| Binding controller | Kubernetes API / etcd 中的 Secret 或 ConfigMap | 原生 volume 更新;envFrom 需要替换 Pod | 保留现有应用的 Kubernetes 接入方式 |
可以把配置的维护位置从 ConfigMap 换到 Configra,但不需要替换 Kubernetes 的内置 API:
- CSI 文件挂载:由驱动把配置变成 Pod 内的文件,不必先创建原生 Secret / ConfigMap。
- 原生同步:一个后台控制器定时从 Configra 读取,再写入 Secret / ConfigMap。应用继续使用原来的挂载或环境变量方式。
两种方式都不替应用重新加载配置。特别是环境变量,只在进程启动时读取,更新后需要重新创建 Pod。
已有 envFrom 的应用,可以直接看本页的“环境变量:完整示例”。其中会创建一个演示 Deployment,实际检查变量,并演示一次配置更新。应用读取 YAML/JSON 文件时,使用文件挂载,不必为了接入 Configra 把配置改成环境变量。
部署前准备
开始前确认:
- 已部署 Configra 服务,API 地址能从集群内访问。不要使用指向 Pod 自身的
localhost。 - 已取得 v1.0.1 源码,下方命令从源码根目录执行。二进制发布包含部署清单,但不含 Dockerfile 和编译所需源码;构建镜像不能只用二进制包。
- 已在 Configra 中创建环境
production。文件示例使用 Configapplication,环境变量示例使用 Configapplication_env,下文分别给出内容。如果使用本地体验的development/payment,要同步修改清单中的环境和 Config key。 - 已准备允许读取该环境的 Token、客户端证书和私钥,见证书与访问凭据。
以下操作会在当前 kubectl context 创建资源,请先确认不是误选了生产集群:
kubectl config current-context
还没有源码时,先下载;已有该版本源码则直接进入其根目录:
git clone --depth 1 --branch v1.0.1 https://github.com/viber-ops/configra.git configra-1.0.1
cd configra-1.0.1
先构建并推送 configra-kubernetes 镜像。把下面的 registry.example.com/team 换成你可推送、集群可拉取的仓库地址;私有仓库还需要为工作负载配置 imagePullSecrets。
docker build -f kubernetes/Dockerfile -t registry.example.com/team/configra-kubernetes:1.0.1 .
docker push registry.example.com/team/configra-kubernetes:1.0.1
镜像架构必须匹配节点。比如在 Apple Silicon Mac 上构建、部署到 amd64 节点时,改用下面的命令;buildx --push 会直接推送,不再单独执行 docker push。混合架构集群可把平台列表改成 linux/amd64,linux/arm64:
kubectl get nodes -L kubernetes.io/arch
docker buildx build --platform linux/amd64 -f kubernetes/Dockerfile \
-t registry.example.com/team/configra-kubernetes:1.0.1 --push .
overlay 是你自己的部署定制目录,用来替换示例镜像、API 地址和 Namespace(命名空间),不需要修改 Configra 程序。下文给出完整 overlay。API 地址由 provider / controller 部署参数设定,应用不能在读取规则里另填一个地址。
确认目标应用命名空间已经存在,下面使用 configra-app;没有时先创建它。把 /secure/ 路径换成真实的受控文件路径,再创建凭据 Secret:
kubectl create namespace configra-app --dry-run=client -o yaml | kubectl apply -f -
kubectl -n configra-app create secret generic configra-credentials \
--from-file=token=/secure/configra-token \
--from-file=tls.crt=/secure/client.crt \
--from-file=tls.key=/secure/client.key
本页的部署示例使用内部服务器 CA。configra-server-trust Secret 的 ca.crt 用来验证 API 服务器,不是 Administration 中签发客户端证书的 CA:
kubectl -n configra-app create secret generic configra-server-trust \
--from-file=ca.crt=/secure/server-ca.crt
把 /secure/server-ca.crt 换成 API 服务器证书的实际签发 CA。若服务器使用公共 PKI,可移除 --server-ca-file、server-trust volumeMount 和 volume,使用系统信任根。不要用 insecureSkipVerify 绕过验证。
这些 Secret 只需要创建一次;重跑时的 AlreadyExists 不代表接入失败。要换凭据时更新已有 Secret,不要先删除正在使用的凭据。configra-app 是 Kubernetes Namespace,production 是 Configra Environment,二者不是同一个字段。
不同工作负载应使用独立 Token 和证书,便于轮换与吊销。但授予同一个 Environment 的 Token 仍有相同的服务端配置读取范围,Kubernetes Namespace 不会缩窄它。
CSI 文件挂载
先在 Configra 选择 production,创建 key 为 application、格式为 YAML 的 Config,保存下面的演示内容。这是 Configra 中的配置,不是 Kubernetes 清单:
server:
port: 8080
log_level: info
文件示例读取的是图中的 application;后面的环境变量示例使用另一个 Config,名为 application_env。截图均为演示数据,点击可查看原图。
文件方式会保留这份嵌套结构,不需要改成扁平映射。JSON Config 也可以作为文件读取;此时把对象的 path 和应用读取路径改成 app.json,扩展名本身不会转换内容格式。
先安装 Secrets Store CSI Driver,它负责把 provider 返回的内容挂载进 Pod。已有集群验证使用 Kubernetes 1.35.0 和 Driver 1.6.1;这不是对其他组合的测试承诺。安装驱动的方法见官方安装文档。需要定时更新文件时,开启 enableSecretRotation=true,用 rotationPollInterval 设置刷新间隔。
Driver 1.6 起,这个间隔是两次轮换之间的最短缓存时间,实际更新还要等 kubelet 再次请求挂载。设为 5 秒,不代表文件一定在 5 秒内更新。详见驱动的轮换机制。
创建 kubernetes/deploy/example-provider/kustomization.yaml,内容如下。把 newName 换成刚推送的镜像仓库,把 --configra-url 换成集群可达、且与服务器证书匹配的 API 地址。images.name 是被替换的原始示例镜像名,不需要改:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../provider
images:
- name: registry.example.com/configra-kubernetes
newName: registry.example.com/team/configra-kubernetes
newTag: '1.0.1'
patches:
- target:
kind: DaemonSet
name: configra-provider
patch: |-
- op: replace
path: /spec/template/spec/containers/0/args/2
value: --configra-url=https://configra-api.configra.svc
给 provider 的 Namespace 单独创建服务器信任 Secret,然后部署:
kubectl create namespace configra-provider --dry-run=client -o yaml | kubectl apply -f -
kubectl -n configra-provider create secret generic configra-server-trust \
--from-file=ca.crt=/secure/server-ca.crt
kubectl kustomize kubernetes/deploy/example-provider
kubectl apply -k kubernetes/deploy/example-provider
kubectl -n configra-provider rollout status daemonset/configra-provider --timeout=120s
kubectl apply -f kubernetes/examples/provider.yaml
kubectl -n configra-app wait pod/configra-file-reader --for=condition=Ready --timeout=120s
kubectl -n configra-app exec configra-file-reader -- \
sh -c 'test -s /etc/application/app.yaml && echo "app.yaml is ready"'
最后一条命令应输出 app.yaml is ready。仓库示例将凭据 Secret 交给 CSI 驱动,应用容器本身不挂载 Token 或客户端私钥,只能读取 /etc/application/app.yaml。它使用 BusyBox 验证文件送达,不会启动业务服务。
SecretProviderClass 是“读取哪些配置、保存成哪些文件”的规则。下面这段会把 production 环境的 application 配置挂载为 app.yaml。它不是完整的应用部署文件;仓库的完整示例还包含 Pod、只读挂载和凭据引用 nodePublishSecretRef:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: configra-application
namespace: configra-app
spec:
provider: configra
parameters:
fileMode: '0444'
objects: |
- type: config
environment: production
config: application
path: app.yaml
默认文件权限是 0440,允许 0400 / 0444。上面的非 root 示例明确使用 0444,意味着挂载内的文件对该 Pod 中其他 UID 也可读;若应用具备正确所有者或组配置,应采用更窄权限。不要假定 fsGroup 会在每次轮换后自动修复所有权,不要用需要轮换的 subPath。
provider 是可信节点扩展:以 root 管理 hostPath 上的 Unix socket,不挂载 ServiceAccount API Token。需要独立评估其节点信任与部署权限。
要检查更新,先执行以下命令记下文件校验值,再把 Configra 中 application 的 server.port 改成 8081 并保存。等待轮换后重复执行。第一条查看挂载状态和版本,第二条只输出文件校验值,不打印配置内容;校验值应与修改前不同。业务应用仍须重读文件才能采用新端口。
kubectl -n configra-app get secretproviderclasspodstatus
kubectl -n configra-app exec configra-file-reader -- cksum /etc/application/app.yaml
原生 Secret / ConfigMap 同步
先安装 CRD,让 Kubernetes 认识 ConfigraBinding 这种同步规则,再在应用命名空间部署控制器。示例有两个副本,正常情况下由选出的主副本负责同步,另一个等待接管。控制器只能使用本命名空间的凭据和目标,不要将它部署到存有 Configra Master Key 的命名空间。
两个副本不代表它们一定在不同节点。用 kubectl -n configra-app get pods -l app.kubernetes.io/name=configra-sync -o wide 检查 NODE 列,再通过部署 overlay 的调度规则将副本分散。示例中的 PodDisruptionBudget 只约束遵守它的驱逐操作,不能阻止节点突然离线或直接删除 Pod。见 Kubernetes 中断说明。
先部署同步控制器
原生同步不需要安装 CSI Driver 或 provider。 创建 kubernetes/deploy/example-sync/kustomization.yaml,替换镜像仓库和 API 地址:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../sync
images:
- name: registry.example.com/configra-kubernetes
newName: registry.example.com/team/configra-kubernetes
newTag: '1.0.1'
patches:
- target:
kind: Deployment
name: configra-sync
patch: |-
- op: replace
path: /spec/template/spec/containers/0/args/2
value: --configra-url=https://configra-api.configra.svc
kubectl apply -f kubernetes/deploy/crd.yaml
kubectl wait crd/configrabindings.configra.viber-ops.github.io --for=condition=Established --timeout=60s
kubectl kustomize kubernetes/deploy/example-sync
kubectl apply -k kubernetes/deploy/example-sync
kubectl -n configra-app rollout status deployment/configra-sync --timeout=120s
rollout status 成功只说明控制器已启动,接下来还要检查 Binding 是否读取成功。环境变量接入请继续看下一节;文件接入则使用下面的示例。
把嵌套 YAML 挂载为文件
在 production 环境保存前面 application 的嵌套 YAML。下面是发布包中 kubernetes/examples/binding.yaml 的完整内容:
apiVersion: configra.viber-ops.github.io/v1alpha1
kind: ConfigraBinding
metadata:
name: application
namespace: configra-app
spec:
credentialsSecretRef:
name: configra-credentials
target:
name: application-config
kind: Secret
mode: files
refreshInterval: 1m
objects:
- type: config
environment: production
config: application
path: app.yaml
上面的 ConfigraBinding 表示每分钟读取一次,把配置保存到名为 application-config 的 Secret,文件名为 app.yaml。
先等待 Secret 生成:
kubectl apply -f kubernetes/examples/binding.yaml
kubectl -n configra-app wait configrabinding/application --for=condition=Ready --timeout=120s
kubectl -n configra-app describe secret application-config
describe secret 应显示一个名为 app.yaml 的数据项和它的字节数,不会展示内容。把下面的完整清单保存为 file-demo.yaml;Pod 会把这个数据项挂载为 /etc/application/app.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: file-demo
namespace: configra-app
spec:
replicas: 1
selector:
matchLabels: {app: file-demo}
template:
metadata:
labels: {app: file-demo}
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile: {type: RuntimeDefault}
containers:
- name: application
image: busybox:1.37.0
command: [sh, -c, 'while true; do sleep 3600; done']
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: {drop: [ALL]}
resources:
requests: {cpu: 5m, memory: 8Mi}
limits: {memory: 32Mi}
volumeMounts:
- name: configuration
mountPath: /etc/application
readOnly: true
volumes:
- name: configuration
secret:
secretName: application-config
defaultMode: 0444
kubectl apply -f file-demo.yaml
kubectl -n configra-app rollout status deployment/file-demo --timeout=120s
kubectl -n configra-app exec deployment/file-demo -- \
sh -c 'test -s /etc/application/app.yaml && echo "app.yaml is ready"'
这个例子用 0444 让非 root 演示容器读取文件;同一 Pod 中可访问该挂载的其他 UID 也能读取,应按实际工作负载收紧权限。没有使用 subPath,因此 Secret 更新可以传播到文件。传播存在延迟,应用仍须重读文件;这个 BusyBox 例子只验证文件存在。
默认使用 Secret。Secret 仍需要集群访问控制和合适的存储加密,名称不代表内容天然安全。ConfigMap 不适合机密值;包含 Vault 派生值时,必须显式设置 allowSensitiveConfigMap: true 才允许写入 ConfigMap。即便没有 Vault 引用,普通 Config 也可能包含敏感信息,需要操作者自行判断。
环境变量:完整示例
目标是让容器读到 PORT=8080、LOG_LEVEL=info、ENABLE_METRICS=true。数据经过三步:Configra 中的 Config → 控制器生成的 Secret → Deployment 的 envFrom。应用不需要安装 SDK。
前提是已完成本页的凭据准备和同步控制器部署。下面的 Configra 配置和 Kubernetes 清单是两种不同文件,不要把第一步的配置交给 kubectl apply。
1. 在 Configra 保存配置
选择环境 production,创建 key 为 application_env、格式为 YAML 的 Config,保存:
PORT: 8080
LOG_LEVEL: info
ENABLE_METRICS: true
保存后应能看到上图中的三个字段。截图来自真实演示环境,点击可查看原图;下方命令和配置均可复制。
这就是“扁平映射”:每个顶层 key 对应一个变量,右边直接是值,没有下一层。也可以把格式选为 JSON,保存等价内容,后面的 Binding 和 Deployment 不用改:
{
"PORT": 8080,
"LOG_LEVEL": "info",
"ENABLE_METRICS": true
}
到容器里,数字 8080 和布尔值 true 都会变成字符串。变量名保留原样,不自动改大小写;必须符合 [A-Za-z_][A-Za-z0-9_]*。有前导零等需要保持原样的值,请在源配置中写成字符串,例如 ACCOUNT_CODE: '00123'。
2. 创建同步规则
保存下面的完整清单为 env-binding.yaml:
apiVersion: configra.viber-ops.github.io/v1alpha1
kind: ConfigraBinding
metadata:
name: application-env
namespace: configra-app
spec:
credentialsSecretRef:
name: configra-credentials
target:
name: application-env
kind: Secret
mode: env
refreshInterval: 30s
objects:
- type: config
environment: production
config: application_env
path: environment.yaml
这里三个名称分别是:config: application_env 指 Configra 中的 Config key;target.name: application-env 是将要生成的 Kubernetes Secret;credentialsSecretRef 指已有的访问凭据。path 仍是每个源对象必填的唯一标识,但 env 模式不会创建 environment.yaml 文件或同名变量,Secret 中的 key 是 PORT、LOG_LEVEL、ENABLE_METRICS。
kubectl apply -f env-binding.yaml
kubectl -n configra-app wait configrabinding/application-env --for=condition=Ready --timeout=120s
kubectl -n configra-app describe secret application-env
应看到三个数据项。目标 Secret 由控制器创建,不要提前手动创建同名 Secret,否则会报 TargetCollision。如果等待超时,先查看下文的排错表,不要反复删除重建。
3. 让应用使用 envFrom
保存为 env-demo.yaml。这是可直接运行的演示 Deployment;接入自己的应用时替换 image 和启动命令,保留 envFrom.secretRef:
apiVersion: apps/v1
kind: Deployment
metadata:
name: env-demo
namespace: configra-app
spec:
replicas: 1
selector:
matchLabels: {app: env-demo}
template:
metadata:
labels: {app: env-demo}
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile: {type: RuntimeDefault}
containers:
- name: application
image: busybox:1.37.0
command: [sh, -c, 'while true; do sleep 3600; done']
envFrom:
- secretRef:
name: application-env
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: {drop: [ALL]}
resources:
requests: {cpu: 5m, memory: 8Mi}
limits: {memory: 32Mi}
kubectl apply -f env-demo.yaml
kubectl -n configra-app rollout status deployment/env-demo --timeout=120s
kubectl -n configra-app exec deployment/env-demo -- \
sh -c 'printf "%s\n" "PORT=$PORT" "LOG_LEVEL=$LOG_LEVEL" "ENABLE_METRICS=$ENABLE_METRICS"'
预期输出:
PORT=8080
LOG_LEVEL=info
ENABLE_METRICS=true
这里只打印三个不含敏感值的演示变量,不要用不带变量名的 env / printenv 排查真实应用,避免把所有密码打进终端或工单。这个 Deployment 不启动 HTTP 服务,PORT 只是用来验证传值。
4. 修改后,确认同步再重启 Pod
在 Configra 将 LOG_LEVEL 改成 debug 并保存。等待控制器下一次同步,用下面的命令只查看这个非敏感字段;返回 debug 才说明 Secret 已更新:
kubectl -n configra-app get secret application-env \
-o go-template='{{index .data "LOG_LEVEL" | base64decode}}{{"\n"}}'
kubectl -n configra-app exec deployment/env-demo -- printenv LOG_LEVEL
此时第一条应返回 debug,第二条仍返回 info。Ready=True 可能是上一次成功留下的状态,重新执行 kubectl wait 不能证明这次编辑已经送达。确认 Secret 是新值后,再替换应用 Pod:
kubectl -n configra-app rollout restart deployment/env-demo
kubectl -n configra-app rollout status deployment/env-demo --timeout=120s
kubectl -n configra-app exec deployment/env-demo -- printenv LOG_LEVEL
现在应返回 debug。Configra 不会替你自动重启 Deployment;也不要把重启同步控制器当成应用重载。若自己的 Deployment 已在 env 中定义同名变量,它会覆盖 envFrom 的值,接入时检查是否有重复定义。参见 Kubernetes 环境变量说明。
5. 加入 Vault 引用,并切换开发环境
跑通后,可以在 Vault 的 namespace platform、item database 中创建 Text 字段 host 和 Secret 字段 password。创建两组值(Variant),分别绑定 production 和 development:
图中选中 production,host 是 db.prod.internal。选择 development 后填写 db.dev.internal 和开发密码。字段 key 仍是 host、password,不要按环境另外建字段。
再把 application_env 改为下面的内容,并在两个 Environment 中都保存一份;引用文本保持相同:
PORT: 8080
LOG_LEVEL: info
ENABLE_METRICS: true
DB_HOST: '{vault.platform.database.host}'
DB_PASSWORD: '{vault.platform.database.password}'
原始配置保存的是引用,不是密码。上图仍选择 production;为 development 保存相同文本后,由读取时指定的 environment 决定实际值。
| Configra Environment | Vault 的 host 演示值 |
容器读取的变量名 |
|---|---|---|
| production | db.prod.internal | DB_HOST、DB_PASSWORD |
| development | db.dev.internal | DB_HOST、DB_PASSWORD |
为开发工作负载准备独立的 Token/证书和凭据 Secret。复制 Binding 到开发工作负载所在 Namespace 时,只需选择 environment: development、对应的 credentialsSecretRef 和命名空间;Config key 仍为 application_env,应用仍读 DB_HOST / DB_PASSWORD。不要为了演示直接把正在运行的生产 Binding 改指向开发环境。
同步拿到的是 Configra 已渲染的值,不是花括号引用。更新 Secret 并替换演示 Pod 后,可以只检查密码是否存在,不展示内容:
kubectl -n configra-app exec deployment/env-demo -- \
sh -c 'test -n "$DB_PASSWORD" && echo "DB_PASSWORD is set"'
Vault 的 File 字段不能作为 env 对象使用,要用文件挂载。env 的 YAML/JSON 值也不能是数组、对象或 null;空字符串则应明确写为 OPTIONAL_VALUE: ''。
哪些配置不能用于 env
下面这个 Config 不能用于 env 模式:控制器不会自动把它改成 DATABASE_HOST。
database:
host: db.prod.internal
需要环境变量就改成 DATABASE_HOST: db.prod.internal;应用本来就读取嵌套 YAML,则保留原结构,改用 files 模式,不要强行展开。重复 key、database.host 这类不符合命名规则的 key、多个 objects 提供同一个变量名,也会被拒绝,不会采用“后面的覆盖前面的”。
若已有应用使用 envFrom.configMapRef 且数据确实不敏感,可将 Binding 的 target.kind 改成 ConfigMap,并将 Deployment 对应的 secretRef 改成 configMapRef。不要只改一边。含 Vault 引用时继续使用 Secret;不建议为了消除报错而开启 allowSensitiveConfigMap。迁移已有 ConfigMap 时,先选择新的目标名并验证,再修改应用引用,控制器不会接管你的旧对象。
清理本节演示时,只删除这两个文件创建的资源。删除 Binding 会连带删除它生成的 Secret,不要对仍有应用使用的 Binding 执行此操作;共享的凭据、信任 Secret 和 Namespace 不在下面的清理范围内。
kubectl delete -f env-demo.yaml -f env-binding.yaml
同步不成功时先看什么
kubectl -n configra-app get configrabindings
kubectl -n configra-app get configrabinding application-env -o yaml
kubectl -n configra-app get pods
Binding 的 status.conditions 给出原因,status.lastSyncedAt 是上次成功同步时间;失败时旧目标和旧时间可能仍然存在。状态不会包含配置内容,也不会直接暴露上游的私有错误。
| 原因 / 现象 | 检查与处理 |
|---|---|
CredentialsUnavailable |
检查 credentialsSecretRef.name;凭据 Secret 必须和 Binding 在同一 Namespace,控制器要有读取权限 |
FetchFailed |
检查 API 网络和服务器 CA、Token 的 Environment 授权、客户端证书有效期/吊销状态,以及 Config key、当前环境的版本和 Vault 引用;不要关闭 TLS 验证 |
InvalidEnvironmentMap |
在 Configra 预览渲染结果;检查是否有嵌套对象、数组、null、非法变量名或重复 key,修正后重新保存 |
DuplicateEnvironmentName |
多个源 Config 定义了同一变量;删除重复来源或重新命名,不能靠调整对象顺序覆盖 |
SensitiveConfigMapDenied |
Vault 派生值不应放入 ConfigMap;改用 Secret,同时修改应用的引用类型 |
TargetCollision |
目标名已被非本 Binding 的对象占用;换新目标名,不能直接删除或接管正在使用的业务 Secret / ConfigMap |
TargetTooLarge |
原生目标总计超过 900 KiB;减小内容,或评估改用文件读取,不要假设换成 Secret 就没有限制 |
CreateContainerConfigError |
先让 Binding 达到 Ready,再检查 Pod 引用的 Secret/ConfigMap 名称和 Namespace |
ImagePullBackOff |
示例 registry 没替换、镜像没推送,或节点没有拉取私有镜像的凭据 |
| Secret 已更新,变量没变 | 先确认查看的是正确目标;再滚动更新应用的 Deployment,并检查 env 是否覆盖了同名变量 |
读取失败、修改和删除
原生控制器只更新自己持有 owner reference 的目标,不覆盖无关对象。读取失败保留旧内容;修改目标名称或类型后,在新目标写入成功后移除旧的自有目标。删除 Binding 会通过 Kubernetes 垃圾回收删除其拥有的目标。
CSI 读取失败不交付部分文件集合。已有文件或原生对象可能继续保留上一次数据;吊销凭据不能收回已经交付的字节。
CSI Driver 和 Configra provider 必须运行在每个消费配置的节点上。应用换到另一个节点时,需要重新挂载并从 Configra 读取;API 不可用时,新 CSI Pod 可能停在挂载阶段。仓库的单 Pod 示例只演示接入,不负责节点故障后的应用重建;实际应用应交给 Deployment 等工作负载控制器管理。
节点失联后的恢复不是即时的。服务流量要等 Kubernetes 发现故障并移除失联端点;sync 控制器则要等待存活副本取得领导权。默认容忍时间还可能让 Pod 在发现故障后继续留在失联节点约五分钟;不要把它当作 Configra 的刷新间隔。见 Kubernetes 节点失联与驱逐。
限制:CSI 至多 32 个对象、总计 3 MiB;原生目标总计 900 KiB;env 模式每份文档至多 128 KiB。
原生 volume 更新具有传播延迟,envFrom 创建的进程环境不会自动改变。参阅 Kubernetes ConfigMap 更新机制与 CSI 轮换说明。



