在 Kubernetes 集群中运行的应用程序的安全密钥
在本教程中,您将学习如何使用 External Secrets Operator 开放式源代码工具,使用 IBM Cloud® Secrets Manager 来管理运行 IBM Cloud Kubernetes Service 集群的应用程序的私钥。
或者,可以使用 Kubernetes Service CLI 插件来管理 TLS 和非 TLS 私钥。 要了解有关此方法的更多信息,请参阅 设置 Kubernetes Ingress。
您是一家企业的开发人员,您的团队正在使用 Kubernetes Service 在 IBM Cloud 上部署容器化应用程序和服务。 在当前流中,使用 Kubernetes Secrets 来存储在集群中运行的应用程序和服务所使用的敏感数据,例如密码和 API 密钥。 为了更好地控制应用程序私钥,您希望能够将集群私钥存储在外部私钥管理服务中,在该服务中可以 静态加密,监视其活动 以及轻松管理这些私钥。
通过 Secrets Manager,您可以集中并保护在 Kubernetes 集群中运行的应用程序所使用的私钥。 您可以配置应用程序以在运行时从 Secrets Manager 安全检索私钥,而不是在部署时注入私钥。 轮换私钥时,可以从 Secrets Manager执行此操作。 例如,假设有以下场景:
- 作为开发者,您可以使用 Secrets Manager 来存储要在 Kubernetes 集群中部署的应用程序的私钥。
- Secrets Manager 提供私钥的标识。 您将该标识包含在应用程序的
ExternalSecrets
配置文件中,并将该配置应用于集群。 - 外部私钥控制器会访存使用 Kubernetes API 定义的配置文件中的
ExternalSecrets
对象。 - 在应用程序运行时,控制器从 Secrets Manager检索私钥数据,并将
ExternalSecrets
对象转换为集群的 Kubernetes 私钥。
此方案具有第三方工具,可影响在 Kubernetes 集群中运行的工作负载的合规性准备情况。 如果添加社区或第三方工具,请记住,您负责维护应用程序的合规性,并与相应的提供者一起对任何问题进行故障诊断。 有关更多信息,请参阅 您使用 IBM Cloud Kubernetes Service的职责。
准备工作
开始之前,请确保您具有 管理员 平台访问权,以便可以创建帐户凭证和供应资源。 您还需要以下先决条件:
-
jq
可帮助您对 JSON 数据进行切片和过滤。 在本教程中使用jq
来抓取和使用存储的环境变量。
设置环境
要使用 Secrets Manager 和 Kubernetes Service,您需要在 IBM Cloud 帐户中创建集群和 Secrets Manager 实例。 您还需要配置许可权,以便可以对这两个服务运行操作。
在此步骤中,您将通过创建服务标识和 IBM Cloud API 密钥来设置访问环境。 在教程结束时,如果不再需要资源,您可以轻松除去这些资源。 或者,您可以使用 可信概要文件 来授权“外部密钥”操作程序。
创建服务ID和API密钥
首先创建能够对 Secrets Manager 和 Kubernetes Service运行操作所需的帐户凭证。
-
从命令行,通过 IBM Cloud CLI 登录到 IBM Cloud。
ibmcloud login
如果登录失败,请运行
ibmcloud login --sso
命令重试。 使用联合标识登录时需要--sso
参数。 如果使用此选项,请转至 CLI 输出中列出的链接以生成一次性密码。 -
创建服务标识并将其设置为环境变量。
export SERVICE_ID=`ibmcloud iam service-id-create kubernetes-secrets-tutorial --description "A service ID for testing ESO integration" --output json | jq -r ".id"`; echo $SERVICE_ID
-
分配服务标识许可权以从 Secrets Manager读取私钥。
ibmcloud iam service-policy-create $SERVICE_ID --roles "SecretsReader" --service-name secrets-manager
通过分配 SecretsReader 服务访问权,外部密钥控制器具有从 Secrets Manager 读取密钥并在 Kubernetes 集群中填充这些密钥的正确访问级别。
-
为您的服务ID创建一个 IBM Cloud API密钥。
export IBM_CLOUD_API_KEY=`ibmcloud iam service-api-key-create kubernetes-secrets-tutorial $SERVICE_ID --description "An API key for testing ESO integration." --output json | jq -r ".apikey"`
稍后使用此 API 密钥为集群部署配置 Secrets Manager。
创建 Kubernetes 集群和 Secrets Manager 实例
在 IBM Cloud 帐户中创建 Kubernetes 集群和 Secrets Manager 实例。
您可以为每个 IBM Cloud 帐户创建一个免费 Kubernetes 集群和 Secrets Manager 服务实例。 如果您的帐户中已有这两种资源,那么可以使用现有免费集群和 Secrets Manager 实例来完成教程。
-
从命令行,选择要在其中创建 Secrets Manager 服务实例的帐户,区域和资源组。
在本教程中,您将与达拉斯区域进行交互。 如果您已登录到其他区域,请确保通过运行以下命令将达拉斯设置为目标区域。
ibmcloud target -r us-south -g default
-
创建一个 Kubernetes 集群。
ibmcloud ks cluster create classic --zone dal10 --flavor free --name my-test-cluster
-
创建一个 Secrets Manager 实例。
ibmcloud resource service-instance-create my-secrets-manager secrets-manager trial us-south
针对 Secrets Manager 和 Kubernetes 集群的供应需要 5-15 分钟才能完成。
-
继续执行下一步之前,请验证是否已成功供应集群和 Secrets Manager 实例。
-
验证工作程序节点的部署是否已完成。
ibmcloud ks worker ls --cluster my-test-cluster
当工作程序节点完成供应时,状态将更改为 就绪。
ID Public IP Private IP Flavor State Status Zone Version kube-c39pf4ld0m87o3fv1utg-mytestclust-default-000000dd 169.xx.xx.xxx 10.xxx.xx.xxx free normal Ready mex01 1.20.7_1543
-
接下来,验证是否已成功供应 Secrets Manager 实例。
ibmcloud resource service-instance my-secrets-manager
当实例完成供应时,状态将更改为 活动。
Name: my-secrets-manager ID: crn:v1:bluemix:public:secrets-manager:us-south:a/f047b55a3362ac06afad8a3f2f5586ea:fe06948b-0c6b-4183-8d4b-e6c1d38ff65f:: GUID: fe06948b-0c6b-4183-8d4b-e6c1d38ff65f Location: us-south Service Name: secrets-manager Service Plan Name: trial Resource Group Name: default State: active Type: service_instance Sub Type: Created at: 2021-01-06T17:11:32Z Created by: zara@example.com Updated at: 2021-03-31T02:33:26Z
-
-
在命令行界面中设置 Kubernetes 集群的上下文。
ibmcloud ks cluster config --cluster my-test-cluster
-
验证
kubectl
命令是否正确运行以及 Kubernetes 上下文是否设置为集群。kubectl config current-context
示例输出:
my-test-cluster/<your_cluster_ID>
创建可信概要文件
可信概要文件允许“外部密钥”操作程序从 Secrets Manager中读取,而不必创建服务标识或管理 API 密钥。
-
获取 Secrets Manager 实例和 Kubernetes 集群的 CRN。
CLUSTER_CRN=$(ibmcloud ks cluster get --cluster my-test-cluster --output json | jq -r '.crn') SECRETS_MANAGER_CRN=$(ibmcloud resource service-instance my-secrets-manager --output JSON | jq -r '.[0].crn')
-
创建概要文件。
ibmcloud iam trusted-profile-create 'External Secrets'
-
授权 Kubernetes 集群使用可信概要文件。
Kubernetes
ibmcloud iam trusted-profile-rule-create 'External Secrets' --name kubernetes --type Profile-CR --conditions claim:namespace,operator:EQUALS,value:external-secrets --conditions claim:name,operator:EQUALS,value:external-secrets --conditions claim:crn,operator:EQUALS,value:$CLUSTER_CRN --cr-type IKS_SA
OpenShift
ibmcloud iam trusted-profile-rule-create 'External Secrets' --name kubernetes --type Profile-CR --conditions claim:namespace,operator:EQUALS,value:external-secrets-operator --conditions claim:name,operator:EQUALS,value:cluster-external-secrets --conditions claim:crn,operator:EQUALS,value:$CLUSTER_CRN --cr-type IKS_SA
-
创建允许可信概要文件从 Secrets Manager 实例读取私钥的访问策略。
ibmcloud iam trusted-profile-policy-create 'External Secrets' --roles SecretsReader --service-instance $SECRETS_MANAGER_CRN --service-name secrets-manager
准备 Secrets Manager 实例
最后,配置 Secrets Manager 实例以开始使用私钥。
-
从命令行验证您是否可以访问 Secrets Manager CLI 插件。
ibmcloud secrets-manager --help
还没有插件吗? 要安装 Secrets Manager CLI 插件,请运行
ibmcloud plugin install secrets-manager
。 -
使用您唯一的 Secrets Manager API端点 URL 导出环境变量。
export SECRETS_MANAGER_URL=`ibmcloud resource service-instance my-secrets-manager --output json | jq -r '.[].dashboard_url | .[0:-3]'`; echo $SECRETS_MANAGER_URL
-
为实例创建私钥组。
私钥组 是一种组织和控制团队中有权访问实例中特定私钥的人员的方法。 要从 IBM Cloud CLI 创建私钥组,请使用
ibmcloud secrets-manager secret-group-create
命令。 运行以下命令以创建私钥组并将其标识存储为环境变量。export SECRET_GROUP_ID=`ibmcloud secrets-manager secret-group-create --name my-test-secret-group --description "Read and write to my test app" --output json --service-url $SECRETS_MANAGER_URL | jq -r '.id'`; echo $SECRET_GROUP_ID
使用 Windows™ 命令提示符 (
cmd.exe
) 或 PowerShell? 如果在命令行上传递 JSON 内容时迂到错误,那么可能需要调整字符串以满足特定于操作系统的报价转义需求。 有关更多信息,请参阅 在 IBM Cloud CLI 中对字符串使用引号。成功! 现在,您可以将私钥存储在要在 Kubernetes 集群中填充的 Secrets Manager 中。 继续下一步。
在 Secrets Manager 中创建私钥
私钥是特定于应用程序的私钥,可能根据需要私钥的单个应用程序或服务而有所不同。 私钥可能由用户名,密码,API 密钥或任何其他类型的凭证组成。
Secrets Manager 支持您可以在服务中创建和管理的各种 私钥类型。 例如,如果需要管理受 IBM Cloud IAM 认证保护的应用程序的 API 密钥,那么可以创建 IAM 凭证。 或者,如果需要管理可保存任何类型的结构化或非结构化数据的私钥,那么可以创建 任意私钥。
在本教程中,您将创建用户名和密码作为示例。 要从 IBM Cloud CLI 创建私钥,请使用 ibmcloud secrets-manager secret-create
命令。
运行以下命令以创建私钥并将其标识存储为环境变量。
export SECRET_ID=`ibmcloud secrets-manager secret-create --secret-type=username_password --secret-name example_username_password --username-password-username user123 --username-password-password cloudy-rainy-coffee-book --secret-labels "my-test-cluster, tutorial" --secret-group-id $SECRET_GROUP_ID --output json $SECRETS_MANAGER_URL | jq -r '.id'`; echo $SECRET_ID
请确保将 instance_id
和 region
更新为您的内容。
输出将显示新创建的私钥的标识。 例如:
e0246cea-d668-aba7-eef2-58ca11ad3707
设置外部密钥操作程序
既然您具有应用程序的私钥,那么可以为集群设置 外部私钥操作程序 工具。 此包通过为应用程序创建转换为 Kubernetes 私钥的 ExternalSecrets
对象来配置 Secrets Manager 与集群之间的连接。
External Secret Operator 是 IBM未维护的开放式源代码工具。 有关此工具的更多信息或要对任何问题进行故障诊断,请参阅 项目文档。
为集群配置外部密钥操作程序
Kubernetes
首先,通过安装官方 Helm Chart 将 external-secrets
资源添加到集群。 有关更多安装选项,请查看 入门指南。
-
运行以下命令以安装 External Secrets Operator Helm 存储库:
helm repo add external-secrets https://charts.external-secrets.io
-
配置 External Secrets Operator 与 Secrets Manager之间的认证。
如果要使用服务标识进行认证:
kubectl -n default create secret generic secret-api-key --from-literal=apikey=$IBM_CLOUD_API_KEY helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace --set installCRDs=true
如果使用可信概要文件进行认证:
echo ' installCRDs: true extraVolumes: - name: sa-token projected: defaultMode: 420 sources: - serviceAccountToken: path: sa-token expirationSeconds: 3600 audience: iam extraVolumeMounts: - mountPath: /var/run/secrets/tokens name: sa-token webhook: extraVolumes: - name: sa-token projected: defaultMode: 420 sources: - serviceAccountToken: path: sa-token expirationSeconds: 3600 audience: iam extraVolumeMounts: - mountPath: /var/run/secrets/tokens name: sa-token' >values.yml helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace -f values.yml
OpenShift
-
通过创建以下资源来安装 External Secrets 操作程序:
echo ' apiVersion: v1 kind: Namespace metadata: name: external-secrets-operator --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: external-secrets-operator namespace: external-secrets-operator spec: targetNamespaces: - external-secrets-operator --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: external-secrets-operator namespace: external-secrets-operator spec: channel: stable installPlanApproval: Automatic name: external-secrets-operator source: community-operators sourceNamespace: openshift-marketplace ' | oc create -f-
-
配置 External Secrets Operator 与 Secrets Manager之间的认证。
如果要使用服务标识进行认证:
echo " apiVersion: operator.external-secrets.io/v1alpha1 kind: OperatorConfig metadata: name: cluster namespace: external-secrets-operator spec: {} --- apiVersion: v1 kind: Secret metadata: name: secret-api-key namespace: default type: Opaque stringData: apikey: $IBM_CLOUD_API_KEY " | oc create -f-
如果使用可信概要文件进行认证:
echo ' apiVersion: operator.external-secrets.io/v1alpha1 kind: OperatorConfig metadata: name: cluster namespace: external-secrets-operator spec: extraVolumeMounts: - mountPath: /var/run/secrets/tokens name: sa-token extraVolumes: - name: sa-token projected: defaultMode: 420 sources: - serviceAccountToken: audience: iam expirationSeconds: 3600 path: sa-token webhook: extraVolumeMounts: - mountPath: /var/run/secrets/tokens name: sa-token extraVolumes: - name: sa-token projected: defaultMode: 420 sources: - serviceAccountToken: audience: iam expirationSeconds: 3600 path: sa-token ' | oc create -f-
更新应用程序配置
在集群中安装 External Secrets Operator 后,可以将 Secrets Manager 定义为应用程序的私钥后端。 首先在要使用的 Secrets Manager 中创建以私钥为目标的配置文件。
-
在应用程序的根目录中,创建
external-secrets-example.yml
文件。touch external-secrets-example.yml
-
修改文件以包含有关要从 Secrets Manager 实例访存的私钥的信息。
apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: ibmcloud-secrets-manager-example spec: provider: ibm: serviceUrl: <endpoint_url> auth: secretRef: secretApiKeySecretRef: name: secret-api-key key: apikey --- apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: ibmcloud-secrets-manager-example spec: secretStoreRef: name: ibmcloud-secrets-manager-example kind: SecretStore target: name: ibmcloud-secrets-manager-example data: - secretKey: username remoteRef: property: username key: username_password/<SECRET_ID> - secretKey: password remoteRef: property: password key: username_password/<SECRET_ID>
您可以选择按私钥标识或私钥名称使用两种方式。 如果选择私钥名称,那么格式将从
secret_type/secret_id
更改为secret_group/secret_type/secret_name
。将
<endpoint_url>
替换 为您之前 获取的 Secrets Manager 端点 URL。 将<SECRET_ID>
替换为您在上一步中创建的私钥的唯一标识。如果要使用可信概要文件进行认证,请将
auth
块替换为以下片段。auth: containerAuth: profile: "External Secrets" iamEndpoint: https://iam.cloud.ibm.com tokenLocation: /var/run/secrets/tokens/sa-token
-
将配置应用于集群。
kubectl apply -f external-secrets-example.yml
-
验证外部私钥操作程序是否能够访存存储在 Secrets Manager 实例中的私钥。
kubectl get secret ibmcloud-secrets-manager-example -o json | jq '.data | map_values(@base64d)'
示例输出:
{ "password": "cloudy-rainy-coffee-book", "username": "user123" }
成功! 现在,您可以访存存储在 Secrets Manager 实例中的私钥数据。 继续下一步。
将应用程序部署到集群
最后,可以在集群中部署使用 external-secret-example.yml
文件中定义的 Secrets Manager 私钥的应用程序。 在应用程序运行时,从 Secrets Manager 访存的私钥数据将转换为可供集群使用的 Kubernetes 私钥。
查找有关如何部署应用程序的示例? 请查看 在集群中部署 Kubernetes-native 应用程序,以了解有关部署单个应用程序实例的更多信息。
(可选) 清除资源
如果您不再需要在本教程中创建的资源,那么可以完成以下步骤以从帐户中除去这些资源。
-
删除测试 Kubernetes 集群。
ibmcloud ks cluster rm --cluster my-test-cluster
-
删除测试 Secrets Manager 实例。
ibmcloud resource service-instance-delete my-secrets-manager
-
删除您的授权。
如果您正在使用服务标识。
ibmcloud iam service-id-delete $SERVICE_ID
如果您正在使用可信概要文件。
ibmcloud iam trusted-profile-delete 'External Secrets'
相关说明
在构造 YAML 文档 时,请记住,通过使用 Secrets Manager 实例中的 REST 来定期轮询数据部分中的每个密钥。 请注意:
- 默认情况下,轮询时间间隔设置为 1 小时,这是首选设置值。 您可以在“外部秘密”模板中使用
spec.refreshInterval
更改该值。 区间可以以s
,m
或h
为单位表示。 - 如果将 YAML 设置为按名称而不是按标识 (
keyByName: true
) 访存 Secrets Manager 私钥,那么 ESO 将发出额外调用以访存相关私钥标识。 有关更多信息,请参阅 外部密钥文档。
后续步骤
太棒了! 在本教程中,您学习了如何设置 Secrets Manager 以安全地向集群填充应用程序私钥。 请查看更多资源,以帮助您开始使用 Secrets Manager。
- 查看 External Secrets Operator 支持的 Secrets Manager 中的私钥类型。
- 了解有关 Secrets Manager API 的更多信息。