k8s面试题
K8s 实习生专场面试题
一、基础理论类
- 请简要解释什么是 Kubernetes(K8s)?它的核心作用是什么?相比传统的虚拟机部署,K8s 有哪些优势?
- K8s 的核心组件有哪些?请分别说明 kube-apiserver、kube-controller-manager、kube-scheduler、etcd 和 kubelet 的主要功能。
- 什么是 Pod?Pod 在 K8s 中的地位是什么?一个 Pod 中可以包含多个容器,这些容器之间有哪些共享资源?
- 请区分 Deployment、StatefulSet 和 DaemonSet 这三种 K8s 控制器,说明它们各自的适用场景,并举例说明在什么情况下会选择使用其中一种而非另外两种。
- 什么是 Service?K8s 中 Service 有哪些类型?请分别解释 ClusterIP、NodePort、LoadBalancer 和 ExternalName 的作用及使用场景。
- 什么是 Namespace?它在 K8s 中的主要用途是什么?请举例说明如何通过 Namespace 实现资源隔离和权限控制。
- 请解释 ConfigMap 和 Secret 的区别,它们各自用于存储什么类型的数据?在使用 Secret 时,有哪些安全注意事项?
二、实践操作类
- 请写出创建一个名为 “my-nginx” 的 Deployment 的 yaml 文件,要求:使用 nginx:1.21 镜像,副本数为 2,为 Pod 添加标签 “app: nginx”,并为容器设置资源请求(requests)CPU 为 100m、内存为 128Mi,资源限制(limits)CPU 为 200m、内存为 256Mi。
- 如何查看名为 “my-nginx” 的 Deployment 下所有 Pod 的运行状态?如果某个 Pod 处于 “CrashLoopBackOff” 状态,你会通过哪些命令和步骤排查问题?
- 请写出将 “my-nginx” Deployment 的副本数从 2 调整为 3 的命令,以及查看调整后副本数变化过程的命令。
- 如何创建一个名为 “my-nginx-service” 的 Service,将流量转发到标签为 “app: nginx” 的 Pod 上,且只能在集群内部访问?创建后如何验证 Service 是否能正常访问 Pod?
- 假设需要将本地的一个名为 “app-config” 的配置文件(内容为数据库连接信息)挂载到 “my-nginx” Deployment 的 Pod 中,路径为 “/etc/config/app-config”,请说明具体的操作步骤(包括创建 ConfigMap 和修改 Deployment 的 yaml 文件)。
- 如何查看 K8s 集群中某个节点(例如 node-1)的资源使用情况(CPU、内存、磁盘等)?如果发现该节点 CPU 使用率过高,你会采取哪些措施进行优化?
三、进阶理解类
- 什么是 K8s 的自愈能力?K8s 是通过哪些机制实现自愈的?例如当 Pod 出现故障时,K8s 会如何处理?
- 请解释什么是滚动更新(Rolling Update)和回滚(Rollback)?在 K8s 中,如何通过 Deployment 实现滚动更新?如果更新后发现应用出现问题,如何快速回滚到上一个稳定版本?
- 什么是 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)?它们之间的关系是什么?请描述一个完整的流程:创建 PV、创建 PVC 绑定 PV,然后将 PVC 挂载到 Pod 中。
- 请简要说明 K8s 的网络模型,包括 Pod 之间的通信、Pod 与外部网络的通信是如何实现的?你是否了解常用的 K8s 网络插件(如 Calico、Flannel),它们的核心原理有何不同?
- 在 K8s 中,如何实现 Pod 的调度控制?除了默认的调度策略,你还了解哪些自定义调度方式(如节点亲和性、Pod 亲和性 / 反亲和性、污点和容忍度)?请举例说明节点亲和性的使用场景。
四、综合场景类
- 假设你需要在 K8s 集群中部署一个 Web 应用,该应用由前端(nginx)、后端(springboot)和数据库(mysql)三部分组成。请设计一个简单的部署方案,包括:需要创建哪些 K8s 资源(Deployment、Service、ConfigMap、Secret、PV/PVC 等),各资源之间的关联关系,以及如何保证应用的高可用性和数据持久性。
- 在 K8s 集群运维过程中,你发现某个 Deployment 的 Pod 频繁重启,查看日志发现是因为数据库连接超时。请列出可能导致该问题的原因(至少 3 点),并说明针对每个原因的排查和解决步骤。
- 如果你作为实习生,需要协助团队完成 K8s 集群的日常维护工作,你认为日常维护中需要重点关注哪些内容(如集群健康状态、资源使用情况、应用运行状态等)?可以使用哪些工具或命令来辅助维护工作?
K8s 实习生专场面试题详细解答
一、基础理论类解答
1. Kubernetes(K8s)定义、核心作用及优势
- 定义:Kubernetes(简称 K8s)是谷歌开源的一款容器编排平台,用于自动化容器的部署、扩展、运维(如故障恢复、滚动更新)等全生命周期管理,旨在实现容器化应用的高效、可靠运行。
- 核心作用:统一管理集群中的容器资源,解决 “容器如何有序部署、如何动态扩缩容、如何处理故障、如何实现跨节点通信” 等问题,让开发者无需关注底层基础设施,专注于应用本身。
- 相比传统虚拟机的优势:
- 资源利用率更高:容器共享宿主机操作系统内核,无需为每个应用分配独立操作系统,内存、CPU 开销远低于虚拟机(如一台宿主机可运行数十个容器,却只能运行少数几个虚拟机)。
- 部署启动更快:容器仅需启动应用进程,无需启动完整操作系统,启动时间通常在秒级(虚拟机需分钟级)。
- 可移植性更强:容器打包了应用及所有依赖(库、配置),可在 “开发环境→测试环境→生产环境” 或不同云厂商(AWS、阿里云、自建集群)间无缝迁移,避免 “在我这能跑,在你那跑不了” 的问题。
- 扩展更灵活:K8s 支持基于 CPU 使用率、请求量等指标自动扩缩容容器副本数,响应业务波动更敏捷。
2. K8s 核心组件及功能
K8s 集群分为控制平面(Control Plane) 和节点(Node) 两部分,核心组件如下:
组件名称 | 所属部分 | 主要功能 |
---|---|---|
kube-apiserver | 控制平面 | 集群的 “统一入口”,所有操作(如创建 Pod、查询 Service)都需通过 API Server 处理;同时负责权限校验、数据验证,是组件间通信的枢纽(如 Scheduler、Controller Manager 需通过它获取集群状态)。 |
kube-controller-manager | 控制平面 | 运行各类控制器进程,确保集群状态与 “期望状态” 一致:- 节点控制器(Node Controller):监控节点健康,节点故障时标记并处理;- 副本控制器(Replica Controller):确保 Deployment/RC 的 Pod 副本数达标;- 端点控制器(Endpoint Controller):维护 Service 与 Pod 的关联关系(Endpoint 对象)。 |
kube-scheduler | 控制平面 | 负责 “Pod 调度”:当用户创建 Pod 时,Scheduler 会分析集群节点的资源(CPU、内存)、亲和性 / 反亲和性、污点容忍度等条件,选择最优节点将 Pod 部署上去。 |
etcd | 控制平面 | 集群的 “数据库”,存储所有集群状态数据(如 Pod 配置、Service 规则、Namespace 信息),采用分布式架构保证高可用,仅与 API Server 交互(其他组件不直接操作 etcd)。 |
kubelet | 节点 | 运行在每个 Node 上的 “代理进程”,负责执行控制平面的指令:- 启动 / 停止 Pod 内的容器;- 监控容器健康状态,向 API Server 上报节点和 Pod 的状态(如 CPU 使用率、Pod 是否运行正常);- 确保容器挂载的存储、网络配置正确。 |
kube-proxy | 节点 | 运行在每个 Node 上的 “网络代理”,负责实现 Service 的网络功能:- 维护节点上的 iptables/ipvs 规则,将 Service 的请求转发到后端 Pod;- 实现 Service 的负载均衡(如轮询)和会话保持(部分场景)。 |
3. Pod 定义、地位及共享资源
- 定义:Pod 是 K8s 中最小的部署单元,不是容器,而是 “容器的集合”—— 一个 Pod 可包含 1 个或多个紧密关联的容器(如 “应用容器 + 日志收集容器”)。
- 地位:Pod 是 K8s 的 “原子操作单位”,所有资源(如 Service、Deployment)都围绕 Pod 展开,用户无法直接部署容器,只能通过 Pod 管理容器。
- 共享资源:同一 Pod 内的容器共享以下资源,实现紧密协作:
- 网络命名空间:共享同一个 IP 地址和端口空间,容器间可通过 “localhost+ 端口” 直接通信(如 Pod 内的应用容器可访问localhost:8080的日志容器)。
- 存储卷(Volume):Pod 内的所有容器可挂载同一个 Volume(如 EmptyDir、PVC),实现文件共享(如应用容器写入日志到 Volume,日志容器从 Volume 读取日志并上传)。
- 进程命名空间(可选):默认不共享,但可通过
shareProcessNamespace: true
配置,让容器间可见彼此的进程(如监控容器可查看应用容器的进程状态)。
4. Deployment、StatefulSet、DaemonSet 的区别与适用场景
三者均为 K8s 的 “控制器”,核心作用是管理 Pod,但适用场景差异显著:
控制器类型 | 核心特点 | 适用场景 | 示例 |
---|---|---|---|
Deployment | 1. 管理 “无状态应用”,Pod 无固定身份(名称、IP 会变);2. 支持滚动更新、回滚、扩缩容;3. Pod 删除后重建时,数据不会保留。 | 无状态服务(如 Web 应用、API 服务、前端静态页面)—— 这类应用不依赖本地数据,多个副本完全等价,可随意替换。 | 部署 Nginx 前端、SpringBoot 后端 API。 |
StatefulSet | 1. 管理 “有状态应用”,Pod 有固定身份(名称格式为<statefulset-name>-<ordinal> ,如 web-0、web-1;IP 可通过 Headless Service 固定);2. 支持有序部署(先启动 0,再启动 1)、有序删除(先删 1,再删 0);3. 可通过 PVC 模板为每个 Pod 分配独立存储,重建后数据不丢失。 | 有状态服务(如数据库、分布式中间件、缓存集群)—— 这类应用依赖固定身份(如主从复制需明确主节点名称)或独立数据(如每个 MySQL 实例有自己的数据库文件)。 | 部署 MySQL 主从集群、Elasticsearch 集群、Redis 集群。 |
DaemonSet | 1. 确保 “集群中所有(或指定)Node 上都运行一个相同的 Pod”;2. 新增 Node 时自动部署 Pod,删除 Node 时自动清理 Pod;3. Pod 通常与 Node 绑定,处理 Node 级别的任务。 | 节点级服务(如监控、日志收集、网络插件)—— 这类服务需要在每个 Node 上运行,为 Node 或 Pod 提供基础功能。 | 部署 Prometheus Node Exporter(监控节点资源)、Fluentd(收集节点日志)、Calico(节点网络插件)。 |
5. Service 定义、类型及作用
- 定义:Service 是 K8s 中用于 “暴露 Pod 网络访问” 的抽象对象,解决 Pod IP 动态变化(Pod 重建后 IP 改变)的问题 —— 通过固定的 Service IP 和端口,将流量转发到后端匹配标签的 Pod,实现 “Pod 不可变,但访问入口固定”。
- 类型及作用:
类型 核心作用 使用场景 ClusterIP 分配一个集群内部唯一的虚拟 IP(仅集群内可访问),将流量转发到后端 Pod。 集群内部服务间通信(如后端 API 服务仅需被前端 Web 服务访问,无需暴露到集群外)。 NodePort 在 ClusterIP 基础上,在每个 Node 上开放一个相同的 “节点端口”(范围 30000-32767),外部可通过 “Node IP:NodePort” 访问 Service。 测试环境中暴露服务(如开发人员通过本地电脑访问集群内的测试应用)。 LoadBalancer 在 NodePort 基础上,集成云厂商的负载均衡器(如阿里云 SLB、AWS ELB),外部流量先进入负载均衡器,再转发到 NodePort,自动实现负载均衡和高可用。 生产环境中暴露公网服务(如面向用户的 Web 应用、对外开放的 API)。 ExternalName 将 Service 映射到一个外部域名(如 externalName: db.example.com
),集群内访问该 Service 时,会自动解析为外部域名。集群内服务需要访问外部服务(如访问云厂商的托管数据库、第三方 API),通过 Service 统一管理外部地址,避免硬编码。
6. Namespace 定义及用途
- 定义:Namespace 是 K8s 中用于 “资源隔离” 的抽象对象,相当于集群内的 “虚拟子集群”,可将 Pod、Service、Deployment 等资源划分到不同 Namespace 中,实现 “同名资源不冲突、权限独立控制”。
- 主要用途:
- 资源隔离:不同 Namespace 的资源相互独立,如 “dev” Namespace 中的 “my-nginx” Deployment,与 “prod” Namespace 中的 “my-nginx” Deployment 无冲突,方便按环境(开发、测试、生产)或团队划分资源。
- 权限控制:通过 RBAC(基于角色的访问控制),可为不同 Namespace 分配不同权限(如开发人员仅能操作 “dev” Namespace 的资源,无法修改 “prod” Namespace 的资源),保障生产环境安全。
- 资源配额:可通过 ResourceQuota 为每个 Namespace 设置资源上限(如 “dev” Namespace 最多使用 20CPU、40Gi 内存),避免某个团队或环境过度占用集群资源。
- 示例:创建 “test” Namespace 后,在该 Namespace 下创建 Pod:
bash
# 创建Namespace kubectl create namespace test # 在test Namespace下创建nginx Pod kubectl run nginx --image=nginx:1.21 -n test # 查看test Namespace下的Pod kubectl get pods -n test
7. ConfigMap 与 Secret 的区别及 Secret 安全注意事项
-
区别:
维度 ConfigMap Secret 存储数据类型 非敏感配置数据(如数据库地址、端口号、应用配置参数) 敏感数据(如数据库密码、API 密钥、证书) 数据存储方式 明文存储(etcd 中以明文形式保存,可通过 kubectl get configmap -o yaml
查看)加密存储(etcd 中以 Base64 编码形式保存,虽非强加密,但可避免明文暴露;部分场景可结合 KMS 实现强加密) 适用场景 存储无需保密的配置(如 nginx 的配置文件、SpringBoot 的 application.properties) 存储需保密的信息(如 MySQL 的 root 密码、HTTPS 证书的私钥) -
Secret 安全注意事项:
- 避免直接查看 Secret 明文:通过
kubectl get secret <secret-name> -o yaml
查看时,数据是 Base64 编码,需避免将编码结果泄露(他人可通过echo <编码值> | base64 -d
解码获取明文)。 - 限制 Secret 的访问权限:通过 RBAC 规则,仅允许必要的 Pod 或用户访问 Secret(如仅让后端应用的 ServiceAccount 有权读取数据库密码 Secret),避免过度授权。
- 使用强加密存储:默认 Base64 编码仅为 “伪加密”,生产环境中建议结合 K8s 的 Secret 加密功能(如使用 etcd 加密存储、集成外部 KMS 服务如阿里云 KMS),确保 etcd 中存储的 Secret 是强加密的。
- 避免在 Pod 中以环境变量暴露 Secret:若将 Secret 挂载为环境变量,可通过
ps
命令查看进程的环境变量,存在泄露风险;建议以 Volume 挂载方式将 Secret 挂载为文件(如/etc/secrets/db-password
),并限制文件权限(如mode: 0600
,仅所有者可读写)。
- 避免直接查看 Secret 明文:通过
二、实践操作类解答
1. 创建 “my-nginx” Deployment 的 yaml 文件
yaml
# my-nginx-deployment.yaml
apiVersion: apps/v1 # Deployment的API版本(apps/v1为稳定版本)
kind: Deployment # 资源类型为Deployment
metadata:name: my-nginx # Deployment名称
spec:replicas: 2 # 副本数为2selector:matchLabels: # 选择器:匹配标签为app: nginx的Podapp: nginxtemplate:metadata:labels: # 为Pod添加标签app: nginxapp: nginxspec:containers:- name: nginx # 容器名称image: nginx:1.21 # 使用nginx:1.21镜像resources:requests: # 资源请求(集群分配资源的最低要求)cpu: 100m # CPU请求100毫核(1核=1000毫核)memory: 128Mi # 内存请求128兆字节limits: # 资源限制(容器最多可使用的资源)cpu: 200m # CPU限制200毫核memory: 256Mi # 内存限制256兆字节
创建命令:kubectl apply -f my-nginx-deployment.yaml
2. 查看 Pod 状态及排查 “CrashLoopBackOff” 问题
(1)查看 “my-nginx” Deployment 下的 Pod 状态
bash
# 方式1:通过Deployment名称关联的标签查询(推荐,精准匹配)
kubectl get pods -l app=nginx # -l 表示按标签筛选,app=nginx是Pod的标签# 方式2:直接查看所有Pod,通过名称筛选(适用于知道Pod名称前缀的场景)
kubectl get pods | grep my-nginx # my-nginx的Pod名称前缀为my-nginx-xxxx-xxxx
输出示例(正常状态):
plaintext
NAME READY STATUS RESTARTS AGE
my-nginx-7f98d7c6b4-2xqzk 1/1 Running 0 5m
my-nginx-7f98d7c6b4-8k7p3 1/1 Running 0 5m
(2)排查 “CrashLoopBackOff” 状态的步骤
“CrashLoopBackOff” 表示 Pod 反复启动后崩溃,通常是容器启动命令错误、配置错误、资源不足等原因,排查步骤如下:
-
查看 Pod 详细事件:获取 Pod 启动过程中的错误信息(如 “容器启动失败”“资源不足被驱逐”):
bash
kubectl describe pod <pod-name> # 替换<pod-name>为故障Pod的名称,如my-nginx-7f98d7c6b4-2xqzk
重点查看 “Events” 部分,例如:
- 若出现 “Failed to start container: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "wrong-cmd": executable file not found in $PATH”,说明容器启动命令错误。
- 若出现 “Insufficient cpu: 100m requested, 0 available”,说明节点 CPU 资源不足,无法满足 Pod 的资源请求。
-
查看容器日志:若容器曾短暂启动(如启动后因配置错误崩溃),可查看日志定位应用层面的问题:
bash
# 查看当前日志(若容器已停止,需加--previous查看上一次启动的日志) kubectl logs <pod-name> # 查看上一次启动的日志(适用于容器已崩溃停止的场景) kubectl logs <pod-name> --previous
例如:若日志显示 “Error: Could not find config file /etc/nginx/nginx.conf”,说明 nginx 配置文件挂载错误或缺失。
-
检查资源限制与节点资源:若 Pod 因资源不足崩溃,查看节点资源使用情况:
bash
# 查看所有节点的资源使用情况 kubectl top node # 查看故障Pod的资源请求/限制是否合理 kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resources}'
若节点 CPU / 内存使用率已达 100%,需清理节点上的无用 Pod,或为集群添加新节点。
-
验证容器镜像和启动命令:检查镜像是否存在、启动命令是否正确:
bash
# 查看Pod的容器配置(镜像、启动命令等) kubectl get pod <pod-name> -o yaml | grep -A 10 "containers:"
例如:若镜像名拼写错误(如
nginx:1.211
而非nginx:1.21
),需修正 Deployment 的镜像配置后重新部署。
3. 调整 Deployment 副本数及查看变化过程
(1)调整副本数从 2 到 3 的命令
- 命令行方式(快速调整,无需修改 yaml 文件):
bash
kubectl scale deployment my-nginx --replicas=3
- yaml 文件方式(适用于需要保存配置的场景):修改
my-nginx-deployment.yaml
中的replicas: 2
为replicas: 3
,然后执行:bash
kubectl apply -f my