如何排查与 Amazon EKS 中节点可用性相关的容器组 (pod) 调度问题?
我在尝试调度 Amazon Elastic Kubernetes Service (Amazon EKS) Worker 容器组 (pod) 时遇到了节点可用性问题或错误。我的容器组 (pod) 卡滞在“待处理”状态。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
内存不足或 CPU 错误
当 Worker 节点上的可用 CPU 或内存不足以让容器组 (pod) 达到运行状态时,您会收到以下错误消息:
- "Warning FailedScheduling 16m default-scheduler 0/2 nodes are available: 1 Too many pods, 2 Insufficient cpu, 2 Insufficient memory. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod"
- "Warning FailedScheduling 11m default-scheduler 0/2 nodes are available: 1 Insufficient cpu, 1 Insufficient memory, 1 node(s) were unschedulable. preemption: 0/2 nodes are available: 1 No preemption victims found for incoming pod, 1 Preemption is not helpful for scheduling"
要解决内存不足或 CPU 不足的问题,请完成以下步骤:
-
启动会话管理器(AWS Systems Manager 的一项功能)SSH 会话连接到 Worker 节点。
-
运行以下 kubectl top node 命令,获取每个节点的当前 CPU 和内存使用百分比:
kubectl top node**注意:**有关上述命令的更多信息,请参阅 Kubernetes 网站上的 kubectl top node。
-
运行以下 kubectl describe 命令,获取有关节点上可用资源总量的信息:
kubectl describe node your_node_name**注意:**将 your_node_name 替换为您的节点名称。有关上述命令的更多信息,请参阅 Kubernetes 网站上的 kubectl describe。
以下输出示例显示了节点上可以分配给容器组 (pod) 的资源:Allocatable: cpu: 1930m ephemeral-storage: 18242267924 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 3388304Ki pods: 17 -
确定您的 Worker 节点使用的 Amazon Elastic Compute Cloud (Amazon EC2) 实例类。然后,查看实例上可用的默认 CPU 和内存。
-
查看您在部署中定义的资源限制和请求。有关更多信息,请参阅 Kubernetes 网站上的 Deployments(部署)。如果您配置了限制,请确保其满足您的工作负载要求。以下输出示例显示了资源限制和请求:
Limits: memory: 170Mi Requests: cpu: 100m memory: 70Mi**注意:**正确设置 Limits(限制)和 Requests(请求)的值可以帮助您确定是否需要纵向扩展 Worker 节点容量。有关详细信息,请参阅 Kubernetes 网站上的 Resource management for Pods and containers(容器组 (pod) 和容器的资源管理)。
网络接口配额问题
当您达到节点上的弹性网络接口配额上限时,您会收到以下错误消息:
"Warning FailedScheduling 117s default-scheduler 0/2 nodes are available: 1 Too many pods. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod"
**注意:**Kubernetes 集群中的每个容器组 (pod) 都有自己的 IP 地址。实例类型支持的 IP 地址数量有助于确定 Worker 节点上可运行的最大容器组 (pod) 数量。如果达到 Worker 节点上可运行的最大容器组 (pod) 数量,那么您的容器组 (pod) 可能会卡滞在 Pending(待处理)状态。
要检查每个节点上可运行的最大容器组 (pod) 数量,请运行以下 describe-instance-types 命令:
aws ec2 describe-instance-types --filters "Name=instance-type,Values=c5.*" --query "InstanceTypes[].{ Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" --output table
该命令的输出显示了有关每种实例类型的最大网络接口数以及每个接口的 IPv4 地址的信息。上述命令的输出显示容器组 (pod) 数量比最大容器组 (pod) 数量少一个,因为输出不包括第一个网络接口 (eth0)。
有关更多信息,请参阅 Amazon EKS 建议的每种 Amazon EC2 实例类型的最大容器组 (pod) 数量。另请参阅每个网络接口的最大 IP 地址数。
有关实例可支持的最大容器组 (pod) 数量的信息,请参阅 GitHub 网站上的 amazon-vpc-cni-k8s。
如果当前 Worker 节点实例上的可用 IP 地址不足,请执行以下操作:
- 将实例类纵向扩展到支持更多容器组 (pod) 的实例类。最佳做法是在纵向扩展之前检查网络接口配额。
- 使用 Karpenter 和 Cluster Autoscaler 来横向扩展节点数量。
污点或容忍度错误
当出现污点或容忍度问题时,您会收到以下错误消息:
"Warning FailedScheduling 12s default-scheduler 0/2 nodes are available: 2 node(s) had untolerated taint {NodeType: MemoryOptimized}. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling"
您要调度的容器组 (pod) 需要一个具有特定污点 (NodeType: MemoryOptimized) 的节点。但是,由于您的集群中没有可用的此类节点,因此调度失败。
要解决污点或容忍度问题,请完成以下步骤:
-
运行以下 kubectl describe 命令,获取您在节点上配置的污点:
kubectl describe node your_node_name**注意:**将 your_node_name 替换为您的节点名称。只有当容器组 (pod) 具有匹配的容忍度时,您才能在节点上调度容器组 (pod)。
-
运行以下 kubectl describe 命令,获取容器组 (pod) 上的容忍度:
kubectl describe pod your_pod_name -n your_namespace**注意:**将 your_pod_name 替换为您的容器组 (pod) 名称,将 your_namespace 替换为您的命名空间。
关联性错误
当您遇到节点关联性问题时,您会收到以下错误消息:
"Warning FailedScheduling 13s default-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling"
要解决关联性问题,请完成以下步骤:
-
将容器组 (pod) 的节点关联性配置更新为使用 preferredDuringSchedulingIgnoredDuringExecution,而不是 requiredDuringSchedulingIgnoredDuringExecution。
**注意:**要调度容器组 (pod),必须使用 requiredDuringSchedulingIgnoredDuringExecution。Kubernetes 调度器仅在符合关联性规则的节点上调度容器组 (pod)。
-
向集群中添加具有匹配关联性的节点,以便 Kubernetes 调度器能够找到可以调度容器组 (pod) 的节点。
-
从部署中移除节点选择器条款,或将节点组更新为满足部署中条件的值。根据您的要求以及 Kubernetes 集群上节点的可用性,选择适当的选项。
以下输出示例显示了部署中的节点选择器配置:
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: instance-az operator: In values: - az1 - az2 -
运行以下 kubectl describe 命令,获取节点的详细信息:
kubectl describe node your_node_name**注意:**将 your_node_name 替换为您的节点名称。
以下示例显示了节点详细信息:
Name: ip-10-1-1-172.ap-south-1.compute.internal Roles: <none> Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=t3.medium beta.kubernetes.io/os=linux instance-az=az1
**注意:**您在部署中定义的键值必须存在于您的节点上,这样 Kubernetes 才能将容器组 (pod) 放置在您的节点上。
容器组 (pod) 安全组错误
当您的容器组 (pod) 安全组出现问题时,您会收到以下错误消息:
"Warning FailedScheduling 3s default-scheduler 0/3 nodes are available: 1 Insufficient vpc.amazonaws.com/pod-eni, 2 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. preemption: 0/3 nodes are available: 1 No preemption victims found for incoming Pod, 2 Preemption is not helpful for scheduling"
**注意:**当您在 Amazon EKS 中为容器组 (pod) 使用安全组时,VPC 资源控制器会为每个容器组 (pod) 创建一个分支网络接口。VPC 资源控制器还会在 Worker 节点中创建中继网络接口来管理分支网络接口。
**重要事项:**要使用容器组 (pod) 安全组,必须在 Nitro 实例类型(例如 C5、M5、R5 和 T3 系列)上启动 Worker 节点。Nitro 实例类型支持必要的网络接口功能,以适应容器组 (pod) 的分支网络接口。
要解决容器组 (pod) 安全组问题,请完成以下步骤:
-
运行以下 kubectl describe 命令,确认您的 Worker 节点实例支持中继接口:
kubectl describe node your_node_name**注意:**将 your_node_name 替换为您的节点名称。
-
在上述命令输出的节点描述中,查看来自 VPC 资源控制器的事件。
以下输出显示了不兼容实例的示例:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal RegisteredNode 22m node-controller Node ip-192-168-59-29.us-east-2.compute.internal event: Registered Node ip-192-168-59-29.us-east-2.compute.internal in Controller Normal ControllerVersionNotice 21m vpc-resource-controller The node is managed by VPC resource controller version v1.4.9 Normal NodeReady 21m kubelet Node ip-192-168-59-29.us-east-2.compute.internal status is now: NodeReady Warning Unsupported 13m (x16 over 21m) vpc-resource-controller The instance type t3.small is not supported for trunk interface (Security Group for Pods)
Fargate 容器组 (pod) 支持错误
当 AWS Fargate 不支持您的容器组 (pod) 时,您会收到以下错误消息:
"Warning FailedScheduling <unknown> fargate-scheduler Pod not supported on Fargate: volumes not supported: mysql-db not supported because: PVC mysql-db not bound"
在 Fargate 上运行并使用 Amazon Elastic File System (Amazon EFS) 卷的容器组 (pod) 与常规容器组 (pod) 的要求相同。当集群中缺少必要的 PersistentVolume 和 PersistentVolumeClaim 资源时,Fargate 不会调度容器组 (pod)。
要解决 Fargate 问题,请完成以下步骤:
- 在集群中创建并正确配置所需的 PersistentVolume 和 PersistentVolumeClaim 资源。有关更多信息,请参阅 Kubernetes 网站上的 Configure a Pod to use a PersistentVolume for storage(配置容器组 (pod) 以使用 PersistentVolume 进行存储)。
- 当卷绑定到容器组 (pod) 时,检查您的 PersistentVolume 和 PersistentVolumeClaim 资源是否存在问题。例如,您可能遇到 EFS 文件系统、权限或其他配置问题。
Fargate 对卷类型的支持错误
当您的容器组 (pod) 包含不支持的卷类型的定义时,您会收到以下错误消息:
"Warning FailedScheduling <unknown> fargate-scheduler Pod not supported on Fargate: volumes not supported: admin-panel is of an unsupported volume Type"
**重要事项:**您无法在 Fargate 容器组 (pod) 上挂载 Amazon Elastic Block Store (Amazon EBS) 卷。
要解决不支持的卷类型问题,请执行以下操作:
- 确保容器组 (pod) 定义指定的是 EFS 卷,而不是 EBS 卷或其他不支持的卷类型。
- 验证您是否正确配置了 PersistentVolume 和 PersistentVolumeClaim 资源,及其是否引用了 EFS 文件系统。
- 检查是否存在可能导致卷无法附加到容器组 (pod) 的 EFS 文件系统、权限或配置问题。
Fargate 上的安全上下文错误
当安全上下文无效时,您会收到以下错误消息:
"Warning FailedScheduling 109s fargate-scheduler Pod not supported on Fargate: invalid SecurityContext fields: Privileged"
要解决安全上下文问题,请确保您的 Fargate 容器组 (pod) 符合以下要求:
- 容器组 (pod) 定义无法指定特权容器安全上下文。Fargate 不接受特权容器。
- 容器组 (pod) 定义无法将主机的根文件系统 (/) 挂载到容器中。Fargate 会将容器与主机的根文件系统隔离开来。
Fargate 上的调度器不正确错误
如果您将 Amazon EKS 与 Fargate 配置文件或自定义调度器一起使用,那么您可能没有正确的 Kubernetes 调度器来管理您的容器组 (pod)。
要解决调度器问题,请完成以下步骤:
-
查看您的容器组 (pod) 事件。
以下示例显示,由于存在与 Fargate 计算类型关联的污点,默认调度器无法为容器组 (pod) 查找节点:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 109s default-scheduler 0/2 nodes are available: 2 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling..**注意:**Fargate 容器组 (pod) 必须由 fargate-scheduler 进行调度。
-
运行以下 kubectl get mutatingwebhookconfigurations 命令,验证您是否在集群上安装了 Fargate Webhook:
kubectl get mutatingwebhookconfigurations 0500-amazon-eks-fargate-mutation.amazonaws.com
如果输出显示了 Webhook 配置,而 fargate-scheduler 仍无法调度容器组 (pod),请检查是否存在其他可能冲突的自定义变异 Webhook 配置。例如,由于 Fargate 按字母顺序处理 Webhook,冲突的 Webhook 可能会导致问题。
端口冲突错误
当 Kubernetes 调度器正在调度容器组 (pod) 的主机上出现端口冲突时,您会收到以下错误消息:
"Warning FailedScheduling 10s default-scheduler 0/2 nodes are available: 1 node(s) didn't have free ports for requested pod ports.1 node(s) didn't match the requested hostname"
出现此错误是因为您使用相同的 hostPort 值配置了多个容器组 (pod),或者主机上的另一个进程已占用该端口。
当您使用 hostNetwork: true 配置容器组 (pod) 时,容器组 (pod) 内运行的容器可以直接访问主机的网络接口。因此,容器端口会直接暴露在相应主机端口的外部网络中。
要解决端口冲突问题,请完成以下步骤:
-
运行以下 kubectl describe 命令来检查端口配置:
kubectl describe deploy nginx-deployment以下输出示例显示了端口信息的位置:
spec: hostNetwork: true containers: - name: nginx image: nginx:latest ports: - containerPort: 80 hostPort: 80 -
修改您的主机网络或主机端口。例如,您可以将 hostNetwork 设置为默认值 false,以便为容器组 (pod) 分配虚拟网络接口。您也可以更新容器组 (pod) 配置以使用主机上尚未使用的其他主机端口。要允许内核自动为您的容器组 (pod) 分配随机主机端口,请将 hostPort 设置为 0,如以下示例所示:
Containers: nginx: Image: nginx:latest Port: 80/TCP Host Port: 0/TCP -
将容器组 (pod) 调度到其他主机上。如果端口冲突特定于您要调度容器组 (pod) 的主机,则将容器组 (pod) 调度到其他节点上。该节点必须位于您的 Kubernetes 集群中。您也可以使用关联性逻辑。有关更多信息,请参阅通过使用节点关联性、污点和容忍度将 Kubernetes 容器组 (pod) 放置在 Amazon EKS 上。
节点关联性冲突错误
当您的节点关联性规则发生冲突时,您会收到以下错误消息:
"Warning FailedScheduling 57s (x3 over 3m3s) default-scheduler 0/15 nodes are available: 1 node(s) were unschedulable, 14 node(s) had volume node affinity conflict"
当由于节点关联性规则发生冲突,导致可用节点无法满足容器组 (pod) 的卷要求时,就会出现此错误。
要解决节点关联性的冲突问题,请完成以下步骤:
-
识别容器组 (pod) 和卷定义中产生冲突的节点关联性规则。例如,您的容器组 (pod) 可能有一条节点关联性规则要求使用 node-type=high-storage 标签,但卷要求使用 node-type=ssd-storage 标签。
-
要解决规则冲突,请更新容器组 (pod) 或卷的节点关联性规则。例如,更新容器组 (pod) 的节点关联性规则以匹配卷的要求,如以下示例所示:
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-type operator: In values: - ssd-storage -
确认您的节点标签与关联性规则相匹配。然后,验证集群中的可用节点是否具有正确的标签以满足新要求。要列出节点及其标签,请运行以下 kubectl get nodes 命令:
kubectl get nodes --show-labels**注意:**确保您有具备所需 node-type=ssd-storage 标签的可用节点。
-
修改您的节点组,或添加新的节点组。如果您使用节点组但节点没有所需的标签,请更新您的现有节点组。或者,使用适当的标签和实例类型创建新的节点组。
没有可用的卷区域错误
当您尝试在集群中部署容器组 (pod) 但没有可用的卷区域时,您会收到以下错误消息:
- "Warning FailedScheduling 60s (x5 over 60s) default-scheduler Pod has unbound PersistentVolumeClaims (repeated 2 times)"
- "Warning FailedScheduling 2s (x16 over 59s) default-scheduler 0/2 nodes are available: 2 node(s) had no available volume zone"
由于可用的卷区域与容器组 (pod) 的卷区域约束不匹配,容器组 (pod) 的卷要求未得到满足。
要解决卷区域问题,请完成以下步骤:
-
查看您的容器组 (pod) 和卷定义,确定导致卷区域问题的具体卷区域约束。例如,检查您是否将容器组 (pod) 或卷设置为使用未运行 Worker 节点的可用区。
-
运行以下 kubectl get pv 命令,检查集群中有哪些卷区域可用:
kubectl get pv --all-namespaces -o jsonpath='{range .items[*]}{.spec.awsElasticBlockStore.availabilityZone}{"\n"}{end}' | sort | uniq**注意:**确保输出列表包含您的容器组 (pod) 或卷所需的卷区域。
-
更新卷区域约束。如果所需的卷区域不可用,请更新容器组 (pod) 或卷配置。该配置必须将卷的创建仅限于运行 Worker 节点的可用区。
-
确认节点组是否跨越多个可用区。如果您的节点组未跨越多个区域,请创建新节点组,使其包含所需的卷区域。
- 语言
- 中文 (简体)
