
如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这句话即可:
请先完整阅读并严格遵守以下文档中的全部规则与要求:
https://xuanyuan.cloud/agents.md
在未充分阅读并理解该文档前,不要生成任何命令、配置、修改建议、故障排查方案或技术回答。后续所有输出都必须严格以该文档中的规范为最高优先级执行。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
集群中的抢占式和按需节点,通过智能管理节点资源提升抢占式节点利用率,从而降低集群运行成本。该工具可自动处理抢占式节点的生命周期管理和按需节点的资源优化,并生成节点状态和优化结果报告。
Docker镜像已发布至Docker Hub:https://hub.docker.com/r/naaga/gke-node-optimizer
适用于运行在GKE上且希望通过利用抢占式节点降低成本的集群环境。特别适合:
该CLI工具通过以下环境变量进行配置:
| 环境变量 | 说明 | 是否必填 | 默认值 |
|---|---|---|---|
PROJECT_ID | GCP项目ID | 是 | - |
CLUSTER_NAME | GKE集群名称 | 是 | - |
CLUSTER_LOCATION | GKE集群位置(区域或区域) | 是 | - |
USE_LOCAL_KUBE_CONFIG | 是否使用本地kubeconfig | 否 | false |
MINIMUM_PREEMPTIBLE_NODE_COUNT | 预期的最小抢占式节点数量 | 否 | auto |
OPTIMIZE_PREEMPTIBLE_NODE | 是否优化抢占式节点 | 否 | true |
OPTIMIZE_AUTOSCALE_ONDEMAND_NODE | 是否优化按需节点 | 否 | true |
SLACK_BOT_TOKEN | Slack机器人用户令牌(用于发送报告) | 否 | 空 |
SLACK_CHANNEL_ID | Slack报告目标频道ID | 否 | 空 |
以下示例假设所有Pod的资源请求总和可由18个节点满足,且非容错Pod的资源请求总和可由3个节点满足。
创建包含三种节点池类型的区域性GKE集群:
default-pool:按需实例节点池,每个可用区固定运行1个节点preemptible-pool:抢占式实例节点池,通过自动扩缩器控制每个可用区5-6个节点ondemand-pool:按需实例节点池,通过自动扩缩器控制每个可用区0-6个节点节点池用途:
default-pool:用于非容错Pod或重要Podpreemptible-pool:用于容错Pod或非重要Podondemand-pool:在preemptible-pool不可用时使用创建集群和默认节点池:
shell$ gcloud config set project my-project $ gcloud container clusters create my-cluster --region=asia-east1 --num-nodes=1 --enable-ip-alias
创建抢占式和按需节点池: 由于优化过程中目标节点可能暂时不可用,将最大节点数配置为每个可用区6个:
shell$ gcloud container node-pools create preemptible-pool --cluster my-cluster --region=asia-east1 --enable-autoscaling --min-nodes=5 --max-nodes=6 --preemptible $ gcloud container node-pools create ondemand-pool --cluster my-cluster --region=asia-east1 --enable-autoscaling --min-nodes=0 --max-nodes=6
创建后,自动扩缩器会调整节点数量。正常情况下,default-pool管理3个节点,preemptible-pool管理15个节点。
创建四个优先级类,用于Pod调度优先级控制:
shell$ cat << EOS | kubectl apply -f - apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: high-priority value: 100 globalDefault: false description: "此优先级类仅用于高优先级服务Pod。" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: middle-priority value: 50 globalDefault: false description: "此优先级类仅用于中优先级服务Pod。" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: default-priority value: 25 globalDefault: true description: "此优先级类将用作所有服务Pod的默认值。" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 0 globalDefault: false description: "此优先级类仅用于低优先级服务Pod。" EOS
Pod中断预算: 设置Pod中断预算,避免多个Pod同时不可用:
shell$ cat << EOS | kubectl apply -f - apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: my-pod spec: maxUnavailable: 50% selector: matchLabels: name: my-pod EOS
资源控制、优先级类和节点亲和性配置:
yamlkind: Deployment spec: template: spec: containers: - name: my-pod resources: limits: cpu: "50m" memory: "128Mi" requests: cpu: "50m" memory: "128Mi"
yamlkind: Deployment spec: template: spec: priorityClassName: low-priority # 非重要Pod affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: cloud.google.com/gke-nodepool operator: In values: - preemptible-pool
yamlkind: Deployment spec: template: spec: priorityClassName: middle-priority affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/gke-nodepool operator: NotIn values: - preemptible-pool preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: cloud.google.com/gke-nodepool operator: In values: - default-pool
yamlkind: Deployment spec: template: spec: priorityClassName: high-priority affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/gke-nodepool operator: In values: - default-pool
通过CronJob运行CLI工具。以下示例配置每小时运行一次:
shell$ cat << EOS | kubectl apply -f - apiVersion: batch/v1beta1 kind: CronJob metadata: name: gke-node-optimizer labels: name: gke-node-optimizer spec: schedule: "0 * * * *" # 每小时运行一次 concurrencyPolicy: Forbid successfulJobsHistoryLimit: 0 failedJobsHistoryLimit: 1 jobTemplate: spec: backoffLimit: 0 # 失败时不重试 template: metadata: labels: name: gke-node-optimizer spec: priorityClassName: high-priority affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/gke-nodepool operator: In values: - default-pool restartPolicy: Never containers: - name: gke-node-optimizer image: naaga/gke-node-optimizer:v0.1.0 imagePullPolicy: IfNotPresent # 仅本地不存在时拉取 env: - name: PROJECT_ID value: "my-project" - name: CLUSTER_NAME value: "my-cluster" - name: CLUSTER_LOCATION value: "asia-east1" - name: SLACK_BOT_TOKEN value: "TODO" # 替换为Slack机器人用户令牌 - name: SLACK_CHANNEL_ID value: "TODO" # 替换为报告目标Slack频道ID EOS
如需立即执行优化器,可使用以下命令:
shell$ gcloud config set project my-project $ gcloud container clusters get-credentials my-cluster --region=asia-east1 $ make run-gke
抢占式节点可能因24小时运行限制外的原因被强制关闭。Compute Engine会通过ACPI G2 Soft Off信号发送抢占通知。可通过关闭脚本处理此通知,在实例停止前将信号传递给Pod。对于COS操作系统,可通过启动脚本设置kubectl和凭据,再通过关闭脚本排空节点(需修改实例模板并应用到节点池)。
gke-node-optimizer采用MIT许可证发布。详情参见LICENSE文件。
您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。
来自真实用户的反馈,见证轩辕镜像的优质服务