Loading... ## kubernetes面试题 > 本身其实没什么用哈哈哈~:为了找工作,刷一下面试题吧,烦人😡 ### 1. k8s对外暴露服务的三种方式有哪些? > 部署完服务终将是为了访问,那么`kubernetes`中`service`和`ingress`都可以将集群内部的服务能够支持外部访问。`service`可以让一组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”)提供功能;`ingress`通过对集群中服务的外部访问进行管理,也可以提供负载均衡、SSL 终结和基于名称的虚拟托管。 - clusterip - nodeport - loadbalancer - externainame - ingress `Ingress`(重点回答) * **提供基于域名和路径的 HTTP/HTTPS 入口控制。** * **通过 Ingress Controller(如 nginx-ingress)感知 Kubernetes API 中的 Ingress 资源,生成 Nginx 配置,并动态重载。** > Ingress Controller工作流程: > > Ingress Controller通过与 Kubernetes API 交互,动态感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则生成一段 Nginx 配置,应用到管理的Nginx服务,然后热加载生效。以此来达到Nginx负载均衡器配置及动态更新的问题。 > nginx-ingress-controller 调用k8s api获取ingress,自动在nginx.conf生成server块转发配置。nginx 七层的负载均衡upstream,转发pod。 > 部署ingress controller pod后,进入此容器会看到nginx配置,同时也能看到这2个进程。 > 流程包流程:客户端 ->Ingress Controller(nginx) -> 分布在各节点Pod > [参考链接详解](https://www.cnblogs.com/reim/p/17026843.html) ### 2. k8s有哪些组件? > k8s分为控制节点和工作节点 控制节点组件: - kube-apiserver:它是k8s集群中各组件数据交互和通信的枢纽,负责对外提供集群各类资源的管理。 - kube-scheduler:它是k8s集群中pod的调度组件。 - kube-controller-manager:它是k8s中的控制器组件,比如deployment,statusfulset等控制器,核心思想:监听,比较资源实际状态与期望状态是否一致,若不一致则进行协调工作使其一致。 - etcd:k8s的元数据存储。 工作节点组件: - kubelet:负责pod的创建运行管理,核心思想:通过监听apiserver获取分配其节点上的pod,然后根据pod的规格详情,调用运行时组件创建pause和业务容器等。 - kube-proxy:网络代理组件,核心思想:监听apiserver获取service,endpoint等资源,基于iptables,ipvs等技术实现数据包转发。 ### 3. docker容器制作方式 - dockerfile - docker commit 细问: 1、dockerfile有哪些常用参数? | 指令 | 说明 | | ------------- | ------------------------------------------------------------ | | `FROM` | 指定基础镜像(必须是第一个有效指令) | | `LABEL` | 添加元数据,如维护者、版本信息等 | | `ENV` | 设置环境变量 | | `RUN` | 在构建镜像时执行命令 | | `COPY` | 从构建上下文目录复制文件/目录到镜像中 | | `ADD` | 功能类似于 COPY,但支持远程 URL 和自动解压`.tar`文件 | | `WORKDIR` | 设置工作目录(类似`cd`,会影响后续指令的路径) | | `EXPOSE` | 声明容器运行时要暴露的端口(仅作为文档说明) | | `CMD` | 指定容器启动时默认执行的命令(可以被`docker run`覆盖) | | `ENTRYPOINT` | 指定容器启动时运行的主命令(更不可变) | | `VOLUME` | 定义匿名挂载点或挂载卷 | | `USER` | 指定运行容器时的用户(默认是 root) | | `ARG` | 定义构建参数,在镜像构建过程中可使用(不会出现在最终镜像中) | | `ONBUILD` | 设置触发器,在此镜像作为其他镜像的基础镜像时执行 | | `SHELL` | 更改默认 shell(例如使用`["bash", "-c"]`代替`sh`) | | `HEALTHCHECK` | 定义容器健康检查命令 | 2、假如我不知道dockerfile在哪?或者想在原先镜像的基础上进行迭代更新? 使用docker commit 提交 ### 4. docker镜像如何瘦身? - 减少镜像的分层:合并指令,删除中间构建产物 - 分段构建:前面的阶段用于构建/编译,后面的阶段仅拷贝运行所需内容 - 使用更小的基础镜像 ### 5. k8s如何做持久化存储? - pv:由管理员预先创建的集群级别的 **存储资源**,表示集群中已有的物理存储(如 NFS、iSCSI、Ceph、云盘等)。 - pvc:用户对存储的请求(类似 Pod 请求 CPU/内存一样,PVC 请求存储)。 - storageclass:提供 **动态存储供应(Dynamic Provisioning)** 的策略描述,是一种“存储类型模板”。 ### 6.k8s如何实现自动扩缩? **分为两层:pod/节点** 1、Horizontal Pod Autoscaler(HPA)横向 Pod 自动伸缩: * **作用**:根据 CPU 利用率、内存或自定义指标,自动增加或减少 **Pod 副本数**。 * **依赖组件**: * `metrics-server`:提供资源指标(如 CPU 使用率) * 可选接入 Prometheus + Adapter 获取自定义指标 * 监控 Pod 的资源指标 * 比较实际指标与目标值 * 调整 Deployment/ReplicaSet 的 replicas 数量 2、Vertical Pod Autoscaler(VPA)纵向 Pod 自动伸缩 * **作用**:根据历史和当前使用情况,自动推荐或调整 Pod 的 **CPU/内存请求值和限制值**。 * **适用场景**:适合工作负载变化大但副本数稳定的场景。 * **限制**:调整资源会导致 Pod 重启。 3、 Cluster Autoscaler(CA)集群自动伸缩(节点层级) * **作用**:当 Pod 无法调度(因资源不足),自动创建新节点;当节点资源空闲,自动回收节点。 * **适用场景**:运行在云平台(如 AWS/GCP/Azure)或具备自动创建节点能力的集群。 * **原理**: * 监控 Pending Pod 状态 * 评估是否需要新增节点 * 云厂商 API 动态调整节点组数量 ### 7. Kubernetes 中 Pod 之间如何通信? * Kubernetes 中,每个 Pod 会被分配唯一的 IP 地址,Pod 之间可以直接通过 IP 通信。 * Pod 跨节点通信依赖于网络插件(如 Calico、Flannel)实现 Overlay 网络,确保所有 Pod IP 互通。 * 通常使用 Service 资源提供稳定访问入口,通过 kube-proxy 实现负载均衡和转发。 * Pod 内部通过 DNS 解析 Service 名称,方便调用。 * 可以通过 NetworkPolicy 限制 Pod 之间的网络访问。 ### 8. k8s镜像拉取策略有哪些? pod镜像拉取策略可以通过imagePullPolicy字段配置镜像拉取策略,主要有3种镜像拉取策略,如下: - Always: 默认值,总是重新拉取,即每次创建pod都会重新从镜像仓库拉取一次镜像。 - IfNotPresent: 镜像在node节点宿主机上不存在时才拉取。(企业实际用的) - Never: 永远不会主动拉取镜像,仅使用本地镜像,需要你手动拉取镜像到node节点,如果本地节点不存在镜像则pod启动失败。 ### 9. k8s pod的存活探针有哪些? kubernetes可以通过存活探针检查容器是否还在运行,可以为pod中的每个容器单独定义存活探针,kubelet将定期执行探针,如果探测失败,将杀死容器,并根据restartPolicy策略来决定是否重启容器,kubernetes提供了3种探测容器的存活探针,如下: - httpGet:通过容器的ip、端口、路径发送http 请求,返回200-400范围内的状态码表示成功。(企业实际用的) - exec:在容器内执行shell命令,根据命令退出状态码是否为0进行判断,0表示健康,非0表示不健康。 - TCPSocket:与容器的ip、端口建立TCP Socket链接,能建立则说明探测成功,不能建立则说明探测失败。 #### 9.1 存活探针属性有哪些? - initialDelaySeconds:表示在容器启动后延时多久秒才开始探测; - periodSeconds:表示执行探测的频率,即间隔多少秒探测一次,默认间隔周期是10秒,最小1秒; - timeoutSeconds:表示探测超时时间,默认1秒,最小1秒,表示容器必须在超时时间范围内做出响应,否则视为本次探测失败; - successThreshold:表示最少连续探测成功多少次才被认定为成功,默认是1,对于liveness必须是1,最小值是1; - failureThreshold:表示连续探测失败多少次才被认定为失败,默认是3,连续3次失败,k8s 将根据pod重启策略对容器做出决定; > 注意:定义存活探针时,一定要设置initialDelaySeconds属性,该属性为初始延时,如果不设置,默认容器启动时探针就开始探测了,这样可能会存在应用程序还未启动就绪,就会导致探针检测失败,k8s就会根据pod重启策略杀掉容器然后再重新创建容器的莫名其妙的问题。在生产环境中,一定要定义一个存活探针。 ### 10. pod的就绪探针有哪几种? 我们知道,当一个pod启动后,就会立即加入service的endpoint ip列表中,并开始接收到客户端的链接请求,假若此时pod中的容器的业务进程还没有初始化完毕,那么这些客户端链接请求就会失败,为了解决这个问题,kubernetes提供了就绪探针来解决这个问题的。 在pod中的容器定义一个就绪探针,就绪探针周期性检查容器,如果就绪探针检查失败了,说明该pod还未准备就绪,不能接受客户端链接,则该pod将从endpoint列表中移除,被剔除了service就不会把请求分发给该pod,然后就绪探针继续检查,如果随后容器就绪,则再重新把pod加回endpoint列表。k8s提供了3种就绪探针,如下: - httpGet:通过容器的ip、容器的端口以及路径来发送http get请求,返回200-400范围内的状态码表示请求成功。 - exec:在容器内执行shell命令,它根据shell命令退出状态码是否为0进行判断,0表示健康,非0表示不健康。 - TCPSocket:通过容器的ip、端口建立TCP Socket链接,能正常建立链接,则说明探针成功,不能正常建立链接,则探针失败。 #### 10.1 就绪探针的属性参数有哪些 - initialDelaySeconds:延时秒数,即容器启动多少秒后才开始探测,不写默认容器启动就探测; - periodSeconds :执行探测的频率(秒),默认为10秒,最低值为1; - timeoutSeconds :超时时间,表示探测时在超时时间内必须得到响应,负责视为本次探测失败,默认为1秒,最小值为1; - failureThreshold :连续探测失败的次数,视为本次探测失败,默认为3次,最小值为1次; - successThreshold :连续探测成功的次数,视为本次探测成功,默认为1次,最小值为1次; ### 11. 就绪探针与存活探针区别是什么? > 两者作用不一样。 > 存活探针,是检测容器是否存活,如果检测失败,kubelet将调用容器运行时(如docker)将检查失败的容器杀死,创建新的启动容器来保持pod正常工作; > 就绪探针,是检测容器是否可以正常接收流量,当就绪探针检查失败,并不重启容器,而是将pod移出endpoint列表,就绪探针确保了service中的pod都是可用的,确保客户端只与正常的pod交互并且客户端永远不会知道系统存在问题。 ### 12. 简单讲一下 pod创建过程 > 比会的:不会就拉倒了~ > > 情况一、如果面试官问的是使用kubectl run命令创建的pod,可以这样说: > #注意:kubectl run 在旧版本中创建的是deployment,但在新的版本中创建的是pod则其创建过程不涉及deployment > 如果是单独的创建一个pod,则其创建过程是这样的: > 1、首先,用户通过kubectl或其他api客户端工具提交需要创建的pod信息给api-server; > 2、api-server验证客户端的用户权限信息,验证通过开始处理创建请求生成pod对象信息,并将信息存入etcd,然后返回确认信息给客户端; > 3、api-server开始反馈etcd中pod对象的变化,其他组件使用watch机制跟踪api-server上的变动; > 4、scheduler发现有新的pod对象要创建,开始调用内部算法机制为pod分配最佳的主机,并将结果信息更新至api-server; > 5、node节点上的kubelet通过watch机制跟踪api-server发现有pod调度到本节点,通过CRI容器运行时接口调用底层的docker启动容器,如果pod定义了pv,此时还会调用CSI容器存储接口分配存储,然后还会调用CNI容器网络接口给pod 分配IP,这样等等一系列的创建pod过程,并将创建成功的结果反馈api-server,然后kubelet就会根据pod定义的探针持续的对容器进行健康检查探测。 > 6、api-server将收到的pod状态信息存入etcd中。 > 至此,整个pod创建完毕。 > > 情况二、如果面试官说的是使用deployment来创建pod,则可以这样回答: > 1、首先,用户使用kubectl create命令或者kubectl apply命令提交了要创建一个deployment资源请求; > 2、api-server收到创建资源的请求后,会对客户端操作进行身份认证,在客户端的~/.kube文件夹下,已经设置好了相关的用户认证信息,这样api-server会知道是哪个用户请求,并对此用户进行鉴权,当api-server确定客户端的请求合法后,就会接受本次操作,并把相关的信息保存到etcd中,然后返回确认信息给客户端。(仅返回创建的信息并不是返回是否成功创建的结果) > 3、api-server开始反馈etcd中过程创建的对象的变化,其他组件使用watch机制跟踪api-server上的变动。 > 4、controller-manager组件会监听api-server的信息,controller-manager是有多个类型的,比如Deployment Controller, 它的作用就是负责监听Deployment,此时Deployment Controller发现有新的deployment要创建,那么它就会去创建一个ReplicaSet,一个ReplicaSet的产生,又被另一个叫做ReplicaSet Controller监听到了,紧接着它就会去分析ReplicaSet的语义,它了解到是要依照ReplicaSet的template去创建pod, 它一看这个pod并不存在,那么就新建此pod,当pod刚被创建时,它的nodeName属性值为空,代表着此pod未被调度。 > 5、接着调度器Scheduler组件开始介入工作,Scheduler也是通过watch机制跟踪api-server上的变动,发现有未调度的pod,则根据内部算法、节点资源情况,pod定义的亲和性反亲和性等等,调度器会综合的选出一批候选节点,在候选节点中选择一个最优的节点,然后将pod绑定到该节点,将信息反馈给api-server。 > 6、kubelet组件布署于Node之上,它也是通过watch机制跟踪api-server上的变动,监听到有一个pod应该要被调度到自身所在Node上来,kubelet首先判断本地是否在此pod,如果不存在,则会进入创建pod流程,创建pod有分为几种情况,第一种是容器不需要挂载外部存储,则相当于直接docker run把容器启动,但不会直接挂载docker网络,而是通过CNI调用网络插件配置容器网络,比如分配pod IP等,如果需要挂载外部存储,则还要调用CSI来挂载存储。kubelet创建完pod,将信息反馈给api-server,api-servier将pod信息写入etcd。 > 7、pod建立成功后,ReplicaSet Controller会对其持续进行关注,如果pod因意外或被我们手动退出,ReplicaSet Controller会知道,并创建新的pod,以保持replicas数量期望值。 > > 以上即是pod的调度过程。 ### 13. pod的调度策略有哪些?(重点) - pod 调度概述 > API Server 接受客户端提交Pod对象创建请求后的操作过程中,有一个重要的步骤就是由调度器程序 kube-scheduler 从当前集群中选择一个可用的最佳节点来接收并运行它,通常是默认的调度器 kube-scheduler 负责执行此类任务。 > > 对于每个待创建的Pod对象来说,调度过程通常分为两个阶段:`过滤 --> 打分`,过滤阶段用来过滤掉不符合调度规则的Node,打分阶段建立在过滤阶段之上,为每个符合调度的Node进行打分,分值越高则被调度到该Node的机率越大。 - 策略实现方式 > 1. nodeName(直接指定Node主机名) > 2. nodeSelector (节点选择器,为Node打上标签,然后Pod中通过nodeSelector选择打上标签的Node) > 3. 污点taint与容忍度tolerations > 4. NodeAffinity 节点亲和性 > 5. Pod Affinity Pod亲和性 > 6. Pod Anti-Affinity Pod反亲和性 > scheduler 的主要作用是将新创建的pod分配到合适的节点上。 > > scheduler决定每个pod应该运行到哪个节点上,以满足资源需求、策略约束和其它调度的要求。 > > 它的主要任务包括: - 资源分配:根据pod的资源需求(如CPU和内存),选择满足条件的节点。 > > - 负载均衡:将pod分布都不同的节点上,避免资源过度集中,保持集群的负载均衡。 > - 策略约束:遵循各种调度策略和约束条件,如节点亲和性/反亲和性、pod亲和性/反亲和性、污点和容忍度等 > - 性能优化:选择最优的节点以提升集群性能和资源利用率。 > - k8s scheduler 的实现原理 scheduler的实现原理主要包括以下几个步骤: > - (1)过滤节点 - 首先,scheduler会筛选出一组候选节点,这些节点能够满足pod的基本要求。 - 过滤条件节点的资源情况(如cpu和内存)、节点标签、污点和容忍度、pod亲和性和反亲和性等。 > - (2)打分节点 - 对通过过滤的候选节点进行打分,评估每个节点的优势。 - 打分根据多个调度策略进行计算,这些策略可以包括资源利用率、节点间均衡、节点亲和性等。 > - (3)选择节点 - 根据打分结果选择得分最高的节点,将pod调度到该节点上。 - 如果多个节点得分相同,scheduler会随机选择一个节点。 > - (4)绑定节点 - 最后,scheduler将pod绑定到选定的节点上。 - 通过向API Server发出绑定请求来实现这一操作。 ### 14. K8S的网络模式有哪些? `首先一个K8s的集群中至少有三个网络:` * `集群节点所在的网络`,这个网络就是你的主机所在的网络,通常情况下是你的网络基础设施提供。如果你的node处于不同的网段,那么你需要保证路由可达。 * `第二个网络是Pod的网络`, K8s中一个Pod由多个容器组成,但是一个pod只有一个IP地址,Pod找那个所有的容器共享同一个IP。这个IP启动pod时从一个IP池中分配的, 叫做 pod CIDR, 或者叫network\_cidr * `第三个网络是K8S服务网络`, service\_cluster\_ip\_range 代入问题: `k8s中的Container是如何互联互通的` `Pod 网络通信` * **Pod 内部容器互通** 容器共享同一网络命名空间,使用 `localhost` 互相访问 * **同一节点的 Pod 互通** 利用 Linux veth pair + 网桥实现二层通信 * **跨节点 Pod 通信** 依赖三层路由和 CNI 插件(如 Flannel、Weave、Calico)实现 * **外部访问 Pod** 通过 Service 的虚拟 IP + kube-proxy 的负载均衡转发到目标 Pod ### 15. k8s的数据持久化有哪些? > 三种持久化: > > - pv(Persistent Volume)集群存储资源池(如:云硬盘、NAS) > - PVC(Persistent Volume Claim):应用存储需求声明(如:需要100G高速SSD) > - StorageClass:存储供给策略模板(自动创建PV的配方) 持久化方案优缺: | 方案类型 | 适用场景 | 生产隐患 | 推荐指数 | | ---------------- | ------------------ | ----------------- | ---------- | | **云盘动态供给** | 云环境数据库主存储 | 跨AZ访问延迟 | ★★★★★ | | **本地PV** | 高性能日志处理 | 节点故障数据风险 | ★★★★☆ | | **NFS共享存储** | 多人协作场景 | 单点性能瓶颈 | ★★★☆☆ | | **Ceph RBD** | 混合云统一存储 | 运维复杂度高 | ★★★★☆ | | **HostPath** | 开发测试环境 | 不可跨节点调度 | ★★☆☆☆ | | **EmptyDir** | 临时计算缓存 | Pod删除数据即丢失 | ★☆☆☆☆ | 引入问题: 1. 你们是用的什么持久化存储? > NFS动态存储,POD的删除不会影响数据的存储。 > > 注:pv是集群级资源,pvc是名称空间级资源 PVC和PV的设计,类似“接口”和“实现”的思想,开发者只知道使用“接口”PVC,运维人员负责给“接口”绑定具体的实现PV,说白了PVC就是一种特殊的Volume存储卷 PVC和PV的实现原理 PVC:描述 Pod想要使用的持久化属性,比如存储大小、读写权限等 PV:描述一个具体的Volume属性,比如Volume的类型、挂载目录、远程存储服务器地址等。 ### 16. DaemonSet是什么? > DaemonSet会确保每个节点上都运行一个Pod,不需要手动指定副本数量。典型应用场景包括日志收集和节点监控等任务。 ### 17. k8s中pod如何实现动态扩缩容?(重点) - HPA:水平Pod自动扩缩容(重点) - VPA: 垂直Pod自动扩缩容 - Cluster Autoscaler: 集群自动扩缩容。 1.HPA 根据指标(如 CPU 使用率、内存使用率、自定义指标等)自动调整应用程序的 Pod 副本数量。) 使用场景:适用于需要根据工作负载动态增加或减少应用实例的场景。 * 自动检测周期由 `kube-controller-manager` 的 `--horizontal-pod-autoscaler-sync-period` 参数设置(默认间隔为 15 秒)。 * metrics-server 提供 [http://**metrics.k8s.io**](https://link.zhihu.com/?target=http%3A//metrics.k8s.io) API 为pod资源的使用提供支持。 * 15s/周期 -> 查询[http://**metrics.k8s.io**](https://link.zhihu.com/?target=http%3A//metrics.k8s.io) API -> 算法计算 -> 调用scale 调度 -> 特定的扩缩容策略执行。 2.VPA 自动调整单个 Pod 的资源请求和限制(如 CPU、内存),而不是 Pod 的数量。 使用场景:适用于工作负载不变但需要动态调整资源分配的应用,如长期运行的服务或数据库。 3.Cluster Autoscaler 根据集群中 Pod 的需求,自动增加或减少节点数。 使用场景:当集群资源不足以支持当前 Pod 的资源需求时,会自动增加节点;当资源利用率较低时,自动减少节点以节省成本。 ### 18. k8s说一下deployment,statefulset,daemonset的区别 - Deployment:Deployment是最常见的管理无状态应用的对象。它支持应用的扩展、更新和回滚。Deployment会自动维护一定数量的Pod副本,并确保在节点故障时自动替换失败的Pod。 - StatefulSet:StatefulSet用于管理有状态的应用,比如数据库。它保证了Pod的名称和网络标识的稳定性,以及Pod的创建、删除和更新的顺序性。这使得StatefulSet特别适合运行需要持久化存储和网络标识的应用。 - DaemonSet:DaemonSet确保在每个节点上都运行一个Pod副本,当有新节点加入集群时,DaemonSet会自动在新节点上创建Pod。这使得DaemonSet特别适合运行日志收集、监控等系统级服务。 ### 19. dockerfile中copy和add的区别? > 唯一区别:从远程or本地获取文件 - add :支持url获取,并且支持解压缩 - copy :只能从docker build所在的主机读取资源并复制到镜像中 ### 20. 描述一下deployment的升级过程 > 在deployment的定义中,可以通过spec.strategy指定pod的更新的策略,目前支持两种策略:Recreate(重建)和RollingUpdate(滚动更新),默认值是RollingUpdate。 - Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新pod时,会先杀掉所有正在运行的pod,然后创建新的pod。 - RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更新pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavaliable和maxSurge)来控制滚动更新的过程。 最后修改:2025 年 06 月 18 日 © 禁止转载 打赏 赞赏作者 支付宝微信 赞 11 如果觉得我的文章对你有用,请随意赞赏