TypeScript Runtime Config
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| ACK | Alibaba Cloud Container Service for Kubernetes | 阿里云容器服务 Kubernetes 版 |
| AKS | Azure Kubernetes Service | Azure 托管 Kubernetes 服务 |
| ASCP | AWS Secrets and Configuration Provider | AWS 秘密与配置提供程序,配合 Secrets Store CSI Driver 使用 |
| AWS | Amazon Web Services | 亚马逊云服务 |
| CSI | Container Storage Interface | 容器存储接口 |
| EKS | Elastic Kubernetes Service | AWS 托管 Kubernetes 服务 |
| ENV | Environment | 环境或环境变量 |
| ESO | External Secrets Operator | 将外部秘密系统中的值同步到 Kubernetes 的控制器 |
| GCP | Google Cloud Platform | Google 云平台 |
| GKE | Google Kubernetes Engine | Google 托管 Kubernetes 服务 |
| IAM | Identity and Access Management | 身份与访问管理 |
| IRSA | IAM Roles for Service Accounts | 通过 Kubernetes 服务账号关联 AWS IAM 角色 |
| KMS | Key Management Service | 密钥管理服务 |
| RAM | Random Access Memory | 随机存取内存 |
| RBAC | Role-Based Access Control | 基于角色的访问控制 |
| SDK | Software Development Kit | 软件开发工具包 |
| TTL | Time To Live | 存活时间;具体指缓存有效期或记录过期时间 |
| VSO | Vault Secrets Operator | 将 Vault 秘密同步到 Kubernetes 的控制器 |
Links#
https://kubernetes.io/docs/concepts/configuration/secret/
https://docs.docker.com/compose/how-tos/environment-variables/
https://docs.aws.amazon.com/eks/latest/userguide/manage-secrets.html
https://cloud.google.com/secret-manager/docs/secret-manager-managed-csi-component
https://learn.microsoft.com/en-us/azure/aks/csi-secrets-store-driver
https://www.alibabacloud.com/help/en/kms/key-management-service/user-guide/integrate-kms-secrets-into-ack
https://external-secrets.io/latest/
https://developer.hashicorp.com/vault/docs/platform/k8s/vso1. Important Points#
configuration goal:
same image
different runtime config
no secret in git
no secret baked into image
fail fast when config missing
config types:
non-secret config:
PORT
LOG_LEVEL
FEATURE_FLAG
PAYMENT_API_URL
secret config:
DATABASE_PASSWORD
JWT_SECRET
API_TOKEN
PRIVATE_KEY
rule:
non-secret -> ConfigMap / env / config file
secret -> Secret / external secret manager / mounted file2. Application Config Loader#
import "dotenv/config";
import { readFileSync, existsSync } from "node:fs";
import { z } from "zod";
const configSchema = z.object({
NODE_ENV: z.enum(["local", "dev", "test", "staging", "prod"]).default("local"),
PORT: z.coerce.number().int().positive().default(3000),
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32)
});
function readSecret(name: string): string | undefined {
const filePath = process.env[`${name}_FILE`];
if (filePath !== undefined && existsSync(filePath)) {
return readFileSync(filePath, "utf8").trim();
}
return process.env[name];
}
const parsed = configSchema.safeParse({
...process.env,
JWT_SECRET: readSecret("JWT_SECRET")
});
if (!parsed.success) {
console.error(parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const config = parsed.data;支持两种 secret 输入:
JWT_SECRET:
environment variable
JWT_SECRET_FILE:
mounted file path
好处:
Docker env works
Docker env_file works
Kubernetes Secret env works
CSI mounted secret file works3. Local#
.env.example#
NODE_ENV=local
PORT=3000
LOG_LEVEL=debug
DATABASE_URL=postgres://order:password@localhost:5432/order
JWT_SECRET=change-me-change-me-change-me-change-me.env.local#
NODE_ENV=local
PORT=3000
LOG_LEVEL=debug
DATABASE_URL=postgres://order:local-password@localhost:5432/order
JWT_SECRET=local-secret-local-secret-local-secretgit rule:
commit .env.example
do not commit .env.local
do not commit real .env.production4. Docker#
environment variables#
docker run --rm -p 3000:3000 -e NODE_ENV=prod -e PORT=3000 -e LOG_LEVEL=info -e DATABASE_URL='postgres://order:password@db:5432/order' -e JWT_SECRET='change-me-change-me-change-me-change-me' order-api:localenv file#
docker run --rm -p 3000:3000 --env-file .env.local order-api:localmounted secret file#
docker run --rm -p 3000:3000 -e JWT_SECRET_FILE=/run/secrets/jwt_secret -v "$PWD/secrets/jwt_secret:/run/secrets/jwt_secret:ro" --env-file .env.local order-api:localrecommendation:
local dev:
env_file is simple
production:
platform should inject env or mounted secret
do not keep .env production file on developer machine5. Kubernetes#
ConfigMap#
apiVersion: v1
kind: ConfigMap
metadata:
name: order-api-config
data:
NODE_ENV: prod
PORT: "3000"
LOG_LEVEL: info
DATABASE_URL: postgres://order:password@postgres:5432/orderSecret#
apiVersion: v1
kind: Secret
metadata:
name: order-api-secret
type: Opaque
stringData:
JWT_SECRET: change-me-change-me-change-me-change-meenvFrom#
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-api
spec:
replicas: 2
selector:
matchLabels:
app: order-api
template:
metadata:
labels:
app: order-api
spec:
containers:
- name: order-api
image: order-api:1.0.0
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: order-api-config
- secretRef:
name: order-api-secretsecret as mounted file#
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-api
spec:
template:
spec:
containers:
- name: order-api
image: order-api:1.0.0
env:
- name: JWT_SECRET_FILE
value: /run/secrets/JWT_SECRET
volumeMounts:
- name: app-secrets
mountPath: /run/secrets
readOnly: true
volumes:
- name: app-secrets
secret:
secretName: order-api-secretKubernetes notes:
env var secret is easy
mounted file secret works better with CSI/external secret providers
application may need restart to reload env var changes
mounted file can be rotated by provider, but app must reread or restart6. AWS / EKS#
options:
Kubernetes Secret:
simple
secret stored in cluster etcd
AWS Secrets Manager + ASCP + Secrets Store CSI Driver:
mount Secrets Manager secret as file in pod
good for centralized secret management
External Secrets Operator:
sync AWS Secrets Manager into Kubernetes Secret
app SDK:
app reads Secrets Manager directly
more app code and IAM handlingapiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: order-api-aws-secrets
spec:
provider: aws
parameters:
objects: |
- objectName: "prod/order-api/jwt"
objectType: "secretsmanager"
jmesPath:
- path: "JWT_SECRET"
objectAlias: "JWT_SECRET"volumes:
- name: secrets-store
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: order-api-aws-secretsAWS Secret 读取身份只授予所需 ARN;能读取配置文件不代表有 Secret Manager 或 KMS 解密权限。
EKS recommendation:
use IRSA / Pod Identity for workload identity
grant least privilege to read only required secret ARNs
prefer mounted file for secret value7. GCP / GKE#
options:
Kubernetes Secret:
simple cluster-native secret
Google Secret Manager add-on / CSI:
mount Secret Manager value as file
uses Workload Identity Federation for GKE
External Secrets Operator:
sync Google Secret Manager into Kubernetes Secret
app SDK:
app reads Secret Manager directlyapiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: order-api-gcp-secrets
spec:
provider: gcp
parameters:
secrets: |
- resourceName: "projects/my-project/secrets/JWT_SECRET/versions/latest"
path: "JWT_SECRET"GKE recommendation:
use Workload Identity Federation
avoid static service account key files
mount secret as file or sync through External Secrets Operator8. Azure / AKS#
options:
Kubernetes Secret:
simple cluster-native secret
Azure Key Vault provider for Secrets Store CSI Driver:
mount Key Vault secret as CSI volume
External Secrets Operator:
sync Azure Key Vault into Kubernetes Secret
app SDK:
app reads Key Vault directlyapiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: order-api-azure-secrets
spec:
provider: azure
parameters:
usePodIdentity: "false"
clientID: "<managed-identity-client-id>"
keyvaultName: "<key-vault-name>"
tenantId: "<tenant-id>"
objects: |
array:
- |
objectName: JWT_SECRET
objectType: secretAKS recommendation:
use managed identity / workload identity
use Key Vault provider when org standardizes on Key Vault
enable rotation if the app can handle it9. Alibaba Cloud / ACK#
options:
Kubernetes Secret:
simple cluster-native secret
ACK secret manager / KMS integration:
integrate KMS secrets into ACK
External Secrets Operator:
check current provider support before choosing
app SDK:
app reads Alibaba Cloud KMS Secrets Manager directlyACK recommendation:
use RAM role / workload identity style access where available
grant least privilege to required KMS secret
prefer provider-supported mounted secret or synced Kubernetes Secret10. Vault#
完整配置与实战见 HashiCorp Vault,包含动态数据库凭据、Agent 文件注入和连接池更新。
options:
Vault Agent Injector:
inject sidecar / template secrets into file
Vault Secrets Operator:
sync Vault secrets to Kubernetes Secrets
External Secrets Operator:
can read from Vault and create Kubernetes Secret
app SDK:
app reads Vault directlyVault recommendation:
use Kubernetes auth
short TTL dynamic secrets when possible
mount as file for apps that support reload
document rotation behavior11. Decision#
| Runtime | Simple | Better For Production | Notes |
|---|---|---|---|
| Local | .env.local |
local secret manager if needed | do not commit local env |
| Docker | --env-file |
platform env / mounted secret | do not bake env into image |
| K8S | ConfigMap + Secret | CSI / External Secrets | env requires restart to update |
| EKS | Kubernetes Secret | AWS Secrets Manager + CSI / ESO | use IRSA / Pod Identity |
| GKE | Kubernetes Secret | Secret Manager + CSI / ESO | use Workload Identity |
| AKS | Kubernetes Secret | Key Vault CSI / ESO | use managed identity |
| ACK | Kubernetes Secret | KMS integration / provider | verify current provider support |
| Vault | mounted file | Vault Agent / VSO / ESO | good for multi-cloud |
12. Production Checklist#
application:
validate config at startup
support env var and *_FILE for secrets
fail fast when required secret missing
do not log config values
container:
no .env in image
no secret in Dockerfile ARG / ENV
use runtime injection
kubernetes:
use ConfigMap for non-secret config
use Secret/external secret for sensitive values
restrict RBAC to secrets
enable encryption at rest for cluster secrets
document rotation behavior
cloud:
use workload identity
least privilege secret read
audit secret access
rotate secrets