Kubernetes节点选择器和节点亲和性
- 2025-06-03 18:37:00
- 丁国栋
- 原创 10
问题:在离线环境的Kubernetes集群中,原先运行正常的Pod在删除后发现无法启动,通过 kubectl descirbe pod
发现是因为无法拉取pasue镜像,需要解决。
分析:在 Kubernetes 中,当 kubectl describe pod 显示 FailedCreatePodSandBox 并提示无法拉取 pause 镜像时,导致 Pod 沙箱(Sandbox)环境创建失败,而 pause 镜像是 Kubernetes 容器运行时(如 containerd 或 CRI-O)创建 Pod 沙箱的基础镜像。
paused 镜像的作用:
- 每个 Pod 在创建时,容器运行时(如 containerd)会先启动一个隐藏的、不可见的 "pause" 容器(使用 pause 镜像)。
- 该容器的作用是为 Pod 提供共享的 Linux 命名空间(如网络、PID 等),并作为 Pod 内其他容器的父容器。
- 它是 Kubernetes Pod 模型的底层实现基础。
通过在每一个节点中执行 ctr images ls|grep pause
命令,发现只有集群的第一个节点有这个镜像,因此为了先拉起服务,需要将这个deployment部署绑定到第一个节点上。
注:如果是使用docker而不是containerd,则使用 docker image list|grep pause
命令。
方法1:使用节点选择器nodeSelector。
通过命令 kubectl get node -o json|jq '.items.[].metadata.labels'
可以获取所有节点的标签,而通过 kubectl get node pangu-server51 -o json|jq '.metadata.labels'
命令可以获取一个节点的标签。
我们可以从中选择适当的标签比如 kubernetes.io/hostname 为特定值。
spec: template: spec: dnsPolicy: ClusterFirst nodeSelector: kubernetes.io/hostname: nodename1 restartPolicy: Always
另外 imagePullPolicy 需要改为 IfNotPresent。
方法2:使用亲和性affinity。
在 Kubernetes 中,可以通过编辑 Deployment 的 spec.template.spec.affinity.nodeAffinity 字段来设置 节点亲和性(Node Affinity),将 Pod 绑定到特定的节点。
spec: template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname # 通过节点主机名选择 operator: In values: - <target-node-name> # 替换为具体节点名称