Kubernetes - 跨命名空间共享秘密

mat*_*h3o 52 namespaces kubernetes

有没有办法在Kubernetes中跨命名空间共享秘密?

我的用例是:我的所有命名空间都有相同的私有注册表,我想避免为每个命名空间创建相同的秘密.

谢谢你的帮助.

Inn*_*gbo 46

Secret API对象驻留在命名空间中.它们只能由同一名称空间中的pod引用.基本上,您必须为每个命名空间创建secrete.

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

  • 配置映射也是如此。https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#restrictions (5认同)

Han*_*ena 38

它们只能由同一名称空间中的pod引用.但您可以将秘密从一个名称空间复制到另一个名称空间.以下是将名称空间localdockerregdefault名称空间复制到的示例dev:

 kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -
Run Code Online (Sandbox Code Playgroud)

  • 准确地说,您需要从中间 YAML 中删除源命名空间: `$ kubectl get Secret <SECRET> --namespace <NS-SRC> -oyaml | grep -v '^\s*命名空间:\s' | kubectl apply --namespace <NS-DST> -f -` ps 未使用其他对象类型进行测试,但应该可以工作 pps 如果要移动,请不要忘记删除源 (11认同)
  • 嗯,当我使用第二个命令(没有“--export”标志)时,我收到一条错误消息“提供的选项中的名称空间不匹配”。kubectl 版本 1.15。我认为您可能需要使用 `sed` 或这两个 `kubectl` 命令之间的其他命令来从输出 yaml 中删除命名空间 (5认同)
  • 如果您从中导出的机密不在默认命名空间中,则此操作将不起作用 (2认同)

Nic*_*owe 31

接受的答案是正确的,如果您想在命名空间之间复制秘密,这里有一个提示。

kubectl get secret <secret-name> -n <source-namespace> -o yaml \
| sed s/"namespace: <source-namespace>"/"namespace: <destination-namespace>"/\
| kubectl apply -n <destination-namespace> -f -
Run Code Online (Sandbox Code Playgroud)

/编辑 2020 年 4 月:

现在有一种方法可以使用 ClusterSecret 操作符跨命名空间及其共享或同步秘密:

https://github.com/zakkg3/ClusterSecret


win*_*lus 13

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

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

在源机密上添加注释:

 annotations:
   reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
Run Code Online (Sandbox Code Playgroud)

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

reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "namespace-1,namespace-2,namespace-[0-9]*"
Run Code Online (Sandbox Code Playgroud)

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


小智 11

--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 -
Run Code Online (Sandbox Code Playgroud)


小智 11

使用 RBAC 授权服务帐户在原始命名空间上使用密钥。但是,不建议在命名空间之间拥有共享秘密。


Api*_*bul 7

我想帮助澄清我在其他答案中发现的两个错误信息。

RBAC 和 ServiceAccount 不能用于imagePullSecret跨命名空间共享。

当然,RBAC 可以允许 Pod 中运行的应用程序使用 kubernetes API 或客户端库从另一个命名空间读取 Secret。(请参阅下面奖励部分中的最小工作示例。)

然而,当共享要在 Pod 规范领域使用的 Secret 时,这种方法不起作用imagePullSecret。原因是:

  1. 在创建 Pod 时使用该密钥的应用程序kubelet本身并未在 Pod 中运行,并且没有关联的 ServiceAccount。
  2. 只能imagePullSecret在同一命名空间内引用 Secret。请参阅 API 参考。

只需使用 . 即可将 Secret 从一个名称空间复制到另一个名称空间kubectl。(没有jqsed需要。)

诀窍是将 JSON 补丁应用到现有的 Secret 上,以获取编辑了命名空间的新 Secret 文档。

kubectl patch secret \
  -n SOURCE-NAMESPACE SECRET-NAME \
  --type=json -p='[{"op": "replace", "path": "/metadata/namespace", "value": "DESTINATION-NAMESPACE"}]'  \
  -o yaml --dry-run=client |
  kubectl apply -f -
Run Code Online (Sandbox Code Playgroud)

奖励:跨命名空间共享 Secret 并使用 kubernetes Python 客户端访问它的最小工作示例。

我不会进一步解释这个例子,因为它不适用于 Secret OP 正在谈论的那种。不过,我认为这对于那些像我一样被 RBAC 解决方案误导的人会有帮助。

apiVersion: v1
kind: Namespace
metadata:
  name: secret-owner-namespace
---
apiVersion: v1
kind: Namespace
metadata:
  name: secret-reader-namespace
---
apiVersion: v1
kind: Secret
metadata:
  name: example-secret
  namespace: secret-owner-namespace
type: Opaque
data:
  # echo -n secret-value | base64
  SECRET_KEY: c2VjcmV0LXZhbHVl
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader-role
  # NOTE: Reader's role is defined inside owner's namespace.
  # That is how `resourcesNames` below can be resolved.
  namespace: secret-owner-namespace
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["example-secret"]
  verbs: ["get", "watch", "list"]
---
# Allow pods in secret-reader-namespace to read the example-secret by:
# binding the default ServiceAccount of the secret-reader-namespace
# to the Role of secret-reader-role.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-reader-rolebinding
  namespace: secret-owner-namespace
subjects:
- kind: ServiceAccount
  name: default
  apiGroup: ""
  namespace: secret-reader-namespace
roleRef:
  kind: Role
  name: secret-reader-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: secret-reading-code-configmap
  namespace: secret-reader-namespace
data:
  read-secret.py: |
    from kubernetes import client, config

    config.load_incluster_config()
    with client.ApiClient() as api_client:
        api_instance = client.CoreV1Api(api_client)
        name = 'example-secret'
        namespace = 'secret-owner-namespace'
        api_response = api_instance.read_namespaced_secret(name, namespace)

    print(api_response)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secret-reader-deployment
  namespace: secret-reader-namespace
  labels:
    app: secret-reader-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: secret-reader-example
  template:
    metadata:
      labels:
        app: secret-reader-example
    spec:
      containers:
      - name: secret-reading-container 
        image: python
        command: ["/bin/sh","-c"]
        args: ["pip install --no-cache-dir --upgrade kubernetes ; python read-secret.py ; sleep infinity"]
        workingDir: /opt/code
        volumeMounts:
        - name: secret-reading-code-volume
          mountPath: "/opt/code"
          readOnly: true
      volumes:
      - name: secret-reading-code-volume
        configMap:
          name: secret-reading-code-configmap
Run Code Online (Sandbox Code Playgroud)