跨名称空间共享机密

在 Kubernetes,有没有一种跨名称空间共享秘密的方法?

我的用例是: 我对所有名称空间都有相同的私有注册中心,并且我希望避免为每个名称空间创建相同的秘密。

129955 次浏览

秘密 API 对象驻留在名称空间中。它们只能由同一名称空间中的 pods 引用。基本上,您必须为每个名称空间创建秘密。

Https://kubernetes.io/docs/concepts/configuration/secret/#details

正如 Innocent Anigbo 所回答的那样,您需要在同一个名称空间中保存这个秘密。如果需要动态地支持或者避免忘记秘密创建,那么可以为名称空间对象 https://kubernetes.io/docs/admin/extensible-admission-controllers/创建一个初始化器(我自己还没有这样做,所以不能肯定)

它们只能由同一名称空间中的 pods 引用。但是你可以直接把 Secret 从一个名字空间复制到另一个名字空间。下面是一个将 localdockerreg secret 从 default名称空间复制到 dev的例子:

kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -

更新 在 Kubernetes v1.14中,--export的标志是 不赞成。因此,以下带有 -oyaml标志的命令在即将出现的版本中将在没有警告的情况下工作。

kubectl get secret localdockerreg --namespace=default -oyaml | kubectl apply --namespace=dev -f -

如果源命名空间不一定是默认的,则在

kubectl get secret localdockerreg --namespace=default -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace=dev -f -

Kubectl 获取 secret gitlab-Registry —— nampace = revsys-com —— export-o yaml | Kubectl application —— nampace = devspectrabc-dev-f-命名空间 = devspectrabc-dev-f-命名空间

公认的答案是正确的: 秘密只能由同一名称空间中的 pods 引用。因此,如果您希望自动执行“ sync”,或者只是复制名称空间之间的秘密,这里有一个提示。

自动(操作员)

为了自动化跨名称空间的共享或同步机密,可以使用 ClusterSecret 操作符:

Https://github.com/zakkg3/clustersecret

使用 sed:

kubectl get secret <secret-name> -n <source-namespace> -o yaml \
| sed s/"namespace: <source-namespace>"/"namespace: <destination-namespace>"/\
| kubectl apply -n <destination-namespace> -f -

用 jq

如果你有 jq,我们可以使用@Evans Tucker 解决方案

kubectl get secret cure-for-covid-19 -n china -o json \
| jq 'del(.metadata["namespace","creationTimestamp","resourceVersion","selfLink","uid"])' \
| kubectl apply -n rest-of-world -f -

@ NicoKowe改进

一行程序将所有秘密从一个名称空间复制到另一个名称空间

$ for i in `kubectl get secrets | awk '{print $1}'`; do  kubectl get secret $1 -n <source-namespace> -o yaml | sed s/"namespace: <source-namespace>"/"namespace: <target-namespace>"/ | kubectl apply -n <target-namespace> -f -  ; done

不推荐使用 --export

sed不是编辑 YAML 或 JSON 的合适工具。

下面是一个使用 jq删除名称空间和其他我们不想要的元数据的示例:

kubectl get secret cure-for-covid-19 -n china -o json \
| jq 'del(.metadata["namespace","creationTimestamp","resourceVersion","selfLink","uid"])' \
| kubectl apply -n rest-of-world -f -

基于@Evans Tucker 的回答,但是在 jq 过滤器中使用白名单而不是删除来保留我们想要的。

kubectl get secret cure-for-covid-19 -n china -o json | jq '{apiVersion,data,kind,metadata,type} | .metadata |= {"annotations", "name"}' | kubectl apply -n rest-of-world -f -

本质上是一样的,但保留了标签。

kubectl get secret cure-for-covid-19 -n china -o json | jq '{apiVersion,data,kind,metadata,type} | .metadata |= {"annotations", "name", "labels"}' | kubectl apply -n rest-of-world -f -

秘密是名称空间的资源,但是您可以使用 Kubernetes 扩展来复制它们。我们使用它将存储在机密中的凭据或证书自动传播到所有名称空间并保持它们的同步(修改源代码并更新所有副本)。 参见库伯内特反射器(https://github.com/EmberStack/kubernetes-reflector)。

该扩展允许您通过注释自动复制并保持跨名称空间的秘密同步:

在源代码秘密上添加注释:

 annotations:
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"

这将在所有命名空间中创建一个 secret 的副本。可以使用以下方法限制创建副本的命名空间:

reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "namespace-1,namespace-2,namespace-[0-9]*"

该扩展还支持 ConfigMaps 和 cert-manager 证书。 免责声明: 我是 Kubernetes 反射器扩展的作者。

使用 RBAC 授权服务帐户在原始名称空间上使用秘密。但是,建议不要在名称样式之间共享秘密。

复制所有机密的解决方案。

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 -;

yq 是用于编辑 YAML 文件的有用命令行工具。我把这个和其他答案结合起来得出了这个结论:

kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq write - 'metadata.namespace' <TARGET_NAMESPACE> | kubectl apply -n <TARGET_NAMESPACE> -f -

您也可以考虑使用 GoDaddy 的外部秘密!您将在 AWS 秘密管理器(ASM)中存储您的秘密,GoDaddy 的秘密控制器将自动创建秘密。此外,ASM 和 K8S 集群之间还可以实现同步。

另一个选择是使用 kubed ,这是 Jetstack 的好心人给我们的 cert-manager 推荐的许多选项之一。这里是他们的链接。

对我来说,@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

从一个 k8集群导出

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>  \;