使用 CLI 管理节点隔离策略

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

如果所使用的版本中的 Web 控制台不再提供管理员 > 安全设置 > 节点隔离策略,您可以继续使用 ac 或 kubectl 管理节点隔离策略。

节点隔离策略的工作原理

节点隔离策略以名为 NodeGroup 的 Kubernetes 自定义资源形式存储。

项目值
API 组security.alauda.io
API 版本v1beta1
KindNodeGroup
资源nodegroups.security.alauda.io
作用域集群

关键字段如下:

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

共享模式如下:

  • Exclusive:只有绑定到该策略的项目才能在策略节点上调度新 Pod。其他项目无法在这些节点上调度新 Pod。
  • Share:绑定到该策略的项目仅限使用策略节点,但其他项目仍可使用这些节点。

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

类型名称描述
标签acp.cpaas.io/node-group-name节点隔离策略名称。
标签acp.cpaas.io/node-group-share-mode节点隔离模式,通常为 Exclusive 或 Share。
污点nodeGroup=<policy-name>:NoSchedule在 Exclusive 模式下添加到策略节点,用于阻止不容忍该污点的 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,然后选择目标 context。将 kubectl config get-contexts 中 NAME 列的值用作 <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 context 配置正确,可以将 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.phase 为 Active 时,控制器已调谐该策略。

检查可用的项目和节点

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

如果环境中存在 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 会受到约束。

替换绑定的项目

以下命令会将整个项目列表替换为 pro 和 dev:

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

替换绑定的节点

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

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

重要:

spec.projects 和 spec.nodes 是数组。合并补丁会替换整个数组。请在补丁中包含完整的最终列表,以避免意外移除项目或节点。

删除节点隔离策略

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

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 对象,请查看策略项目配额:

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

查看属于策略项目的命名空间:

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 的调度

在属于绑定项目的命名空间中创建测试 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

查看注入的节点选择器和容忍度:

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 未调度到策略节点命名空间未添加标签、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. 相关资源存在时,检查 Node、Namespace 和 ProjectQuota 标签。
  8. 在测试命名空间中创建新的测试 Pod,以验证调度。
  9. 仅在验证完成后重新创建业务工作负载或迁移现有 Pod。