ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Linux高级运维面试宝典拆解:Nginx调优、负载均衡与K8s实战

2026/9/17 17:15:23 拓冰建站 浏览量
Linux高级运维面试宝典拆解:Nginx调优、负载均衡与K8s实战 简介面向具备一定Linux与中间件基础、正在备战中高级运维岗位的IT技术人员这份面试宝典围绕Nginx、Docker、Kubernetes及常见中间件展开系统梳理Web服务优化、负载均衡、TCP/IP协议、K8s核心组件与调度原理、Prometheus监控、MySQL主从与GTID、Redis同步、Kafka/RabbitMQ对比等高频考点并穿插shell脚本参数、iptables规则、Zabbix自定义监控等实用技能既能查漏补缺也可作为面试答题思路速查手册。资源为单个PDF文档大小2.78MB便于离线查阅。目前已有78位学习者下载。文档中包含大量Nginx配置示例、K8s工作流程说明与组件原理图解建议结合实践环境动手验证从而真正理解配置背后的原理与设计取舍。1. 一份《Linux高级运维面试宝典》为什么值得逐行拆一份号称《Linux高级运维面试宝典》的PDF被很多候选人当成题库背结果面试官把“gzip压缩”追问一句“gzip_buffers 4 64k 到底分配了几块内存”就卡住了。真正能发挥作用的宝典不是题目清单而是把Nginx优化、负载均衡、TCP/IP、Docker、K8s这些点连成一张网让你能解释配置背后的取舍。这篇拆解围绕这份PDF里的高频考点展开重点落在可以直接复现的配置、参数验证和常见坑上适合准备中高级运维岗位或者正在做架构选型的人。2. Nginx性能调优的四个高频考点从gzip到limit_reqNginx在面试中的占比最高但很多人只背结论比如“开gzip”“加expires”却解释不了参数之间的权衡。这一章把PDF中的Nginx优化题整理成几个可以动手验证的小节每节都给出配置和验证方法避免只会说“优化”不会调参。2.1 隐藏版本号和进程身份安全面第一问隐藏版本号通常放在nginx.conf的http块里配合修改worker进程的用户和组一起说。先看基础配置# nginx.conf 核心片段 user nginx; # worker进程使用 nginx 用户运行 worker_processes auto; # 自动匹配CPU核数 server_tokens off; # 隐藏版本号user指令控制worker进程的属主和属组权限过大是生产环境最常见的安全隐患。server_tokens off 会让错误页和Server响应头不再携带Nginx版本号修改后执行nginx -t nginx -s reload验证配置再用curl -I http://127.0.0.1/查看Server头。如果看到“Server: nginx”而不是“Server: nginx/1.24.0”说明生效。源码安装时server_tokens的默认行为会和发行版包安装不同所以线上环境以实际版本为准。2.2 expires缓存与日志切割静态资源的常规操作静态资源优化是Nginx面试的基础题expires和access_log配合是常见做法。# 图片类静态资源缓存30天 location ~* \.(jpg|jpeg|gif|png|swf)$ { expires 30d; access_log off; }expires 30d 给这些文件加上Cache-Control: max-age2592000和Expires头让浏览器在30天内直接读本地缓存。access_log off 避免图片类请求刷爆访问日志因为图片量通常远大于HTML页面。日志切割方面Nginx本身没有内置轮转机制生产环境一般交给logrotate/usr/local/nginx/logs/access.log { daily rotate 30 compress delaycompress missingok notifempty sharedscripts postrotate [ -f /usr/local/nginx/logs/nginx.pid ] kill -USR1 cat /usr/local/nginx/logs/nginx.pid endscript }logrotate按天切割保留30份旧的压缩存储。postrotate里的kill -USR1信号让nginx重新打开日志文件不需要重启进程。如果只mv日志文件不通知nginxnginx会继续往已删除的inode里写数据磁盘空间不会被释放。2.3 Gzip压缩参数先看配置再看原理gzip压缩是Nginx优化里必问的题目但关键在参数含义。gzip on; # 开启gzip gzip_buffers 4 64k; # 压缩结果流缓存4块64k gzip_http_version 1.1; # 仅对HTTP/1.1及以上生效 gzip_min_length 1k; # 小于1k不压缩 gzip_vary on; # 输出 Vary: Accept-Encoding gzip_comp_level 5; # 压缩级别 gzip_types text/plain text/css application/json application/javascript;各参数的作用如下表参数作用注意点gzip on开启压缩输出默认offgzip_buffers 4 64k申请4个64k的内存作为压缩结果流缓存按需分配不是一次性占满256kgzip_min_length字节数低于该值不压缩太小的响应压缩收益低反而浪费CPUgzip_http_version指定HTTP协议版本默认1.1老客户端为1.0时可能不压缩gzip_vary on让缓存服务器区分压缩版本配合CDN时建议开启gzip_comp_level1-9压缩级别5是速度和体积的折中“gzip_buffers 4 64k”容易误解成总缓冲48k实际是压缩结果流缓存最多使用4个64k的bufferNginx在压缩过程中按段写入超过64k时申请下一个64k。面试官如果问哪些内容不要压缩可以回答jpeg、png、mp4等本身已经压缩过的格式再压一遍收益很小还会增加CPU开销。2.4 防盗链valid_referers和rewrite的配合防盗链的原理是检查Referer字段来源域名不在白名单就重写或拒绝。location ~* \.(jpg|gif|swf)$ { valid_referers none blocked *.benet.com benet.com; if ($invalid_referer) { rewrite ^/ http://www.benet.com/error.png; } }valid_referers各字段含义值含义noneReferer为空比如直接浏览器地址栏访问图片blockedReferer存在但不以http://或https://开头*.benet.com匹配该域名及其子域名的来源当来源不在白名单时$invalid_referer为1执行rewrite跳转到错误图片。这里要提醒if rewrite在Nginx里是“邪恶指令”可以把请求重写走但不要把业务逻辑写在if里。更稳妥的方式是把rewrite换成return 403直接拒绝盗链请求减少流量消耗。如果希望记录盗链来源可以在if里加上access_log /var/log/nginx/hotlink.log;方便后续封禁。2.5 limit_req限流rate、burst、nodelay的真实关系限流是Nginx面试的进阶题。首先在http块定义区域limit_req_zone $binary_remote_addr zoneone:10m rate1r/s;然后在server或location下应用location ~* \.html$ { limit_req zoneone burst5 nodelay; proxy_pass http://backend_tomcat; }$binary_remote_addr是客户端的二进制IP地址zoneone:10m表示名为one的共享内存区域占10MB用来记录每个IP的请求状态。rate1r/s表示平均每秒只允许1个请求。burst5表示允许瞬时多排5个请求nodelay表示排队的请求不延迟、立即处理如果没有nodelay超出rate的请求会排队等待超过burst则直接返回503。真正起限流作用的是rate和burstnodelay只改变排队请求的处理时机。生产环境建议加limit_req_status 429;让超限请求返回429便于区分限流和服务错误。3. 负载均衡面试LVS调度算法与Nginx upstream选型负载均衡是高级运维面试的分水岭。面试官通常会从四层和七层的区别开始问然后深入到调度算法。这一章把PDF中的LVS十种算法和Nginx upstream策略整理成容易记忆的模型不要求背全但要知道每个算法解决什么问题。3.1 四层和七层到底差在哪四层负载均衡工作在OSI模型的传输层只能根据IP和端口转发七层负载均衡工作在应用层可以基于URL、Header、Cookie等应用层信息做决策。四层只看到“有一个TCP连接从10.0.0.1:12345到10.0.0.100:80”七层还能看到“这个请求是GET /api/userUser-Agent是Chrome”。维度四层负载均衡七层负载均衡工作层级传输层应用层典型实现LVSNginx、HAProxy决策依据IP 端口URL、Header、Cookie连接关系客户端与后端一条连接客户端与代理、代理与后端两条连接优点性能高、吞吐大灵活可以做路由和改写缺点无法按内容分发CPU开销更大吞吐受应用层处理影响注意连接关系四层负载均衡转发的是同一个TCP连接所以LVS的DR模式下响应流量可以不经过调度器直接回给客户端七层负载均衡必须维护两层连接Nginx作为反向代理时客户端连接和后端连接是独立的这也解释了为什么Nginx代理高流量时CPU消耗比LVS高。3.2 LVS十种调度算法的面试回答方式LVS的调度算法不需要全背但最好能说出常用算法的取舍。下表覆盖了PDF中的十种算法算法核心逻辑适用场景RR按顺序循环分发后端处理能力接近WRR按权重比例分发后端性能差异明显LC新请求分配给当前连接数最少的服务器长连接服务WLC连接数与权重做除法选结果小的最常用的默认算法LBLC按目标IP绑定最近使用的服务器Cache集群LBLCR目标IP映射到一组服务器再按LC选择动态Cache集群DH按目标IP做散列会话保持SH按源IP做散列会话保持SED(当前连接数1)/权重取最小避免性能好的服务器被忽略NQ有空闲连接直接分配否则用SED需要快速响应的场景SED算法的计算过程是面试中容易卡住的地方。假设A、B、C三台机器权重分别是1、2、3新请求进来时SED计算为A(11)/12B(12)/21.5C(13)/31.33于是优先给C。因为C权重高期望延迟低。NQ则更简单只要有一台机器当前连接数为0就不做计算直接分配过去。3.3 Nginx upstream六种调度方式Nginx的upstream模块提供了负载均衡配置入口调度方式写在upstream块内。upstream web_cluster { least_conn; server 10.0.1.10:8080 weight2 max_fails2 fail_timeout30s; server 10.0.1.11:8080 weight1 max_fails2 fail_timeout30s; } server { listen 80; location / { proxy_pass http://web_cluster; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }默认不写调度方式就是RR轮询weight控制权重权重越高被分配到的概率越大least_conn是当前连接数少的优先ip_hash保证同一客户端IP固定访问一台后端url_hash按请求的URL做哈希hash关键字则支持自定义键比如hash $arg_sessionid;。ip_hash用于会话保持但因为同一IP总有固定后端如果那台机器宕机这部分用户会失败不能完全替代服务端Session同步。url_hash常用于缓存类场景让同一个资源定向到同一台后端提升缓存命中率。注意在upstream里写ip_hash;之后weight设置会被忽略两者不能同时生效。3.4 健康检查的坑端口检测和URL检测Nginx原生的健康检查是“被动”的通过max_fails和fail_timeout判断只有请求转发失败才把后端标记为不可用。upstream backend { server 192.168.1.10:8080 max_fails2 fail_timeout10s; server 192.168.1.11:8080 max_fails2 fail_timeout10s; }max_fails2表示在fail_timeout时间内失败2次就暂时摘掉该节点fail_timeout10s表示10秒后重新试探。但这种方式的问题在于如果出现上传大文件时后端故障Nginx已经在上传过程中无法把这次连接切到另一台服务器只能断掉。要主动检测后端是否可用需要借助nginx_upstream_check_module第三方模块或者用Nginx Plus的商业功能。Nginx原版健康检查只能检测端口不能像HAProxy那样指定URL来检测这也是面试中Nginx和HAProxy对比的常见考点。LVS也有类似限制它对网络稳定性依赖大不能使用正则表达式处理请求内容因此动静分离这类需求通常不会用LVS解决而是交给Nginx或HAProxy。4. Nginx进程模型、HTTP链接处理与location匹配规则Nginx的进程模型和location匹配规则是区分“用过Nginx”和“理解Nginx”的试金石。这一章按“进程怎么跑、请求怎么进、配置怎么配”的顺序拆每一步都可以在实际环境中验证。4.1 Master和Worker各干什么Master进程负责读取和评估配置、维持worker进程的状态worker进程才是真正处理请求的人。这种分离设计让Nginx可以在不中断服务的情况下reload配置。执行kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)后Master重新加载配置并启动新的worker旧worker处理完现有连接后退出。日常查看ps -ef | grep nginx # root 1234 1 0 ... nginx: master process # nginx 1235 1234 0 ... nginx: worker processworker_processes建议设置为auto或者CPU核心数worker_connections决定单个worker能同时打开的最大连接数。常用配置worker_processes auto; events { worker_connections 10240; }在Linux 2.6以上内核中Nginx的worker可以复用连接不需要像Apache那样每个连接一个进程这是Nginx支撑高并发的底层原因。4.2 HTTP请求从三次握手到响应的完整链路面试官问“Nginx如何处理HTTP请求”要按阶段回答。首先客户端三次握手建立TCP连接内核把建立的连接放入监听队列Nginx的事件模型把连接分发给某个空闲worker。worker收到新连接后分配一个512字节的连接内存池然后初始化http模块。如果客户端在client_header_timeout指令设置的时间内没有发送完整请求头连接会被判定超时并关闭之后才进入请求头校验、URI解析、location匹配、转发或静态文件处理。最后写入响应记录access log并根据keepalive配置决定连接是关闭还是复用。对应配置keepalive_timeout 65; client_header_timeout 10s; client_body_timeout 10s; send_timeout 10s;keepalive_timeout是客户端和Nginx之间的长连接保持时间client_header_timeout是读取请求头的超时时间client_body_timeout是读取请求体时的超时时间但只对两次读操作之间的间隔生效不是整个请求体必须在这个时间内读完send_timeout是发送响应到客户端时两次写操作之间的超时时间。面试时能说出“哪个阶段用哪个”就能得分。4.3 large_client_header_buffers 4 8k是什么意思这是一个经典陷阱题答案不是4乘8k等于48k而是4个8k的buffer最多32k。Nginx先分配一个8k来读请求头如果请求头超过8k就再分配一个8k最多分配4个。如果请求头超过32k返回414 Request-URI Too Large。相关配置client_header_buffer_size 4k; large_client_header_buffers 4 16k;client_header_buffer_size是单个请求头缓冲区的初始大小默认1klarge_client_header_buffers是当请求头过大时进入的扩展缓冲。生产环境遇到“请求头太大”的报错优先调大large_client_header_buffers把单个扩展buffer调小反而可能导致频繁申请多个buffer。注意配置单位是k不是kbNginx配置文件中k表示1024字节。4.4 location优先级和rewrite规则location的匹配顺序不按配置文件里的书写顺序而是按类型决定优先级写法含义优先级 /path精准匹配最高命中后不再继续匹配^~ /path普通前缀匹配命中后不再检查正则次高~ /path正则匹配区分大小写中~* /path正则匹配不区分大小写中/path普通前缀匹配命中后继续检查正则最低普通字符串匹配按最长前缀优先但即便命中了普通前缀如果后面有正则可以匹配正则覆盖前面的结果只有^~能“短路”正则。示例location /logo.png { access_log off; } location ^~ /static/ { expires 7d; } location ~* \.(js|css)$ { expires 1h; } location / { proxy_pass http://web_cluster; }访问/logo.png走精准匹配访问/static/app.js命中^~即使后面的js正则也匹配也不会再查正则访问/other.js则命中js正则。rewrite规则只能放在server、location、if中而且只能改写URI中参数之外的部分。rewrite的标志位里last停止当前重写并重新执行location匹配break停止当前重写但不再匹配直接处理当前locationredirect返回302临时重定向permanent返回301永久重定向。例如location ^~ /download/ { rewrite ^/download/(.*)$ /files/$1 break; }这个配置把/download/路径重写到/files/路径break避免循环重写同时保证当前location不被重新匹配。5. 被问到Docker和K8s时如何把Nginx经验迁移过去容器化面试题往往让传统运维不适但换个角度看Docker网络对应Nginx监听地址和iptables转发K8s Service对应upstream动态管理。这一章不讲空概念只讲怎么用命令验证以及如何把已有知识迁移到容器集群。5.1 Docker网络模式先跑个命令看现状Linux运维对网络命名空间不陌生Docker网络的基础就是它。先看当前环境有哪些网络docker network ls docker network inspect bridge | head -n 30默认的bridge网络会让容器通过veth对桥接到docker0然后通过iptables做NAT访问外网。host模式让容器直接使用宿主机网络栈没有隔离none模式没有网络container模式共享另一个容器的网络命名空间overlay模式是跨节点容器通信的基础。面试中常问“Nginx容器要在80端口提供服务怎么办”两个答案docker run -d --name nginx-web --network host nginx:alpine docker run -d --name nginx-web -p 8080:80 nginx:alpinehost模式性能好但端口冲突需要自己管理-p映射依赖iptables的DNAT规则每个映射都会多一条规则。如果宿主机本身跑了Nginx再起一个host模式的Nginx容器就会抢80端口这时候可以改用-p映射或提前分好端口。这个选择逻辑和Nginx的listen指令一样同一套资源只能有一个占用者容器只是换了一种隔离方式。5.2 K8s核心概念Pod、Service、Label和ControllerK8s的调度单位是Pod不是一个容器。一个Pod里的容器共享同一个网络命名空间所以localhost可以互通。Label是键值对通过selector关联资源Controller负责维持Pod副本数Service提供稳定的虚拟IP和DNS入口后端对应一组Pod的Endpoints。可以用命令直接验证kubectl get pods -l appnginx -o wide kubectl describe pod nginx-xxxxx | grep -A 5 Events第一条命令用Label选择器过滤出appnginx的Pod看它们分布在哪些节点第二条命令看Events调度失败、镜像拉取失败、探针失败都会在这里体现。Pod调度的基本流程Scheduler watch到未调度的Pod根据节点资源、亲和性规则选择节点kubelet拿到Pod定义后创建容器。这个流程对应Nginx upstream里“选哪台后端”的逻辑只不过Nginx靠round-robin或hashK8s靠Scheduler的调度策略。Service背后靠kube-proxy维护转发规则常见模式是iptables和ipvs。iptables模式随机选中后端规则数量随着Endpoint增加会变多ipvs模式支持加权轮询、最小连接等调度算法。如果已经理解LVS的算法看到kube-proxy的ipvs模式不需要额外学直接沿用那套算法模型。5.3 滚动更新与网络插件把reload换成实例替换Nginx更新配置靠reload热加载K8s更新服务则依赖Deployment的滚动更新机制。执行下面命令会创建新版本Pod每个Pod就绪后才继续更新下一个kubectl set image deployment/nginx nginxnginx:alpine kubectl rollout status deployment/nginx kubectl rollout undo deployment/nginxset image触发镜像更新rollout status可以看到更新进度如果新版本启动失败rollout undo立即回滚到上一个版本。Nginx reload和K8s滚动更新不是同一层面的操作reload是配置热更新滚动更新是实例替换实例替换涉及新的IP、新的网络命名空间因此需要Service做动态关联。跨节点网络方面flannel是常见的CNI插件。VXLAN模式通过UDP封装跨节点流量适合三层网络环境host-gw模式直接利用路由表把数据包转发到目标节点性能更高但要求所有节点二层互通。面试被问到“Pod的IP为什么能跨节点访问”VXLAN和host-gw就是两个可讲的答案。对应到Nginx场景前者类似通过隧道到达后端后者类似把后端地址直接写进路由表。6. 用top命令把Linux负载指标讲成排查动作top是linux常用命令里最容易被低估的一个。面试宝典里对top的整理从load average到buffers和cached的区别都有但很多人只会按P看CPU排序。下面把它拆成“先看哪几行再按哪几个键”。6.1 第一行和第二三行怎么看top - 09:30:00 up 10 days, 2:45, 2 users, load average: 0.15, 0.20, 0.30 Tasks: 120 total, 1 running, 119 sleeping, 0 stopped, 0 zombie %Cpu(s): 5.0 us, 1.0 sy, 0.0 ni, 94.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stload average三个值分别对应最近1分钟、5分钟、15分钟的平均负载。单核系统负载超过1.00表示有任务在排队多核系统负载不应该长期超过CPU核心总数。第二行看Tasks里的zombie数量僵尸进程多说明有父进程没有正确回收子进程。第三行重点看wawa高表示CPU在等I/O对应磁盘或网络瓶颈us高说明用户态计算密集si高说明软中断处理占用了大量CPU。内存方面top第四行的buffers和cached经常被混为一谈。buffers是块设备的读写缓冲区cached是文件系统的页面缓存两者都是Linux底层为了加速磁盘访问做的机制。判断内存是否够用不能只看free列还要看buffers和cached可以被回收的部分。6.2 用top交互命令定位问题top运行中可以按单个字母键完成大部分操作交互键作用k按PID终止进程可指定信号默认15r调整进程优先级(nice)正值降低优先级M按内存占用排序P按CPU占用排序s调整刷新间隔默认5秒f管理显示字段k和r在生产环境要谨慎使用优先用P和M找到异常进程再决定是否介入。如果想把top结果写入监控脚本用批处理模式top -b -n 1 | head -n 20-b表示非交互批处理-n 1表示只输出一次head截取前20行。持续观察某个进程可以组合参数top -b -d 2 -n 30 -p $(pgrep -f nginx | head -n 1)-d 2表示每2秒刷新-n 30表示采样30次-p指定进程PID。这个命令可以直接跑在Zabbix自定义监控里把输出重定向到文件再解析就得到一个完整的CPU采样脚本。面试时能这样用top比只背参数表更能体现Linux排查能力。本文还有配套的精品资源点击获取