Skip to content

DevOps 面试题

本页只放 DevOps 面试标准回答、项目话术、追问点和知识点跳转。Docker、Nginx、Jenkins、Kubernetes、发布、回滚、排障的详细原理统一放到知识点页、DevOps 从零到精通验收清单DevOps 商业场景训练营

使用方式

mermaid
flowchart TD
    A["面试页:标准回答"] --> B["知识点页:交付链路原理"]
    B --> C["训练营:商业发布和排障"]

高频问题

面试题标准回答原理知识点
DevOps 是什么DevOps 是把开发、测试、构建、部署、运行、监控和反馈连接起来的工程实践,目标是让软件交付可重复、可追踪、可回滚、可观测,减少环境差异和人工操作风险。从零到生产级掌握
代码到上线全过程怎么走开发提交代码到 Git 后,CI 流水线拉取代码,执行编译、测试、打包,生成 jar 或 dist,再构建 Docker 镜像并推送镜像仓库。部署阶段更新 Kubernetes Deployment,Pod 拉取镜像启动,通过 readinessProbe 后加入 Service,最终由 Ingress 或 Nginx 对外暴露。上线后通过日志、指标和链路追踪观察错误率、延迟和业务指标。从零到精通验收清单
构建和部署有什么区别构建是把源码变成可运行产物,例如 jar、dist、镜像;部署是把产物放到目标环境运行,并接入流量。构建失败多是代码、依赖、测试问题;部署失败多是镜像、配置、权限、网络、资源或健康检查问题。从零到生产级掌握
Docker 镜像和容器区别镜像是只读模板,容器是镜像运行后的进程实例。一个镜像可以启动多个容器,容器删除后内部非持久化数据会丢失。Docker 入门
hello-world运行成功能证明什么它大致证明CLI连接daemon、Registry拉取、本地镜像存储、containerd/OCI runtime创建进程和stdout日志链路可用;不能证明端口发布、Docker DNS、Volume、资源限制、Compose和业务镜像都正常。第一次运行实验
EXPOSE和-p有什么区别EXPOSE只是镜像元数据,声明应用预期监听的容器端口,不自动开放宿主机端口;-p才配置宿主机地址和端口到容器端口的发布。即使映射存在,也仍需确认应用监听、网络和健康状态。端口映射完整路径
stop后文件为什么还在,rm后为什么没了stop只停止主进程,容器对象和可写层仍在,start同一容器时文件还在;rm会删除容器元数据和可写层,新run得到新可写层。跨容器数据应放Volume或外部存储,但Volume不是备份。可写层生命周期实验
Docker 和虚拟机区别虚拟机虚拟完整操作系统,隔离强但资源重、启动慢;Docker 容器共享宿主机内核,通过 namespace 和 cgroup 做隔离和资源限制,启动快、交付轻,但不是完整虚拟机。Docker 入门
Docker安装了哪些核心组件Docker CLI调用Engine API,dockerd管理镜像、容器、网络和Volume,containerd管理任务与镜像内容,shim维持任务和IO,runc根据OCI配置创建进程;Buildx负责高级构建,Compose插件将多服务项目转换为Engine对象。安装组件原理
为什么docker组近似root权限docker组成员能访问rootful daemon的Unix Socket,可以创建高权限容器、挂载宿主机目录和设备,因此通常可间接获得宿主机高权限。不能把socket设为所有用户可写,也不能挂给普通业务容器。Docker Socket权限
rootless Docker解决什么问题rootless让daemon和容器以普通宿主机用户运行,通过User Namespace降低漏洞直接获得宿主机root的风险;但低端口、网络、cgroup、存储驱动、设备和监控存在兼容边界,也不解决镜像漏洞和Secret泄露。Rootless原理
hello-world成功能证明什么它大致证明CLI连接daemon、Registry拉取、containerd/runc创建进程和stdout链路可用,但不能证明端口发布、网络DNS、Volume、日志轮转、cgroup限制、Compose和升级行为,生产还需分层验收。安装后分层验证
修改daemon.json后怎么安全生效先保存旧配置、docker info、运行对象并检查systemd ExecStart,用JSON解析和目标版本dockerd validate校验,排除flags重复;生产先摘流金丝雀节点,重启后看status与journal,再验证Root Dir、日志、Registry、网络、Volume、新容器和业务,失败恢复旧配置且不删除数据目录。daemon配置与安全变更
daemon-reload和restart有什么区别daemon-reload只让systemd重新读取unit和drop-in,不会重启dockerd或加载daemon.json;restart才会重启dockerd并重新读取daemon配置。只改daemon.json通常校验后restart,改了systemd drop-in才需要先daemon-reload。配置加载与systemd
为什么修改Docker默认日志配置后旧容器没变化daemon默认日志驱动和选项在创建容器时写入HostConfig,旧容器restart仍沿用原配置,通常需要受控重建。还要检查应用是否写容器内普通文件,那部分不受Docker日志驱动轮转控制。日志驱动与轮转
修改data-root后容器为什么都不见了dockerd从当前data-root加载镜像、容器和Volume元数据。切到新空目录后看到的是空视图,旧数据不一定被删。应停止扩散、核对旧新路径并按迁移或配置回滚恢复,不能prune或删除旧目录。data-root原理
live-restore能保证Docker重启无影响吗不能。它只在部分daemon不可用场景尽量保持容器进程运行,CLI管理、新容器、网络变更、日志和插件仍可能受影响,也不保证所有跨版本升级无缝,生产仍需摘流、演练和回滚。live-restore边界
Docker Engine升级为什么做金丝雀升级可能影响API、containerd/runc、storage driver、网络、日志和容器管理。应先在测试环境验证,备份配置和业务数据,摘流一个节点升级,验证完整链路后再分批扩散;live-restore不等于完全无影响。Engine升级流程
Docker容器底层原理是什么容器本质是宿主机进程。namespace隔离PID、Mount、Network等视图,cgroup限制和统计CPU、内存、PID和IO,OverlayFS合并镜像只读层与容器可写层,Capabilities和seccomp限制权限。Docker通过containerd、shim和OCI runtime创建进程,所以容器共享宿主机内核。Docker容器运行底层原理
docker run背后发生什么CLI调用Engine API,daemon解析镜像和配置,缺失时拉取镜像层,准备rootfs、容器可写层、Volume、网络和端口,再生成OCI配置。containerd通过shim调用runc创建namespace、cgroup并执行Entrypoint,主进程退出后容器进入Exited。docker run全过程
docker stop、kill、restart有什么区别stop先发送停止信号并等待宽限期,超时才强杀;kill默认通常直接SIGKILL,也可指定信号;restart停止再启动同一容器,不会自动使用新镜像重建,也不会必然加载Compose的新环境、端口和挂载。生产优先优雅stop,配置或镜像变化走受控重建。容器生命周期命令
docker exec和attach有什么区别exec在运行容器已有namespace和cgroup中创建额外进程,常用于诊断;attach连接主进程已有标准输入输出,不创建新Shell,按键和信号可能影响主进程。容器退出后不能exec,但仍可能inspect和logs。top、exec与attach
docker save/load和export/import有什么区别save/load面向镜像,保留镜像层和配置;export导出容器rootfs快照,import得到扁平化镜像,不保留原分层和完整运行配置,也不包含Volume。镜像迁移优先Registry或save/load,数据库使用一致性备份。镜像与容器导入导出
删除容器、镜像、Volume分别影响什么rm容器删除容器元数据和可写层,普通命名卷与镜像默认保留;image rm删除本地镜像引用和无引用层;volume rm直接删除卷数据。删除前必须检查状态、Mounts、引用、业务归属和备份,不能用无条件批量命令替代判断。安全删除流程
namespace和cgroup区别namespace解决“进程能看到什么”,如PID、网络、挂载和hostname;cgroup解决“进程能使用多少、已经用了多少”,如CPU quota、memory max和pids max。两者分别解决隔离视图和资源治理。namespacecgroup
Docker镜像分层和容器可写层是什么镜像层只读并可共享,运行容器时增加可写层,OverlayFS把它们合成统一rootfs。修改下层文件会Copy-on-Write到上层,删除通过whiteout隐藏;删除容器会删除可写层,Volume不随普通容器删除。OverlayFS与Copy-on-Write
容器PID 1有什么特殊性容器主进程通常是PID 1,需要接收停止信号并回收孤儿子进程。Shell form可能让sh成为PID 1且不正确转发SIGTERM,导致stop超时后SIGKILL。应优先exec form或脚本最后exec,复杂子进程场景可评估init。PID 1原理
Dockerfile怎么写才适合生产使用可追踪的基础镜像版本或摘要,多阶段构建分离编译和运行环境,按变化频率排列步骤并用.dockerignore控制上下文;应用使用固定UID的非root用户和Exec form入口;密钥不进入ARG、ENV、上下文或镜像层;记录commit,扫描漏洞,并验证JDK容器内存、健康检查和优雅停机。Dockerfile生产验收
Spring Boot容器化启动全过程CI将源码编译测试并打成Jar,镜像固化JRE、Jar和入口;Docker创建namespace、cgroup、网络和挂载并启动JVM,SpringApplication准备Environment、刷新IOC和启动内嵌Tomcat,readiness通过后接流量;停止时SIGTERM到JVM并执行优雅停机。Spring Boot容器化运行
为什么Xmx不能等于容器内存限制容器限制覆盖整个cgroup,除Heap外还有Metaspace、Direct Memory、线程栈、Code Cache、GC/JIT native结构、Agent和子进程。Xmx等于限制会使Heap外无预算,即使没有Java Heap OOM也可能被cgroup OOM Kill。容器内存预算
JDK 8运行在容器中要注意什么必须记录具体8u更新和发行版。早期版本可能按宿主机资源估算Heap、GC线程和CPU,后续版本或厂商回移了容器支持。要在目标镜像内检查java version、PrintFlagsFinal、Heap和availableProcessors,不能无条件复制旧参数。JDK 8容器感知
Spring Boot容器如何优雅停机使用Exec form让JVM成为PID 1,开启Spring graceful shutdown并设置阶段超时;平台先摘流再发SIGTERM,等待在途请求并关闭线程池、连接池和消费者。宽限期不足后的SIGKILL没有清理机会,长任务还要可中断、幂等和可恢复。优雅停机全过程
docker build背后发生什么构建器读取Dockerfile和过滤后的构建上下文,解析基础镜像与步骤依赖,按指令、父结果和输入内容判断缓存;RUNCOPY等形成内容寻址文件层,ENVUSERENTRYPOINTCMD等形成镜像配置,最后组装镜像清单并保存或推送。Dockerfile构建原理
CMD和ENTRYPOINT有什么区别ENTRYPOINT定义固定入口,CMD提供默认命令或默认参数。运行时追加参数通常替换CMD而保留ENTRYPOINT,--entrypoint才覆盖入口。生产通常使用Exec form,让参数边界明确且信号直接到应用进程。最终命令合并
为什么Dockerfile顺序影响缓存后续步骤依赖前一步结果。过早COPY . .会让任意源码或临时文件变化导致后续缓存失效;先复制依赖描述并下载依赖,再复制源码,业务改动时可以复用稳定依赖层。镜像层与缓存
多阶段构建解决什么问题编译阶段保留Maven、JDK和源码,运行阶段只复制Jar等必要产物,因此最终镜像不含编译工具和源码,能减小体积和攻击面。但凭据、构建缓存、日志和供应链可信仍要单独治理。多阶段构建
为什么不能在一层复制密钥再在下一层删除镜像层不可变,后续删除只是在上层隐藏文件,下层内容仍可能从镜像历史或缓存恢复。密钥必须从一开始就不进入普通上下文和层,构建时使用BuildKit Secret Mount,运行时使用Secret系统或受控挂载。密钥边界
Docker Compose工作原理是什么Compose读取配置文件,完成变量插值、文件合并和校验,生成services、networks、volumes等项目模型,再通过Docker Engine API创建或更新对象并按依赖启动。容器最终仍由daemon、containerd和OCI runtime运行,Compose不是新的容器运行时。Compose工作原理
compose up、start、restart有什么区别up按当前模型创建或重建资源;start只启动已有停止容器;restart重启已有容器,通常不会把新环境、端口和挂载配置重新创建进去。配置变化后应先看config,再执行up -d并inspect最终容器。Compose生命周期
depends_on为什么不能保证数据库可用短语法主要控制启动顺序,容器进程启动不等于数据库初始化完成。可结合healthcheck和service_healthy改善初始启动,但运行中还会重启和网络抖动,所以应用必须有连接超时、有限重试、退避、熔断和降级。依赖与健康原理
Compose的.env和env_file有什么区别项目.env主要用于Compose解析${VAR}时的插值;service的env_file用于向指定容器注入环境变量。存在于.env不等于自动进入容器,应先看docker compose config,再看容器inspect中的实际Env。变量两条链路
为什么不建议固定container_nameCompose通过项目名、服务名和序号隔离实例,服务名还用于网络DNS。固定container_name容易跨项目冲突并阻碍服务扩展多个副本,调用方应依赖服务名而不是具体容器名或IP。Project与Service
Docker Compose适合生产吗Compose适合开发、测试、CI临时环境和可接受单机故障域的小规模部署。普通Compose主要协调单Docker Engine,不提供完整跨节点调度、滚动发布、自愈和集群存储编排;高可用微服务通常使用Kubernetes等平台,但任何平台仍需备份、监控和回滚。Compose生产边界
Docker怎么查看容器信息先用 docker ps -a 定位容器和状态,再用 docker inspect 查看 State、退出码、OOMKilled、启动时间、镜像ID、Entrypoint/Cmd、端口、网络、挂载、资源限制、健康和重启策略。运行中再用 statstopexec,退出后结合 logs、events 和历史监控还原现场。Docker容器信息与生产诊断
docker inspect主要看什么.State 看运行、退出、PID、OOMKilled和健康;.Config 看环境、命令和标签;.HostConfig 看端口、资源、日志驱动和重启策略;.NetworkSettings 看网络和IP;.Mounts 看最终挂载;.Image 看实际镜像内容ID。inspect字段模型
容器Exit 137一定是OOM吗不一定。137通常表示SIGKILL,可能来自OOM Killer、手工kill或stop超时强杀。应结合 OOMKilled、Docker events、宿主机内核日志和监控判断;即使OOMKilled,也只是容器总内存超限,不等于Java Heap泄漏。Java容器OOM案例
docker logs为什么看不到日志docker logs 读取日志驱动接收的stdout/stderr。应用如果只写容器内文件,Docker不会自动读取;要检查应用日志配置和挂载,生产应统一采集并配置日志轮转。容器日志来源
Docker容器访问不了怎么排查先确认DNS、refused、timeout、TLS还是HTTP错误,再用ps -a和inspect判断容器状态。未运行时查ExitCode、OOMKilled、logs和events;Running时按宿主机端口、发布规则、容器IP、应用监听逐层验证。容器间调用再查共同网络、服务名DNS、TCP和应用协议。Docker访问故障Runbook
容器反复Restarting怎么排查保存RestartCount、StartedAt/FinishedAt、ExitCode、OOMKilled、重启策略、时间戳日志和events,确认主进程为何退出。常见原因包括Entrypoint、配置、权限、依赖、OOM以及脚本后台启动后PID 1退出;重启策略只会重复启动,不能修复根因。Restarting排查
Running为什么不等于服务正常Running只表示容器主进程存在。应用可能仍在启动、只监听127.0.0.1、Full GC、线程池耗尽、健康检查失败或依赖不可用;还要看Health、真实入口请求、错误率、P99和业务成功率。Running故障分支
Docker磁盘满怎么排查先用df -hdf -i区分容量与inode,再确认Docker Root Dir,用docker system df -v区分镜像、可写层、Volume和构建缓存;检查日志驱动、Dump和deleted-open文件。不能直接全局prune,应先确认对象归属、备份和恢复。Docker磁盘排查
容器已经删除后还能怎么排查inspect、当前stats和进程现场已经丢失,只能依赖集中日志、历史指标、APM、daemon和内核日志、Docker events外部采集、发布记录、镜像Digest、审计记录和持久Volume。这也是生产必须提前建设外部可观测性的原因。三种现场状态
Docker bridge网络的数据包怎么走Docker为容器创建独立Network Namespace和eth0,eth0通过veth pair连接宿主机Linux bridge。同网段容器由bridge按MAC转发;访问外网时再经过宿主机路由和SNAT;外部访问发布端口时经过宿主机DNAT转发到容器IP和端口。Docker bridge网络原理
容器里的localhost为什么访问不到另一个容器每个容器有独立Network Namespace,localhost只指当前容器自己的loopback。容器间应加入同一自定义网络,通过服务名或网络别名访问目标容器端口,不应硬编码会变化的容器IP。容器localhost原理
EXPOSE和-p有什么区别EXPOSE只是镜像元数据,声明预期监听端口,不会创建宿主机转发;-p 宿主机端口:容器端口才发布端口并建立转发规则。应用自身还必须监听容器网络可达地址,通常是0.0.0.0端口发布原理
host网络模式有什么优缺点host模式共享宿主机Network Namespace,省去bridge和部分NAT路径,但容器没有独立网络隔离,直接占用宿主机端口,容易冲突且安全边界变弱,不应作为端口配置错误的通用修复。网络模式比较
Volume和Bind Mount怎么选Named Volume由Docker管理位置和生命周期,适合数据库等持久数据;Bind Mount绑定明确宿主机路径,适合配置和开发目录,但与宿主机目录、权限和SELinux耦合。两者都可能遮住容器目标路径原有内容。Volume和Bind Mount区别
为什么挂载后镜像中的文件不见了挂载在容器进程启动前覆盖rootfs同一路径,镜像文件仍在下层,只是在容器合并视图中被挂载点遮住。尤其是空Bind目录,不会自动复制镜像内默认文件。挂载覆盖原理
Docker Volume是不是备份不是。Volume只让数据生命周期独立于容器,通常仍在单台宿主机;磁盘损坏、误删、down -vvolume prune都可能导致丢失。真正备份还需要独立副本、保留策略、校验和恢复演练。Volume与备份边界
为什么不能直接复制运行中MySQL数据目录MySQL写入时数据页、redo log和元数据可能处于不同时间点,直接复制可能得到逻辑上不一致、无法恢复的文件集合。应使用逻辑备份、数据库物理热备工具或数据库配合的存储快照,并验证恢复。数据库备份原理
MySQL官方镜像首次启动做什么Entrypoint检查数据目录。空目录时校验MYSQL_*变量,初始化系统表和数据字典,启动临时mysqld,创建root、默认库和业务用户,执行initdb脚本,再停止临时服务并exec正式mysqld;已有数据目录则跳过初始化逻辑。MySQL首次初始化
为什么修改MYSQL_ROOT_PASSWORD不生效该变量只用于空数据目录首次初始化。密码写入MySQL系统表后,后续挂同一Volume时Entrypoint检测到已初始化并跳过账号创建。应通过ALTER USER受控轮换并同步Secret和连接池,不能删除生产卷。初始化变量边界
MySQL容器为什么会OOM容器限制覆盖整个mysqld,除Buffer Pool还有Performance Schema、表缓存、连接线程栈、sort/join/read Buffer、临时表和插件内存。Buffer Pool过大、连接数高和重SQL并发会共同突破cgroup限制,应统一预算并压测。MySQL容器内存
MySQL镜像升级为什么不能直接切回旧Tag新版本可能升级数据字典、系统表和磁盘格式,旧mysqld未必支持读取升级后的同一目录。数据库回退依赖升级前一致性备份、快照或未升级副本,并处理升级期间增量;镜像回滚不等于数据降级。MySQL容器升级
Redis的maxmemory为什么不能等于容器内存maxmemory主要约束Redis数据及淘汰边界,进程RSS还包括内存分配器碎片、客户端与复制Buffer、AOF Buffer、Module和线程栈;RDB/AOF后台任务fork后,写入还可能触发Copy-on-Write复制内存页。两者设成相等会没有峰值余量,容易被cgroup OOM Kill。maxmemory与RSS
Redis容器怎样安全提供服务优先只放进应用内部网络,不发布宿主机6379;调试端口只绑定127.0.0.1。保持protected mode,Redis 6+用ACL拆分应用、健康和运维权限,密码通过Secret注入,外部链路再结合TLS、防火墙和安全组。Redis容器网络与ACL
Redis的RDB/AOF为什么需要VolumeRDB和AOF通常写入/data,容器删除会丢失可写层,Volume让持久化文件生命周期独立于容器。但Volume仍可能因宿主机损坏、误删和down -v丢失,所以它不是备份,还必须做独立副本、校验和恢复演练。Redis持久化与Volume
Redis持久化为什么会产生内存峰值和延迟BGSAVE和AOF rewrite通常先fork;fork要复制页表并可能暂停主线程,之后父进程继续写会触发Copy-on-Write,额外占用物理页,子进程还竞争CPU和磁盘IO。数据越大、写入越密集,峰值和抖动越明显。RDB与fork/COW
Redis容器配置restart为什么不等于高可用restart只在同一Docker Engine上重新启动进程,解决不了宿主机、Volume和网络故障,也没有数据副本与自动选主。主从、哨兵、Cluster分别解决副本、故障转移和分片问题,并且节点必须跨故障域部署。Redis部署形态边界
Redis容器重启后数据丢失怎么排查先inspect确认旧、新容器的/data最终Mounts,再查Compose项目名变化、是否执行down -v、RDB/AOF及dir配置、启动加载日志、持久化错误、权限和磁盘。先保留Volume与文件现场,在隔离环境恢复,不能直接删除疑似损坏文件。Redis数据丢失排查
Nginx容器为什么使用daemon off容器生命周期由PID 1决定。官方入口最终以前台方式启动Nginx,使master成为主进程,Docker才能正确观察状态并发送停止信号;若Nginx自行转后台而入口退出,容器会被判定结束。Nginx镜像启动链
Nginx容器配置修改后为什么没生效可能改错源文件、挂载目标错误、空目录遮住镜像配置、include覆盖或没有reload。应inspect Mounts,在容器内用nginx -T确认合并结果、nginx -t校验,再reload并从真实入口验证。配置挂载与生效
容器里的Nginx为什么不能用localhost代理另一个容器每个容器有独立Network Namespace,localhost只指当前Nginx容器。后端应与Nginx加入共同网络并使用Compose服务名和容器端口,例如app:8080;容器IP重建会变化,不能写死。容器反向代理与Docker DNS
Nginx reload、Docker restart和recreate区别reload由master校验新配置、启动新worker并让旧worker处理完连接后退出;restart停止再启动同一容器,会中断进程且不采用新镜像;镜像、端口、环境或挂载变化需要按当前模型recreate。三种生效方式
Nginx容器出现502和504怎么查502多是DNS、端口、协议、连接拒绝或上游提前关闭;504是连接或读取上游超时,常关联慢SQL、线程池/连接池和下游。先看error log,再按端口发布、监听、Docker DNS、TCP、应用和依赖逐跳验证。Nginx容器排障Runbook
Nginx为什么能支持高并发Nginx使用多进程加事件驱动模型。Master管理配置、监听资源、信号和Worker生命周期;Worker把大量非阻塞socket注册到epoll,只在可读、可写、建连完成或超时时推进连接状态机,避免每连接一个线程的栈和切换成本。但阻塞模块、TLS、压缩和慢磁盘仍可能卡住Worker。Nginx事件驱动原理
epoll返回的是完整请求吗不是。epoll返回FD就绪事件,例如socket当前可读或可写;Worker随后执行非阻塞read/write,可能只得到部分请求头或发送部分响应,因此还要保存解析位置、Buffer、上游阶段和超时等连接状态。epoll与连接状态机
worker_processes乘worker_connections就是最大QPS吗不是。它至多近似连接槽位的一部分,还受FD、内存和系统限制;代理请求同时占客户端和上游连接,keep-alive、WebSocket和文件也占FD。QPS还由请求耗时、CPU、网络和后端容量决定。连接与FD容量
Nginx reload为什么通常不中断请求Master校验新配置后创建新Worker接新连接,再通知旧Worker停止accept并处理完已有请求后退出;配置无效时保留旧Worker。WebSocket、长下载可能让旧Worker长期存在,因此仍要观察Worker代际和最长连接。平滑reload原理
异步非阻塞是否表示Nginx永远不会阻塞不是。socket主路径使用非阻塞事件模型,但第三方模块、同步调用、磁盘抖动、复杂正则、脚本、gzip和TLS等仍可能长时间占用Worker;一个Worker被卡住会拖慢它管理的许多连接。Worker阻塞边界
Nginx怎样选择server和location先按本地IP和端口确定listen组,TLS阶段结合SNI,读取Host后按精确、通配符和正则规则选server,未匹配进入default server。URI规范化后精确location优先;否则找最长前缀,^~可跳过同级正则,否则按顺序取第一个匹配正则,正则不匹配才使用最长前缀。虚拟主机与location算法
root和alias有什么区别root通常把完整规范化URI追加到根目录;alias用目标目录替换匹配的location前缀。目录型alias尾部斜杠、正则捕获、父目录执行权限和SELinux是高频错误点,应推导最终文件绝对路径后排查。root与alias
proxy_pass带不带斜杠有什么区别本质是是否带URI部分。普通前缀location中,不带URI通常传递当前请求URI;带URI时用它替换匹配的location前缀。正则、命名location、变量和rewrite组合规则更复杂,必须用上游日志验证最终路径。proxy_pass路径矩阵
rewrite last和break有什么区别last修改URI后重新进行location匹配,可能进入新规则;break停止当前rewrite指令集,通常继续当前location后续处理。简单外部跳转优先return,复杂rewrite必须证明不会形成内部重定向循环。rewrite执行循环
nginx -t通过是否代表发布安全不代表。它主要验证语法、上下文和部分引用资源可加载,不证明upstream、DNS、业务路由、TLS客户端兼容和容量。还需执行Host/URI/Header路由矩阵、金丝雀、外部验证和指标观察。配置发布流程
Nginx轮询、least_conn和ip_hash怎么选无状态且请求成本接近时用加权轮询;请求时长差异大可评估least_conn,但连接少不等于CPU低;ip_hash只提供弱粘滞,NAT会倾斜、节点变化会重映射,不能代替共享Session。缓存分片可评估consistent hash,但要治理热Key。负载均衡算法
max_fails和fail_timeout是主动健康检查吗不是。开源Nginx通常根据真实代理请求中的连接错误、超时和配置的失败响应做被动判断;达到阈值后暂时跳过节点再尝试恢复。check interval常来自第三方模块,标准商业主动健康属于NGINX Plus等能力。被动与主动健康
Nginx重试为什么可能重复下单第一个后端可能已提交数据库,但响应返回前连接断开;Nginx看到失败后把POST重试到第二节点,就可能重复执行。非幂等请求应谨慎重试,订单支付必须有幂等Key、唯一约束、状态机、去重和补偿。非幂等重试风险
upstream keepalive 32是什么意思通常表示每个Worker为该upstream缓存最多32条空闲连接,不是总连接数、并发数或所有Worker共享32条。活跃连接可额外存在,多Worker会放大空闲连接,后端FD和超时仍需规划。upstream连接复用
为什么扩Nginx或应用实例后系统反而更慢扩容提高了进入共享依赖的并发,总数据库连接、慢SQL、热点锁、Redis热Key和重试量可能放大;瓶颈转移到DB后P99和504继续上升。必须做入口到数据库的端到端容量分析。扩容后的新瓶颈
Nginx rate、burst和nodelay分别是什么rate定义每个Key长期平均速率;burst定义可容纳的超额请求数量,默认超额请求按rate延迟,超过burst拒绝;nodelay让burst内超额立即放行,但仍记录速率债务,后续突发空间要随时间恢复,不是永久增加额度。limit_req时间线
burst是不是每秒额外放行数量不是。burst是当前可容纳的超额状态上限,不按自然秒重置。默认形成延迟整形,nodelay时立即放行但占用突发空间;超过burst仍拒绝,恢复速度由rate和经过时间决定。burst原理
limit_req多个Worker和多个Nginx实例是否共享同一Master下Worker通过共享zone共用Key状态,不会每Worker各一份;不同主机或Pod的zone不共享,三实例各10r/s可能形成约30r/s总额度。全局额度要统一网关或Redis等共享状态。单机与多实例边界
limit_conn限制的是TCP连接数吗不完全是。HTTP模块通常在请求Header完整读取并进入处理后计数,不覆盖所有TCP连接;HTTP/2/3的并发stream可能分别计数。SYN洪峰、慢Header和系统连接上限还需防火墙、超时和内核层治理。limit_conn计数边界
为什么不能直接按X-Forwarded-For限流XFF是客户端可伪造Header。只有请求来自明确可信LB/CDN网段时,才能由realip模块还原地址;否则攻击者轮换伪造值既能绕过额度,也能制造高基数Key耗尽zone。真实IP信任链
Nginx本地限流和Redis全局限流怎么选Nginx共享zone性能高且依赖少,适合单入口本地保底,但多实例不共享;Redis/Lua可做用户或租户全局额度,但增加网络、热Key和故障语义。常用分层是Nginx粗限流保护节点,统一网关/Redis做可信用户全局配额。全局限流方案
request_time和upstream_response_time有什么区别request_time覆盖Nginx观察到的整个请求生命周期,可能含客户端上传、限流等待、多次upstream和向慢客户端发送;upstream_response_time描述每次上游响应阶段。前者明显更大时要查客户端、排队、重试和响应发送。Nginx分段耗时
Nginx 499是什么499表示客户端在Nginx完成响应前关闭连接,可能是用户取消、网络断开、上层LB/SDK超时或后端太慢。它不是纯客户端责任,要与upstream耗时、客户端超时和重试时间线一起分析。499原因链
为什么最终200仍要监控upstream_status首节点可能502或超时,Nginx重试次节点后成功,最终status是200;upstream地址、状态和耗时会记录多次尝试。只监控最终5xx会掩盖坏节点、重试流量和额外延迟。多次upstream日志
proxy_cache的keys_zone存响应Body吗不存全部Body。keys_zone主要保存缓存Key和元数据索引,Header/Body通常在磁盘文件中;重启后Loader分批扫描磁盘重建索引,Manager按inactive和max_size等清理。Nginx缓存结构
proxy_cache_lock解决什么同一Key MISS或过期时减少并发回源,通常让一个请求填充,其他请求等待或按超时/stale策略处理。它只保护当前缓存实例,多台Nginx仍可能各自回源,锁等待过长也会增加客户端延迟。缓存击穿与锁
stale缓存有什么风险stale在upstream错误、超时或更新时返回过期内容,提高可用性但牺牲新鲜度。适合公开展示,不适合余额、权限、库存承诺和支付状态,必须由业务SLA定义允许的陈旧窗口。stale边界
proxy_cache_bypass和proxy_no_cache区别bypass决定当前请求是否跳过读取缓存,no_cache决定当前上游响应是否写入缓存。个性化请求常需两者同时设置,避免回源后把私人响应写入共享缓存。缓存读写跳过
Jenkins Controller、Agent和Executor区别Controller保存配置、调度Queue、管理凭据、插件和Pipeline状态;Agent是真正执行命令的运行环境;Executor是Node可同时占用的构建槽位,不等于CPU核。Executor过多会让多个Build的JVM、Docker和磁盘IO竞争。Jenkins执行模型
Jenkins任务为什么一直排队先看Queue Item原因,常见是Label无匹配Node、Agent离线、Executor占满、禁止并发、Lock/Throttle等待、Quiet Period或Controller压力。不能只重启,应结合Node、Executor和上一个Build定位。Queue排查
Jenkins workspace@2是什么同一Job在同一Node并发时,Jenkins可能创建workspace、workspace@2隔离文件目录。脚本不能硬编码绝对路径;即使目录隔离,Maven缓存、Docker daemon、固定端口和部署环境仍可能冲突。Workspace并发
Workspace、stash和artifact区别Workspace是Node临时目录;stash用于同一Pipeline跨Node传相对小文件;archive关联Build记录;正式Jar和镜像应进入Nexus/Registry。生产应一次构建,多环境推广同一不可变制品。构建文件生命周期
Jenkins运行JDK和业务编译JDK必须一样吗不必。现代Jenkins进程使用当前LTS支持的现代Java,业务可通过Tool、Maven Toolchains、容器或不同Label Agent使用JDK 7/8/17/21编译。必须固定具体版本并验证Maven、TLS和插件兼容。Jenkins与JDK版本
Jenkins Pipeline CPS是什么Jenkins把大部分Pipeline Groovy转换为Continuation-Passing Style,保存下一步动作、变量和Flow状态,让sh、input、node等异步Step可暂停并在Controller重启后恢复。状态需可序列化,因此Stream、Iterator等不能跨暂停点长期持有。Pipeline CPS原理
@NonCPS什么时候使用用于短小、纯内存且不调用Pipeline Step的普通Groovy计算。它不能在内部调用sh、node、echo、input等Step,也不能从方法中间恢复。序列化错误应先简化对象,不能给整段流水线盲目加@NonCPS。NonCPS边界
Jenkins input为什么可能占Executor如果在已分配顶层或Stage Agent的范围里等待input,可能长期占着Executor和Workspace。应使用顶层agent none,把审批放独立Stage并加timeout,批准后再申请生产Agent。input与Agent
timeout和retry能保证部署安全吗不能。timeout中断Step但不会撤销已提交事务、消息和远程副作用;retry重新执行闭包,不知道上一次执行到哪。部署必须幂等,重试只覆盖安全步骤,并保存旧版本和显式回滚验证。timeout与retry
parallel为什么会互相影响并行分支同时消耗Executor、CPU、IO和测试资源;同Workspace写文件会覆盖,即使目录分开也可能共享Maven缓存、Docker daemon、固定端口和数据库。应使用独立Agent/目录、唯一资源名和清理。并行资源隔离
Pipeline如何做到一次构建多环境发布固定Commit只构建一次Jar或镜像,推送制品仓库并记录Digest;测试、预发、生产都推广同一Digest,审批只决定是否推广,不重新编译。失败时基于已记录旧版本显式回滚并验证。一次构建多环境推广
为什么生产要一次构建多环境推广同一Commit重复构建可能因依赖、基础镜像Tag、时间戳和工具环境产生不同制品。应构建一次并记录Digest,测试、预发、生产推广同一不可变内容,审批的是已验证Digest,不是会继续移动的分支名。不可变制品推广
数据库变更怎样支持代码回滚使用Expand→Migrate→Contract:先新增兼容结构;发布兼容新旧代码并双写/回填/校验;所有版本不再依赖旧结构后,在后续独立发布删除。先删列会让旧代码回滚后直接SQL失败。数据库兼容发布
滚动、蓝绿和金丝雀有什么区别滚动分批替换,资源省但新旧并存要求兼容;蓝绿保留两套应用并切流,回切快但数据库和消息仍共享;金丝雀按小比例放量,用版本指标控制风险,但依赖稳定分流、最小样本和自动停止。发布策略对比
健康检查通过为什么不等于发布成功readiness只证明实例准备接流量,固定200更只证明Handler存活。还要外部冒烟、核心业务状态验证,并观察按版本拆分的5xx、P99、线程池、数据库和下单/支付/采集等业务指标。健康与业务指标
为什么回滚镜像不能解决所有发布事故镜像回退不会自动回退配置、数据库Schema、新格式数据、MQ消息、缓存和外部副作用。必须确认旧代码兼容当前状态,回切后处理消息、库存、支付和污染数据,必要时选择前滚修复。多对象回滚
什么时候应该前滚而不是回滚数据库或消息格式已经难以逆转、旧版本不兼容当前数据,而问题能用小改动快速修复时可前滚。但仍需最小测试、灰度、指标闸门和审计,不能以紧急为由跳过控制。前滚修复判断
Nginx 做什么Nginx 常用于反向代理、静态资源、入口负载均衡、HTTPS 终止、限流、缓存和真实 IP 透传。它适合入口层横切能力,不适合写复杂业务逻辑。Nginx 总览
Nginx 502 和 504 区别502 通常表示网关拿不到正常后端响应,例如后端不可达、端口不通、连接失败;504 通常表示网关等待后端响应超时。排查时 502 先看 upstream、端口和后端存活,504 重点看后端耗时、超时配置和依赖慢。Nginx 总览商业场景训练营
Jenkins Pipeline 做什么Jenkins Pipeline 把拉代码、测试、打包、构建镜像、推送镜像、部署和健康检查写成可审计流水线。它不是只点发布按钮,而是让发布过程自动化、可追踪、可回滚。Jenkins Pipeline
Jenkins 凭据怎么处理密码、Token、私钥应放 Jenkins Credentials 或密钥系统中,通过凭据绑定注入流水线,不能明文写在 Jenkinsfile 或日志里。Jenkins Pipeline
Shared Library中vars、src、resources有什么区别vars暴露Pipeline全局变量,call可像函数调用;src按包结构进入类路径,适合领域类和纯逻辑测试;resources保存随库版本发布的文本模板或短脚本,通过libraryResource读取,不能保存Secret。目录结构与执行边界
@Librarylibrary Step有什么区别@Library在Jenkinsfile编译和CPS转换前加载,因此可以静态导入src类;library Step在运行阶段动态加载,此时脚本已经编译,通常只能通过动态接口使用新加载内容。动态版本参数必须使用白名单。编译期加载 · 运行期加载
Trusted Library为什么危险Trusted Library能绕过Groovy Sandbox并使用Jenkins内部能力,能修改该库的人可能接近Jenkins管理员权限。必须采用受保护仓库、强制评审、不可变版本、最小Trusted代码、隔离Agent和审计。Trusted Library原理与威胁
为什么生产Shared Library不能跟随mainmain是可变引用,即使项目代码没有变化,共享库提交变化也会改变Pipeline行为,导致构建不可复现并扩大故障半径。项目应固定不可变Tag或Commit,记录实际SHA并分批升级。版本漂移原理
Shared Library怎样避免Shell注入对仓库、Tag、Digest和相对路径做整串白名单,拒绝路径穿越、控制字符和绝对路径;避免Groovy双引号直接拼接Shell命令,使用受控环境变量或参数数组,并隔离不可信PR与生产凭据。注入原理 · 安全Demo
Shared Library怎样测试和发布纯逻辑使用JUnit或Spock,Pipeline分支使用模拟工具,CPS、Sandbox和插件行为使用Test Harness或临时Jenkins,最后通过少量项目金丝雀。发布不可变语义版本,由自动PR分批升级,失败时固定回旧版本并处理已发生的外部副作用。测试金字塔 · 发布流程
Kubernetes 为什么需要 ServicePod重建后UID和IP会变化。Service提供稳定DNS、ClusterIP和端口;EndpointSlice按Selector维护后端Pod IP和Ready条件,节点数据面转发新连接。没有Service,调用方要自行发现动态Pod并实现连接级负载。Service与EndpointSlice原理
Deployment、ReplicaSet、Pod 关系Deployment管理发布策略和ReplicaSet;每个ReplicaSet对应一个Pod Template版本并维持该版本副本;Pod是最终调度单位。模板变化时Deployment创建新ReplicaSet并滚动扩新缩旧,而不是原地修改Pod。K8s工作负载控制链
startup、readiness和liveness区别startup保护慢启动并在成功前门控其他探针;readiness控制Pod是否进入正常Service Endpoint,失败不重启;liveness失败达阈值由kubelet重启该容器,通常不迁移Pod。共享数据库不应加入Liveness,否则依赖抖动会制造集体重启。K8s探针状态机
ConfigMap 和 Secret 区别ConfigMap保存非敏感配置;Secret表达密码、Token和证书等敏感小数据,但Base64不是加密。生产还需TLS、etcd静态加密/KMS、RBAC、节点与应用安全、审计和外部密钥系统,并明确env快照与Volume投射更新的差异。K8s配置、Secret与轮换
PVC已经Bound为什么Pod还挂载失败Bound只证明PVC绑定PV;Pod调度后,块盘还要Attach到Node、NodeStage准备文件系统、NodePublish挂到Pod路径并处理权限。应查Pod Event、VolumeAttachment、PV拓扑和CSI Controller/Node日志,而不是重复删除PVC。K8s存储全过程
Helm atomic为什么不是事务atomic会在Install失败时卸载或Upgrade失败时尝试回滚Kubernetes清单,但无法撤销数据库迁移、Hook已调用的外部API、消息、CRD变更和应用已写数据,自动回滚本身也可能失败。生产仍需兼容迁移、幂等和补偿。Helm发布与回滚边界
发布失败怎么处理先停止继续放量,确认失败发生在构建、镜像推送、部署、启动、健康检查还是流量入口。再看流水线日志、镜像标签、K8s events、Pod logs 和探针状态。若已影响生产,优先回滚到上一稳定版本,同时保留现场证据再分析根因。商业场景训练营
服务访问不了怎么排查先锁定客户端和请求层:验证DNS,检查Service port/targetPort和Selector、EndpointSlice地址/Ready、Pod真实监听,再比较PodIP与ClusterIP;只有跨节点失败查CNI/路由/MTU,有Endpoint仍失败查Policy和数据面,Service成功而Ingress失败再进入七层入口。K8s网络排查流程
发布后接口变慢怎么排查先看新旧版本流量占比、错误率和 P99,再看 Pod CPU/内存/GC、应用线程池、DB、Redis、MQ 和外部接口。还要检查配置、连接池、JVM 参数和镜像环境是否变化。必要时先回滚。商业场景训练营K8s 可观测性
为什么灰度和回滚不能只靠代码回滚依赖镜像、配置、数据库结构、消息格式、前端资源都兼容。很多事故不能回滚不是因为没有旧代码,而是数据库变更不可逆、配置已变、消息格式不兼容。商业场景训练营

项目话术

text
在医疗数据采集与资产平台里,DevOps 不只是发布脚本。采集服务、资产服务、搜索同步、MQ 消费者、网关都要有独立镜像和配置,发布前要跑测试和构建镜像,发布时通过 Kubernetes 滚动更新,readiness 通过后才接流量。发布后重点观察采集成功率、失败批次、MQ 堆积、ES 同步延迟、接口 P99 和错误率。如果新版本异常,先停止放量或回滚,再根据 traceId、日志、指标和 K8s events 定位原因。

常见追问

追问回答方向跳转
为什么不能用 latest 镜像latest 不可追踪,回滚和复现困难。Dockerfile
为什么容器内不要写大量本地日志容器磁盘可能打满,日志应输出到 stdout 并由日志系统采集。Docker 排障
为什么不建议直接使用privilegedprivileged会赋予几乎所有Capabilities并放宽设备和安全限制,显著扩大容器控制宿主机的能力。应定位真实所需目录权限、设备或单个Capability,按最小权限配置。容器安全边界
Running为什么不等于服务健康Running只表示容器主进程存在,应用可能Full GC、线程池耗尽或依赖异常;还要看health、接口成功率、延迟和业务探针。健康检查与假存活
为什么 Service 有 Endpoint 仍访问失败Endpoint只说明发现到地址、端口和状态,不证明应用真实监听和业务可用。还要检查targetPort、TCP/UDP、监听地址、源Egress与目标Ingress Policy、kube-proxy/eBPF规则、CNI跨节点路径、MTU、Conntrack和应用依赖。有Endpoint后的分层排查
Ingress返回404/502/503/504怎么排查先用正确Host和SNI绕过DNS测试入口,确认响应来自Controller还是应用;404查Class/Host/Path/Rewrite,502查端口、协议和连接重置,503查Ready Endpoint和入口主动拒绝,504查连接/响应分段超时,并关联Controller日志、EndpointSlice、应用日志和Trace。Ingress七层故障证据链
为什么发布前要关注数据库兼容代码可以回滚,但不兼容的表结构和数据迁移可能无法简单回滚。商业场景训练营

怎么判断 DevOps 是否真正学懂

验收问题合格回答方向深度知识点
为什么不能只上传 jar 发布要讲出环境漂移、制品不可追踪、配置不可审计、回滚困难。从零到精通验收清单
为什么镜像 tag 不能只用 latest要讲出不可复现、不可审计、无法精确回滚。从零到精通验收清单
容器为什么不是虚拟机要讲出共享宿主机内核、namespace、cgroup、镜像层。从零到精通验收清单
502 和 504 怎么排查要按 Nginx 日志、upstream、端口、后端耗时、依赖慢逐层查。从零到精通验收清单
Pod Ready 但服务访问失败怎么查要看 Service endpoints、端口、协议、Ingress、NetworkPolicy、应用依赖。K8s 架构从零到精通验收清单
为什么回滚不只是代码问题要讲镜像、配置、数据库、MQ 消息格式、前端资源都要兼容。商业场景训练营

面试回答模板

text
DevOps 我会按“代码如何变成线上服务”回答:代码提交后进入 CI,完成编译、测试、打包,构建 Docker 镜像并推送镜像仓库;CD 阶段更新 Kubernetes Deployment,Pod 启动后通过 readinessProbe 接入 Service,再由 Ingress 或 Nginx 对外提供访问。上线后要通过日志、指标、链路追踪和业务指标观察,如果错误率、P99 或核心业务指标异常,就停止发布或回滚。排查问题时按入口、Service、Pod、容器、应用、依赖、资源逐层定位。

本章小结

DevOps 面试不能只背命令。好的回答要讲清交付链路、工具边界、发布风险、回滚条件和排查顺序。详细原理和 Demo 回到对应知识点页学习。