Spark Pod全部调度至单个Minikube节点问题求助
参考一篇部署Spark到Kubernetes的教程操作,将Minikube节点副本数设置为3:
minikube start --nodes 3 --memory 8192 --cpus 4 # 为Spark分配足够资源 $ kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready control-plane,master 68m v1.22.3 minikube-m02 Ready <none> 68m v1.22.3 minikube-m03 Ready <none> 67m v1.22.3
部署相关资源后,所有Pod均被调度至单个节点,尽管其他节点资源充足:
$ kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES spark-master-9d67dd4b7-tps82 1/1 Running 0 48m 10.244.2.2 minikube-m03 <none> <none> spark-worker-766ccb5887-64bzk 1/1 Running 0 13s 10.244.2.17 minikube-m03 <none> <none> spark-worker-766ccb5887-6gvfv 1/1 Running 0 13s 10.244.2.18 minikube-m03 <none> <none>
Spark Worker的部署配置:
kind: Deployment apiVersion: apps/v1 metadata: name: spark-worker spec: replicas: 15 selector: matchLabels: component: spark-worker template: metadata: labels: component: spark-worker spec: containers: - name: spark-worker image: mjhea0/spark-hadoop:3.2.0 command: ["/spark-worker"] ports: - containerPort: 8081 resources: requests: cpu: 100m
Spark Master的部署配置:
kind: Deployment apiVersion: apps/v1 metadata: name: spark-master spec: replicas: 1 selector: matchLabels: component: spark-master template: metadata: labels: component: spark-master spec: containers: - name: spark-master image: mjhea0/spark-hadoop:3.2.0 command: ["/spark-master"] ports: - containerPort: 7077 - containerPort: 8080 resources: requests: cpu: 100m
为什么所有Pod都集中在单个节点?
核心原因:K8s调度器默认的装箱策略
Kubernetes默认调度器采用**"装箱"(Bin Packing)**策略——优先将Pod调度到资源尚未被填满的节点,直到该节点无法容纳更多Pod,才会选择其他节点。这种策略的目的是提高节点资源利用率,减少节点间网络开销。你的Spark Worker每个仅请求100m CPU,单节点4核(4000m)的资源完全能容纳多个Worker Pod,因此调度器会先把Pod集中部署到同一个节点。
另外,集群中的minikube节点是控制平面节点,默认带有node-role.kubernetes.io/master:NoSchedule污点,普通业务Pod不会被调度到这里,实际可用的工作节点只有minikube-m02和minikube-m03。
验证方式
可以通过以下命令查看目标节点的剩余资源,确认是否真的有足够空间:
kubectl describe node minikube-m02
在输出的Allocated resources部分,查看Requests的CPU、内存占用情况,就能明确节点剩余资源状态。
解决方法:配置Pod反亲和性
如果希望Pod分散到不同节点,需要给Spark Worker的Deployment添加Pod反亲和性规则,引导调度器将Worker Pod尽量分散部署。修改后的配置示例:
kind: Deployment apiVersion: apps/v1 metadata: name: spark-worker spec: replicas: 15 selector: matchLabels: component: spark-worker template: metadata: labels: component: spark-worker spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: component operator: In values: - spark-worker topologyKey: kubernetes.io/hostname containers: - name: spark-worker image: mjhea0/spark-hadoop:3.2.0 command: ["/spark-worker"] ports: - containerPort: 8081 resources: requests: cpu: 100m
这里使用的是软反亲和性(preferredDuringSchedulingIgnoredDuringExecution),调度器会优先满足分散要求,但若没有其他可用节点,仍会将Pod部署到同一节点。如果需要强制分散,可以改用requiredDuringSchedulingIgnoredDuringExecution(硬规则),但需确保节点数量足够容纳所有Pod,否则会有Pod处于Pending状态。
内容的提问来源于stack exchange,提问作者gaut

