简介:在这篇文章中,将介绍 Placement 如何抉择到所需的集群,Placement 能够提供的调度性能,以及一些场景下的最佳实际,使用者能够参考示例来编写合乎本人要求的 Placement。其余一些高级调度性能,如反对污点 (taints) 和容忍 (tolerations),以及拓扑抉择 (spread),正在 OCM 社区探讨中。
作者:
邱见|红帽资深软件工程师,Open Cluster Management (OCM) 社区发起人,负责人
郝青|红帽高级软件工程师,Open Cluster Management (OCM) 社区维护者 Open
Cluster Management(OCM) 我的项目曾经在 2021 年 11 月 9 日成为 CNCF 的沙箱我的项目。OCM 作为一个社区驱动的我的项目,专一于 Kubernetes 应用程序的多集群和多云场景。
最新 OCM 社区版本 0.6.0 已于 2022 年 1 月 21 日正式公布。具体内容可拜访 Open Cluster Management 0.6 公布[1]。
在多集群环境中,不同角色的用户对多集群操作有着不同的需要。比方管理员等用户须要对指标集群进行一些配置, 应用程序开发人员可能心愿将工作负载部署到特定集群,这些工作负载能够是 Kubernetes 的 Service、Deployment、ConfigMap 或不同 Kubernetes 对象的捆绑包。这些用户对指标集群会有一些要求,比方:
- 我只想在 Amazon Web Services(AWS) 上配置集群。
- 我只想将工作负载部署到标签为 group=dev 的集群上。
- 我心愿工作负载始终在具备最大可分配内存的 3 个集群上运行。
为了抉择出指标集群,能够抉择在部署管道 (deploy pipeline) 中对间接指定指标集群名称,或应用某种模式的标签选择器。对于对资源有要求的工作负载,须要一个细粒度的调度器来将工作负载散发到具备足够资源的群集。当群集属性更改时,调度后果应该放弃动静更新。
在 OCM 中,后面形容的调度性能是通过 Placement 来实现的。在这篇文章中,将介绍 Placement 如何抉择到所需的集群,Placement 能够提供的调度性能,以及一些场景下的最佳实际,使用者能够参考示例来编写合乎本人要求的 Placement。其余一些高级调度性能,如反对污点 (taints) 和容忍 (tolerations),以及拓扑抉择 (spread),正在 OCM 社区 [2] 探讨中。
在浏览本文前,可拜访以下链接理解相干基本概念:
- ManagedCluster 和 ManagedClusterSet[3]
- Placement[4]
为什么咱们须要 ManagedClusterSet?
“ClusterSet”是在 Kubernetes SIG 多集群工作小组的“多集群服务 (MultiClusterService/MCS)”API 中曾经实际许久的概念,它意指多个领有雷同属性 / 特色的“集群小组”的概念。在多集群网络的场景里咱们须要依据底座基础设施的拓扑为集群分组,同样的在 OCM 多集群治理平台里我也能够依据集群的场景用处,工作个性具体分组。这也是 OCM 引入 ClusterSet 模型的最后原因之一。
在此基础上,OCM 在引入多集群分组的语义的同时思考到了不同分组之间的“软租户隔离性”— 尤其思考到不同集群小组可能是由不同的角色 / 团队去保护的,同时这些团队之间应该互相自治不烦扰。在 OCM 的世界中,咱们会容许管理员为每一种角色 / 团队会调配一个命名空间 /namespace,同时通过利用 Kubernetes 原生提供的命名空间之间的隔离性使不同角色区别开来(其中所谓的角色落进理论场景里能够是一个利用或者也能够是一个组织团队等等)。那么这些角色只有在被调配的命名空间里流动就能够充沛编排所关联的多个集群上的资源。
总而言之,在一个通用的多集群中枢管制立体里,如何解决多个用户 / 角色拆散的问题其实是最首要的问题之一,OCM 之所以引入了 ClusterSet 模型且额定提供了其到命名空间的映射,是为了心愿 OCM 作为一个平台能解决“多集群场景”里帮忙用户解决最琐碎同时又最操心的问题。至于如何生产所关联的集群列表请参考上面的 Placement 模型。
什么是 Placement?
Placement API 用于在一个或多个托管集群组 (ManagedClusterSet) 中抉择一组托管群集(ManagedCluster),以便将工作负载部署到这些群集上。
如果定义了无效的 Placement,则 Placement 控制器 (controller) 将生成相应的调度决策 (PlacementDecision),并在状态 (Status) 中列出选定的托管群集 (ManagedCluster)。作为最终用户,你能够解析出选定的集群,而后对指标集群进行操作。你也能够将更高层级的工作负载编排器 (orchestrator) 与 PlacementDecision 集成,来扩大 Placement 的调度能力。
例如,ArgoCD 曾经与 Placement 集成。ArgoCD 的使用者能够在 ApplicationSet 的 clusterDecisionResource 中指定一个关联了的 PlacementDecision 资源的 ConfigMap,就能够利用 Placement 的调度决策,将利用主动调配到一组指标集群。如下:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: book-import
spec:
generators:
- clusterDecisionResource:
configMapRef: ocm-placement
labelSelector:
matchLabels:
cluster.open-cluster-management.io/placement: local-cluster
requeueAfterSeconds: 30
template:
…
apiVersion: v1
kind: ConfigMap
metadata:
name: ocm-placement
data:
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: placementdecisions
statusListKey: decisions
matchKey: clusterName
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: PlacementDecision
metadata:
labels:
cluster.open-cluster-management.io/placement: local-cluster
name: local-cluster-decision-1
status:
decisions:
- clusterName: cluster1
reason: ""
- clusterName: cluster2
reason: ""
KubeVela 作为凋谢应用程序模型 OAM(Open Application Model) 的实现,也行将利用 Placement API 进行工作负载调度。
与原生 Kubernetes 调度模型的区别与分割?
与 Kubernetes 的动态调度不同,Placement 应用动静调度的机制。调度抉择会随着集群属性变动也随之扭转,用户能够通过在 Placement 上调整调度的稳固值来缩小调度决策的抖动。另外,Placement API 尝试将整个调度过程显示化,让用户能够通过 API 查问调度抉择的原委,不便用户更加容易的调试调度配置和参数。
同时在原生 Kubernetes 中的调度是一次性的,而在多集群场景里咱们往往须要的是一个“申明式的调度”— 咱们定义出调度策略的“硬条件”和“软条件”是什么,再依据理论的集群拓扑 / 实时状态决策最终匹配的集群,所以它更像是原生 Kubernetes 中的驱散调度 / 反调度 PodDisruptionBudget 的模型而非动态调度中的 Taint/Toleration 的模型。
OCM 在 Placement 模型中同时思考到了大规模多集群调度时集群列表长度暴涨的问题,在 Placement 的匹配产物 PlacementDecision 中所有匹配后果都是分页展现的以防止冲破 Kubernetes CRD 对模型的限度。
Placement 如何抉择集群?
有了上述的初步介绍,让咱们更深刻地理解 Placement API,看看它是如何抉择所需的集群以及它能够提供哪些调度性能。
如下是一个 Placement 例子:
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: Placement
metadata:
name: placement
namespace: ns1
spec:
numberOfClusters: 4
clusterSets:
- clusterset1
- clusterset2
predicates:
- requiredClusterSelector:
labelSelector:
matchLabels:
vendor: OpenShift
prioritizerPolicy:
mode: Exact
configurations:
- scoreCoordinate:
builtIn: ResourceAllocatableMemory
- scoreCoordinate:
builtIn: Steady
weight: 3
- scoreCoordinate:
type: AddOn
addOn:
resourceName: default
scoreName: cpuratio
Spec 蕴含以下四个字段:
numberOfClusters: 示意要抉择的符合要求的 ManagedClusters 数量。
clusterSets: 示意从中抉择 ManagedCluster 的 ManagedClusterSet 名称。
predicates: 包含了一组预选策略。能够应用标签选择器 (labelSelector) 和申明选择器 (claimSelector) 来抉择 ManagedCluster。每一个预选策略配置之间是或的关系。
prioritizerPolicy: 定义了优选策略。优选策略中通过 mode 设置是否应用默认的优选器 (prioritizer)。同时也能够在 configurations 中配置具体的优选器 (prioritizer)。目前 Placement 内置反对的优选器 (prioritizer) 包含均衡 (Balance),稳固 (Steady),最大可调配 CPU 资源 (ResourceAllocatableCPU) 和最大可分配内存资源 (ResourceAllocatableMemory)。Placement 同时也反对通过第三方提供的分数来抉择集群。weight 权重是一个 -10 到 10 的整数,用以调整不同的优选器打分对总分的影响。
如果未定义 Spec 中各字段的值,则应用默认值。每个字段中默认值的详细信息在 PlacementSpec[5] 中定义。
如果 Spec 为空,所有绑定到 Placement 命名空间 (namespace) 的 ManagedClusterSet 中的所有 ManagedCluster 将作为可能的选项。
以上每个字段的定义都在调度中施展着作用。如下是一个典型的调度过程:
调度框架首先从 clusterSets 中定义的 ManagedClusterSet 中抉择出可用的 ManagedCluster。
过滤器插件 (filter plugin) 通过预选策略 predicates 中定义的标签 (label) 和申明 (claim) 选择器进一步筛选 ManagedCluster。
在优选策略 prioritizerPolicy 启用的优选器插件 (prioritizer plugin) 会为每个筛选后的 ManagedCluster 打一个分数,并且按总分从高到低确定优先级。
调度框架会抉择前 k 个 ManagedCluster,并把这些集群列在 PlacementDecision 中。k 的值是在 numberOfClusters 定义的集群数量。
如果将以上步骤对应的上述的例子中,调度过程如下:
调度框架首先抉择 ManagedClusterSet clusterset1 和 clusterset2 中的集群作为可用的 ManagedCluster。
过滤器插件 (filter plugin) 筛选出带有标签 (label)vendor=OpenShift 的 ManagedCluster。
优选器插件 (prioritizer plugin)ResourceAllocatableMemory 和 Steady 为每一个筛选的 ManagedCluster 打分。当配置了优选策略 AddOn,Placement 会尝试取得集群对应的第三方资源提供的分数 cpuratio。并用如下公式计算每个 ManagedCluster 的总分:
1(ResourceAllocatableMemory 的默认权重) ResourceAllocatableMemory 的打分 + 3(Steady 的权重) Steady 的打分 + 1(AddOn 的默认权重) * cpuratio(AddOn 的分数)
调度框架依照每个 ManagedCluster 的总分从高到低排列,并返回最高分数的 ManagedCluster 作为后果。
在第 3 步优选器插件工作时,实际上多个插件的组合。每个插件的算法和权重都会影响最终的调度后果。下一节中,会更具体的介绍每个插件,以便你更好的理解 Placement 是如何抉择 ManagedCluster 的。
优选器插件如何工作?
在撰写此文时,咱们有如下四个默认的优选器:
均衡 (Balance): 均衡每个集群上的调度决策 (PlacementDecision) 数量。领有 PlacementDecision 数量最多的集群将失去最低分 -100 分,如果没有 PlacementDecision 则被赋予最高分 100 分。其余的分数介于 -100 到 100 之间。
稳固 (Steady): 确保现有的 PlacementDecision 中已全集群的后果保持稳定。现有的 PlacementDecision 曾经选中的集群将失去最高分 100 分,没有被选中的集群失去最低分 0 分。
最大可调配 CPU 资源 (ResourceAllocatableCPU) 和最大可分配内存资源 (ResourceAllocatableMemory) 基于集群的可调配 CPU 或者内存做决策。领有最多可分配资源 (CPU 或者内存) 的集群将失去最高分 100 分,领有起码资源的集群将失去最低分 -100 分。其余的分数介于 -100 到 100 之间。
优选策略 AddOn 还反对通过第三方提供的分数抉择集群。这部分也是 Placement 在 OCM v0.6.0 中的最新性能。OCM v0.6.0 中提供了新的 API AddOnPlacementScore 用以反对一种基于自定义分数的更具可扩展性的调度形式。
作为使用者,能够在 yaml 文件中 prioritizerPolicy 下配置 AddOn,来指定自定义分数以抉择集群。
作为分数的提供者,第三方的控制器 (controller) 能够在核心 (Hub Cluster) 或托管群集 (Managed Cluster) 上运行,controller 须要保护 AddOnPlacementScore 的生命周期并将分数更新到其中。
对于可扩大调度的更多具体内容,能够参考社区文档[6]。
在做出调度决策时,ManagedCluster 依照最终的总分排序。总分是每个优选器的打分乘以权重的总和: 总分 = sum(prioritizer_x_weight * prioritizer_x_score),其中 prioritizer_x_weight 是优选器 (prioritizer)X 的权重,prioritizer_x_score 是优选器 (prioritizer)X 为一个 ManagedCluster 打的分数。
能够通过调整优选器 (prioritizer) 的权重来影响最终的分数,比方:
通过给资源类型的优选器 ResourceAllocatableCPU 和 ResourceAllocatableMemory 设置权重,来基于可调配的资源做调度。
通过给资源类型的优选器设置一个更高的权重,使得调度后果对于资源的变动更加敏感。
通过给优选器 Steady 设置更高的权重,使得调度后果能够疏忽资源的变动保持稳定。
如下是一些理论的例子,来阐明多个优选器是如何独特工作以失去最终的调度后果。这些例子也能够视为是在一些场景下的最佳实际。
以下示例中假如有三个托管集群 (ManagedCluster) 绑定在命名空间 (namespace)ns1,其中 cluster1,cluster2,cluster3 别离有 60MB,80MB 和 100MB 可分配内存。
示例 1:抉择具备最大可分配内存的集群。
在此示例中,心愿抉择具备最大可分配内存的集群。为了按可分配内存对集群进行优先级排序,能够在优选策略 (prioritizerPolicy) 中配置 ResourceAllocatableMemory。
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: Placement
metadata:
name: demo
namespace: ns1
spec:
numberOfClusters: 2
prioritizerPolicy:
configurations:
- scoreCoordinate:
builtIn: ResourceAllocatableMemory
Placement 创立之后,能够通过 oc describe placement 命令,查看 events 来理解优先级排序是如何选中集群的。
# oc describe placement demo -n ns1
Name: demo
Namespace: ns1
Labels: <none>
Annotations: <none>
API Version: cluster.open-cluster-management.io/v1alpha1
Kind: Placement
…
Status:
Conditions:
Last Transition Time: 2021-11-09T07:02:14Z
Message: All cluster decisions scheduled
Reason: AllDecisionsScheduled
Status: True
Type: PlacementSatisfied
Number Of Selected Clusters: 2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 10s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 10s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 10s placementController cluster1:0 cluster2:100 cluster3:200
在这个例子中,在 Additive 模式下,优选器包含了默认权重为 1 的 Balance 和 Steady 以及显示配置了权重为 1 的 ResourceAllocatableMemory。一个集群的最终得分将由如下公式决定:
1 prioritizer_balance_score + 1 prioritizer_steady_score + 1 * prioritizer_resourceallocatablememory_score
从下面的 event 中能够看进去,cluster1 总分为 0,cluster2 总分为 100,cluster3 总分为 200。调度后果应该抉择 cluster2 和 cluster3。
能够通过 oc describe placementdecision 命令来验证调度后果,如下:
# oc describe placementdecision demo-decision-1 -n ns1
Name: demo-decision-1
Namespace: ns1
Labels: cluster.open-cluster-management.io/placement=placement-jkd42
Annotations: <none>
API Version: cluster.open-cluster-management.io/v1alpha1
Kind: PlacementDecision
...
Status:
Decisions:
Cluster Name: cluster2
Reason:
Cluster Name: cluster3
Reason:
Events: <none>
能够看到,在 PlacementDecision 的 status 中,cluster2 和 cluster3 被列在其中。
让咱们尝试增加一个新的集群,并且这个集群上有着比被选中集群高出一些的可分配内存。
Placement 调度器会监督 (watch) 托管集群。一旦有资源变动,将触发从新调度。当初,让咱们试着增加一个有 100MB 可分配内存的新集群 cluster4,同时查看 Placement 中的事件 (event)。
# oc describe placement demo -n ns1
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 100s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 100s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 100s placementController cluster1:0 cluster2:100 cluster3:200
能够看到并没有事件更新,调度后果也没有发生变化。所以当咱们增加一个仅仅比 cluster2 的内存高出 20MB 的 cluster4 时,调度后果并不会被影响。
让咱们尝试增加一个新的集群,并且这个集群上有着比被选中集群高出很多的可分配内存。
当初,让咱们试着增加一个有 150MB 可分配内存的新集群 cluster4,同时再次查看 Placement 中的事件 (event)。
# oc describe placement demo -n ns1
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 2m10s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 2m10s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 2m10s placementController cluster1:0 cluster2:100 cluster3:200
Normal DecisionUpdate 3s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 3s placementController cluster1:200 cluster2:145 cluster3:189 cluster4:200
这一次,调度后果更新了,Placement 被从新调度到了 cluster3 和 cluster4 上。
# oc describe placementdecision demo-decision-1 -n ns1
...
Status:
Decisions:
Cluster Name: cluster3
Reason:
Cluster Name: cluster4
Reason:
在下面这个例子中,当资源只产生了少许变动时,调度后果并不会被影响。而当资源产生比拟大的变动时,变动会立即反馈在调度后果中。这样便引发出如下 2 个挑战:
如果心愿调度后果对资源变动放弃敏感,应该怎么做?
如果心愿调度后果保持稳定,疏忽资源的变动,应该怎么做?
还记得咱们在 prioritizerPolicy 中有 4 个优选器并且能够调整他们的权重吗?咱们能够通过批改 prioritizerPolicy 的配置来解决下面两个问题。
示例 2:抉择具备最大可分配内存的群集,并使 Placement 对资源变动放弃敏感。
为了使调度后果对资源的变动敏感,这次咱们显式设置了优选器 ResourceAllocatableMemory,权重为 3。
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: Placement
metadata:
name: placement7
namespace: ns1
spec:
numberOfClusters: 2
prioritizerPolicy:
configurations:
- scoreCoordinate:
builtIn: ResourceAllocatableMemory
weight: 3
当 Placement 创立好之后,让咱们通过 oc describe 命令来查看 Placement 和 PlacementDecision 的后果。
# oc describe placement demo -n ns1
...
Status:
Conditions:
Last Transition Time: 2021-11-09T08:58:40Z
Message: All cluster decisions scheduled
Reason: AllDecisionsScheduled
Status: True
Type: PlacementSatisfied
Number Of Selected Clusters: 2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 35s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 35s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 35s placementController cluster1:-200 cluster2:100 cluster3:400
# oc describe placementdecision demo-decision-1 -n ns1
...
Status:
Decisions:
Cluster Name: cluster2
Reason:
Cluster Name: cluster3
Reason:
初始的调度后果为 cluster2 和 cluster3。当初,让咱们试着再次退出一个有 100MB 可分配内存的集群,而后查看 Placement 事件。
# oc describe placement demo -n ns1
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 3m1s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 3m1s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 3m1s placementController cluster1:-200 cluster2:100 cluster3:400
Normal DecisionUpdate 2s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 2s placementController cluster1:-200 cluster2:200 cluster3:500 cluster4:400
这一次,PlacementDecision 更新了,并且后果从新调度到了 cluster3 和 cluster4。
# oc describe placementdecision demo-decision-1 -n ns1
...
Status:
Decisions:
Cluster Name: cluster3
Reason:
Cluster Name: cluster4
Reason:
示例 3:抉择具备最大可分配内存的集群并稳固调度后果。
为了使调度后果保持稳定,这次咱们显式设置了优选器 Steady,并且设置权重为 3。
apiVersion: cluster.open-cluster-management.io/v1alpha1
kind: Placement
metadata:
name: demo
namespace: ns1
spec:
numberOfClusters: 2
prioritizerPolicy:
configurations:
- scoreCoordinate:
builtIn: ResourceAllocatableMemory
- scoreCoordinate:
builtIn: Steady
weight: 3
Placement 创立好之后,再次通过 oc describe 命令来查看 Placement 和 PlacementDecision 的后果。
# oc describe placement demo -n ns1
...
Status:
Conditions:
Last Transition Time: 2021-11-09T09:05:36Z
Message: All cluster decisions scheduled
Reason: AllDecisionsScheduled
Status: True
Type: PlacementSatisfied
Number Of Selected Clusters: 2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 15s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 15s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 15s placementController cluster1:0 cluster2:100 cluster3:200
# oc describe placementdecision demo-decision-1 -n ns1
...
Status:
Decisions:
Cluster Name: cluster2
Reason:
Cluster Name: cluster3
Reason:
初始的调度后果为 cluster2 和 cluster3。
当初,让咱们试着再次退出一个有 150MB 可分配内存的集群,而后查看 Placement 事件。这一次 event 并没有更新。
# oc describe placement demo -n ns1
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal DecisionCreate 80s placementController Decision demo-decision-1 is created with placement demo in namespace ns1
Normal DecisionUpdate 80s placementController Decision demo-decision-1 is updated with placement demo in namespace ns1
Normal ScoreUpdate 80s placementController cluster1:0 cluster2:100 cluster3:200
再次查看 PlacementDecision,能够看到调度后果并没有变动,固定在了 cluster2 和 cluster3。
# oc describe placementdecision demo-decision-1 -n ns1
...
Status:
Decisions:
Cluster Name: cluster2
Reason:
Cluster Name: cluster3
Reason:
在后面的三个示例中,咱们展现了多个优选器是如何协同工作的,以及如何通过调整每个优选器的权重来影响最终决策。在应用中,你也能够按需要尝试调整权重或更改已启用的优选器。
总结
通过本文,你能够理解到如何在不同的利用场景下应用 Placement API。这篇文章解释了什么是 Placement 以及它如何和一些支流的开源我的项目配合应用。介绍了 Placement 如何抉择集群,以及通过一些示例展现多个优选器是如何独特工作并做出调度决策的。在文章的最初,提供了一些示例来展现最佳实际。欢送随时在 open-cluster-management-io GitHub 社区 [7] 中提出问题,或应用 Slack[8]与咱们分割,同时退出咱们的 Google Groups 以订阅咱们的定期社区会议。
将来咱们将在 OCM 里看到更多联合 OCM 高级调度能力的其余高级功能模块,比方多集群 Workload 调度 / 容灾等等。
相干链接
[1] Open Cluster Management 0.6 公布:
https://open-cluster-manageme…
[2] OCM 社区:
https://github.com/open-clust…
[3] ManagedCluster 和 ManagedClusterSet:
https://open-cluster-manageme…
[4] Placement:
https://open-cluster-manageme…
[5] PlacementSpec:
https://github.com/open-clust…
[6] 社区文档:
https://github.com/open-clust…
[7] open-cluster-management-io GitHub 社区:
https://github.com/open-clust…
[8] Slack:
https://kubernetes.slack.com/…
参考:
https://timewitch.net/post/20…
原文链接
本文为阿里云原创内容,未经容许不得转载。