接入多云平台

0.4.0 后,Clusterpedia 提供了更加友好的接入多云平台的方式。

用户通过创建 ClusterImportPolicy 来自动发现多云平台中纳管的集群,并将这些集群自动同步为 PediaCluster,用户不需要根据纳管的集群来手动去维护 PediaCluster 了。

我们在 Clusterpedia 仓库 中维护了各个多云平台的 ClusterImportPolicy大家也提交用于对接其他多云平台的 ClusterImportPolicy

用户在安装 Clusterpedia 后,创建合适的 ClusterImportPolicy 即可,用户也可以根据自己的需求来创建新的 ClusterImportPolicy

Cluster API ClusterImportPolicy

用户可以参考 Cluster API Quick Start 来安装 Cluster API,或者参考 快速部署 Cluster API + Clusterpedia 来搭建示例环境。

创建用于对接 Cluster API 平台的 ClusterImportPolicy

$ kubectl applyf -f https://raw.githubusercontent.com/clusterpedia-io/clusterpedia/main/deploy/clusterimportpolicy/cluster_api.yaml
$ kubectl get clusterimportpolicy
NAME          AGE
cluster-api   4d19h

如果集群中已经存在由 Cluster API 创建的集群,那么可以查看 ClusterPediaCluster 资源

$ kubectl get cluster
NAME                PHASE         AGE     VERSION
capi-quickstart     Provisioned   3d23h   v1.24.2
capi-quickstart-2   Provisioned   3d23h   v1.24.2

$ kubectl get pediaclusterlifecycle
NAME                        AGE
default-capi-quickstart     3d23h
default-capi-quickstart-2   3d23h

$ kubectl get pediacluster
NAME                        READY   VERSION   APISERVER
default-capi-quickstart     True    v1.24.2
default-capi-quickstart-2   True    v1.24.2

PediaCluster 会根据 Cluster 自动创建,并且当 Cluster 的 kubeconfig 发生变动时会自动更新 PediaCluster.

新建一个 Cluster 资源时,Clusterpedia 根据 Cluster API ClusterImportPolicy 等到 ControlPlaneInitialized 为 True 时才会自动创建 PediaCluster,可以通过 kubectl get kubeadmcontrolplane 来查看集群的初始化状态

NAME                    CLUSTER           INITIALIZED   API SERVER AVAILABLE   REPLICAS   READY   UPDATED   UNAVAILABLE   AGE   VERSION
capi-quickstart-2xcsz   capi-quickstart   true                                 1                  1         1             86s   v1.24.2

Cluster 初始化完成后,就可以直接使用 kubectl 来检索多集群资源了

使用 kubectl 前,需要为多集群资源检索生成集群快捷配置 —— 为 kubectl 生成集群访问的快捷配置

$ # Since CNI is not installed, the nodes are not ready.
$ kubectl --cluster clusterpedia get no
CLUSTER                     NAME                                            STATUS     ROLES           AGE   VERSION
default-capi-quickstart-2   capi-quickstart-2-ctm9k-g2m87                   NotReady   control-plane   12m   v1.24.2
default-capi-quickstart-2   capi-quickstart-2-md-0-s8hbx-7bd44554b5-kzcb6   NotReady   <none>          11m   v1.24.2
default-capi-quickstart     capi-quickstart-2xcsz-fxrrk                     NotReady   control-plane   21m   v1.24.2
default-capi-quickstart     capi-quickstart-md-0-9tw2g-b8b4f46cf-gggvq      NotReady   <none>          20m   v1.24.2

Karmada ClusterImportPolicy

对于 Karmada 平台,用户首先需要先将 Clusterpedia 部署在 Karmada APIServer 中,部署步骤可以参考 https://github.com/Iceber/deploy-clusterpedia-to-karmada

创建用于对接 Karmada 平台的 ClusterImportPolicy

$ kubectl create -f https://raw.githubusercontent.com/clusterpedia-io/clusterpedia/main/deploy/clusterimportpolicy/karmada.yaml
$ kubectl get clusterimportpolicy
NAME      AGE
karmada   7d5h

查看 Karmada ClusterPediaClusterLifecycle

$ kubectl get cluster
NAME      VERSION   MODE   READY   AGE
argocd              Push   False   8d
member1   v1.23.4   Push   True    22d
member3   v1.23.4   Pull   True    22d

$ kubectl get pediaclusterlifecycle
NAME              AGE
karmada-argocd    7d5h
karmada-member1   7d5h
karmada-member3   7d5h

Clusterpedia 会为每一个 Karmada Cluster 创建对应的 PediaClusterLifecycle,可以使用 kubectl describe pediaclusterlifecycle <name> 来查看 Karmada Cluster 与 PediaCluster 的转换状态

未来会在 kubectl get pediaclusterlifecycle 中详细状态

查看成功创建的 PediaCluster

NAME              APISERVER                 VERSION   STATUS
karmada-member1   https://172.18.0.4:6443   v1.23.4   Healthy

karmada clusterimportpolicy 要求 karmada 集群为 Push 模式,并且处于 Ready 状态,所以为 member-1 集群创建了 karmada-member-1 pediacluster 资源。

VCluster ClusterImportPolicy

创建用于自动发现 VClusterClusterImportPolicy

$ kubectl create -f https://raw.githubusercontent.com/clusterpedia-io/clusterpedia/main/deploy/clusterimportpolicy/vcluster.yaml
$ kubectl get clusterimportpolicy
NAME      AGE
vclsuter  5h

需要注意,VCluster 集群在创建时需要保证生成的 kubeconfig 的 Server 地址可以由宿主集群内的其他 Pod 访问。

可以设置为 VCluster Service 域名,也可以是 Node IP 或者 Ingress 地址

syncer:
  extraArgs:
  - --out-kube-config-server=https://<vcluster name>.<namespace>.svc
  - --tls-san=<vcluster name>.<namespace>.svc,127.0.0.1

在 default 命名空间创建两个 VCluster, 创建虚拟集群 vcluster-1

# vcluster-1.yaml
syncer:
  extraArgs:
  - --out-kube-config-server=https://vcluster-1.default.svc
  - --tls-san=vcluster-1.default.svc,127.0.0.1
$ vcluster create -n default -f vcluster-1.yaml vcluster-1

创建虚拟集群 vcluster-2

# vcluster-2.yaml
syncer:
  extraArgs:
  - --out-kube-config-server=https://vcluster-2.default.svc
  - --tls-san=vcluster-2.default.svc,127.0.0.1
$ vcluster create -n default -f vcluster-2.yaml vcluster-2

查看所有的 VCluster 集群

$ vcluster list
 NAME              NAMESPACE         STATUS    CONNECTED   CREATED                         AGE
 caiwei-vcluster   caiwei-vcluster   Running               2022-08-26 16:10:52 +0800 CST   484h49m6s
 vcluster-1        default           Running               2022-09-15 20:57:59 +0800 CST   1m59s
 vcluster-2        default           Running               2022-09-15 20:59:34 +0800 CST   24s

我们可以直接使用 kubectl + Clusterpedia 来检索任意 VCluster 内的资源

使用 kubectl 前,需要为多集群资源检索生成集群快捷配置 —— 为 kubectl 生成集群访问的快捷配置

 $ kubectl --cluster clusterpedia get po -A
NAMESPACE     CLUSTER                              NAME                       READY   STATUS    RESTARTS   AGE
default       vc-caiwei-vcluster-caiwei-vcluster   backend-77f8f45fc8-5ssww   1/1     Running   0          20d
default       vc-caiwei-vcluster-caiwei-vcluster   backend-77f8f45fc8-j5m4c   1/1     Running   0          20d
default       vc-caiwei-vcluster-caiwei-vcluster   backend-77f8f45fc8-vjzf6   1/1     Running   0          20d
kube-system   vc-default-vcluster-1                coredns-669fb9997d-cxktv   1/1     Running   0          3m40s
kube-system   vc-default-vcluster-2                coredns-669fb9997d-g7w8l   1/1     Running   0          2m6s
kube-system   vc-caiwei-vcluster-caiwei-vcluster   coredns-669fb9997d-x6vc2   1/1     Running   0          20d

$ kubectl --cluster clusterpedia get ns
CLUSTER                              NAME              STATUS   AGE
vc-default-vcluster-2                default           Active   2m49s
vc-default-vcluster-1                default           Active   4m24s
vc-caiwei-vcluster-caiwei-vcluster   default           Active   20d
vc-default-vcluster-2                kube-node-lease   Active   2m49s
vc-default-vcluster-1                kube-node-lease   Active   4m24s
vc-caiwei-vcluster-caiwei-vcluster   kube-node-lease   Active   20d
vc-default-vcluster-2                kube-public       Active   2m49s
vc-default-vcluster-1                kube-public       Active   4m24s
vc-caiwei-vcluster-caiwei-vcluster   kube-public       Active   20d
vc-default-vcluster-2                kube-system       Active   2m49s
vc-default-vcluster-1                kube-system       Active   4m24s
vc-caiwei-vcluster-caiwei-vcluster   kube-system       Active   20d

Clusterpedia 会自动发现宿主集群内的虚拟集群(VCluster),并根据 VCluster ClusterImportPolicy 创建相应的 PediaCluster,用户可以直接访问 Clusterpedia 来检索资源

$ kubectl get pediaclusterlifecycle
NAME                                 AGE
vc-caiwei-vcluster-caiwei-vcluster   20d
vc-default-vcluster-1                5m57s
vc-default-vcluster-2                4m24s

$ kubectl get pediacluster
NAME                                 READY   VERSION        APISERVER
vc-caiwei-vcluster-caiwei-vcluster   True    v1.23.5+k3s1   https://caiwei-vcluster.caiwei-vcluster.svc
vc-default-vcluster-1                True    v1.23.5+k3s1   https://vcluster-1.default.svc
vc-default-vcluster-2                True    v1.23.5+k3s1   https://vcluster-2.default.svc

新建 ClusterImportPolicy

如果 Clusterpedia 仓库 中没有维护某个平台的 ClusterImportPolicy,那么我们可以新建 ClusterImportPolicy

关于 ClusterImportPolicy 原理和字段的详细描述可以参考 集群自动接入策略

现在假定有一个多云平台 MCP,该平台使用自定义资源 —— Cluster 来代表被纳管的集群,并且将集群的认证信息保存在和集群同名的 Secret 中

apiVersion: cluster.mcp.io
kind: Cluster
metadata:
  name: cluster-1
spec:
  apiEndpoint: "https://172.10.10.10:6443"
  authSecretRef:
    namespace: "default"
    name: "cluster-1"
status:
  conditions:
    - type: Ready
      status: True
---
apiVersion: v1
kind: Secret
metadata:
  name: cluster-1
data:
  ca: **cluster ca bundle**
  token: **cluster token**

我们为 MCP 平台定义一个 ClusterImportPolicy 资源,并且默认同步 pods 和 apps group 下的资源

apiVersion: policy.clusterpedia.io/v1alpha1
kind: ClusterImportPolicy
metadata:
  name: mcp
spec:
  source:
    group: "cluster.mcp.io"
    resource: clusters
    versions: []
  references:
    - group: ""
      resource: secrets
      versions: []
      namespaceTemplate: "{{ .source.spec.authSecretRef.namespace }}"
      nameTemplate: "{{ .source.spec.authSecretRef.name }}"
      key: authSecret
  nameTemplate: "mcp-{{ .source.metadata.name }}"
  template: |
    spec:
      apiserver: "{{ .source.spec.apiEndpoint }}"
      caData: "{{ .references.authSecret.data.ca }}"
      tokenData: "{{ .references.authSecret.data.token }}"
      syncResources:
        - group: ""
          resources:
          - "pods"
        - group: "apps"
          resources:
          - "*"
      syncResourcesRefName: ""    
  creationCondition: |
    {{ if ne .source.spec.apiEndpoint "" }}
      {{ range .source.status.conditions }}
        {{ if eq .type "Ready" }}
          {{ if eq .status "True" }} true {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}    
  • spec.source 定义了需要监听的资源 Cluster
  • spec.references 定义了将 MCP Cluster 转换为 PediaCluster 时涉及到的资源,当前只有 secrets 资源
  • spec.nameTemplate 会根据 MCP Cluster 资源渲染出 PediaCluster 资源的名字
  • spec.template 通过 MCP Cluster 和 spec.references 中定义的资源来渲染出 PediaCluster 资源,具体规则可以参考 PediaCluster Template
  • spec.creationCondition 可以根据 MCP Cluster 和 spec.references 定义的资源来可以决定了什么时候可以创建 PediaCluster,这里定义了当 MCP Cluster 处于 Ready 后再创建 PediaCluster,具体使用可以参考 Creation Condition