前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何优雅的跨 Namespace 同步 Secret 和 ConfigMap?

如何优雅的跨 Namespace 同步 Secret 和 ConfigMap?

作者头像
我的小碗汤
发布2023-03-19 16:59:40
1.1K0
发布2023-03-19 16:59:40
举报
文章被收录于专栏:我的小碗汤我的小碗汤

Secret 和 ConfigMap 资源对象是命名空间级别的。它们只能被同一命名空间中的 Pod 引用。所以有时候不得不手动为每个命名空间创建它们。

但有很多场景,我们想让它们是全局的,至少可以是跨命名空间共享的 Secret 和 ConfigMap,例如这些场景:

  1. 所有命名空间都有相同的私有注册表,避免为每个命名空间创建相同的 Secret
  2. Kubeshere 中 Devops 项目中的 harbor 凭证、源代码仓库的凭证

如何自动化的在跨命名空间,甚至跨 Kubernetes 集群之间“同步”这些配置,有很多方法。本文就此用例讨论,并用凭证在 Kubesphere Devops 项目之间同步做示例。

可选的方案

脚本

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

sed 实现简单的同步:

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 -

上面这两种可定制化不强,还是手动方式。

ClusterSecret

要跨命名空间自动共享或同步 Secret,可以使用 Python 开发的 ClusterSecret Operator:

https://github.com/zakkg3/ClusterSecret

ClusterSecret Operator 通过 ClusterSecret CRD 去管理。确保所有匹配的(包括新创建的) 命名空间都有可用的 Secret。ClusterSecret 上的任何更改都会更新所有相关的 Secret。删除 ClusterSecret 也会删除所有克隆的 Secret。

kubernetes-reflector

C#开发的 Kubernetes 反射器:

https://github.com/EmberStack/kubernetes-reflector

它将存储在 Secret 中的凭据或证书自动传播到所有命名空间并保持同步,修改源会更新所有副本。该扩展允许您通过注释自动复制和保持跨命名空间的 Secret:

在源 Secret 上添加注释:

 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]*"

不足

Kubernetes-reflector 和 ClusterSecret 已经很强大,但还是美中不足。

ClusterSecret 不支持 ConfigMaps 的同步和跨集群的同步,只是简单的通过 matchNamespaceavoidNamespaces 实现模糊的匹配和不匹配。

Kubernetes-reflector 不支持跨集群同步,也是通过正则表达式实现了目标命名空间的模糊匹配。

就项目的 README来看,二者都不支持 label 选择 namespace,用户在 Kubesphere 上创建 Devops 项目,不可能永远遵循模糊匹配表达式。

Config Syncer

以前的名称为 Kubed:

https://github.com/kubeops/config-syncer

Config Syncer 可以 保持 ConfigMaps 和 Secrets 在命名空间和集群之间同步。使用 Go 语言开发,官方文档也比较细致。

参考官方文档安装:

https://appscode.com/products/kubed/v0.12.0/setup/install/

安装 config-syncer

添加 Helm 仓库和更新仓库:

$ helm repo add appscode https://charts.appscode.com/stable/
$ helm repo update

搜索可用的最新安装包:

#  helm search repo appscode/kubed --version v0.13.2
NAME            CHART VERSION   APP VERSION     DESCRIPTION
appscode/kubed  v0.13.2         v0.13.2         Config Syncer by AppsCode - Kubernetes daemon

拉取到本地并解压:

helm fetch  appscode/kubed --version v0.13.2
tar -zxf kubed-v0.13.2.tgz
cd kubed/

修改 values.yaml:

config:
  # Set cluster-name to something meaningful to you, say, prod, prod-us-east, qa, etc.
  # so that you can distinguish notifications sent by kubed
  clusterName: dev
  # If set, configmaps and secrets from only this namespace will be synced
  configSourceNamespace: ""
  # kubeconfig file content for configmap and secret syncer
  kubeconfigContent: ""

这里的 config.clusterName 默认为 unicorn,如果不修改,kubed 同步之后的资源对象的 label 上会为 kubed.appscode.com/origin.cluster: unicorn,所以出于规范考虑,建议集群名设置为真实的集群名。如果 kubed 只在本集群内同步,就不需要填写 kubeconfigContent 了。

执行安装:

$ helm install config-sync -f values.yaml  -n kubed --create-namespace .
NAME: config-sync
LAST DEPLOYED: Fri May 20 19:43:00 2022
NAMESPACE: kubed
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
To verify that Config Syncer has started, run:

  kubectl get deployment --namespace kubed -l "app.kubernetes.io/name=kubed,app.kubernetes.io/instance=config-sync"

查看 Pod 启动是否成功:

$ kubectl get pod --namespace kubed -l "app.kubernetes.io/name=kubed,app.kubernetes.io/instance=config-sync"
NAME                                 READY   STATUS    RESTARTS   AGE
config-sync-kubed-8687c98ffb-ldsvz   1/1     Running   0          3m50s

$ kubectl get deployment --namespace kubed -l "app.kubernetes.io/name=kubed,app.kubernetes.io/instance=config-sync"
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
config-sync-kubed   1/1     1            1           3m53s

在 Kubesphere 中实践

Kubeshere Devops 项目中的 harbor 凭证、源代码仓库的凭证,有时候每个项目都是一样的,所以没必要每次创建 Devops 项目都去手动创建凭证,一切都变的自动化才是正道。

Kyverno 规则

需要提前创建一个 Kyverno 规则,创建这个的目的下面会做说明。

cat <<EOF | kubectl apply -f -
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  generation: 10
  name: mutate-credential-secret
spec:
  background: true
  failurePolicy: Fail
  rules:
  - exclude:
      resources:
        namespaces:
        - kubesphere-devops-system
    generate:
      clone: {}
    match:
      resources:
        kinds:
        - Secret
        selector:
          matchLabels:
            kubed.appscode.com/origin.namespace: kubesphere-devops-system
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            participant: kyverno
          finalizers:
          - finalizers.kubesphere.io/credential
        type: credential.devops.kubesphere.io/basic-auth
    name: mutate-credential-secret
EOF

可以参考 Kyverno 官方文档 sample-example:

https://kyverno.io/docs/writing-policies/match-exclude/#resource-filters

源 Secret

我们将kubesphere-devops-system命名空间中的凭证作为同步的来源:

cat <<EOF | kubectl apply -f -
kind: Secret
apiVersion: v1
metadata:
  name: common-encode
  namespace: kubesphere-devops-system
  labels:
    app: common-encode
  annotations:
    kubed.appscode.com/sync: "kubesphere.io/devopsproject"
    kubesphere.io/creator: admin
    kubesphere.io/description: 密码经过UrlEncode
data:
  id: XX==
  password: XX==
  username: XX==
type: will-be-modify-by-kyverno
---
kind: Secret
apiVersion: v1
metadata:
  name: common
  namespace: kubesphere-devops-system
  labels:
    app: common
  annotations:
    kubed.appscode.com/sync: "kubesphere.io/devopsproject"
    kubesphere.io/creator: admin
    kubesphere.io/description: 公用账户
data:
  password: XX==
  username: XX==
type: will-be-modify-by-kyverno
EOF

参考 kubed 官方文档:

https://appscode.com/products/kubed/v0.12.0/guides/config-syncer/intra-cluster/

源 Secret 必须指定注解:

kubed.appscode.com/sync: "kubesphere.io/devopsproject"

表明目标命名空间中必须包含label keykubesphere.io/devopsprojectKubesphereDevops项目,默认包含这个label key

需要说明的是:

Kubesphere 根据 Secret 的 type 字段前缀有:credential.devops.kubesphere.io/就会处理。为了避免 kubesphere-devops-system 下的源 Secret 被 ks-controller-manager 同步。所以源 Secret 的 type 不可为:

type: credential.devops.kubesphere.io/basic-auth

源 Secret type 可以自定义一个:

type: will-be-modify-by-kyverno

通过 kyverno 修改为:

type: credential.devops.kubesphere.io/basic-auth

目标命名空间

下面这个 Devops 项目作为命名空间:

k get ns -l kubesphere.io/devopsproject
NAME                       STATUS   AGE
test-ns1xxx                Active   133d

同步结果

创建之后,就在存在 label keykubesphere.io/devopsproject的 namespace 下创建了同名 Secret:

$  k get secret -A | grep common
kubesphere-devops-system          common                                                          will-be-modify-by-kyverno                    2      29s
kubesphere-devops-system          common-encode                                                   will-be-modify-by-kyverno                    3      13m
test-ns1xxx                       common                                                          credential.devops.kubesphere.io/basic-auth   2      28s
test-ns1xxx                       common-encode                                                   credential.devops.kubesphere.io/basic-auth   3      13m

同步之后,kubed 会加一些 labels:

  • kubed.appscode.com/origin.cluster
  • kubed.appscode.com/origin.name
  • kubed.appscode.com/origin.namespace

和 annotations:

  • kubed.appscode.com/origin
 apiVersion: v1
 data:
   id: XX==
   password: XX==
   username: XX==
 kind: Secret
 metadata:
   annotations:
     kubed.appscode.com/origin: '{"namespace":"kubesphere-devops-system","name":"common-encode","uid":"a649bc60-0197-4ec2-914b-b6412d2c7d29","resourceVersion":"589340738"}'
   labels:
     app: common-encode
     kubed.appscode.com/origin.cluster: unicorn
     kubed.appscode.com/origin.name: common-encode
     kubed.appscode.com/origin.namespace: kubesphere-devops-system
   name: common-encode
   namespace: des-ns
 type: will-be-modify-by-kyverno

而且会将同步源 Secret 中设置的注解去掉

kubed.appscode.com/sync: "kubesphere.io/devopsproject"

总结

Kubed 可以跨 Kubernetes 命名空间、跨集群同步 ConfigMaps/Secrets。而且暴露了各种监控指标,可以满足大多数配置同步场景。

- END -

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 进击云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可选的方案
    • 脚本
      • ClusterSecret
        • kubernetes-reflector
          • 不足
            • Config Syncer
              • 安装 config-syncer
          • 在 Kubesphere 中实践
            • Kyverno 规则
              • 源 Secret
                • 目标命名空间
                  • 同步结果
                  • 总结
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档