Clusternet(Cluster Internet) 是一个腾讯开源的 Kubernetes 多集群管理云原生项目,可帮助你像访问 Internet 一样轻松管理数以百万计的 Kubernetes 集群。

 腾讯开源的 Kubernetes 多集群管理和跨集群编排工具 Clusternet(部署kubernetes集群) Clusternet 开源 第1张

Clusternet(Cluster Internet) 是一个腾讯开源的 Kubernetes 多集群管理云原生项目,可帮助你像访问 Internet 一样轻松管理数以百万计的 Kubernetes 集群。无论集群运行在公共云、私有云、混合云还是边缘,Clusternet 都可以让你管理/访问它们,就像它们在本地运行一样。这也有助于消除为每个集群处理不同管理工具的需要。Clusternet 还可以帮助你从托管集群中的一组 API 将应用程序部署和协调到多个集群。当你的集群在 VPC 网络、边缘或防火墙后面运行时,Clusternet 可以通过可配置的方式设置网络隧道。

Clusternet 还提供了一个 Kubernetes 风格的 API,你可以继续使用 Kubernetes 的方式,比如 KubeConfig,来访问某个管理的 Kubernetes 集群,或者一个 Kubernetes 服务。

以 Clusternet 项目为基础实现多云多集群管理平台,为用户提供跨云、跨集群、跨 region/zone 的分布式容器服务,将更好的满足多种场景需求。

1 架构

下图是 Clusternet 的一个简单的架构图:

 腾讯开源的 Kubernetes 多集群管理和跨集群编排工具 Clusternet(部署kubernetes集群) Clusternet 开源 第2张

Clusternet 主要由 Clusternet-agent 和 clusternet-hub 两个组件组成,非常轻量级。

其中 clusternet-agent 组件需要部署在各个子集群中,主要负责:

  • 将当前集群作为子集群自动注册到父集群,也称为子集群 ManagedCluster
  • 上报当前集群元信息,包括 Kubernetes 版本、运行平台、healthz/readyz/livez 健康状态、节点状态等
  • 与父集群建立一个 TCP 全双工的 websocket 安全隧道连接

clusternet-hub 组件部署和运行在父集群中,通过 AA(Aggregated APIServer) 的方式进行工作,主要负责:

  • 批准各个子集群注册请求,并为子集群创建专用资源,例如 namespace、ServiceAccount 和 RBAC 规则等
  • 作为聚合的 apiserver (AA),用作 websocket 服务器,维护来自子集群的多个 websocket 连接
  • 提供 Kubernstes 风格的 REST API 来重定向/代理/升级请求到每个子集群 ( 从一组 API 协调应用程序并将其部署到多个集群;

注意:由于 clusternet-hub 作为 AA 运行,所以需要确保父级 apiserver 可以访问该 clusternet-hub 服务。

2 概念

对于每个想要被管理的 Kubernetes 集群,我们称之为子集群,子集群注册到的集群,我们称之为父集群。组件 clusternet-agent 在子集群中运行,clusternet-hub 在父集群中运行。Clusternet 支持向不同集群分发和管理各种应用资源,包括原生 Kubernetes 各类资源(Deployment/StatefulSet/ConfigMap/Secret 等)、各类 CRD 资源,以及 HelmChart 应用等等。

下图是 Clusternet 的多集群应用分发模型,其中绿色的模块是需要用户去创建的,紫色的模块是 Clusternet 内部做流转的资源对象,此外 Clusternet 还提供了 kubectl 插件,可以通过 kubectl clusternet apply 命令来创建资源。

 腾讯开源的 Kubernetes 多集群管理和跨集群编排工具 Clusternet(部署kubernetes集群) Clusternet 开源 第3张

  • ClusterRegistrationRequest 是 clusternet-agent 在父集群中为子集群注册创建的对象
  • ManagedCluster 是 clusternet-hub 在批准 ClusterRegistrationRequest 后在父集群中创建的一个对象
  • HelmChart 是一个 helm chart 配置的对象
  • Subscription 定义了订阅者想要安装到集群中的资源,对于每个匹配的集群,将在其专用命名空间中创建一个相应的 Base 对象
  • Localization 和 Globalization 将以优先级来定义 Override,数字越小则优先级越低,Localization是命名空间范围的资源,而 Globalization 是集群范围的。
  • Base 对象将被渲染为应用了 Globalization 和 Localization 设置 Description 对象,Descritpion 是最终要部署到目标子群中的资源

3 部署

从上面的架构可以看出我们需要在子集群和父集群中分别部署 clusternet-agent 和 clusternet-hub 组件。

首先在集群中 Clone 项目代码:

  1. $gitclonehttps://github.com/clusternet/clusternet.git

在父集群中部署 clusternet-hub 组件:

  1. $kubectlapply-fdeploy/hub

然后为 clusternet-agent 创建一个 bootstrap token:

  1. $#下面命令将创建一个bootstraptoken:07401b.f395accd246ae52d
  2. $kubectlapply-fmanifests/samples/cluster_bootstrap_token.yaml

然后在子集群中部署 clusternet-agent,帮助子集群注册到父集群,clusternet-agent 可以配置以下三种同步模式(通过标志 --cluster-sync-mode 配置):

  • Push(推) 模式是指父集群的所有资源变化将由 clusternet-hub 自动同步、推送并应用到子集群
  • Pull(拉) 模式表示 clusternet-agent 将自动 watch、同步和应用所有从父集群到子集群的资源变化
  • Dual 推拉结合模式,这种模式强烈推荐,通常与特性 AppPusher 一起使用

特性 AppPusher 在 agent 端工作,这主要是出于以下两个原因:

  • 不建议在注册后改变同步模式,这可能会带来不一致的配置和行为,这就是为什么强烈推荐双模式。当双模式被设置后,AppPusher 提供了一种方法来帮助将 Push 模式切换到 Pull 模式,而无需真正更改标志 --cluster-sync-mode,反之亦然。
  • 出于安全考虑,如子集群的安全风险等。
  1. 当一个子集群禁用 AppPusher 时,父集群不会向其部署任何应用程序,即使设置为 Push 或 Dual 模式,这个时候,这个子集群的工作方式就像 Pull 模式。
  2. 要部署的资源被表示为 Description 对象,你也可以运行你自己的控制器来 watch 该对象的变化,然后来分发和部署资源。

部署 clusternet-agent 后,首先要创建一个包含集群注册用的 Token 的 Secret:

  1. $#createnamespaceclusternet-systemifnotcreated
  2. $kubectlcreatensclusternet-system
  3. $#hereweusethetokencreatedabove
  4. $PARENTURL=https://192.168.10.10REGTOKEN=07401b.f395accd246ae52denvsubst<./deploy/templates/clusternet_agent_secret.yaml|kubectlapply-f-

上面的 PARENTURL 是你想注册的父集群的 apiserver 地址,必须指定 https 方案,它是目前唯一支持的方案。如果 apiserver 不是在标准的 https 端口(:443)上监听,请在 URL 中指定端口号,以确保代理连接到正确的端点,例如 https://192.168.10.10:6443。

  1. $#部署之前,根据自己的需求更新同步模式
  2. $kubectlapply-fdeploy/agent

部署完成后检查集群注册情况:

  1. $#clsrr是ClusterRegistrationRequest对象的别名
  2. $kubectlgetclsrr
  3. NAMECLUSTERIDSTATUSAGE
  4. clusternet-dc91021d-2361-4f6d-a404-7c33b9e01118dc91021d-2361-4f6d-a404-7c33b9e01118Approved3d6h
  5. $kubectlgetclsrrclusternet-dc91021d-2361-4f6d-a404-7c33b9e01118-oyaml
  6. apiVersion:clusters.clusternet.io/v1beta1
  7. kind:ClusterRegistrationRequest
  8. metadata:
  9. labels:
  10. clusters.clusternet.io/cluster-id:dc91021d-2361-4f6d-a404-7c33b9e01118
  11. clusters.clusternet.io/cluster-name:clusternet-cluster-dzqkw
  12. clusters.clusternet.io/registered-by:clusternet-agent
  13. name:clusternet-dc91021d-2361-4f6d-a404-7c33b9e01118
  14. spec:
  15. clusterId:dc91021d-2361-4f6d-a404-7c33b9e01118
  16. clusterName:clusternet-cluster-dzqkw
  17. clusterType:EdgeClusterSelfProvisioned
  18. status:
  19. caCertificate:REDACTED
  20. dedicatedNamespace:clusternet-dhxfs
  21. managedClusterName:clusternet-cluster-dzqkw
  22. result:Approved
  23. token:REDACTED

在 ClusterRegistrationRequest 被批准后,状态将被更新,如果需要的话,可以用相应的凭证来访问父集群。这些凭证已经用指定范围内的 RBAC 规则设置了,可以查看下面的两个规则。

  1. apiVersion:rbac.authorization.k8s.io/v1
  2. kind:ClusterRole
  3. metadata:
  4. annotations:
  5. clusternet.io/autoupdate:"true"
  6. labels:
  7. clusters.clusternet.io/bootstrapping:rbac-defaults
  8. clusters.clusternet.io/cluster-id:dc91021d-2361-4f6d-a404-7c33b9e01118
  9. clusternet.io/created-by:clusternet-hub
  10. name:clusternet-dc91021d-2361-4f6d-a404-7c33b9e01118
  11. rules:
  12. -apiGroups:
  13. -clusters.clusternet.io
  14. resources:
  15. -clusterregistrationrequests
  16. verbs:
  17. -create
  18. -get
  19. -apiGroups:
  20. -proxies.clusternet.io
  21. resourceNames:
  22. -dc91021d-2361-4f6d-a404-7c33b9e01118
  23. resources:
  24. -sockets
  25. verbs:
  26. -'*'
  27. ---
  28. apiVersion:rbac.authorization.k8s.io/v1
  29. kind:Role
  30. metadata:
  31. annotations:
  32. clusternet.io/autoupdate:"true"
  33. labels:
  34. clusters.clusternet.io/bootstrapping:rbac-defaults
  35. clusternet.io/created-by:clusternet-hub
  36. name:clusternet-managedcluster-role
  37. namespace:clusternet-dhxfs
  38. rules:
  39. -apiGroups:
  40. -'*'
  41. resources:
  42. -'*'
  43. verbs:
  44. -'*'

然后检查被管理集群的状态:

  1. $#mcls是ManagedCluster对象的别名
  2. $#kubectlgetmcls-A
  3. $#orappend"-owide"todisplayextracolumns
  4. $kubectlgetmcls-A-owide
  5. NAMESPACENAMECLUSTERIDCLUSTERTYPESYNCMODEKUBERNETESREADYZAGE
  6. clusternet-dhxfsclusternet-cluster-dzqkwdc91021d-2361-4f6d-a404-7c33b9e01118EdgeClusterSelfProvisionedDualv1.19.10true7d23h
  7. $kubectlgetmcls-nclusternet-dhxfsclusternet-cluster-dzqkw-oyaml
  8. apiVersion:clusters.clusternet.io/v1beta1
  9. kind:ManagedCluster
  10. metadata:
  11. labels:
  12. clusters.clusternet.io/cluster-id:dc91021d-2361-4f6d-a404-7c33b9e01118
  13. clusters.clusternet.io/cluster-name:clusternet-cluster-dzqkw
  14. clusternet.io/created-by:clusternet-agent
  15. name:clusternet-cluster-dzqkw
  16. namespace:clusternet-dhxfs
  17. spec:
  18. clusterId:dc91021d-2361-4f6d-a404-7c33b9e01118
  19. clusterType:EdgeClusterSelfProvisioned
  20. syncMode:Dual
  21. status:
  22. apiserverURL:http://10.0.0.10:8080
  23. appPusher:true
  24. healthz:true
  25. k8sVersion:v1.19.10
  26. lastObservedTime:"2021-06-30T08:55:14Z"
  27. livez:true
  28. platform:linux/amd64
  29. readyz:true

默认情况下,clusternet-agent 每3分钟更新一次 ManagedCluster 的状态,这可以通过标志 --cluster-status-update-frequency 来进行配置。

然后我们可以通过 krew 来安装 Clusternet 的 kubectl 插件:

  1. $kubectlkrewinstallclusternet

安装完成后就可以使用 kubectl clusternet 命令了:

  1. $kubectlclusternet-h
  2. Usage:
  3. clusternet[flags]
  4. clusternet[command]
  5. AvailableCommands:
  6. applyApplyaconfigurationtoaresourcebyfilenameorstdin
  7. createCreatearesourcefromafileorfromstdin.
  8. deleteDeleteresourcesbyfilenames,stdin,resourcesandnames,orbyresourcesandlabelselector
  9. editEditaresourceontheserver
  10. getDisplayoneormanyresources
  11. helpHelpaboutanycommand
  12. scaleSetanewsizeforaDeployment,ReplicaSetorReplicationController
  13. versionPrintthepluginversioninformation

4 示例

当 Clusternet 部署完成后,接下来我们就可以来尝试将应用部署到多个集群了。Clusternet 支持从一个托管集群的一组 API 中向多个集群部署应用程序。

注意:Deployer 特性需要由 clusternet-hub 开启。

首先,让我们看一个示例应用。下面名为 "app-demo" 的 Subscription 定义了要分发的目标子集群,以及要部署的资源。

  1. $kubectlapply-fdeploy/hub
0

在应用这个 Subscription 对象之前,请用你的集群 ID 更新 examples/applications/subscription.yaml。

在安装了 kubectl 插件 kubectl-clusternet 之后,你可以运行下面的命令将这个应用程序分发到子集群:

  1. $kubectlapply-fdeploy/hub
1

然后可以使用下面的命令查看刚刚创建的资源:

  1. $kubectlapply-fdeploy/hub
2

Clusternet 将帮助部署和协调应用程序到多个集群,可以通过以下命令检查状态。

  1. $kubectlapply-fdeploy/hub
3

当然也可以在子集群中用 Helm 命令行工具来验证安装情况,比如:

  1. $kubectlapply-fdeploy/hub
4

这样我们就成功将一个应用轻松分发到多个集群了。关于 Clusternet 的更多细节和使用方法请查看官方仓库:https://github.com/clusternet/clusternet 了解更多。

转载请说明出处
知优网 » 腾讯开源的 Kubernetes 多集群管理和跨集群编排工具 Clusternet(部署kubernetes集群)

发表评论

您需要后才能发表评论