在Kubernetes中是否有一种方法可以跨命名空间共享机密?
我的使用情况是:我为所有命名空间使用相同的私有注册表,并且我想避免为每个命名空间创建相同的机密。
在Kubernetes中是否有一种方法可以跨命名空间共享机密?
我的使用情况是:我为所有命名空间使用相同的私有注册表,并且我想避免为每个命名空间创建相同的机密。
正如Innocent Anigbo所回答的那样,您需要在相同的命名空间中拥有该密钥。如果您需要动态支持或避免忘记创建密钥,则可能可以为命名空间对象创建初始化程序https://kubernetes.io/docs/admin/extensible-admission-controllers/(我自己没有做过,所以不能确定)
yq
是一个有用的命令行工具,用于编辑YAML文件。我将其与其他答案结合使用,得到了以下结果:
kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq write - 'metadata.namespace' <TARGET_NAMESPACE> | kubectl apply -n <TARGET_NAMESPACE> -f -
kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq eval '.metadata.namespace = "<TARGET_NAMESPACE>"' - | kubectl apply -n <TARGET_NAMESPACE> -f -
- Marcus嗯,问题很好,但所有的解决方案都不好!
秘密包含敏感数据,正如您所了解的那样,按设计,您不能从另一个命名空间使用秘密。因此,我不建议使用花哨的“集群范围”运算符,它将把您的秘密“推送”到名称空间“toto-*”中。
这听起来是对秘密和 Kubernetes 声明式模型的不良使用。
这是最简单的方法,创建一个Helm 图表来创建命名空间并设置它,通过创建要共享的资源。
我喜欢 https://external-secrets.io/,这是一种拉取声明性方法。正如您可以在 https://external-secrets.io/v0.7.2/provider/kubernetes/ 中阅读的那样,您可以声明一个ExternalSecret
以从另一个命名空间的秘密中提取数据。
external-secrets.io 已经准备就绪,经过实战测试,支持某些提供者(vault…)。
要轻松地共享 CA,请使用https://cert-manager.io/docs/projects/trust-manager/。这是一种推式方法;-/,但该工具已准备就绪。
kubectl delete secret --namespace $TARGET_NAMESPACE--all;
kubectl get secret --namespace default --output yaml \
| sed "s/namespace: $SOURCE_NAMESPACE/namespace: $TARGET_NAMESPACE/" \
| kubectl apply --namespace $TARGET_NAMESPACE --filename -;
对我来说,@Hansika Weerasena建议的方法没有起作用,出现了以下错误:
error: the namespace from the provided object "ns_source" does not match the namespace "ns_dest". You must pass '--namespace=ns_source' to perform this operation.
kubectl get secret my-secret -n ns_source -o yaml > my-secret.yaml
这个文件需要被编辑,并且命名空间需要改为您想要的目标命名空间。然后只需执行以下操作:
kubectl apply -f my-secret.yaml -n ns_destination
从一个 k8s 集群导出
mkdir <namespace>; cd <namespace>; for i in `kubectl get secrets -n <namespace> | awk '{print $1}'`; do kubectl get secret $i -n <namespace> -o yaml > $i.yaml; done
导入到第二个 k8s 集群
cd <namespace>; find . -type f -exec kubectl apply -f '{}' -n <namespace> \;
您也可以考虑使用GoDaddy的Kubernetes外部秘密!在那里,您将把您的秘密存储在AWS Secret Manager(ASM)中,而GoDaddy的秘密控制器将自动创建这些秘密。此外,ASM和K8S集群之间会进行同步。
使用Helm时,我通常在我的CD流水线中定义一个(组)变量(例如$REGISTRY_PASS
),并向helm chart添加一个模板文件:
apiVersion: v1
data:
.dockerconfigjson: |
{{ .Values.registryPassword }}
kind: Secret
metadata:
name: my-registry
namespace: {{ .Release.Namespace }}
type: kubernetes.io/dockerconfigjson
在部署图表时,我通过命令行设置变量registryPassword
,如下所示:
helm install foo/ --values values.yaml \
--set registryPassword="$REGISTRY_PASS" \
--namespace whatever \
--create-namespace
这完全兼容本地测试和CD。
为了获取正确格式的$REGISTRY_PASS
值,我使用kubectl create secret
kubectl create secret docker-registry secret-tiger-docker \
--docker-email=tiger@acme.example \
--docker-username=tiger \
--docker-password=pass1234 \
--docker-server=my-registry.example:5000
创建初始密钥,然后使用kubectl get secret
获取base64编码的字符串(.dockerconfigjson
)。
kubectl get secret secret-tiger-docker -o yaml
使用 RBAC 跨命名空间访问密码。
https://kubernetes.io/docs/reference/access-authn-authz/rbac/例如,使用 ClusterRole。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
使用kubectl命令获取名称空间为revsys-com的gitlab-registry secret,并将其以yaml格式导出,然后通过管道符号传递给kubectl apply命令,在名称空间为devspectrum-dev的环境中进行应用。