使用 CLI 管理节点隔离策略

节点隔离策略提供项目级节点隔离。平台管理员可以将一个或多个项目绑定到选定的集群节点,并选择这些节点是仅供已绑定项目独占使用,还是与其他项目共享。

在 Web 控制台不再提供 管理员 > 安全设置 > 节点隔离策略 的版本中,你仍然可以使用 ackubectl 管理节点隔离策略。

节点隔离策略的工作原理

节点隔离策略作为名为 NodeGroup 的 Kubernetes 自定义资源进行存储。

项目
API groupsecurity.alauda.io
API versionv1beta1
KindNodeGroup
Resourcenodegroups.security.alauda.io
Scope集群

关键字段如下:

字段描述
metadata.name策略名称。必须以小写字母或数字开头和结尾,可以包含小写字母、数字和 -,最长 63 个字符。
metadata.annotations["alauda.io/display-name"]可选显示名称。
spec.shareMode节点共享模式。有效值为 ExclusiveShare
spec.projects[].name使用该策略的项目名称。
spec.nodes[].name分配给该策略的节点名称。
status.phase策略调和状态,例如 Active

共享模式如下:

  • Exclusive:只有与该策略绑定的项目才能在该策略节点上调度新的 Pod。其他项目不能在这些节点上调度新的 Pod。
  • Share:与该策略绑定的项目会被限制在该策略节点上,但其他项目仍然可以使用这些节点。

创建或更新策略后,平台会为相关的 NodeNamespace 资源添加标签,在 ProjectQuota 对象存在时也会为其添加标签,并在创建或更新 Pod 时注入调度约束。常见的标签和污点包括:

类型名称描述
Labelacp.cpaas.io/node-group-name节点隔离策略名称。
Labelacp.cpaas.io/node-group-share-mode节点隔离模式,通常为 ExclusiveShare
TaintnodeGroup=<policy-name>:NoScheduleExclusive 模式下添加到策略节点,用于阻止不容忍该污点的 Pod。

开始之前

在运行本指南中的命令之前,请确认以下事项:

  • 已安装 ac CLI。如果使用 kubectl,请先为目标集群准备 kubeconfig。
  • 你的账号可以管理 nodegroups.security.alauda.io
  • 你知道目标业务集群名称,例如 business-1
  • 你知道要绑定的项目名称和节点名称。
  • 你已经评估了对现有工作负载的影响。

重要限制:

  • NodeGroup 是集群作用域资源。管理 NodeGroup 资源时不要指定 -n
  • 在一个业务集群中,每个项目只能属于一个节点隔离策略。
  • 在一个业务集群中,每个节点只能属于一个节点隔离策略。
  • 创建策略不会迁移现有 Pod。与策略不匹配的现有 Pod 只有在重新创建后才会受到约束。
  • Exclusive 模式下,策略节点上的现有 Pod 不会被自动驱逐。如有需要,请手动迁移。
  • Web 控制台创建页面会过滤掉控制平面节点,并禁用已被其他策略使用的项目和节点。使用 CLI 时,请在创建或更新策略前自行检查冲突。

连接到 ACP

使用 ac 管理节点隔离策略。ac CLI 管理 ACP 多集群会话,并且可以切换到目标业务集群。

ac login <acp-url> --name <session-name>
ac config get-clusters
ac config use-cluster <cluster-name>
ac config current-context

示例:

ac login https://acp.example.com --name prod
ac config use-cluster business-1
ac config current-context

确认 NodeGroup CRD 存在:

ac api-resources --api-group=security.alauda.io
ac get crd nodegroups.security.alauda.io

如果你更喜欢使用 kubectl,请先从 ac 导出 kubeconfig,然后选择目标上下文。使用 kubectl config get-contextsNAME 列的值作为 <target-context>

ac config view --raw > kubeconfig
export KUBECONFIG=./kubeconfig
kubectl config get-contexts
kubectl config use-context <target-context>
kubectl get nodegroups.security.alauda.io

以下示例使用 ac。如果你的 kubectl 上下文配置正确,也可以将 ac 替换为 kubectl

查看节点隔离策略

查看当前集群中的所有节点隔离策略:

ac get nodegroups.security.alauda.io

使用指定字段查看策略列表:

ac get nodegroups.security.alauda.io \
  -o 'custom-columns=NAME:.metadata.name,MODE:.spec.shareMode,PROJECTS:.spec.projects[*].name,NODES:.spec.nodes[*].name,PHASE:.status.phase'

查看某个策略的详细信息:

ac get nodegroups.security.alauda.io <policy-name> -o yaml
ac describe nodegroups.security.alauda.io <policy-name>

检查策略是否已完成调和:

ac get nodegroups.security.alauda.io <policy-name> \
  -o jsonpath='{.status.phase}{"\n"}'

status.phaseActive 时,控制器已经调和了该策略。

检查可用项目和节点

在创建或更新策略之前,请检查这些项目和节点是否已被其他策略使用。

如果环境中存在 ProjectQuota 对象,请查看其节点隔离标签:

ac get projectquotas.auth.alauda.io \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

查看未绑定到任何策略的 ProjectQuota 对象:

ac get projectquotas.auth.alauda.io \
  --selector='!acp.cpaas.io/node-group-name'

查看节点及其节点隔离标签:

ac get nodes \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

查看未绑定到任何策略的计算节点:

ac get nodes \
  --selector='!node-role.kubernetes.io/master,!node-role.kubernetes.io/control-plane,!acp.cpaas.io/node-group-name'

创建节点隔离策略

创建 nodegroup-pro.yaml

apiVersion: security.alauda.io/v1beta1
kind: NodeGroup
metadata:
  name: pro-nodegroup
  annotations:
    alauda.io/display-name: "pro nodes"
spec:
  shareMode: Exclusive
  projects:
    - name: pro
  nodes:
    - name: node-1
    - name: node-2

当绑定项目必须独占使用这些节点时,将 spec.shareMode 设置为 Exclusive。当绑定项目必须运行在选定节点上,但其他项目仍然可以使用这些节点时,将其设置为 Share

应用该策略:

ac apply -f nodegroup-pro.yaml

确认策略状态:

ac get nodegroups.security.alauda.io pro-nodegroup
ac get nodegroups.security.alauda.io pro-nodegroup -o yaml

确认节点已被添加标签:

ac get nodes \
  --selector='acp.cpaas.io/node-group-name=pro-nodegroup' \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

对于 Exclusive 策略,确认某个策略节点带有 nodeGroup 污点:

ac describe node node-1

在输出中,检查 Taints 是否包含:

nodeGroup=pro-nodegroup:NoSchedule

共享节点通常不会保留 nodeGroup=<policy-name>:NoSchedule 污点。

更新节点隔离策略

在更新策略之前,请先检查其当前配置:

ac get nodegroups.security.alauda.io <policy-name> -o yaml

更新显示名称

ac annotate nodegroups.security.alauda.io <policy-name> \
  alauda.io/display-name="<display-name>" \
  --overwrite

更改共享模式

将策略切换为共享模式:

ac patch nodegroups.security.alauda.io <policy-name> \
  --type=merge \
  -p '{"spec":{"shareMode":"Share"}}'

将策略切换为独占模式:

ac patch nodegroups.security.alauda.io <policy-name> \
  --type=merge \
  -p '{"spec":{"shareMode":"Exclusive"}}'

当策略切换为 Exclusive 后,控制器会向策略节点添加 nodeGroup=<policy-name>:NoSchedule。该污点不会驱逐现有 Pod,但会约束新的 Pod。

替换已绑定项目

以下命令将整个项目列表替换为 prodev

ac patch nodegroups.security.alauda.io <policy-name> \
  --type=merge \
  -p '{"spec":{"projects":[{"name":"pro"},{"name":"dev"}]}}'

替换已绑定节点

以下命令将整个节点列表替换为 node-1node-2

ac patch nodegroups.security.alauda.io <policy-name> \
  --type=merge \
  -p '{"spec":{"nodes":[{"name":"node-1"},{"name":"node-2"}]}}'

重要:

spec.projectsspec.nodes 是数组。merge patch 会替换整个数组。为避免意外删除项目或节点,请在 patch 中包含完整的最终列表。

删除节点隔离策略

删除策略后,已绑定的项目将不再受限于策略节点,这些节点也不再为该策略保留。

ac delete nodegroups.security.alauda.io <policy-name>

确认策略已删除:

ac get nodegroups.security.alauda.io

确认相关标签已清理:

ac get nodes \
  --selector='acp.cpaas.io/node-group-name=<policy-name>'

ac get projectquotas.auth.alauda.io \
  --selector='acp.cpaas.io/node-group-name=<policy-name>'

ac get namespaces \
  --selector='acp.cpaas.io/node-group-name=<policy-name>'

如果策略长时间处于删除状态,不要直接移除其 finalizer。请先检查节点隔离控制器和 webhook。

验证调度行为

创建或更新策略后,请验证其是否生效。

验证标签

查看策略节点:

ac get nodes \
  --selector='acp.cpaas.io/node-group-name=<policy-name>' \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

查看策略项目的 ProjectQuota,如果环境中存在 ProjectQuota 对象:

ac get projectquotas.auth.alauda.io \
  --selector='acp.cpaas.io/node-group-name=<policy-name>' \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

查看属于策略项目的 Namespace:

ac get namespaces \
  --selector='acp.cpaas.io/node-group-name=<policy-name>' \
  -L acp.cpaas.io/node-group-name,acp.cpaas.io/node-group-share-mode

验证新 Pod 调度

在属于已绑定项目的 Namespace 中创建一个测试 Pod:

ac -n <namespace> run nodegroup-check \
  --image=busybox:1.36 \
  --restart=Never \
  --command -- sleep 3600

查看 Pod 被调度到的节点:

ac -n <namespace> get pod nodegroup-check -o wide

查看注入的 node selector 和 toleration:

ac -n <namespace> get pod nodegroup-check -o yaml

在输出中,检查以下字段:

spec:
  nodeSelector:
    acp.cpaas.io/node-group-name: <policy-name>
  tolerations:
    - key: nodeGroup
      operator: Equal
      value: <policy-name>
      effect: NoSchedule

验证完成后删除测试 Pod:

ac -n <namespace> delete pod nodegroup-check

注意:

现有 Pod 只有在重新创建后才会再次经过调度流程。

故障排查

问题可能原因处理方式
nodegroups.security.alauda.io 不存在目标集群未安装或未启用节点隔离组件。确认你选择了正确的集群,然后检查节点隔离功能开关及相关组件。
创建或更新被拒绝项目或节点已经属于其他策略,或者你的账号没有权限。检查 acp.cpaas.io/node-group-name 标签并确认你的权限。
策略未变为 Active控制器尚未完成调和,或者引用的项目或节点不存在。检查项目和节点名称,然后查看节点隔离控制器日志。
新 Pod 未调度到策略节点Namespace 未添加标签,Pod 未重新创建,或者 webhook 未注入调度约束。检查 Namespace 标签,删除并重新创建 Pod,然后检查 webhook 和控制器。
其他项目的现有 Pod 仍保留在独占节点上这是预期行为。NoSchedule 不会驱逐现有 Pod。如需迁移,请手动重新创建、驱逐或调整相关工作负载。
更新节点列表后节点标签未变化控制器仍在同步,或者策略状态异常。稍等片刻后重新查询。如果标签仍未更新,请检查控制器日志和 NodeGroup 事件。

推荐的操作流程

在生产环境中,建议按以下流程操作:

  1. 确认目标业务集群上下文。
  2. 查询现有 NodeGroup 列表。
  3. 检查项目和节点是否已经绑定到其他策略。
  4. 编写并保存 NodeGroup YAML。
  5. 使用 ac apply -f 创建或更新策略。
  6. 等待 status.phase 变为 Active
  7. 在相关资源存在时,检查 NodeNamespaceProjectQuota 标签。
  8. 在测试 Namespace 中创建一个新的测试 Pod 以验证调度。
  9. 仅在验证完成后再重新创建业务工作负载或迁移现有 Pod。