跨命名空间共享秘密

226

在Kubernetes中是否有一种方法可以跨命名空间共享机密?

我的使用情况是:我为所有命名空间使用相同的私有注册表,并且我想避免为每个命名空间创建相同的机密。


2
这个程序可以自动化秘密分享:https://github.com/zakkg3/ClusterSecret - NicoKowe
您可以通过适当的RBAC权限从不同命名空间访问机密。请参见此链接:https://dev59.com/dMT5oIgBc1ULPQZFthsO#73419051 - Hem
20个回答

2

2

yq是一个有用的命令行工具,用于编辑YAML文件。我将其与其他答案结合使用,得到了以下结果:

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

请注意,这是适用于yq < v4版本的命令。在yq v4版本中,该命令如下所示: kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq eval '.metadata.namespace = "<TARGET_NAMESPACE>"' - | kubectl apply -n <TARGET_NAMESPACE> -f - - Marcus

2

嗯,问题很好,但所有的解决方案都不好!

秘密包含敏感数据,正如您所了解的那样,按设计,您不能从另一个命名空间使用秘密。因此,我不建议使用花哨的“集群范围”运算符,它将把您的秘密“推送”到名称空间“toto-*”中。

这听起来是对秘密和 Kubernetes 声明式模型的不良使用。

解决方案1:命名空间设置 Helm 图表

这是最简单的方法,创建一个Helm 图表来创建命名空间并设置它,通过创建要共享的资源。

解决方案2:使用 external-secret.io

我喜欢 https://external-secrets.io/,这是一种拉取声明性方法。正如您可以在 https://external-secrets.io/v0.7.2/provider/kubernetes/ 中阅读的那样,您可以声明一个ExternalSecret以从另一个命名空间的秘密中提取数据。

external-secrets.io 已经准备就绪,经过实战测试,支持某些提供者(vault…)。

解决方案 3:共享 CA

要轻松地共享 CA,请使用https://cert-manager.io/docs/projects/trust-manager/。这是一种推式方法;-/,但该工具已准备就绪。


2
复制所有密码的解决方案。
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 -;

0

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

0

从一个 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>  \;

0

您也可以考虑使用GoDaddy的Kubernetes外部秘密!在那里,您将把您的秘密存储在AWS Secret Manager(ASM)中,而GoDaddy的秘密控制器将自动创建这些秘密。此外,ASM和K8S集群之间会进行同步。


但是外部秘密也与一个命名空间相关联。 - Max Voitko

0

使用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

无论应用程序安装到哪个命名空间,它都将始终可以访问本地注册表,因为密钥是在拉取镜像之前安装的。

0

使用 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"]

-1

使用kubectl命令获取名称空间为revsys-com的gitlab-registry secret,并将其以yaml格式导出,然后通过管道符号传递给kubectl apply命令,在名称空间为devspectrum-dev的环境中进行应用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接