使用AWS Workload Credentials Provider在EKS中管理应用密钥的实践

发布时间:2026/6/29 18:07:23
使用AWS Workload Credentials Provider在EKS中管理应用密钥的实践 本文档完整记录了在中国区 EKS 集群上部署 AWS Workload Credentials Provider 的全过程。通过 Sidecar 模式应用可以无感知地获取 AWS Secrets Manager 中的敏感配置无需在代码中处理复杂的 AWS 认证逻辑。在 Kubernetes 中管理 Secret 始终是个让人头疼的问题。传统的工作流中每个开发团队都要自己实现一套从 AWS 获取 Secret 的逻辑——有的用 SDK有的用 init container有的干脆写死在配置文件里。这不仅重复造轮子还带来了严重的安全隐患。AWS Workload Credentials ProviderWCP的出现改变了这一切。作为 AWS Secrets Manager Agent 的演进版本它采用了 Sidecar 代理模式——你在 Pod 中描述想要的 SecretWCP 负责获取、缓存和提供。在我们的实践中整个系统体现了优雅的分层思想。这种分层设计让每个组件职责单一便于独立演进和故障隔离。具体来说我们将整个架构划分为四个层次系统分层架构层级组件职责基础设施层EKS 集群、ECR、VPC提供计算和网络资源身份层EKS Pod Identity、IAM托管 AWS 凭证代理层WCP SidecarSecret 获取、缓存、刷新应用层Agent 应用业务逻辑无感知使用 Secret一个典型的 Pod 包含两个容器协同工作Agent 容器业务应用运行 LLM 代理服务通过 localhost 访问 SecretWCP 容器Sidecar提供本地 HTTP 服务缓存来自 Secrets Manager 的 API KeyWCP 网络架构与通信模型在深入部署之前理解 WCP 的通信模型至关重要。WCP 的设计哲学是将 Secret 管理下沉到基础设施层让应用容器无感知地使用。下图展示了 Pod 内部的网络拓扑外部访问Pod网络命名空间localhost:2773HTTPSAssumeRole注入凭证HTTPAgent App:8080WCP SidecarHTTP ServerAWS Secrets ManagerEKS Pod Identity用户通信时序Agent 调用 LLM 的完整流程GLM-5.2 APISecrets ManagerWCP SidecarAgent App用户GLM-5.2 APISecrets ManagerWCP SidecarAgent App用户1. Pod 启动阶段TTL 300秒预取完成2. 请求处理阶段Header: X-Aws-Parameters-Secrets-Token无需调用 AWS APIGetSecretValue(llm/api/config)返回 Secret 缓存到内存POST /chat {message:你好}GET localhost:2773/secretsmanager/get返回 Secret (缓存命中 1ms)POST open.bigmodel.cn/...Authorization: Bearer API Key返回 LLM 响应{response:我是GLM...}在整个通信过程中WCP 的性能表现是我们最关心的指标。基于实际测试我们收集了以下关键性能数据指标数值说明缓存命中延迟~1ms内存读取无网络 IO缓存未命中~50-100ms需调用 AWS API默认 TTL300s可配置预取数量2 个llm/api/config, test/wcp/demo在决定使用 Sidecar 模式之前我们对比了三种不同的部署方案。每种方案都有其特定的适用场景和权衡。建议生产环境使用 Sidecar 模式。WCP 的设计初衷就是 per-Pod 代理每个应用有自己的缓存实例故障域隔离。方案优点缺点适用场景Sidecar隔离性好故障不扩散缓存独立额外容器开销推荐生产环境DaemonSet资源共享节点级缓存单点故障权限共享测试环境SDK 直连简单直接重复造轮子无缓存不推荐配置详解以下是完整的 Dockerfile包含了 Rust 依赖的中国区镜像加速配置# # Stage 1: Builder # FROM public.ecr.aws/docker/library/rust:1.92-bookworm AS builder # 配置中国镜像加速 (Rust crates) RUN mkdir -p /usr/local/cargo \ echo [source.crates-io] /usr/local/cargo/config.toml \ echo replace-with rsproxy-sparse /usr/local/cargo/config.toml \ echo [source.rsproxy-sparse] /usr/local/cargo/config.toml \ echo registry sparsehttps://rsproxy.cn/index/ /usr/local/cargo/config.toml \ echo [net] /usr/local/cargo/config.toml \ echo git-fetch-with-cli true /usr/local/cargo/config.toml WORKDIR /src COPY . . RUN CARGO_HOME/usr/local/cargo cargo build --release \ cp /src/target/release/aws-workload-credentials-provider /aws-workload-credentials-provider # # Stage 2: Runtime # FROM public.ecr.aws/docker/library/debian:bookworm-slim RUN apt-get update \ apt-get install -y --no-install-recommends ca-certificates \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --frombuilder /aws-workload-credentials-provider /app/aws-workload-credentials-provider RUN chmod 0755 /app/aws-workload-credentials-provider ENTRYPOINT [/app/aws-workload-credentials-provider] CMD [sm, start, --config, /etc/wcp/config.toml]在这个 Dockerfile 中有几个关键配置需要特别注意配置说明rsproxy-sparse中国区 Rust crates 镜像加速依赖下载bookwormDebian 12glibc 2.36readOnlyRootFilesystem: true运行时根文件系统只读安全最佳实践ConfigMapWCP 采用 TOML 格式配置。核心参数说明配置项默认值说明ttl_seconds300Secret 缓存过期时间秒cache_size1000最大缓存 Secret 数量http_port2773WCP 监听端口ssrf_headersX-Aws-Parameters-Secrets-Token请求必须携带的 SSRF 防护头部prefetch.secrets-启动时预取的 Secret 列表apiVersion:v1kind:ConfigMapmetadata:name:wcp-confignamespace:namespacedata:config.toml:|[logging] log_level INFO log_to_file false[capabilities.secrets_manager]enabled true http_port 2773 region region max_conn 800[capabilities.secrets_manager.cache]ttl_seconds 300 cache_size 1000[capabilities.secrets_manager.security]ssrf_headers [X-Aws-Parameters-Secrets-Token]ssrf_env_variables [AWS_TOKEN][capabilities.secrets_manager.prefetch]cache_buffer_ratio 0.8 max_jitter_seconds 5[[capabilities.secrets_manager.prefetch.secrets]]secret_id llm/api/configDeploymentSidecar 模式 Deployment 关键配置配置项说明localhost:2773WCP 只监听 127.0.0.1仅本 Pod 可访问emptyDir (Memory)WCP 使用内存临时存储serviceAccountName绑定 EKS Pod Identity 的 ServiceAccountapiVersion:apps/v1kind:Deploymentmetadata:name:agent-appnamespace:namespacespec:replicas:1template:spec:serviceAccountName:wcp-app-sacontainers:-name:agentimage:account-id.dkr.ecr.region.amazonaws.com.cn/agent-app:latestports:-containerPort:8080env:-name:WCP_HOSTvalue:localhost-name:WCP_PORTvalue:2773-name:WCP_TOKENvalue:namespace-token-12345-name:SECRET_NAMEvalue:llm/api/configreadinessProbe:httpGet:path:/healthport:8080-name:wcp-providerimage:account-id.dkr.ecr.region.amazonaws.com.cn/wcp:latestargs:-sm-start---config-/etc/wcp/config.tomlenv:-name:AWS_REGIONvalue:region-name:AWS_TOKENvalue:namespace-token-12345volumeMounts:-name:wcp-configmountPath:/etc/wcpreadOnly:true-name:wcp-tmpmountPath:/tmpvolumes:-name:wcp-configconfigMap:name:wcp-config-name:wcp-tmpemptyDir:medium:MemoryAgent 应用代码Agent 应用通过localhost:2773访问 WCP 获取 Secret必须携带 SSRF TokenfuncgetEnv(key,defaultValuestring)string{ifvalue:os.Getenv(key);value!{returnvalue}returndefaultValue}funcgetSecretFromWCP()(*LLMConfig,error){url:fmt.Sprintf(http://%s:%s/secretsmanager/get?secretId%s,getEnv(WCP_HOST,localhost),getEnv(WCP_PORT,2773),getEnv(SECRET_NAME,llm/api/config))req,_:http.NewRequest(GET,url,nil)req.Header.Set(X-Aws-Parameters-Secrets-Token,getEnv(WCP_TOKEN,))client:http.Client{Timeout:10*time.Second}resp,err:client.Do(req)iferr!nil{returnnil,err}deferresp.Body.Close()varresultstruct{SecretStringstringjson:SecretString}json.NewDecoder(resp.Body).Decode(result)varllmConfig LLMConfig json.Unmarshal([]byte(result.SecretString),llmConfig)returnllmConfig,nil}测试验证Pod 状态检查$ kubectl get pods-nnamespace-owide NAME READY STATUS RESTARTS AGE agent-app-748ddb77d5-mwbms2/2 Running05mWCP 日志确认预取成功2026-06-28T11:18:40.818Z INFO - listening on http://127.0.0.1:2773 2026-06-28T11:18:45.728Z INFO - Pre-fetch complete: success2, failed0Health 检查$ kubectlexec-nnamespacedeployment/agent-app-cagent --\curl-shttp://localhost:8080/health{status:healthy}Chat 对话测试$ kubectlexec-nnamespacedeployment/agent-app-cagent --\curl-s-XPOST http://localhost:8080/chat\-HContent-Type: application/json\-d{message:你好}响应示例{model:GLM-5.2,response:我是GLM由Z.ai开发的大语言模型...}整个方案的核心价值在于让应用专注于业务逻辑将 Secret 管理交给基础设施。WCP 的本地缓存机制将 Secret 获取延迟从 50-100ms 降至 1ms同时 SSRF 防护确保了即使在高风险场景下也能安全地提供 Secret 服务。最后需要说明的是本文档只展示了 WCP 的 Secrets Manager 能力。实际上 WCP 还支持ACM 证书导出功能——它可以自动从 AWS Certificate Manager 导出 SSL/TLS 证书到本地文件系统并支持证书到期自动刷新和自定义刷新命令。如果你的应用需要管理 HTTPS 证书WCP 同样可以通过 Sidecar 或系统服务的方式提供自动化的证书管理。