k8s 集群调度,标签,亲和性和反亲和性,污点和容忍,pod启动状态 排错详解

目录

pod启动创建过程

kubelet持续监听的原因

调度概念

调度约束

调度过程

优点

原理

优先级选项

示例

指定调度节点

标签基本操作

获取标签帮助

添加标签(Add Labels):

更新标签(Update Labels)

删除标签(Remove Labels)

查询标签(Query Labels)

使用标签选择器(Label Selectors)

标签匹配的运算符

亲和性

节点亲和性:

Pod 亲和性:

硬策略和软策略

硬策略示例

软策略示例

软硬策略结合示例

pod亲和和反亲和

调度策略

Pod 亲和性调度策略的详细说明

示例

创建一个标签为 app=myapp01 的 Pod

使用 Pod 亲和性调度,创建多个 Pod 资源

使用 Pod 反亲和性调度

污点(Taint) 和 容忍(Tolerations)

概念

格式和支持的效果(选项)

污点的基本操作

添加污点:

查看污点:

删除污点:

示例

容忍

举例说明

值得注意的操作

维护节点和应用程序操作

pod启动阶段的状态解读与排错技巧

Pod启动阶段(相位 phase)

pod可能的状态

故障排除步骤


 

pod启动创建过程

这里有三个 List-Watch,分别是 Controller Manager(运行在 Master),Scheduler(运行在 Master),kubelet(运行在 Node)。 他们在进程已启动就会监听(Watch)APIServer 发出来的事件。

  • 用户通过 kubectl 或其他 API 客户端提交创建 Pod 的请求给 APIServer

  • APIServer 将 Pod 对象的元数据尝试存入 etcd 中,待写入操作执行完成,APIServer返回确认信息给客户端。

  • etcd 接受创建 Pod 的信息后,在集群中保存该信息,并触发 Create 事件给APIserver。

  • Controller Manager 监听到 Create 事件后,调用 Replication Controller 来确保 Node 上的副本数量符合定义。一旦副本数量少于 RC 中定义的数量,RC 会自动创建副本。总之它是保证副本数量的 Controller(PS:扩容缩容的担当)。

  • Replication Controller 创建 Pod 的副本。

  • APIServer 更新 etcd 中的 Pod 信息,并向 Controller Manager 发送更新事件。

  • Scheduler 监听到更新事件后,根据调度算法将 Pod 绑定到合适的 Node 上。

  • Scheduler 更新 Pod 的信息,包括它所部署的 Node,然后将信息反馈给 APIServer。

  • APIServer 更新 etcd 中的 Pod 信息,并将更新成功的事件发送给 Scheduler。

  • kubelet 在 Node 上监听 APIServer 发送的 Pod 更新事件,根据更新信息调用 Docker 启动容器。

  • kubelet 将 Pod 的状态信息反馈给 APIServer,并更新至 etcd。

  • APIServer 将 Pod 的状态信息持久化存储在 etcd 中,APIServer将确认信息发送至相关的 kubelet,事件将通过它被接受,完成整个启动创建过程。

kubelet持续监听的原因

kubelet持续监听的原因在于保持对集群中 Pod 状态的实时感知和响应。即使创建过程完成,kubelet仍然需要:

  • 实时调整资源: 如果通过 kubectl 进行扩容或缩容操作,kubelet会感知这些变化,根据最新的 Pod 副本数量,调整 Node 上的资源。

  • 镜像更新: 如果 Pod 的镜像文件升级,kubelet会自动获取最新的镜像文件并加载,确保 Pod 使用的是最新的容器镜像。

通过持续监听,kubelet能够及时响应各种变化,确保集群中的 Pod 始终处于最新、正确的状态。这种实时性是 Kubernetes 系统的关键特性之一。

调度概念

Kubernetes集群调度是指Kubernetes系统中的调度器(scheduler)负责将应用程序的工作负载(如Pod)分配到可用的集群节点上。调度器通过考虑诸如节点资源利用率、硬件约束、亲和性和反亲和性规则等因素,选择最佳的节点来放置Pod,以实现高效的资源利用和负载均衡。调度器的工作包括评估节点的可用资源、满足Pod的资源需求、遵循用户定义的调度策略等。

  • Kubernetes 是通过 List-Watch 机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦。

  • 用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。

  • APIServer 经过 API 调用,权限控制,调用资源和存储资源的过程,实际上还没有真正开始部署应用。这里 需要 Controller Manager、Scheduler 和 kubelet 的协助才能完成整个部署过程。

  • 在 Kubernetes 中,所有部署的信息都会写到 etcd 中保存。实际上 etcd 在存储部署信息的时候,会发送 Create 事件给 APIServer,而 APIServer 会通过监听(Watch)etcd 发过来的事件。其他组件也会监听(Watch)APIServer 发出来的事件。

调度约束

Kubernetes中的调度约束,这些约束是指在将Pod调度到节点上时需要考虑的各种条件和限制。这些约束包括但不限于:

  • 资源约束: 每个节点有一定的资源限制,如CPU和内存。调度器会考虑Pod的资源请求和节点的可用资源,确保Pod能够得到满足并不会超出节点的资源容量。

  • 亲和性和反亲和性: 可以指定Pod之间或Pod与节点之间的亲和性和反亲和性规则,以确保它们被调度到合适的节点上。例如,可以将Pod调度到与特定标签匹配的节点上,或者避免将它们调度到某些节点上。

  • 节点亲和性: 通过节点亲和性规则,可以指定Pod应该调度到与某些节点属性匹配的节点上。例如,将Pod调度到具有特定硬件特性或数据存储的节点上。

  • Pod 亲和性: 通过Pod亲和性规则,可以确保一组Pod被调度到同一节点上,或者避免它们被调度到同一节点上。

  • 污点和容忍: 污点用于标记节点上的不可接受条件,而容忍则允许一些Pod调度到带有污点的节点上。这有助于将特定类型的工作负载调度到适合的节点上。

这些约束通过Kubernetes的调度器实现,调度器会根据这些约束选择最佳的节点来放置Pod,以满足用户需求并确保集群的高效利用。

调度过程

Kubernetes(k8s)调度涉及调度器、控制器管理器和kubelet。当使用kubectl创建作业时,kube-controller检测到它,创建一个Pod实例,并将其发送到API服务器。kube-scheduler在检测到未调度的Pod时,选择一个节点,将Pod绑定到它,并向API服务器发送绑定指令。相应节点上的kubelet在检测到绑定指令后,指示节点的容器API运行Pod。这个过程确保了Kubernetes集群中资源的有效分配和工作负载的分发。

优点

Scheduler是Kubernetes的调度器,其主要任务是将定义的Pod分配到集群的节点上。

  • 公平:确保每个节点都能获得公平的资源分配,避免资源不均衡。

  • 资源高效利用:最大化集群中所有资源的利用率,确保资源被充分利用而不浪费。

  • 效率:调度器需要具备良好的性能,能够快速而有效地对大批量的Pod完成调度工作,以满足用户的需求。

  • 灵活:允许用户根据自己的需求控制调度的逻辑,例如通过标签、调度策略等方式定制调度规则,以适应不同的应用场景和需求。

原理

调度器作为一个独立的程序运行,并监听 API Server,负责将未指定节点的 Pod 分配到合适的节点上。整个调度过程分为预算策略(predicate)和优选策略(priorities)两个阶段,分别用于先过滤不满足条件的节点和对通过的节点进行排序。最后,从中选择优先级最高的节点进行调度。如果在任何一个阶段出现错误,调度器会立即返回错误信息。

如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。 经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。

优先级选项

Kubernetes Pod 调度过程中使用的一系列优先级选项及其作用:

  • LeastRequestedPriority(最低资源请求优先级):根据节点的 CPU 和内存使用率来确定权重,使用率越低的节点权重越高。这意味着优先选择资源利用率较低的节点来部署 Pod。

  • BalancedResourceAllocation(平衡资源分配优先级):根据节点上 CPU 和内存使用率的平衡程度来确定权重。如果节点上的 CPU 和内存使用率越接近,权重越高。通常与最低资源请求优先级一起使用,以便在选择节点时考虑资源的平衡分配。

  • ImageLocalityPriority(镜像本地性优先级):倾向于选择已经存在所需镜像的节点部署 Pod。权重根据镜像的总大小来确定,镜像总大小越大,权重越高。

示例

举例来说,假设有三个 Kubernetes 节点:node01、node02 和 node03。现在有一个 Pod 需要调度到其中一个节点上。

  • LeastRequestedPriority(最低资源请求优先级):如果 node01 的 CPU 和内存使用率较低,node02 的使用率中等,而 node03 的使用率较高,那么优先选择调度到 node01,因为它的资源使用率最低。

  • BalancedResourceAllocation(平衡资源分配优先级):假设 node01 的 CPU 使用率为20%,内存使用率为60%,而 node02 的 CPU 和内存使用率均为50%,则根据平衡资源分配优先级,可能更倾向于选择 node02,因为它的资源使用情况更平衡。

  • ImageLocalityPriority(镜像本地性优先级):如果 node01 已经存在 Pod 所需的镜像,而 node02 和 node03 没有,那么优先选择调度到 node01,因为它具有镜像的本地性。

指定调度节点

pod.spec.nodeName 将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配

vim myapp.yaml
apiVersion: apps/v1  
kind: Deployment  
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      nodeName: node01
      containers:
      - name: myapp
        image: soscscs/myapp:v1
        ports:
        - containerPort: 80

kubectl apply -f myapp.yaml

kubectl get pods -o wide
  • apiVersion: apps/v1: 指定了使用的 Kubernetes API 版本。

  • kind: Deployment: 定义了这个配置文件描述的 Kubernetes 资源类型,即部署。

  • metadata: 包含有关资源的元数据,比如名称。

  • name: myapp: 指定部署的名称为 "myapp"。

  • spec: 定义了部署的规格,包括副本数量、选择器和模板。

  • replicas: 3: 指定了要创建的 Pod 的副本数量为 3。

  • selector: 定义了用于选择要管理的 Pod 的标签。

    • matchLabels: 指定了匹配标签的条件。

    • app: myapp: 指定了标签 app 的值为 myapp

  • template: 定义了要创建的 Pod 的模板。

    • metadata: 包含了 Pod 模板的元数据,包括标签。

    • labels: 指定了 Pod 模板的标签。

      • app: myapp: 指定了标签 app 的值为 myapp
    • spec: 指定了 Pod 的规格。

    • nodeName: node01: 使用 nodeName 字段将 Pod 直接调度到名为 node01 的节点上。

    • containers: 指定了要在 Pod 中运行的容器列表。

      • name: myapp: 定义了容器的名称为 myapp

      • image: soscscs/myapp:v1: 指定了要在容器中运行的镜像。

      • ports: 指定了容器要监听的端口。

      • containerPort: 80: 指定了容器监听的端口号为 80。

通过应用此配置文件,成功地创建了一个名为 myapp 的 Deployment,其中包含了三个 Pod,每个 Pod 都直接调度到了名为 node01 的节点上,并且每个 Pod 内运行一个名为 myapp 的容器,该容器使用 soscscs/myapp:v1 镜像并监听端口 80。

kubectl describe pod myapp-

查看详细事件,发现未经过 scheduler 调度分配

这些事件显示了 Pod 的创建过程,但没有显示与调度相关的事件,这是因为在 Pod 的配置中明确指定了 nodeName: node01,这意味着 Pod 将直接调度到名为 node01 的节点上,而不经过调度器的调度分配过程。

因此,在描述中看不到与调度相关的事件,而只能看到与 Pod 创建、拉取镜像、容器创建和启动等过程相关的事件。

pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,然后调度 Pod 到目标节点,该匹配规则属于强制约束

标签基本操作

获取标签帮助

kubectl label --help

添加标签(Add Labels):

添加标签是为资源附加额外的元数据,以便更容易地对其进行标识和分类。例如,为名为nginx的Pod添加标签app=web

kubectl label <资源类型> <资源名称> <标签键>=<标签值>
kubectl label pods nginx app=web
  • 这将给名为nginx的Pod添加了一个名为app,值为web的标签。

  • 添加标签是为资源附加额外的元数据,以便更容易地对其进行标识和分类。例如,为名为nginx的Pod添加标签app=web

更新标签(Update Labels)

更新标签是对已存在的标签进行更改。例如,将名为nginx的Pod的app标签的值从web更改为frontend

kubectl label <资源类型> <资源名称> <标签键>=<新标签值> --overwrite
kubectl label pods nginx app=frontend --overwrite
  • 使用--overwrite标志来确保标签的值被覆盖。

删除标签(Remove Labels)

删除标签是从资源中删除指定的标签。例如,从名为nginx的Pod中删除app标签:

kubectl label <资源类型> <资源名称> <标签键>-
kubectl label pods nginx app-
  • 删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可

  • 这将从Pod中删除名为app的标签。

查询标签(Query Labels)

查询标签是查找具有特定标签的资源。例如,查找具有app=web标签的所有Pod:

kubectl get <资源类型> -l <标签选择器>
kubectl get pods -l app=web

这将返回所有具有app=web标签的Pod列表。

使用标签选择器(Label Selectors)

spec:
  selector:
    <标签键>: <标签值>

在定义资源时使用标签选择器,以便在对资源进行操作时能够指定匹配的标签。例如,定义一个Service并选择具有特定标签的Pod:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

在这个例子中,Service选择了具有app=web标签的Pod作为其后端。

标签匹配的运算符

  • In:表示 label 的值必须在指定的列表中。

  • 例如:key: "app", operator: In, values: ["web", "db"] 表示 "app" 的值必须是 "web" 或 "db"。

  • NotIn:表示 label 的值不能在指定的列表中。

  • 例如:key: "env", operator: NotIn, values: ["dev", "test"] 表示 "env" 的值不能是 "dev" 或 "test"。

  • Gt:表示 label 的值必须大于指定的值。

  • 例如:key: "replica", operator: Gt, values: ["3"] 表示 "replica" 的值必须大于 3。

  • Lt:表示 label 的值必须小于指定的值。

  • 例如:key: "version", operator: Lt, values: ["2.0"] 表示 "version" 的值必须小于 2.0。

  • Exists:表示某个 label 必须存在。

  • 例如:key: "app", operator: Exists 表示 "app" 必须存在。

  • DoesNotExist:表示某个 label 不能存在。

  • 例如:key: "deprecated", operator: DoesNotExist 表示 "deprecated" 不能存在。

  • 这些运算关系在定义亲和性规则时用于匹配标签的条件

亲和性

官方:将 Pod 指派给节点 | Kubernetes

在 Kubernetes 中,"亲和性"(Affinity)是一种机制,用于控制 Pod 如何被调度到节点上。亲和性规则允许你指定 Pod 与特定节点或其他 Pod 之间的偏好关系。通过使用亲和性,可以确保相关的 Pod 在同一节点上运行,或者避免将它们调度到同一节点上,以提高性能、可用性或安全性。

亲和性在 Kubernetes 中有两种类型:节点亲和性和 Pod 亲和性。节点亲和性定义了 Pod 与节点之间的关系,而 Pod 亲和性定义了 Pod 与其他 Pod 之间的关系。

节点亲和性

  • 通过 nodeAffinity 字段指定,可以使用 nodeSelector 或 nodeSelectorTerms 定义节点上的标签和条件,以确保 Pod 被调度到满足这些条件的节点上。

  • pod.spec.nodeAffinity 中的 preferredDuringSchedulingIgnoredDuringExecution 是软策略,表示首选但不是强制要求。系统会尽量遵循这些偏好,但在无法满足时也可以进行调度。

  • pod.spec.nodeAffinity 中的 requiredDuringSchedulingIgnoredDuringExecution 是硬策略,表示 Pod 必须满足这些条件才能被调度。如果无法满足条件,Pod 将不会被调度。

Pod 亲和性

  • 通过 affinity 字段中的 podAffinity 和 podAntiAffinity 字段定义。podAffinity 用于描述 Pod 与其他 Pod 的关系,而 podAntiAffinity 用于定义 Pod 与其他 Pod 的排斥关系。可以使用 labelSelector 和 topologyKey 来定义匹配规则。

  • pod.spec.affinity.podAffinitypod.spec.affinity.podAntiAffinity 中的 preferredDuringSchedulingIgnoredDuringExecution 是软策略,表示首选但不是强制要求。系统会尽量遵循这些偏好,但在无法满足时也可以进行调度。

  • pod.spec.affinity.podAffinitypod.spec.affinity.podAntiAffinity 中的 requiredDuringSchedulingIgnoredDuringExecution 是硬策略,表示 Pod 必须满足这些条件才能被调度。如果无法满足条件,Pod 将不会被调度。

硬策略和软策略

在 Kubernetes 中,硬策略和软策略通常用于定义 Pod 的亲和性或节点的亲和性。这些策略决定了 Kubernetes 调度器在安排 Pod 时的行为。

  • 硬策略(requiredDuringSchedulingIgnoredDuringExecution)

  • 当使用硬策略时,调度器必须严格遵守亲和性规则。这意味着 Pod 必须满足定义的亲和性条件才能被调度到节点上。如果无法满足条件,Pod 将会一直处于 Pending 状态,直到满足条件为止。即使在运行时,如果条件不再满足,Pod 也不会被迁移到其他节点。

  • 软策略(preferredDuringSchedulingIgnoredDuringExecution)

  • 当使用软策略时,调度器会尽量遵守定义的亲和性规则,但不是必须的。如果有多个节点符合软策略的条件,调度器会倾向于选择满足条件的节点,但如果无法满足条件,调度器仍然可以将 Pod 调度到其他节点上。如果在运行时条件不再满足,Pod 也不会被迁移到其他节点。

这两种策略提供了灵活性和可靠性之间的权衡。硬策略确保 Pod 被调度到满足条件的节点上,但可能会导致更多的 Pod 无法调度。软策略提供了更灵活的调度,但可能会导致一些 Pod 被调度到不太理想的节点上。在设计亲和性规则时,需要根据具体情况选择适当的策略来平衡资源利用率和可用性要求

硬策略示例

# 创建目录
mkdir /opt/affinity
# 切换目录
cd /opt/affinity

# 编辑 Pod 配置文件
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  # 定义节点亲和性
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname    # 指定node的标签
            operator: NotIn     # 设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
            values:
            - node02


# 应用 Pod 配置
kubectl apply -f pod1.yaml

# 获取 Pod 列表
kubectl get pods -o wide

# 删除所有 Pod,重新应用配置,并查看 Pod 列表
kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide

# 如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态。

这个示例中,创建了一个名为 affinity 的 Pod,并且定义了节点亲和性规则,使用了硬策略 requiredDuringSchedulingIgnoredDuringExecution。逐步解析这个示例:

  • metadata 部分指定了 Pod 的元数据,包括名称和标签。

  • spec 部分定义了 Pod 的规格,其中包含了容器的相关信息。

  • affinity 字段下,定义了节点亲和性规则。这里使用了 nodeAffinity,表示节点亲和性。

  • requiredDuringSchedulingIgnoredDuringExecution 中,指定了节点选择器条件。matchExpressions 用于指定匹配条件,key 指定了要匹配的标签键,这里是 kubernetes.io/hostname,即节点的主机名。operator 设置为 NotIn,表示标签值不在指定的列表中。而 values 则列出了不允许的节点主机名,这里只有一个节点 node02

  • 最后,应用了这个 Pod 的配置文件,并通过 kubectl get pods -o wide 命令来查看 Pod 的状态和所在的节点。由于节点亲和性规则指定了 Pod 不能运行在 node02 上,所以 Pod 被成功调度到了 node01 上,状态为 Running

  • 最后的删除并重新创建操作是为了再次验证规则,确保当条件不满足时,Pod 状态会一直保持在 Pending

这个示例清晰地展示了硬策略的行为:当指定的条件无法满足时,Pod 将无法被调度,并且状态会一直保持在 Pending

软策略示例

# 编辑 Pod2 配置文件
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  # 定义节点亲和性,优先使用软策略
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1   # 如果有多个软策略选项的话,权重越大,优先级越高
        preference:
          matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - node03


# 应用 Pod2 配置
kubectl apply -f pod2.yaml

# 获取 Pod 列表
kubectl get pods -o wide

这个YAML文件描述了一个Pod对象,其中包含一个名为affinity的Pod。

  • apiVersion: 指定了Kubernetes API的版本,这里使用的是v1版本。

  • kind: 定义了Kubernetes对象的类型,这里是一个Pod对象。

  • metadata: 包含了有关该Pod的元数据,包括名称(name)和标签(labels)。

  • name: 指定了Pod的名称为affinity

  • labels: 为Pod添加了一个标签,标签的键为app,值为node-affinity-pod

  • spec: 包含了Pod的规格,即容器和其他配置信息。

  • containers: 定义了Pod中的容器列表。

    • name: 指定了容器的名称为with-node-affinity

    • image: 指定了容器所使用的镜像为soscscs/myapp:v1

  • affinity: 定义了Pod的亲和性规则。

    • nodeAffinity: 定义了节点亲和性规则。

    • preferredDuringSchedulingIgnoredDuringExecution: 指定了软节点亲和性规则,即在调度时优先考虑,但在执行时忽略。

      • weight: 指定了该规则的权重为1,权重越大,优先级越高。

      • preference: 指定了偏好项,即优先调度到具有特定主机名的节点。

      • matchExpressions: 定义了匹配表达式。

        • key: 指定了匹配的键为kubernetes.io/hostname,即主机名。

        • operator: 指定了匹配操作符为In,表示匹配主机名列表中的任何一个值。

        • values: 指定了匹配的主机名列表,这里只有一个值node03

总结:该Pod对象具有一个软节点亲和性规则,表示优先调度到具有主机名为node03的节点。权重为1,这意味着在具有多个软策略选项的情况下,优先级较高。然而,根据输出结果,该Pod最终被调度到了节点node02上,这是由于node02满足了调度要求并且优先级高于node03

软硬策略结合示例

如果把硬策略和软策略合在一起使用,则要先满足硬策略之后才会满足软策略

# 定义 Pod 配置
apiVersion: v1
kind: Pod
metadata:
  name: affinity
  labels:
    app: node-affinity-pod
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  # 定义节点亲和性
  affinity:
    nodeAffinity:
      # 先满足硬策略,排除有 kubernetes.io/hostname=node02 标签的节点
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - node02
      # 再满足软策略,优先选择有 aaa=a 标签的节点
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: aaa
            operator: In
            values:
            - a

这个示例中,定义了一个Pod对象,其中包含了硬节点亲和性规则和软节点亲和性规则。让我们分析一下:

  • requiredDuringSchedulingIgnoredDuringExecution:这是一个硬节点亲和性规则,表示在调度时必须满足的条件。在这个规则中,指定了排除具有主机名为node02的节点,即必须在不包括node02的节点上调度该Pod。

  • preferredDuringSchedulingIgnoredDuringExecution:这是一个软节点亲和性规则,表示在调度时优先考虑的条件,但在执行时会被忽略。在这个规则中,指定了优先选择具有标签aaa=a的节点,即希望将该Pod调度到具有aaa=a标签的节点上。

根据这两个规则的组合,首先,调度器会先满足硬节点亲和性规则,即排除node02节点。然后,在满足了硬性要求的节点中,调度器会优先考虑软节点亲和性规则,即选择具有aaa=a标签的节点。这样,最终的调度结果将是在不包括node02节点的节点中,优先选择具有aaa=a标签的节点。

pod亲和和反亲和

  • 在Kubernetes(k8s)中,Pod亲和性和反亲和性用于指定Pod与节点的关系。亲和性定义了Pod如何倾向于在同一节点上调度,而反亲和性则定义了Pod如何避免与特定节点调度在一起。

  • 通过使用nodeSelector字段,你可以在PodSpec中指定节点标签,使Pod倾向于调度到具有特定标签的节点上,这就是亲和性的一种实现方式。相反,反亲和性可以通过tolerations字段实现,该字段定义了Pod可以容忍的节点上的污点,从而避免在这些节点上被调度。

  • 这样的机制有助于优化Pod的调度,使其更好地适应节点资源和约束条件。

调度策略

当使用 Kubernetes 进行 Pod 调度时,可以使用三种不同的调度策略来控制 Pod 的部署位置,分别是 nodeAffinity(节点亲和性)、podAffinity(Pod 亲和性)和 podAntiAffinity(Pod 反亲和性)。

  • 节点亲和性(nodeAffinity)

  • 匹配标签:对节点的标签进行匹配。

  • 操作符:支持的操作符包括 InNotInExistsDoesNotExistGt(大于)和 Lt(小于)等。

  • 拓扑域支持:不支持拓扑域,只考虑节点的标签。

  • 调度目标:指定 Pod 应该调度到具有特定标签的节点上。

  • Pod 亲和性(podAffinity)

  • 匹配标签:对其他 Pod 的标签进行匹配。

  • 操作符:与节点亲和性相同,支持的操作符包括 InNotInExistsDoesNotExist 等。

  • 拓扑域支持:支持拓扑域,可以指定 Pod 应该与其他 Pod 在同一拓扑域(比如同一节点)还是不同拓扑域。

  • 调度目标:指定 Pod 应该与其他具有特定标签的 Pod 部署在同一拓扑域。

  • Pod 反亲和性(podAntiAffinity)

  • 匹配标签:同样对其他 Pod 的标签进行匹配。

  • 操作符:与节点亲和性和 Pod 亲和性相同。

  • 拓扑域支持:同样支持拓扑域,可以指定 Pod 应该与其他 Pod 在同一拓扑域还是不同拓扑域。

  • 调度目标:指定 Pod 应该与其他具有特定标签的 Pod 部署在不同的拓扑域,即不在同一节点或同一拓扑域。

这些调度策略可以帮助用户更灵活地控制 Pod 的部署,根据业务需求和系统架构,优化资源利用和提高容错能力。

Pod 亲和性调度策略的详细说明

  • 调度条件

  • 仅当节点和至少一个已运行且具有标签键为“app”且值为“myapp01”的 Pod 处于同一拓扑域时,才可以将该 Pod 调度到节点上。

  • 具体来说,如果节点 N 具有带有键为 lab 和某个值 V 的标签,则 Pod 有资格在节点 N 上运行,以便集群中至少有一个具有键为 lab和值为 V 的节点正在运行具有键“app”和值“myapp01”的 Pod。

  • topologyKey

  • topologyKey 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑域中。

  • 调度器试图在每个拓扑域中放置数量均衡的 Pod。

  • 拓扑域的定义

  • 如果 lab对应的值不一样就是不同的拓扑域。比如 Pod1 在 lab=a 的 Node 上,Pod2 在 lab=b 的 Node 上,Pod3 在 lab=a 的 Node 上,则 Pod2 和 Pod1、Pod3 不在同一个拓扑域,而 Pod1 和 Pod3 在同一个拓扑域。

示例

kubectl label node node01 lab=a
kubectl label node node02 lab=b

这两个命令的目的是给节点 node01node02 分别打上标签 lab=alab=b

创建一个标签为 app=myapp01 的 Pod

vim pod3.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp01  # 设置 Pod 的名称为 myapp01
  labels:
    app: myapp01  # 给 Pod 添加标签 app: myapp01
spec:
  containers:
  - name: with-node-affinity  # 定义容器名称为 with-node-affinity
    image: soscscs/myapp:v1  # 使用镜像 soscscs/myapp:v1

kubectl apply -f pod3.yaml
kubectl get pods --show-labels -o wide

这段代码创建了一个名为 myapp01 的 Pod,并为其打上了标签 app=myapp01。下面是对代码的说明:

  • vim pod3.yaml:创建了一个名为 pod3.yaml 的文件,并编辑该文件以定义 Pod 对象的配置。

  • metadata 部分指定了 Pod 的名称和标签。

  • spec 部分定义了 Pod 的规格,其中包含一个容器,使用镜像 soscscs/myapp:v1

  • kubectl apply -f pod3.yaml:使用 Pod 配置文件 pod3.yaml 创建 Pod 对象。

  • kubectl get pods --show-labels -o wide:显示所有 Pod 的信息,包括标签,以宽格式输出。可以看到 myapp01 Pod 已经成功创建,并且具有标签 app=myapp01,并且运行在 node01 节点上。

这样就成功创建了一个名为 myapp01 的 Pod,并为其打上了指定的标签。

使用 Pod 亲和性调度,创建多个 Pod 资源

vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp02  # 设置 Pod 的名称为 myapp02
  labels:
    app: myapp02  # 给 Pod 添加标签 app: myapp02
spec:
  containers:
  - name: myapp02  # 定义容器名称为 myapp02
    image: soscscs/myapp:v1  # 使用镜像 soscscs/myapp:v1
  affinity:  # 定义亲和性
    podAffinity:  # Pod 亲和性规则
      requiredDuringSchedulingIgnoredDuringExecution:  # 在调度期间要求的 Pod 亲和性规则,在执行期间被忽略
      - labelSelector:  # 标签选择器
          matchExpressions:  # 匹配表达式列表
          - key: app  # 标签键为 app
            operator: In  # 使用 In 操作符
            values:  # 值列表
            - myapp01  # 匹配值为 myapp01
        topologyKey: lab  # 拓扑域键为 lab

kubectl apply -f pod4.yaml
kubectl get pods --show-labels -o wide

这段代码创建了一个名为 myapp02 的 Pod,并使用了 Pod 亲和性调度策略,以确保它与具有特定标签的其他 Pod 在同一拓扑域上。下面是对代码的说明:

  • vim pod4.yaml:创建了一个名为 pod4.yaml 的文件,并编辑该文件以定义 Pod 对象的配置。

  • metadata 部分指定了 Pod 的名称和标签。

  • spec 部分定义了 Pod 的规格,其中包含一个容器,使用镜像 soscscs/myapp:v1

  • affinity 部分定义了 Pod 的亲和性策略,这里使用了 podAffinity 策略。

    • requiredDuringSchedulingIgnoredDuringExecution 指定了 Pod 调度时必须满足的条件。

    • labelSelector 指定了匹配其他 Pod 标签的条件,这里要求匹配的标签为 app=myapp01

    • topologyKey 指定了用于确定拓扑域的键,这里设置为 lab

  • 这段代码将确保创建的 myapp02 Pod 与具有标签 app=myapp01 的其他 Pod 在同一拓扑域上调度。

使用 Pod 反亲和性调度

vim pod5.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp10  # Pod 的名称
  labels:
    app: myapp10  # Pod 的标签
spec:
  containers:
  - name: myapp10  # 容器的名称
    image: soscscs/myapp:v1  # 容器所使用的镜像
  affinity:
    podAntiAffinity:  # 反亲和性调度规则
      preferredDuringSchedulingIgnoredDuringExecution:  # 在调度时优先考虑的规则,执行时忽略
      - weight: 100  # 权重
        podAffinityTerm:  # 匹配的 Pod 亲和性条件
          labelSelector:  # 标签选择器
            matchExpressions:  # 匹配的表达式
            - key: app  # 匹配的键
              operator: In  # 匹配操作符
              values:  # 匹配的值
              - myapp01  # 与该 Pod 亲和的标签值
          topologyKey: kubernetes.io/hostname  # 拓扑域键

kubectl apply -f pod5.yaml

kubectl get pods --show-labels -o wide
  • 这个示例展示了如何在 Pod 中使用反亲和性调度。在这个例子中,Pod myapp10 的调度规则指定了反亲和性,即希望它不要与具有特定标签的其他 Pod 调度到同一个节点上。
vim pod6.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp20  # Pod 的名称
  labels:
    app: myapp20  # Pod 的标签
spec:
  containers:
  - name: myapp20  # 容器的名称
    image: soscscs/myapp:v1  # 容器所使用的镜像
  affinity:
    podAntiAffinity:  # 反亲和性调度规则
      requiredDuringSchedulingIgnoredDuringExecution:  # 在调度时必须满足的规则,执行时忽略
      - labelSelector:  # 标签选择器
          matchExpressions:  # 匹配的表达式
          - key: app  # 匹配的键
            operator: In  # 匹配操作符
            values:  # 匹配的值
            - myapp01  # 与该 Pod 亲和的标签值
        topologyKey: lab  # 拓扑域键
  • 这样配置的 Pod 在调度时将会确保不与具有标签 app: myapp01 的其他 Pod 调度到同一个拓扑域上

由于指定 Pod 所在的 node01 节点上具有带有键 lab和标签值 a 的标签,node02 也有这个lab=a的标签,所以 node01 和 node02 是在一个拓扑域中,反亲和要求新 Pod 与指定 Pod 不在同一拓扑域,所以新 Pod 没有可用的 node 节点,即为 Pending 状态。

kubectl get pod --show-labels -owide
kubectl label nodes node02 lab=b --overwrite
kubectl get pod --show-labels -o wide
  • 根据输出,可以看出新的 Pod myapp20 因为反亲和性调度规则而处于 Pending 状态。由于 Pod myapp01 具有标签 app=myapp01,并且拓扑域键 lab 的值为 a,而节点 node01node02 都有拓扑域键 lab 的标签,因此它们被认为处于相同的拓扑域。

  • 由于新的 Pod myapp20 需要避免与具有标签 app=myapp01 的 Pod 调度到同一拓扑域,但在目前的节点中,没有节点符合该条件,因此该 Pod 保持在 Pending 状态。更新了 node02 的标签,但似乎仍然不符合新 Pod 的调度要求。

  • 最终,创建了一个新的 Pod myapp21,它成功在 node02 上运行,因为现在 node02 的标签为 lab=b,与之前的标签不同,因此不再满足与 Pod myapp20 的反亲和性调度要求。

污点(Taint) 和 容忍(Tolerations)

  • 节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 Pod。

  • Taint 和 Toleration 相互配合,可以用来避免 Pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 Pod,是不会被该节点接受的。如果将 toleration 应用于 Pod 上,则表示这些 Pod 可以(但不一定)被调度到具有匹配 taint 的节点上。

  • 使用 kubectl taint 命令可以给某个 Node 节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去。

概念

污点(Taints)

  • 污点是应用于节点的标记,用于阻止将新的Pod调度到带有该污点的节点上。

  • 污点由键值对(key=value)组成,其中键表示污点的名称,而值表示污点的效果,例如NoSchedule、PreferNoSchedule和NoExecute。

  • 通过在节点上设置污点,可以限制哪些Pod可以被调度到该节点上。

容忍度(Tolerations)

  • 容忍度是Pod的属性,用于指定Pod可以被调度到带有特定污点的节点上。

  • 每个容忍度包含键值对(key=value),其中键表示要容忍的污点的名称,而值表示要容忍的污点的效果。

  • Pod只有在其定义了与节点上污点匹配的容忍度时,才能被调度到带有该污点的节点上。

调度行为

  • 如果Pod的容忍度与节点上的污点匹配,那么该Pod可以被调度到带有该污点的节点上。

  • 如果Pod的容忍度与节点上的污点不匹配,且污点的效果是NoSchedule或PreferNoSchedule,那么该Pod将不会被调度到该节点上。

  • 如果Pod的容忍度与节点上的污点不匹配,但污点的效果是NoExecute,那么该节点上的已有Pod可能会被驱逐(Evicted)。

示例用法

  • 可以使用污点和容忍度来实现特定的调度需求,例如将某些特殊的Pod调度到专门的节点上,或者确保某些Pod不会被调度到某些节点上。

格式和支持的效果(选项)

#污点的组成格式如下:
key=value:effect

每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。

个污点由键值对(key=value)和一个效果(effect)组成。效果描述了污点的作用,而键值对表示该污点的标签。支持的效果包括:

  • NoSchedule(不调度): Kubernetes将不会将Pod调度到具有该污点的节点上。

  • PreferNoSchedule(尽量避免调度): Kubernetes将尽量避免将Pod调度到具有该污点的节点上,但不是绝对禁止。

  • NoExecute(不执行): Kubernetes将不会将Pod调度到具有该污点的节点上,并且会将节点上已经存在的Pod驱逐出去,确保节点不再运行这些Pod。

这种机制为Kubernetes提供了更精细的调度控制,使得系统可以根据特定的需求和场景进行灵活的调度决策。

污点的基本操作

用一个具体的示例来说明如何在Kubernetes中执行这些操作。

假设我们有一个名为node-1的节点,我们要给它添加一个污点,阻止Pod在这个节点上调度,除非它们具有特定的标签。我们将添加一个名为special=true:NoSchedule的污点。

添加污点

kubectl taint nodes <node-name> key=value:taint-effect
kubectl taint nodes node-1 special=true:NoSchedule

这将在node-1节点上添加一个名为special、值为true的污点,并且该污点的效果为NoSchedule,意味着除非Pod具有与此污点匹配的容忍(Toleration),否则不会在该节点上调度。

查看污点

kubectl describe node <node-name>
kubectl describe node node-1

运行此命令将显示有关node-1节点的详细信息,包括其上的污点。

删除污点

kubectl taint nodes <node-name> key:NoSchedule-
kubectl taint nodes node-1 special:NoSchedule-

这会从node-1节点上删除名为special的污点,并且污点的效果为NoSchedule

示例

# 显示集群中的节点信息,包括名称、状态、角色、年龄和版本
kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   11d   v1.20.11
node01   Ready    <none>   11d   v1.20.11
node02   Ready    <none>   11d   v1.20.11

# master 节点设置了一个 NoSchedule 类型的污点,导致不允许在此节点上调度 Pod
kubectl describe node master
......
Taints:             node-role.kubernetes.io/master:NoSchedule

# 给 node01 节点设置一个名为 key1,值为 value1 的 NoSchedule 类型的污点
kubectl taint node node01 key1=value1:NoSchedule

# 在节点说明中查找 Taints 字段,用于查看节点上设置的污点信息
kubectl describe node node-name  

# 从 node01 节点中移除名为 key1 的污点
kubectl taint node node01 key1:NoSchedule-

# 显示 Pod 的信息,包括名称、就绪状态、状态、重启次数、年龄、IP 地址、所在节点等
kubectl get pods -o wide

# 给 node02 节点设置一个名为 check,值为 mycheck 的 NoExecute 类型的污点,导致 Pod 在此节点上被驱逐
kubectl taint node node02 check=mycheck:NoExecute

# 查看 Pod 状态,会发现 node02 上的 Pod 已经被全部驱逐
# 注:如果是 Deployment 或者 StatefulSet 资源类型,为了维持副本数量则会在别的 Node 上再创建新的 Pod
kubectl get pods -o wide

容忍

通过在 Pod 上设置容忍(Tolerations),可以允许 Pod 在存在污点的节点上被调度。这使得在一些特定情况下,例如需要部署某些特殊任务或者维护节点时,依然能够将 Pod 调度到被标记为污点的节点上。容忍(Tolerations)允许 Pod 忽略节点上的污点并允许被调度,从而灵活地管理集群资源。

举例说明

# 在节点 node01 上设置了一个名为 mycheck 的污点,并且指定了 NoExecute 效果
kubectl taint node node01 check=mycheck:NoExecute

# 编辑名为 pod3.yaml 的 Pod 配置文件
vim pod3.yaml

# 应用 Pod3 的配置文件
kubectl apply -f pod3.yaml

# 当在两个节点上都设置了污点后,Pod 将无法创建成功
kubectl get pods -o wide
# 此时输出显示 Pod 处于 Pending 状态,无法调度到任何节点运行

# 编辑 pod3.yaml 文件,为 Pod 定义容忍策略,使其能够在具有污点的节点上运行
vim pod3.yaml
# pod3.yaml 文件内容
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: with-node-affinity
    image: soscscs/myapp:v1
  tolerations:
  - key: "check"
    operator: "Equal"
    value: "mycheck"
    effect: "NoExecute"
    tolerationSeconds: 3600
# 为 Pod 设置容忍策略,确保其能够在具有指定污点的节点上运行
# 其中的 key、value、effect 需要与节点上设置的污点保持一致
# operator 的值为 Exists 将会忽略 value 值,即存在即可
# tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在节点上继续保留运行的时间

# 再次应用更新后的 Pod3 配置文件
kubectl apply -f pod3.yaml

# 验证 Pod 创建成功,并在指定的节点上正常运行
kubectl get pods -o wide
# 输出显示 Pod 已成功创建并运行在节点 node01 上

值得注意的操作

  • 未指定 key 值时,表示容忍所有的污点 key。
tolerations:
  - operator: "Exists"
  • 未指定 effect 值时,表示容忍所有的污点作用。
tolerations:
  - key: "key"
    operator: "Exists"
  • 多个 Master 存在时,防止资源浪费,可设置如下:
kubectl taint node Master-Name node-role.kubernetes.io/master=:PreferNoSchedule
  • 若某个 Node 更新升级系统组件,为防止业务中断,可先在该 Node 设置 NoExecute 污点,驱逐 Pod。
kubectl taint node node01 check=mycheck:NoExecute
  • 若其他 Node 资源不足,可暂时给 Master 设置 PreferNoSchedule 污点,使 Pod 在 Master 上创建。
kubectl taint node master node-role.kubernetes.io/master=:PreferNoSchedule
  • 所有 Node 更新操作完成后,移除污点。
kubectl taint node node01 check=mycheck:NoExecute-

维护节点和应用程序操作

管理节点的调度状态:

  • Cordon: 使用 kubectl cordon <NODE_NAME> 命令将指定节点标记为不可调度状态。这将阻止新的 Pod 在此节点上调度。

  • Drain: 使用 kubectl drain <NODE_NAME> 命令使节点进入排水状态。这将释放节点上的所有 Pod,并且不再接受新的 Pod。执行排水操作通常在需要维护节点或者从集群中移除节点时使用。

    • 注:执行 drain 命令,会自动做了两件事情: 1.设定此 node 为不可调度状态(cordon) 2.evict(驱逐)了 Pod
  • Uncordon: 使用 kubectl uncordon <NODE_NAME> 命令将节点标记为可调度状态,恢复节点的正常调度功能。这允许新的 Pod 再次在该节点上调度。

设置和移除污点:

  • 设置污点: 使用 kubectl taint node <NODE_NAME> <KEY>=<VALUE>:<EFFECT> 命令在节点上设置污点。污点可以阻止 Pod 在具有特定标签和效果的节点上调度。

  • 移除污点: 使用 kubectl taint node <NODE_NAME> <KEY>=<VALUE>:<EFFECT>- 命令在节点上移除指定的污点。这将允许 Pod 再次在该节点上调度。

常见的污点效果(Effect):

  • NoSchedule: 阻止新的 Pod 调度到节点上,但不会驱逐现有的 Pod。

  • PreferNoSchedule: 倾向于不在该节点上调度新的 Pod,但不会阻止 Pod 调度。

  • NoExecute: 阻止新的 Pod 调度到节点上,并且将现有 Pod 驱逐出该节点。

常见参数:

  • --ignore-daemonsets:

    • 当执行 kubectl drain <NODE_NAME> 命令时,使用该选项可以忽略 DaemonSet 管理下的 Pod。DaemonSet 是 Kubernetes 中一种控制器类型,它确保在集群中的每个节点上运行一个副本的 Pod。通常情况下,节点的排水操作不会影响 DaemonSet 管理的 Pod,因为它们被认为是关键的系统组件,需要保持运行。使用 --ignore-daemonsets 选项可以确保在排水节点时不会影响 DaemonSet 的 Pod。
  • --delete-local-data:

    • 当执行 kubectl drain <NODE_NAME> 命令时,如果节点上有挂载本地卷的 Pod,使用该选项可以强制删除这些 Pod。本地卷是直接挂载在节点上的存储卷,而不是通过网络挂载的。在某些情况下,需要强制删除这些 Pod,例如当节点需要被彻底清空时。
  • --force:

    • 当执行 kubectl drain <NODE_NAME> 命令时,使用该选项可以强制释放不是由控制器管理的 Pod。控制器管理的 Pod 包括 Deployment、StatefulSet、DaemonSet 等。通常情况下,控制器会确保 Pod 的数量和状态符合预期,但是如果需要强制释放一些不是由控制器管理的 Pod,可以使用 --force 选项。

通过合理管理节点的调度状态和设置/移除污点,可以有效地管理集群中的资源,确保应用程序的高可用性和稳定性。

pod启动阶段的状态解读与排错技巧

Pod启动阶段(相位 phase)

Pod 创建完之后,一直到持久运行起来,中间有很多步骤,也就有很多出错的可能,因此会有很多不同的状态。

  • 调度到某台 node 上: Kubernetes 根据一定的优先级算法选择一个 node 节点来运行 Pod。

  • 拉取镜像: Pod 需要拉取其包含的镜像,以便在节点上创建容器。

  • 挂载存储配置等: Pod 可能需要挂载存储卷或配置文件等资源。

  • 运行起来: 当所有必需的资源准备就绪后,Pod 开始在节点上运行。如果定义了健康检查,系统会根据检查结果设置 Pod 的状态。

pod可能的状态

  • Pending(挂起): 表示 Pod 资源对象已创建,但尚未完成调度或正在拉取镜像。

  • Running(运行中): Pod 已经被调度到节点上,并且至少有一个容器正在运行,或处于启动或重启状态。也就是说Running状态下的Pod不一定能被正常访问

  • Succeeded(成功): 表示 Pod 中的所有容器已成功终止,通常用于短期任务执行完毕后的状态反馈。有些pod不是长久运行的,比如job、cronjob,一段时间后Pod中的所有容器都被成功终止,并且不会再重启。需要反馈任务执行的结果。

  • Failed(失败): 所有容器都已终止,并且至少有一个容器由于失败而终止,可能是由于命令错误等原因。也就是说,容器以非0状态退出或者被系统终止,比如 command 写的有问题。

  • Unknown(未知): 表示无法读取 Pod 的状态,通常是由于控制器(kube-controller-manager)无法与 Pod 通信导致的。

故障排除步骤

需要排查 Pod 启动或运行中的问题时,以下是一些详细的故障排除步骤:

  • 查看 Pod 事件: 使用 kubectl describe 命令检查 Pod 事件,以了解 Pod 启动过程中可能出现的问题。这将提供关于 Pod 创建、调度和运行过程中的详细信息。
kubectl describe pod <POD_NAME>

期望输出: Pod 的事件日志,包括调度、镜像拉取、容器启动等信息。

  • 查看 Pod 日志: 如果 Pod 处于 Failed 状态,使用 kubectl logs 命令查看 Pod 的日志以获取失败的原因。可以通过指定容器名称来查看特定容器的日志。
kubectl logs <POD_NAME> [-c <CONTAINER_NAME>]

期望输出: 容器的标准输出和标准错误日志,显示应用程序的运行日志或错误信息。

  • 进入 Pod 内部: 如果 Pod 处于 Running 状态但服务没有提供,可以使用 kubectl exec 命令进入 Pod 内部。这样可以检查 Pod 内部的环境和运行状态,以便进一步诊断问题。
kubectl exec -it <POD_NAME> -- /bin/bash

期望操作: 在 Pod 内部运行命令进行故障排查,如检查网络配置、运行状态或日志文件。

  • 查看集群信息: 使用 kubectl get nodes 命令检查集群中节点的状态,以确保节点正常运行。这可以帮助排除可能导致 Pod 无法调度或运行的节点问题。
kubectl get nodes

期望输出: 集群中所有节点的列表,包括它们的状态(Ready、NotReady 或其他)。

  • 检查集群状态: 使用 kubectl cluster-info 命令检查整个集群的状态,包括控制平面和核心服务。这有助于确定是否存在集群范围的问题。
kubectl cluster-info

期望输出: 集群控制平面组件的状态和访问URL,如 Kubernetes master 和 kubeDNS。

  • 查看 kubelet 日志: 最后,查看 kubelet 的日志以发现与 Pod 启动或运行相关的任何问题。可以使用 journalctl 命令来查看 kubelet 的日志。
journalctl -u kubelet

期望输出: kubelet 服务的日志,提供与 Pod 生命周期和节点状态相关的详细信息。

通过执行以上步骤,可以对 Pod 启动或运行中的问题进行详细的排查和诊断,从而有效地解决问题并确保应用程序正常运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/424277.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue的中国陕西民俗网

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

家政按摩上门服务小程序搭建

家政按摩上门服务小程序支持技师入驻申请&#xff0c;用户可以通过在线下单预约家政服务&#xff0c;并根据距离、价格、销量好评度等条件进行筛选和选择。用户可以选择技师进行预约&#xff0c;并填写自己的服务地点和时间&#xff0c;享受上门服务。同时&#xff0c;技师也可…

C++_数据类型_整形

数据类型 C规定在创建一个变量或常量时&#xff0c;必须要指定出相应得数据类型&#xff0c;否则无法给变量分配内存 整形 作用 整形变量表示的是整数型的数据 方式 越界

攻防世界-get_post

题目信息 相关知识 -G&#xff1a;表示GET请求&#xff0c;缺省POST -d参数用于发送 POST 请求的数据体 使用-d参数以后&#xff0c;HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法&#xff0c;因此可以省略-X PO…

跨站脚本攻击xss-labs(1-20)靶机练手

目录 一、跨站脚本攻击&#xff08;XSS&#xff09; 1.1 漏洞简介 1.2:类型 1.3 XSS危害 1.4XSS防御规则 二、环境搭建 三、xsst通关记录 Level 1&#xff1a;文本解析为 HTML Level 2&#xff1a;htmlspecialchars;input 标签 value 注入 定义和用法 字符过滤绕过 …

pytorch基础2-数据集与归一化

专题链接&#xff1a;https://blog.csdn.net/qq_33345365/category_12591348.html 本教程翻译自微软教程&#xff1a;https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次编辑&#xff1a;2024/3/2&#xff1b;最后编辑&#xff1a;2024/3/2 本教程…

2024-03-01(金融AI行业与大数据生态圈)

1.金融这一块的算法&#xff0c;不像推荐系统&#xff0c;图像等领域&#xff0c;金融领域的算法都比较成熟了。现在来说门槛低&#xff0c;属于初期阶段&#xff0c;上升期。 2.反欺诈的数据标签比较少&#xff0c;有一种“标签染色”的方法来做反欺诈模型的标签。 3.常用反…

什么是Vue指令?请列举一些常见的Vue指令以及它们的用法

Vue.js 是一款流行的前端框架&#xff0c;它的指令&#xff08;Directives&#xff09;是 Vue.js 提供的一种特殊属性&#xff0c;用于在模板中对 DOM 元素进行直接操作。指令通常是以 v- 开头的特殊属性&#xff0c;用于响应式地将数据绑定到 DOM 元素上。 在 Vue 中&#xf…

【NTN 卫星通信】卫星和无人机配合的应用场景

1 场景概述 卫星接入网是一种有潜力的技术&#xff0c;可以为地面覆盖差地区的用户提供无处不在的网络服务。然而&#xff0c;卫星覆盖范围对于位于考古或采矿地点内部/被茂密森林覆盖的村庄/山谷/靠近山丘或大型建筑物的用户可能很稀疏。因此&#xff0c;涉及卫星接入和无人驾…

131. 分割回文串(力扣LeetCode)

文章目录 131. 分割回文串题目描述回溯代码 131. 分割回文串 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xff1a; 输入&#xf…

C#,基于密度的噪声应用空间聚类算法(DBSCAN Algorithm)源代码

1 聚类算法 聚类分析或简单聚类基本上是一种无监督的学习方法&#xff0c;它将数据点划分为若干特定的批次或组&#xff0c;使得相同组中的数据点具有相似的属性&#xff0c;而不同组中的数据点在某种意义上具有不同的属性。它包括许多基于差分进化的不同方法。 E、 g.K-均值…

kafka文件存储机制和消费者

1.broker文件存储机制 去查看真正的存储文件&#xff1a; 在/opt/module/kafka/datas/ 路径下 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 如果是6415那么这个会存储在563的log文件之中&#xff0c;因为介于6410和10090之间。 2.…

STM32使用FlyMcu串口下载程序与STLink Utility下载程序

文章目录 前言软件链接一、FlyMcu串口下载程序原理优化手动修改跳线帽选项字节其他功能 二、STLink Utility下载程序下载程序选项字节固件更新 前言 本文主要讲解使用FlyMcu配合USART串口为STM32下载程序、使用STLink Utility配合STLink为STM32下载程序&#xff0c;以及这两个…

Stable Diffusion 模型分享:AAM XL (Anime Mix)(动漫截屏风格 XL)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 AAM XL (Anime Mix) 是一个动漫截屏风格的模型&#xff0c;是 AAM - AnyLoRA Anime Mix 模…

【办公类-25-01】20240302 UIBOT上传 ”班级主页-育儿知识(家园小报)“

作品展示&#xff1a; 一、背景需求&#xff1a; 本学期制作了 “育儿知识&#xff08;家园小报&#xff09;”合并A4内容 【办公类-22-08】周计划系列&#xff08;4&#xff09;“育儿知识&#xff08;家园小报&#xff09;“ &#xff08;2024年调整版本&#xff09;-CSDN博…

【Qt学习笔记】(四)Qt窗口

Qt窗口 1 菜单栏1.1 创建菜单栏1.2 在菜单栏中添加菜单1.3 创建菜单项1.4 在菜单项之间添加分割线1.5 给菜单项添加槽函数1.6 给菜单项添加快捷键 2 工具栏2.1 创建工具栏2.2 设置停靠位置2.3 设置浮动属性2.4 设置移动属性2.5 添加 Action 3 状态栏3.1 状态栏的创建3.2 在状态…

【高级数据结构】Trie树

原理 介绍 高效地存储和查询字符串的数据结构。所以其重点在于&#xff1a;存储、查询两个操作。 存储操作 示例和图片来自&#xff1a;https://blog.csdn.net/qq_42024195/article/details/88364485 假设有这么几个字符串&#xff1a;b&#xff0c;abc&#xff0c;abd&…

基于springboot+vue的高校教师科研管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Redis高级特性和应用(发布、订阅、Stream、慢查询、Pipeline、事务、Lua)

Redis高级特性和应用 发布和订阅 Redis提供了基于“发布/订阅”模式的消息机制&#xff0c;此种模式下&#xff0c;消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道( channel)发布消息&#xff0c;订阅该频道的每个客户端都可以收到该消息。 操作命令 Redis主要…

手写 Attention 迷你LLaMa2——LLM实战

https://github.com/Yuezhengrong/Implement-Attention-TinyLLaMa-from-scratch 1. Attention 1.1 Attention 灵魂10问 你怎么理解Attention&#xff1f; Scaled Dot-Product Attention中的Scaled&#xff1a; 1 d k \frac{1}{\sqrt{d_k}} dk​ ​1​ 的目的是调节内积&…