今天,我们将讨论如何优化 Kubernetes 中存储机密的流程,并学习授权我们的开发人员查看/修改部署在 Kubernetes 集群中的机密。我们还将根据开发人员所属的 GitHub 团队将访问权限委托给他们。
因此,让我问你一个基本问题,如何在 K8s 集群中存储密钥?
如果您回答说您使用的是普通的 base64 编码清单文件并手动管理它们,则:
当前方法中的问题
不容易可见 - 没有 GUI 来轻松管理机密
无版本控制
如果您想与开发人员共享,则需要将 K8s 凭据公开给他们。(不过,您可以为它们创建和设置适当的 RBAC 权限,但在某些用例中不能使用)
不支持任何第三方身份验证,例如 - 使用 GitHub Team/Org 授予开发人员预定义的访问级别。
简单解决方案 - 将 Vault 与外部机密一起使用
是的,你没听错,一旦设置好了,将访问权限委派给用户将是一件轻而易举的:)
第1季第3集 GIF by BET Plus
我们的行动项目
安装 External Secrets Operator
安装保管库
将 Vault 配置为允许使用 GitHub PAT 登录
为外部密钥配置保管库身份验证
配置外部密钥以从保管库创建密钥
在 Vault 中创建一个示例密钥,并查看该密钥是在 K8s 中创建的
安装 External Secrets Operator
https://external-secrets.io/latest/introduction/overview/
它有三个组件 - 外部机密控制器、Webhook 和证书控制器
您可以使用 Helm 快速安装外部机密!
https://external-secrets.io/latest/introduction/getting-started/
values.yaml
#? count of the controller pods for HA
replicaCount: 3
#? enable/disable the leader election - at any time, only one active controller is recommended
leaderElect: true
#? how many secrets to update concurrently
concurrent: 3
#? PDB configuration - helpful when doing maintenance tasks
podDisruptionBudget:
enabled: true
minAvailable: 1
#? Recommended - Exposes metrics!
serviceMonitor:
enabled: true
webhook:
serviceMonitor:
enabled: true
certController:
serviceMonitor:
enabled: true
helm repo add external-secrets https://charts.external-secrets.io
helm upgrade --install external-secrets external-secrets/external-secrets -f values.yaml -n external-secrets --create-namespace
部署后,它将如下所示:
注 - 您可以看到三个部署,但由于我们启用了其中只有一个将处于活动状态并保留租约,其他副本将等待主副本关闭,然后其中一个备用副本将成为领导者。是不是很酷?external-secretsleaderElect
奖金!- 更多关于K8s领导人选举的信息:https://carlosbecker.com/posts/k8s-leader-election/
安装保管库
加工
Vault的内部工作非常有趣,用几句话总结起来有点复杂,我们需要另一个博客来更详细地解释它。如果您完全一无所知,那么您可以在此处阅读有关此内容的更多信息:
https://developer.hashicorp.com/vault/docs/what-is-vault#what-is-vault-1
https://developer.hashicorp.com/vault/docs/internals/architecture
要安装 Vault,我们将使用 Banzaicloud 的 Vault Operator,又名 Bank Vaults!
为了在 Kubernetes 环境中部署任何东西并确保其可靠性和可用性,Operator 正在成为事实上的标准。
您知道吗:Kubernetes Operator 是一个特定于应用程序的控制器,它扩展了 Kubernetes API 的功能,以代表 Kubernetes 用户创建、配置和管理复杂应用程序的实例。
在这里查看更多: https://operatorframework.io/what/
使用 Helm 安装 vault-operator
helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com
helm repo update
helm upgrade --install vault-operator banzaicloud-stable/vault-operator -n vault-operator
设置 RBAC
rbac.yaml- 需要应用它来为我们的设置提供所需的 RBAC 访问权限。
kubectl apply -f vault/rbac.yml -n vault-operator
解释-在这里,我们正在创建一个 Secret vault-sa-token-manual,它将保存名为 vault 的 ServiceAccount 的 Kubernetes 访问令牌(在 Kubernetes v1.24 之前,我们不必手动创建密钥,请参阅 - stackoverflow.com/a/72258300)。此 ServiceAccount 有权读取/更新 Pod 以及对机密的所有访问权限。
注 - 您还可以通过仅添加必需的谓词/资源名称/命名空间来微调访问。
另外,您是否注意到我们正在绑定一个名为 ServiceAccount 的默认值?来自官方文档 - 允许委派身份验证和授权检查。ClusterRole 具有调用 Token Review API 的权限。ClusterRolesystem:auth-delegatorVaultsystem:auth-delegator
Christian Bale GIF by PeacockTV
使用 CRD 部署 Vault
现在,由于我们已经使用 Vault Operator 为集群提供支持,因此我们可以使用简单的 YAML 文件部署 Vault。
vault-deploy.yaml
身份验证和授权
在这里,我们使用 GitHub 身份验证后端对用户进行身份验证。他们的访问级别由他们所属的 GitHub 团队定义。
例如,我的帐户 (k4kratik) 被分配了 admin policy 。同样,我在我的组织中创建了一个 GitHub 团队,该团队将授予其成员在策略中定义的访问权限,并且还为开发人员创建了一个团队,我只想为其配置只读访问权限,该团队将被分配 .vault_adminDEVS_RWrw_access_policyDEVS_ROro_access_policy
以上可视化如下:
配置文件说明:
从 #1 行到 #102 行,我认为这几乎是不言自明的。让我们从第 #106 行开始。(externalConfig 开始的位置)
externalConfig.policies
就像任何其他设置一样,我们在这里定义 IAM 策略,这些策略将分配给用户/团队。
ro_access_policy:仅权限。read
rw_access_policy:RW 权限。[“读取”, “列表”, “更新”]
vault_admin:仅使用动词定义并不能授予所有权限。因此,我们已显式定义了所有管理员级别的访问权限。*
为什么?: 更多信息 : https://discuss.hashicorp.com/t/vault-admin-policy/39803/2
管理员所需的访问权限:https://developer.hashicorp.com/vault/tutorials/policies/policies#write-a-policy
externalConfig.auth:kubernetes
type:当我们将其设置为在 Kubernetes 上运行时,它的值应该是external-secretskubernetes
path:保管库中此身份验证条目的标识符。
config
token_reviewer_jwt:ServiceAccount 的 JWT Token,因为它具有角色,可以帮助我们使用 K8s 的 API 来验证其他 JWT。若要获取其值,请运行以下命令,如博客前面部分所示,我们已经设置了所需的 RBAC。vaultsystem:auth-delegatorTokenReview
命令(此命令并替换为TOKEN_REVIEWER_JWT_TOKEN_HERE )
kubectl get secret vault-sa-token-manual -n vault-operator -o go-template='{{.data.token}}' | base64 --decode
kubernetes_ca_cert:PEM 编码的 CA 证书,供用于与 Kubernetes API 通信的 TLS 客户端使用。
命令
kubectl get secret vault-sa-token-manual -n vault-operator -o go-template='{{index .data "ca.crt"}}' | base64 --decode
kubernetes_host:的端点。确保可从 Vault Pod 访问它。Kubernetes API server
kubectl config view --minify --output jsonpath="{.clusters[*].cluster.server}"
disable_issuer_verification: - 禁用颁发者验证。true
roles - 定义附加到此身份验证机制的角色
name:角色的名称
bound_service_account_names: - 我们只想允许外部机密 SA,所以只添加它。["external-secrets"]
bound_service_account_namespaces ["external-secrets"]- 我们只想允许外部机密命名空间,所以只添加它。
token_policies:-重要!- 要附加的策略的名称,我们的外部密钥只需要读取访问权限即可读取密钥。ro_access_policy
token_max_ttl:令牌到期时间。
外部配置.auth:github
type:由于我们正在通过 GitHub 设置身份验证,因此其值应为github
path:保管库中此身份验证条目的标识符。
config
organization:您的 GitHub 组织的名称。(用这个替换GITHUB_ORGANIZATION_NAME_HERE)
注意!- 您必须是此组织的一员,否则您将无法登录,并且您将收到以下错误:Configuration is not set!
token_ttl:生成的令牌的生存期。
map(GitHub 的映射)
teams(映射具有保管库策略的 GitHub Teams)
格式:
TEAM_NAME : POLICY_NAME
例如
DEV_RW:rw_access_policy
DEV_RO:ro_access_policy
users(使用 Vault 策略的 GitHub 用户的映射)
例如:k4kratikvault_admin
externalConfig.secrets
path: - Vault 将挂载此秘密引擎的路径。secret
type: - 秘密引擎类型:键/值kv
options:
version: 2 (推荐)
startupSecrets(启动密钥)
测试密钥,将在启动时创建。
审计
审核设备是保险柜中的组件,它们共同保留对保险柜的所有请求的详细日志。
文件审计设备将审计日志写入文件。https://developer.hashicorp.com/vault/docs/audit/file#configuration
部署 Vault
kubectl apply -f vault/vault-deploy.yml
它将部署 Pod,如下所示:
登录到 Vault UI
让我们公开用于登录的Vault UI
kubectl port-forward svc/vault -n vault-operator 8200:8200
您将受到以下屏幕的欢迎:
使用 GitHub PAT(个人访问令牌)登录
生成至少具有权限的 GitHub PAT(指南在这里read:org)
我们将使用该 PAT 登录 Vault
注意 - 记住我们创建的身份验证策略,根据我们的 GitHub 用户名、组织或团队,我们将获得相关访问权限。
检查引擎,你会发现我们的测试秘诀:secretTEST_PROJECT_ONE/test
使用 Root Token 登录 [不推荐]
获取根令牌
kubectl get secrets vault-unseal-keys -o jsonpath={.data.vault-root} | base64 --decode
使用此令牌登录,如下所示
检查我们配置的内容:
检查我们定义的身份验证 - 'github' 和 'k8s-one'
让我们检查一下 auth 方法,我们的角色是否存在k8s-onek8s-one-external-secrets-role
这总结了基本的保管库身份验证和授权设置 + 外部机密。
Jimmy Fallon GIF by The Tonight Show Starring Jimmy Fallon
但要抱住你的马!我们仍然需要使用外部密钥从 Vault 创建密钥。如果博客看起来太长,我们深表歉意,但相信我,最终这一切都是值得的。
Season 1 GIF by Showtime
设置外部机密
外部机密有两种重要的对象类型
SecretStore(或) - 它定义如何访问外部 API 密钥提供程序。(例如 Vault、AWS Secrets Manager)ClusterSecretStore
ExternalSecret(or ) - 它描述了应该获取哪些数据,应该如何转换数据并将其保存为 K8s 。ClusterExternalSecretSecret
让我们创建一个群集范围的密钥存储,以将其与保管库连接。
kubectl apply -f external-secrets/secret-store.yml
它如下所示
在创建 之前,让我们在 Vault 中创建一些测试密钥ExternalSecret
现在,让我们创建一个 to use our 并使用它创建一个 k8s 密钥。ExternalSecretClusterSecretStore
sample-external-secret.yaml (GitHub的)
k apply -f external-secrets/sample-external-secret.yaml
让我们通过检查密钥来验证它
瞧!我们可以看到我们的秘密被创建了,我们也可以看到我们在 Vault 中的值经历了