跨命名空间共享秘密
Posted
技术标签:
【中文标题】跨命名空间共享秘密【英文标题】:Sharing secret across namespaces 【发布时间】:2018-02-28 02:12:28 【问题描述】:有没有办法在 Kubernetes 中?
我的用例是:我的所有命名空间都有相同的私有注册表,我想避免为每个命名空间创建相同的秘密。
【问题讨论】:
这会自动分享秘密:github.com/zakkg3/ClusterSecret 【参考方案1】:Secret API 对象位于命名空间中。它们只能被同一命名空间中的 pod 引用。基本上,您必须为每个命名空间创建秘密。
https://kubernetes.io/docs/concepts/configuration/secret/#details
【讨论】:
配置映射相同。 kubernetes.io/docs/tasks/configure-pod-container/… 这是正确的答案,值得一提的是,您可以通过 kubectl + sed 克隆到另一个命名空间,全部在一行中,请参阅下面的答案。【参考方案2】:它们只能被同一命名空间中的 pod 引用。但是您可以将秘密从一个名称空间复制到另一个名称空间。下面是一个将 localdockerreg
秘密从 default
命名空间复制到 dev
的示例:
kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -
###更新###
在 Kubernetes v1.14 中,--export
标志是 deprecated。因此,以下带有-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 -
【讨论】:
如果您要导出的机密不在默认命名空间中,这将不起作用 适用于我在 v1.13 上的任何两个命名空间 嗯,当我使用第二个命令(没有--export
标志)时,我收到一条错误消息,提示“提供的选项中的命名空间不匹配”。 kubectl 版本 1.15。我认为您可能需要在这两个 kubectl
命令之间使用 sed
或其他东西来从输出 yaml 中删除命名空间
准确来说,需要从中间 YAML 中移除源命名空间:$ kubectl get secret <SECRET> --namespace <NS-SRC> -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace <NS-DST> -f -
p.s.未使用其他对象类型进行测试,但应该可以工作 p.p.s.如果您要移动,请不要忘记删除源
工作,如果在集群之间使用 kubectl 更改上下文,则使用上下文【参考方案3】:
接受的答案是正确的:Secrets 只能被同一命名空间中的 pod 引用。因此,如果您希望自动化“同步”或只是在命名空间之间复制秘密,这里有一个提示。
自动化(操作员)
要在命名空间之间自动共享或同步秘密,请使用 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 -
【讨论】:
有一些元数据在移植秘密时应该被删除,见Evans answer 为此您必须安装 jq,并且在某些情况下这是不可能的。但我也添加了这个选项,谢谢马特! 不用担心,我只是想为第一次看到这个答案的人强调两个答案之间的功能差异 我的评论也应该说“可能要删除”,因为保留源元数据也很有用【参考方案4】:Secret 是命名空间资源,但您可以使用 Kubernetes 扩展来复制它们。我们使用它来将存储在秘密中的凭据或证书自动传播到所有命名空间并保持同步(修改源并更新所有副本)。 请参阅 Kubernetes 反射器 (https://github.com/EmberStack/kubernetes-reflector)。
该扩展允许您通过注释自动复制和保持跨命名空间的秘密:
在源密钥上添加注释:
annotations:
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
这将在所有命名空间中创建密钥的副本。您可以使用以下方法限制创建副本的命名空间:
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "namespace-1,namespace-2,namespace-[0-9]*"
该扩展也支持 ConfigMaps 和 cert-manager 证书。 免责声明:我是 Kubernetes Reflector 扩展的作者。
【讨论】:
【参考方案5】:--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 -
【讨论】:
这应该是第一个解释命名空间的使用和技术的第二个答案。如果你来这里是想将秘密复制到一个新的命名空间,请使用这个。【参考方案6】:Another option would be to use kubed,由 Jetstack 的好心人推荐,他们给了我们证书管理器。 Here is what they link to.
【讨论】:
【参考方案7】:正如 Innocent Anigbo 所回答的,您需要在同一个命名空间中拥有秘密。如果您需要动态支持或避免忘记创建秘密,则可以为命名空间对象 https://kubernetes.io/docs/admin/extensible-admission-controllers/ 创建一个初始化程序(我自己没有这样做,所以不能确定)
【讨论】:
【参考方案8】:从@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
【讨论】:
【参考方案9】:基于@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 -
【讨论】:
【参考方案10】:使用 RBAC 授权 serviceaccoun 使用原始命名空间上的密钥。但是,不建议在命名空间之间使用共享密钥。
【讨论】:
【参考方案11】:复制所有秘密的解决方案。
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 -;
【讨论】:
【参考方案12】:yq
是用于编辑 YAML 文件的有用命令行工具。我将它与其他答案结合使用来得到这个:
kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq write - 'metadata.namespace' <TARGET_NAMESPACE> | kubectl apply -n <TARGET_NAMESPACE> -f -
【讨论】:
请注意,这是针对 yq kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq eval '.metadata.namespace = "<TARGET_NAMESPACE>"' - | kubectl apply -n <TARGET_NAMESPACE> -f -【参考方案13】:您也可以考虑使用GoDaddy's Kubernetes External Secrets!您将在 AWS Secret Manager (ASM) 中存储您的秘密,GoDaddy 的秘密控制器将自动创建这些秘密。此外,ASM 和 K8S 集群之间会有同步。
【讨论】:
【参考方案14】:kubectl 获取秘密 gitlab-registry --namespace=revsys-com --export -o yaml |\ kubectl apply --namespace=devspectrum-dev -f -
【讨论】:
以上是关于跨命名空间共享秘密的主要内容,如果未能解决你的问题,请参考以下文章
如何跨 Namespace 同步 Secret 和 ConfigMap?
如何跨 Namespace 同步 Secret 和 ConfigMap?
无法在 Kubernetes 集群中执行 GitLab Runner:无法在命名空间“gitlab”中的 API 组“”中创建资源“秘密”