Skip to content

Exo #5

Open
Open

Description

@latermonk

在Kubernetes中使用External Secrets Operator(ESO)从HashiCorp Vault获取Secret,可通过以下步骤实现。ESO提供了一种将外部Secret管理系统(如Vault)与Kubernetes原生Secret无缝集成的方案,避免了直接在应用中耦合Secret管理逻辑,同时支持动态同步和安全性增强。


1. 安装External Secrets Operator

ESO通过Helm安装,需确保集群已配置Helm环境:

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
  -n external-secrets --create-namespace --set installCRDs=true

此命令会创建external-secrets命名空间并安装必要的CRD(如SecretStore和ExternalSecret)。


2. 配置Vault与Kubernetes认证

2.1 部署并初始化Vault

使用Helm在Kubernetes中部署Vault(开发模式简化流程):

helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --set "server.dev.enabled=true"

初始化Vault并获取Root Token,需解封Vault(生产环境需使用Shamir密钥分割)。

2.2 启用Kubernetes认证

在Vault中启用Kubernetes认证方式,并绑定Kubernetes集群信息:

vault auth enable kubernetes
vault write auth/kubernetes/config \
  token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
  kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT" \
  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

此步骤允许Vault验证Kubernetes的Service Account Token。

2.3 创建策略与角色

定义Vault策略(如允许读取特定路径的Secret),并创建角色绑定到Kubernetes的Service Account:

vault policy write demo-policy - <<EOF
path "secret/data/demo/*" {
  capabilities = ["read"]
}
EOF

vault write auth/kubernetes/role/demo-role \
  bound_service_account_names=internal-app \
  bound_service_account_namespaces=default \
  policies=demo-policy \
  ttl=1h

此角色demo-role允许Service Account internal-app在默认命名空间内访问指定Secret。

2.4 vault创建secret

vault kv put secret/demo/database password="123456"

3. 配置External Secrets Operator

3.1 创建SecretStore

定义SecretStore资源,指定如何连接Vault:

kubectl apply -f  - <<EOF
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "http://vault.default.svc.cluster.local:8200"  # Vault服务地址
      path: "secret"  # KV引擎路径
      version: "v2"   # KV引擎版本
      auth:
        # 使用Token认证(生产环境推荐AppRole)
        tokenSecretRef:
          name: "vault-token"  # 存储Vault Token的Kubernetes Secret
          key: "token"
EOF

需将Vault的Root Token存入Kubernetes Secret:

kubectl create secret generic vault-token --from-literal=token='root'

3.2 创建ExternalSecret

定义ExternalSecret资源,指定要同步的Secret路径和目标Kubernetes Secret:

kubectl apply -f  - <<EOF
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: vault-example
spec:
  refreshInterval: 15s  # 同步间隔
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: example-sync  # 目标Kubernetes Secret名称
  data:
  - secretKey: password  # Kubernetes Secret中的键
    remoteRef:
      key: secret/demo/database  # Vault中的路径
      property: password         # Vault Secret中的属性
EOF

此配置将从Vault路径secret/demo/database中提取password字段,并存储到Kubernetes Secretexample-sync的password键中。


4. 验证与调试

  • 检查同步结果:

    kubectl get secret example-sync -o jsonpath='{.data.password}' | base64 -d

    应输出Vault中存储的密码值。

  • 查看ESO日志:

    kubectl logs -f deploy/external-secrets -n external-secrets

    确保无认证或网络错误。


5. 高级配置

5.1 使用ClusterSecretStore

若需跨命名空间共享SecretStore,可使用ClusterSecretStore:

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: vault-cluster-store
spec:
  provider: { /* 同SecretStore配置 */ }

其他命名空间的ExternalSecret可通过secretStoreRef.kind: ClusterSecretStore引用。

5.2 动态生成临时凭证

生产环境中避免使用Root Token,推荐通过Vault的AppRole或Kubernetes Service Account动态获取临时Token。


注意事项

  1. 安全性:生产环境需禁用开发模式,启用Vault的TLS加密,并定期轮换Token。
  2. 网络连通性:确保Vault服务在Kubernetes集群内可访问,防火墙开放端口8200。
  3. 审计与监控:启用Vault的审计日志,监控ESO的同步状态。

通过上述步骤,可高效、安全地将Vault中的Secret集成到Kubernetes应用中,同时减少手动管理Secret的复杂度。

Activity

  1. latermonk commented on Jan 26, 2025

    @latermonk
    OwnerAuthor

    Need add:

    vault kv put secret/demo/database password="123456"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions