首页 > 其他分享 >【k8s面试题2025】2、练气初期

【k8s面试题2025】2、练气初期

时间:2025-01-16 23:31:17浏览次数:3  
标签:面试题 kubelet 调度 2025 集群 Pod 节点 运行 练气

在练气初期,灵气还比较稀薄,只能勉强在体内运转几个周天。

文章目录

简述k8s静态pod

  1. 定义

    • 静态Pod是一种特殊类型的Pod,它是由kubelet直接管理的,不需要通过Kubernetes的控制平面(如API Server)进行创建和调度。这意味着它的生命周期独立于Kubernetes的常规Pod管理机制。通常情况下,它是通过在节点上的特定目录(配置文件路径)中定义配置文件来创建的,kubelet会定期检查这个目录,一旦发现有新的Pod配置文件或者配置文件发生变化,就会根据这些文件来创建、更新或者删除静态Pod。
  2. 配置方式

    • 文件路径:在Kubernetes集群中,kubelet会在特定的目录下查找静态Pod的配置文件,这个目录通常是/etc/kubernetes/manifests(具体路径可以在kubelet的配置参数中修改)。例如,如果你想在一个节点上创建一个静态Pod,你可以将Pod的YAML配置文件放置在这个目录下。
    • 配置文件内容:静态Pod的配置文件格式与普通Pod的YAML配置文件格式相同。它包含了Pod的基本信息,如apiVersionkindmetadata(包括Pod的名称、标签等)和spec(包括容器的相关信息,如容器的名称、镜像、端口等)。例如:
    apiVersion: v1
    kind: Pod
    metadata:
      name: static - pod - example
      labels:
        app: static - pod - app
    spec:
      containers:
      - name: static - pod - container
        image: my - image
        ports:
        - containerPort: 8080
    
  3. 与普通Pod的区别

    • 管理方式
      • 普通Pod:由Kubernetes的控制平面(主要是API Server、Scheduler和Controller Manager等组件)进行管理。当你通过kubectl create -f pod - yaml这样的命令创建一个普通Pod时,请求会发送到API Server,然后经过Scheduler调度到合适的节点上,Controller Manager会监控Pod的状态并确保其符合期望状态。
      • 静态Pod:由kubelet直接管理。它绕过了Kubernetes的调度器和其他控制平面组件,直接在所在节点创建和运行。例如,在一些特殊场景下,如需要在节点上运行一个对Kubernetes控制平面有依赖的工具容器,使用静态Pod可以确保它在节点上稳定运行,不受控制平面组件故障的影响。
    • 生命周期
      • 普通Pod:其生命周期受Kubernetes的多种控制器(如Deployment、ReplicationController等)的影响。例如,当你删除一个Deployment时,它所管理的所有Pod也会被删除;当通过Deployment进行Pod的滚动更新时,旧版本的Pod会被逐步替换。
      • 静态Pod:生命周期相对简单,主要由kubelet和其配置文件决定。如果配置文件被删除,对应的静态Pod也会被删除;如果配置文件内容发生变化,kubelet会根据新的配置更新静态Pod。
  4. 使用场景

    • 运行系统级组件:用于在Kubernetes集群的节点上运行一些系统级的关键组件,如kube - proxy、kube - DNS等。这些组件对于集群的正常运行非常重要,使用静态Pod可以确保它们在节点上可靠地启动和运行,不受集群控制平面可能出现的故障影响。
    • 特殊的监控或管理工具:当需要在节点上运行一些特殊的监控工具或者管理工具容器时,静态Pod是一个很好的选择。例如,一个用于收集节点硬件信息的监控容器,将其作为静态Pod运行可以保证它在节点上持续运行,并且可以通过自定义的配置文件来灵活调整其运行参数。

为 Kubernetes 集群移除新节点:

一、准备工作

  1. 节点状态确认
    • 在移除节点之前,需要确保该节点的当前状态。可以使用 kubectl get nodes 命令查看节点的状态。
    • 确认节点是否处于 Ready 状态或其他状态,例如,如果节点处于 NotReady 状态,可能需要先解决该节点的问题或确保该状态不会影响节点的移除操作。
    • 同时,检查该节点上是否有正在运行的重要 Pod,因为移除节点可能会影响这些 Pod 的运行。例如,如果该节点上运行着一些关键业务的 Pod,需要考虑将这些 Pod 迁移到其他节点,以避免服务中断。

二、驱逐节点上的 Pod

  1. 使用 kubectl drain 命令
    • 为了确保节点上的 Pod 被安全地迁移到其他节点,可以使用 kubectl drain <node-name> 命令。
    • 该命令会将节点标记为不可调度(unschedulable),并将节点上的 Pod 驱逐到其他可用节点上。
    • 例如:
    kubectl drain node1
    
    • 这个命令会尝试将 node1 上的所有 Pod 驱逐,同时会遵循 Pod 的 PodDisruptionBudgets(如果有的话),确保服务的可用性和可靠性。
    • 注意:如果节点上存在一些 DaemonSet 管理的 Pod 或者一些无法驱逐的 Pod(例如,被本地存储卷绑定的 Pod),命令会给出相应的警告或错误信息。对于这些情况,可能需要手动处理,如手动删除 DaemonSet 或处理本地存储卷的绑定问题。

三、节点移除操作

  1. 使用 kubectl delete node 命令

    • 一旦节点上的 Pod 被安全驱逐,就可以使用 kubectl delete node <node-name> 命令从集群中删除该节点。
    • 例如:
    kubectl delete node node1
    
    • 此命令会将节点从 Kubernetes 的 API 服务器中删除,但不会对节点的物理机器或虚拟机进行任何操作,只是从集群的管理层面移除节点信息。
    • 该命令会删除节点的元数据、标签、注解等信息,使其不再出现在 kubectl get nodes 的列表中。
  2. 在节点上清理 K8s 组件(可选)

    • 从集群中删除节点后,可以选择在节点上清理 K8s 组件,包括 kubelet、kube-proxy 等。
    • 对于使用 kubeadm 安装的节点,可以使用 kubeadm reset 命令来清理节点上的 K8s 配置和状态。例如:
    kubeadm reset
    
    • 此命令会移除 kubelet 的配置文件、证书、存储在节点上的 etcd 数据(如果有),并停止 kubelet 和 kube-proxy 服务,将节点恢复到未加入集群的状态。
    • 对于使用其他安装工具或手动安装的节点,需要手动停止相应的服务,如 systemctl stop kubeletsystemctl stop kube-proxy,并删除相应的配置文件和数据目录。

四、验证和后续处理

  1. 验证节点移除结果
    • 再次使用 kubectl get nodes 命令,确认节点已不在节点列表中。
    • 同时,可以检查其他节点上是否成功接纳了从移除节点迁移过来的 Pod,使用 kubectl get pods -o wide 查看 Pod 的分布情况,确保没有 Pod 处于异常状态。
    • 例如,如果节点 node1 被移除,检查其他节点上的 Pod 数量是否增加,以及它们的状态是否正常。
  2. 网络和存储清理(可能需要)
    • 对于使用网络插件(如 Calico、Flannel 等)的集群,可能需要清理节点在网络方面的残留信息,以避免网络异常。
    • 对于使用了持久卷(PV)和持久卷声明(PVC)且与移除节点相关的情况,需要检查存储的使用情况,确保存储资源的合理分配和重新利用。
    • 例如,如果节点上的 Pod 使用了 NFS 存储,需要确保 NFS 服务器端的存储资源没有被异常占用或锁定。

在移除 K8s 集群中的节点时,要遵循安全、有序的步骤,确保对节点上的 Pod 进行合理的处理,避免对业务造成不必要的影响,同时要进行后续的清理和验证工作,以保证集群的正常运行和资源的合理利用。

请注意,在执行这些操作时,务必谨慎操作,根据实际的集群环境和业务需求调整操作步骤,避免因误操作导致服务中断或数据丢失等问题。


为 K8s 集群添加新节点

一、前置条件检查

  1. 硬件和软件要求
    • 硬件资源
      • 确保新节点具备足够的 CPU、内存和存储资源,以满足容器和应用程序的运行需求。一般来说,需要根据集群中预期运行的工作负载来评估,避免资源不足影响性能或稳定性。
      • 例如,对于运行多个微服务的集群,新节点至少应具有 2 核 CPU、4GB 内存和一定的磁盘空间,并且要考虑后续的扩容需求。
    • 操作系统兼容性
      • 新节点应运行支持的操作系统,通常是主流的 Linux 发行版,如 Ubuntu、CentOS、Debian 等。同时,要确保操作系统版本在 K8s 支持的范围内。
      • 比如,对于某些 K8s 版本,可能要求使用 Ubuntu 18.04 或更高版本,以避免因操作系统不兼容导致的问题。
    • 网络连通性
      • 新节点必须能够与现有集群节点进行网络通信,包括 TCP/IP 通信和 UDP 通信(部分组件可能需要)。
      • 确保没有防火墙或网络策略阻止 K8s 组件之间的通信,如 API Server 的 6443 端口、etcd 的 2379 端口等。

二、容器运行时安装与配置

  1. 选择容器运行时
    • 常见容器运行时
      • Docker:曾经是最常用的容器运行时,但在较新的 K8s 版本中,K8s 更推荐使用 containerd 或 CRI-O。不过 Docker 仍然可用。
      • containerd:轻量级容器运行时,是 Docker 的核心组件,可独立使用。在 K8s 中使用 containerd 可以提高性能和资源利用率。
      • CRI-O:专门为 K8s 设计的容器运行时,遵循 CRI(Container Runtime Interface)规范,提供更精简的容器运行环境。
    • 安装步骤示例(containerd)
      • 首先添加容器运行时的软件源,对于 Ubuntu 可以使用 apt 或对于 CentOS 可以使用 yum 进行添加。
      • 然后使用相应的包管理工具安装 containerd 包,如 sudo apt-get install containerd
      • 配置 containerd,通常需要修改 /etc/containerd/config.toml 文件,设置镜像仓库、存储驱动等。例如,配置镜像仓库为 Docker Hub 或其他私有仓库,设置存储驱动为 overlayfs 等。

三、K8s 组件安装与配置

  1. kubelet 安装与配置

    • 安装 kubelet
      • 从 K8s 官方的软件源下载 kubelet 包,根据操作系统使用相应的包管理工具进行安装。
      • 例如,对于 Ubuntu 可以使用 sudo apt-get install kubelet 进行安装。
    • 配置 kubelet
      • 设置 kubelet 的启动参数,主要包括 --kubeconfig(指定 K8s 集群的配置文件路径)、--node-ip(新节点的 IP 地址)等。
      • 配置文件通常位于 /var/lib/kubelet/config.yaml,可设置资源预留、容器日志目录、Pod 目录等信息。
      • 例如,设置资源预留参数,确保系统有足够的资源留给 K8s 组件和操作系统本身,避免资源竞争。
  2. kube-proxy 安装与配置

    • 安装 kube-proxy
      • 与 kubelet 类似,从官方软件源安装 kube-proxy 包,如 sudo apt-get install kube-proxy
      • kube-proxy 负责将服务请求转发到相应的 Pod,是实现服务发现和负载均衡的重要组件。
    • 配置 kube-proxy
      • 可以使用配置文件(如 /var/lib/kube-proxy/config.conf)设置模式(如 iptables 或 ipvs)、集群的 CIDR 等。
      • 不同的模式有不同的性能和特点,可根据集群规模和性能需求选择,如在大规模集群中,ipvs 模式可能性能更优。

四、加入集群

  1. 生成加入命令
    • 在现有集群的主节点上,使用 kubeadm token create --print-join-command 生成新节点加入集群的命令。
    • 此命令包含认证信息(如 token)、CA 证书哈希和 API Server 的地址,确保新节点能安全加入集群。
    • 例如,生成的命令可能是 kubeadm join 192.168.1.100:6443 --token <token> --discovery-token-ca-cert-hash <hash>
  2. 执行加入命令
    • 在新节点上执行上述生成的加入命令,将新节点添加到集群。
    • 执行过程中,新节点会与主节点通信,下载集群信息、证书和配置文件,进行身份验证,并注册自己为集群的一部分。
    • 例如,通过 sudo sh -c '<join_command>' 执行加入命令。

五、验证与调试

  1. 节点状态检查
    • 在主节点上使用 kubectl get nodes 查看新节点是否已成功加入。
    • 新节点的状态开始可能是 NotReady,等待一段时间后应变为 Ready,表明新节点已准备好接收和运行 Pod。
    • 例如,运行 kubectl get nodes 会显示节点列表,其中包括新节点的信息和状态。
  2. 日志检查
    • 若新节点未正常变为 Ready,可查看 kubeletkube-proxy 的日志,找出问题所在。
    • 可以使用 journalctl -u kubeletjournalctl -u kube-proxy 查看相应的日志信息。
    • 日志可以显示错误信息,如证书验证失败、网络连接问题、资源不足等,根据日志内容进行相应的修复。
  3. 功能测试
    • 在新节点上部署一个简单的测试 Pod,检查是否能正常运行。
    • 例如,使用 kubectl run test-pod --image=nginx --restart=Never 创建一个临时的 Nginx 容器,然后使用 kubectl describe pod test-pod 查看其运行状态,确保它能正常启动和运行。

添加新节点是扩展 K8s 集群规模和提高集群性能的重要操作,需要全面考虑硬件、软件、网络等多个方面的因素,确保每个步骤正确执行,并通过检查和测试保证新节点能正常融入集群,为集群的整体运行贡献力量。

在这里插入图片描述

Kubernetes 中 Pod 的调度流程

一、Pod 调度的基本流程概述

当用户通过 kubectl create 或通过 API 创建一个 Pod 时,Kubernetes 会触发调度流程,以确定将 Pod 分配到哪个节点上运行。这个过程涉及多个组件的协同工作,主要包括 API Server、Scheduler 和 Kubelet,它们共同确保 Pod 在合适的节点上启动和运行。

二、调度流程详细步骤

  1. Pod 创建和 API Server 接收

    • 当用户创建一个 Pod 时,无论是通过 YAML 文件还是其他方式,请求会被发送到 API Server。
    • API Server 是 Kubernetes 集群的控制平面组件,它会验证 Pod 的配置是否合法,并将其存储在 etcd 中。
    • 总结:API Server 作为入口,负责接收和验证 Pod 请求,将 Pod 信息存储到 etcd 中,为后续的调度和管理提供数据基础。
  2. 调度器监听 Pod 事件

    • Scheduler 会持续监听 API Server 上的 Pod 事件。一旦发现有新的未调度的 Pod(即没有指定 nodeName 属性的 Pod),它会将该 Pod 纳入调度队列。
    • Scheduler 会根据一系列的调度算法和策略来为 Pod 选择合适的节点。这些算法和策略考虑了多种因素,包括节点的资源(如 CPU、内存)、节点的标签、节点的亲和性/反亲和性、污点和容忍度等。
    • 总结:Scheduler 不断监控 API Server 中未调度的 Pod,根据多种因素来为它们寻找合适的节点,其核心任务是做出最优的节点选择。
  3. 节点筛选和评分

    • 筛选阶段
      • Scheduler 首先会根据 Pod 的要求和节点的属性进行筛选。例如,如果 Pod 要求一定的 CPU 和内存资源,那些资源不足的节点会被排除。同时,它会考虑节点的标签、污点和容忍度等因素。
      • 节点的亲和性/反亲和性也会影响筛选过程,例如,如果 Pod 要求运行在有特定标签的节点上,只有满足这些标签的节点会被保留。
      • 总结:通过对节点的各项属性进行筛选,排除不符合 Pod 要求的节点,缩小选择范围。
    • 评分阶段
      • 对于通过筛选的节点,Scheduler 会根据一些指标对它们进行评分。这些指标可以包括节点的资源可用性、资源分配的均匀性、节点上已有的负载等。
      • 不同的调度算法可能会采用不同的评分方式,例如,有些算法会优先考虑负载均衡,有些会优先考虑资源使用效率等。
      • 总结:对通过筛选的节点进行评分,以便选出最适合 Pod 运行的节点,不同的调度算法有不同的评分依据。
  4. 最终决策和绑定

    • Scheduler 根据评分结果,选择得分最高的节点作为最终的目标节点。
    • 然后,Scheduler 会将 Pod 与选定的节点进行绑定,通过更新 Pod 的 nodeName 属性将这一信息存储在 API Server 中,最终通过 API Server 持久化到 etcd 中。
    • 总结:根据评分选出最佳节点,将 Pod 与该节点绑定,更新信息并存储,完成调度的核心决策。
  5. Kubelet 启动 Pod

    • Kubelet 是运行在每个节点上的组件,它会持续监控 API Server 中分配到本节点的 Pod。
    • 当 Kubelet 发现有新的 Pod 被调度到自己所在的节点时,它会根据 Pod 的配置信息来启动容器。这包括拉取容器镜像、创建容器所需的存储卷、设置网络等操作。
    • 总结:Kubelet 负责接收分配到本节点的 Pod 任务,并执行实际的容器启动操作,将调度决策转化为实际的容器运行。

三、重要的调度策略和机制

  1. 资源请求和限制

    • 在 Pod 的配置中,可以指定资源请求(requests)和资源限制(limits)。
    • 资源请求会影响调度决策,确保节点有足够的资源来满足 Pod 的基本运行需求;资源限制则是对容器使用资源的上限约束,防止过度使用资源。
    • 总结:资源请求和限制是调度的重要依据,影响节点筛选和评分,同时保证了资源的合理分配和使用。
  2. 亲和性和反亲和性

    • 节点亲和性允许用户将 Pod 调度到满足特定条件的节点,如具有特定标签的节点。
    • 反亲和性可以防止 Pod 过于集中在某些节点,实现分布的均衡或满足高可用需求。
    • 总结:亲和性和反亲和性是灵活的调度工具,可实现精确的节点选择和负载均衡,提高集群的可靠性和性能。
  3. 污点和容忍度

    • 节点可以设置污点,以排斥某些 Pod。
    • Pod 可以设置容忍度,容忍特定的污点,从而能够在有污点的节点上运行。
    • 总结:污点和容忍度机制允许对节点的使用进行精细化管理,控制哪些 Pod 可以在哪些节点上运行,提高集群资源的调配灵活性。
  4. 调度器扩展

    • 用户可以编写自定义的调度算法,实现更复杂的调度需求。
    • 通过实现 Scheduler Extender 接口,可以将自定义算法集成到 Scheduler 中。
    • 总结:支持调度器扩展,以满足特殊的业务或性能要求,增加了调度的灵活性和定制性。

Kubernetes 的 Pod 调度是一个复杂而精细的过程,涉及多个组件和多种策略,从 Pod 的创建、API Server 的接收,到 Scheduler 的筛选、评分和决策,再到 Kubelet 的执行,以及重要的调度策略和机制的协同工作,确保了 Pod 在集群中高效、合理地分配和运行。这些机制相互配合,保证了集群资源的优化利用和服务的稳定运行。

标签:面试题,kubelet,调度,2025,集群,Pod,节点,运行,练气
From: https://blog.csdn.net/qq_44810930/article/details/145192749

相关文章

  • 2025/1/14 笔记 OSPF开放式最短路径优先协议
    一.距离矢量型协议:运行距离矢量路由协议的路由器周期性的泛洪自己的路由表。通过路由的交互,每台路由器都从相邻的路由器学习到路由,并且加载于自己的路由表中;但是对于网络中的所有路由器而言,路由器并不清楚网络的结构,只能简单的知道要去往某个地方方向在哪里,距离是多远。这既是......
  • 2025.1.16 html
    写一个静态网页代码,分为三个区域,top区域有Login和Register;menu区域有treemenu;还有一个main区域。点击Login,Registe或treemenu会在main区域里显示相应的内容。''top.html页面代码'top.htmlLoginRegister'Login.html页面代码'PleaseLogInLogin:......
  • 2025年员工绩效考核指南
    为什么要进行年度绩效评估?评估用于形式化和记录员工与其工作期望相比的工作方式。这样,可以增强或指出性能需要更改或改进。此正式评估支持薪酬决定或人员行动,例如重新分类,永久性额外关税和纠正措施。谁需要接受评估?作为最佳实践,任何定期工作且处于预期继续职位的员工都必须接受......
  • 2025年1月16日
    调整今天突然意识到自己翻蠢了你如果真的想往上走你就得狠得下心来说狠得下心就恨得下心你所有的事情都得靠你自己在你的上升道路上,对他人不能有一丝的同情不能有一丝的期待你有一丝的同情你就有了破绽你有了破绽他人就会利用这个破绽设局做你的局就是明面上看起来......
  • [2025.1.16 JavaSE学习]线程常用方法
    线程常用方法setName:设置线程名称getName:返回线程名称start:使线程开始执行,JVM底层调用该线程的start0()方法run:调用线程对象run方法setPriority:更改线程优先级,三个级别:getPriority:获取线程优先级sleep:线程休眠interrupt:中断线程,但并没有真正地结束线程(不是终止,是中断),......
  • 2025-1-12至16-uniapp初体验
    2025-1-12今天主要就是在熟悉app开发软件应用,发现它的页面开发起来跟我们的web是一样的,初始界面就跟VScode操作一样,毕竟第一步是要做页面,然后它的控制台跟tomcat集成之后使用很像,之后就是复习一下web的css。盒子模型:margin:外边距控制边框离屏幕的距离(top上,left左等)paddi......
  • THUWC2025 游记
    Day-C先进入金国大臣面积群,然后发现xyf又在行联考学生群故事。Day-1早上赶飞机进京。飞机上启动钢丝。到达大兴机场之后坐火车前往北京西站,然后坐地铁到海淀黄庄。非常饿,但是决定先排队。排队队伍非常抽象,还有些神秘生物要处理五分钟/人次。。。就导致排了两个小时,三点半......
  • Java集合常见面试题大全
    目录一、集合概述1.1 Java集合概览1.2 说说List,Set,Queue,Map四者的区别?1.3  集合框架底层数据结构总结1.4 如何选用集合?1.5 为什么要使用集合?二、Collection子接口之List2.1 Arraylist和Vector的区别?2.2 Arraylist与LinkedList区别?......
  • 【前端框架】2025 React 状态管理终极指南!
    全文约10800字,预计阅读需要30分钟。React作为当下最受欢迎的前端框架,在构建复杂且交互丰富的应用时,状态管理无疑是至关重要的一环。从简单的本地状态,到能让多个组件协同工作的全局状态,再到涉及服务器通信、导航切换、表单操作以及持久化存储等不同场景下的状态管理,每一个方面......
  • 2025省选模拟6
    2025省选模拟6T1、圣诞树原cf140E先说60pts做法:首先考虑如何处理两层之间的转移。每两层之间我们只需要用总方案数减去两层重合的方案数即可,对于两层重合的方案数,我们其实并不需要知道具体集合是什么,只需要知道集合的大小,然后乘上一个组合数即可,所以我们需要知道不考虑......