夜雨聆风学习资料网

ARTICLE · 1026163

同一域名,手机和电脑该看哪个站?Nginx/Ingress 设备分发跳转完整配置 + 14 条验证清单

同一域名,手机和电脑该看哪个站?Nginx/Ingress 设备分发跳转完整配置 + 14 条验证清单

同一域名,手机和电脑该看哪个站?Nginx/Ingress 设备分发跳转完整配置 + 14 条验证清单

版本基线:nginx 1.30.5(stable,2026-09-15 时点;mainline 为 1.31.6)· ingress-nginx controller-v1.15.1(Helm chart 4.15.1,2026-03-19 发布)。文中所有配置项均已用 crawl4ai 抓取 nginx.org 官方模块文档 与 kubernetes.github.io/ingress-nginx 官方注解文档 逐条比对,关键处标注出处。

——◆——

一、一个被「想当然」坑到的需求

需求很常见:同一个业务,PC 站和移动站各一套,希望手机访问 PC 域名自动跳移动站、桌面访问移动站自动跳回 PC 站,爬虫永远不跳,用户能手动切换并记住选择。

需求文档里通常已经写好了方案:「一台 Nginx 上配两个 server 块,用 if 判断 $http_user_agentreturn 302 到对面域名」。

但这份方案有个前提没验证:PC 站到底经不经过 Nginx?

实际去核对拓扑才发现,两端的承载形态完全不同: 

  • 移动站是静态资源,前面挂了一台 Nginx —— 可以按原方案写 map + if

  • PC 站是 Node/PM2 起的 SSR 服务(Nuxt 之类),前面根本没有 Nginx,流量从 LB 直接进 ingress-nginx 再到 Service。

Vault 里记的实测结论是这样的:

code
Client ─► ingress-nginx ─►  pc-service(80→3000) ─► pc-deployment  [PM2 cluster + Nuxt SSR]Client ─► nginx(静态)     ─►  m-site

结论:需求文档里的「两个 Nginx server 块」只对了一半。 PC 侧的跳转逻辑要么写进应用中间件,要么用 ingress-nginx 的 server-snippet 注解。

💡 这是本文最想先讲的一条:先实测「请求到底经不经过这个网关」,再决定跳转逻辑放哪。 DNS 指向、LB VIP、Service 链路都要确认,否则配置写了也不生效——而它「看起来是对的」。

——◆——

二、三条红线(先立规矩,再写配置)

不管落在 Nginx 还是 Ingress,有三条不能破:

红线 1:一律 302,禁止 301

301 是「永久重定向」,会被浏览器和 CDN 永久缓存。一旦某个 PC 用户被错跳一次,后续他自己清缓存都未必能修好,服务端改配置也救不回来;CDN 缓存了 301 更麻烦——所有访问者被批量错跳。

回看官方示例,ingress-nginx 文档里给的 server-snippet 例子恰恰写的是 return 301

nginx
if ( $agentflag = 1 ) {  return 301 https://m.example.com;}

照抄它的 301 会踩坑。 设备分发是「按请求特征分流」,本质上是可变的(UA 会变、用户会换设备、策略会调整),必须是 302。

红线 2:爬虫判定必须放在最前面

移动跳转最容易出的 SEO 事故,是把搜索引擎爬虫也跳走

这里有个隐蔽的坑:百度移动爬虫的 UA 里含有 iPhone 字样。如果先判断「像手机就跳移动站」,百度移动爬虫就会被判成手机、被跳走,进而影响收录。

所以判定顺序必须固定为:爬虫 → 用户 Cookie 偏好 → 设备 UA

红线 3:保留完整路径与参数

用 $request_uri(官方定义:full original request URI (with arguments)),不要用 rewrite ^(.*) ... $1 这类改写。

$request_uri 天然带着查询参数和原始路径,跳转后用户落在移动站的同一个页面,而不是被丢回首页。

nginx
return 302 https://m.example.com$request_uri;   # ✅# return 302 https://m.example.com/;            # ❌ 路径全丢

三条红线与完整判定链,一张图看懂:

设备分发跳转:判定链与三条红线

——◆——

三、先实测,再选载体:四种场景对号入座

跳转逻辑放哪,取决于后端承载形态,不是取决于「你喜欢哪种写法」。

后端形态
跳转逻辑放哪
本文对应方案
有 Nginx(静态站 / 反代)
该 Nginx 的 map + server{} 判定
方案 A
无 Nginx(PM2/Nuxt、纯 Node、Tomcat 等)
ingress-nginx
 的 server-snippet,或应用中间件
方案 B / C
混合(同一域名下多后端)
按 host 判断:经 Nginx 的走 Nginx,其余走 Ingress
A + B 组合
独立域名(m. 子域) vs 同域不同路径(/m/
前者可整域 302;后者需按路径前缀分流
见 §3.4

载体选型决策图 —— 先实测,再选落点:

跳转逻辑放哪:先实测再选载体

3.1 场景 A:静态站 + 自建 Nginx

最直接。map 定义变量(必须写在 http 上下文,见下方校验说明),server{} 里做判定。

3.2 场景 B:Node/PM2/Nuxt 无 Nginx

流量经 ingress-nginx,用 server-snippet 注解注入 server{} 级配置。注意两个开关必须同时打开,否则注解被静默拒绝(§5.2 详解)。

3.3 场景 C:应用层中间件

如果团队更愿意把逻辑收在代码里(例如 Nuxt middleware / Express 中间件 / Tomcat Filter),好处是跟业务发布走同一个流程、可单测;代价是每个后端都要实现一遍,且要自己处理 CDN 缓存头。

选型建议能放网关就别放应用。网关层一处配置、全站生效,且改配置不需要重新发包;应用层只适合「网关确实够不着」的场景。

3.4 场景 D:独立域名 vs 同域路径

  • 独立域名www.example.com ↔ m.example.com):整域 302 最简单,也是本文主线。

  • 同域不同路径/ ↔ /m/):需要按路径前缀分流,且要小心别把 /m/ 自己又跳回去,形成重定向死循环(浏览器会报 ERR_TOO_MANY_REDIRECTS)。此时应把 /m/ 加入排除名单。

——◆——

四、方案 A:Nginx 原生完整配置

4.1 http {} 上下文:先定义所有变量

先说一条官方硬约束map 指令的 Context 只有 http(nginx.org 官方文档明确标注)。写在 server{} 里会直接报:

code
nginx: [emerg] "map" directive is not allowed here

同理,自定义变量如果只在 server{} 里 if 引用、却没在 http{} 里 map 声明,启动时会报:

code
nginx: [emerg] unknown "no_redirect" variable

完整变量定义(可直接复制):

nginx
# ================= http {} 上下文 =================# 1) 设备判定map $http_user_agent $is_mobile {    default                                   0;    "~(iphone|ipod)"                         1;    "~android.mobile"                       1;   # 注意:有 Android 无 Mobile = 平板    "~(windows phone|iemobile|blackberry)"   1;    "~(opera m(ob|in)i|webos)"               1;}# 2) 爬虫判定(必须最先判)map $http_user_agent $is_bot {    default 0;    "~(bot|spider|crawler|slurp|baiduspider|googlebot|bingbot|360spider|sogou|bytespider|yandex|duckduckbot|facebookexternalhit)" 1;}# 3) 用户手动偏好(Cookie)map $http_cookie $force_ver {    default                   "";    "~site_version=mobile"   "m";    "~site_version=desktop"  "d";}# 4) 用户已明确选择「留在 PC」map $http_cookie $pc_stay {    default        0;    "~pc_stay=1"  1;}# 5) 永不跳转的路径白名单(robots / 校验文件 / 静态资源)map $request_uri $no_redirect {    default 0;    "~^/(robots\.txt|favicon\.ico|sitemap[^/]\.xml)$"          1;    "~^/(Baidu_verify_|google|bing|yandex)[a-z0-9_]\.html$"    1;    "~\.(js|css|png|jpe?g|gif|svg|ico|woff2?|ttf|map|json|txt)$" 1;}# 6) PC 专用页(手机访问也留在 PC)map $request_uri $pc_only {    default 0;    "~^/course/detail($|\?)" 1;   # 换成你自己的 PC 专用页路径}# 7) 切换端点自身不参与跳转map $request_uri $skip_endpoints {    default 0;    "~^/(switch|stay-pc)($|\?)" 1;}# 8) 全站回滚开关(平时 1,故障时改 0 即全站回 PC)map $http_user_agent $switch_on { default 1; }
⚠️ 注意 $no_redirect 里的 sitemap[^/]\.xml——用 [^/] 而不是 .*,避免正则跨越路径分隔符造成误匹配。

4.2 移动站 server{}:桌面来了就回 PC

nginx
# ================= 移动站 m.example.com =================server {    listen 443 ssl;    server_name m.example.com;    set $go_pc 0;    if ($no_redirect = 0) { set $go_pc 1; }     # 默认倾向:非白名单一律考虑回 PC    if ($is_bot)          { set $go_pc 0; }     # 爬虫:留    if ($is_mobile)       { set $go_pc 0; }     # 手机:留    if ($force_ver = m)   { set $go_pc 0; }     # 用户选过手机版:留    if ($force_ver = d)   { set $go_pc 1; }     # 用户选过电脑版:回    if ($skip_endpoints)  { set $go_pc 0; }     # 切换端点:留    if ($switch_on = 0)   { set $go_pc 1; }     # 总开关关闭:全部回 PC    if ($go_pc = 1)       { return 302 https://www.example.com$request_uri; }    location / {        root  /var/www/m-site;        index index.html;    }}

4.3 PC 站 server{}:手机来了就去移动站

nginx
# ================= PC 站 www.example.com =================server {    listen 443 ssl;    server_name www.example.com example.com;    set $go_mobile 0;    if ($no_redirect = 0) { set $go_mobile $is_mobile; }  # 默认倾向:只有手机才去移动站    if ($is_bot)          { set $go_mobile 0; }    if ($pc_stay)         { set $go_mobile 0; }           # 用户点过「留在电脑版」    if ($arg_stay = 1)    { set $go_mobile 0; }           # ?stay=1 一次性留 PC    if ($force_ver = m)   { set $go_mobile 1; }    if ($force_ver = d)   { set $go_mobile 0; }    if ($pc_only)         { set $go_mobile 0; }    if ($skip_endpoints)  { set $go_mobile 0; }    if ($switch_on = 0)   { set $go_mobile 0; }    if ($go_mobile = 1)   { return 302 https://m.example.com$request_uri; }    # --- 手动切换端点(回 PC 用)---    location = /switch {        if ($arg_v = mobile) {            add_header Set-Cookie "site_version=mobile; Domain=.example.com; Path=/; Max-Age=2592000; SameSite=Lax" always;            return 302 https://m.example.com$safe_path;        }        add_header Set-Cookie "site_version=desktop; Domain=.example.com; Path=/; Max-Age=2592000; SameSite=Lax" always;        return 302 https://www.example.com$safe_path;    }    location / { proxy_pass http://127.0.0.1:3000; }}

关于 /switch 端点,有两个细节值得说:

① add_header ... always 不能省。 nginx 官方 add_header 文档写明:默认只在响应码为 200、201、204、206、301、302、303、304、307、308 时才加头。而我们这里正是 return 302——理论上默认也能加。但 always 参数能让它在任何响应码下都生效,避免未来逻辑改动(比如改成 404 分支)导致 Cookie 静默丢失。显式写上 always,是给自己留的安全边际。

② $safe_path 防开放重定向。 如果直接把用户传来的 $arg_p 拼进 Location,攻击者可以构造:

code
/stay-pc?p=https://evil.com/x.html

把用户跳到外部站点。用 map 白名单收敛(只放行以 / 开头的站内相对路径):

nginx
map $arg_p $safe_path {    default         "";    "~^(/[^/].*)$"  $1;    # 只接受 /xxx,拒绝 //evil.com、https://evil.com}

不匹配时落到 default "",即回本站首页。

4.4 Cookie 共享

跨子域共享 Cookie,Domain 必须写前置点

nginx
add_header Set-Cookie "site_version=desktop; Domain=.example.com; Path=/; Max-Age=2592000; SameSite=Lax" always;

  • Domain=.example.com —— 前置点让 www. 与 m. 共享;

  • Max-Age=2592000 —— 30 天记忆;

  • SameSite=Lax —— 兼容 HTTPS 跳转链路的默认安全档位。

——◆——

五、方案 B:ingress-nginx server-snippet 完整配置

5.1 能力边界(先看清哪些注解做不到)

注解
能否做条件跳转
说明
permanent-redirect
 / temporal-redirect
只能整域写死,没法按 UA 判断
server-snippet
官方示例即设备跳转场景
控制器 ConfigMap http-snippet
用来放 map 定义
控制器 ConfigMap server-snippet
会注入所有 server,范围过大,不要用

5.2 两个开关缺一不生效(本节最容易踩)

ingress-nginx 默认禁止 *-snippet 注解。 官方 ConfigMap 文档给出的默认值是:

开关
官方默认值
不放开时的报错
allow-snippet-annotationsfalseSnippet directives are disabled by the Ingress administrator
annotations-risk-levelHighannotation ... is too risky for environment

官方对 annotations-risk-level 的定义是「Represents the risk accepted on an annotation」,接受值为 Critical / High / Medium / Low;取值 Medium 时,风险为 HighCritical 的注解都不会被接受

而 server-snippet 被 ingress-nginx 源码标记为 Critical 风险,因此必须把 annotations-risk-level 提到 Critical

code
Low(0) < Medium(1) < High(2) < Critical(3)默认 maxrisk = High(2),而 server-snippet 的 risk = Critical(3)→ 3 > 2,被拒绝

别把 annotations-risk-level 理解成「风险高低」,它是「我能接受多高风险的注解」的上限阈值。

5.3 values.yaml(Helm 部署)

yaml
# values.yaml —— ingress-nginx Helm chart 4.15.1 / controller 1.15.1controller:allowSnippetAnnotationstrue          # ① 允许 snippet 注解config:annotations-risk-level"Critical"   # ② 放行 Critical 风险注解    # ③ 配套:词黑名单,收紧可注入内容(官方建议值)annotation-value-word-blocklist"load_module,lua_package,_by_lua,location,root,proxy_pass,serviceaccount,{,},',\""    # ④ map 必须在 http 上下文 —— 用 http-snippet 注入http-snippet: |      map $http_user_agent $is_mobile {          default                                0;          "~(iphone|ipod)"                      1;          "~android.mobile"                    1;          "~(windows phone|iemobile|blackberry)" 1;          "~(opera m(ob|in)i|webos)"            1;      }      map $http_user_agent $is_bot {          default 0;          "~(bot|spider|crawler|slurp|baiduspider|googlebot|bingbot|360spider|sogou|bytespider|yandex|duckduckbot)" 1;      }      map $http_cookie $force_ver {          default                  "";          "~site_version=mobile"  "m";          "~site_version=desktop" "d";      }      map $http_cookie $pc_stay { default 0; "~pc_stay=1" 1; }      map $request_uri $no_redirect {          default 0;          "~^/(robots\.txt|favicon\.ico|sitemap[^/]\.xml)$"            1;          "~^/(Baidu_verify_|google|bing|yandex)[a-z0-9_]\.html$"      1;          "~\.(js|css|png|jpe?g|gif|svg|ico|woff2?|ttf|map|json|txt)$"  1;      }      map $request_uri $pc_only { default 0; "~^/course/detail($|\?)" 1; }      map $request_uri $skip_endpoints { default 0; "~^/(switch|stay-pc)($|\?)" 1; }      map $http_user_agent $switch_on { default 1; }

5.4 Ingress 注解

yaml
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: web-pcnamespace: defaultannotations:    nginx.ingress.kubernetes.io/server-snippet: |      set $go_mobile 0;      if ($no_redirect = 0) { set $go_mobile $is_mobile; }      if ($is_bot)          { set $go_mobile 0; }      if ($pc_stay)         { set $go_mobile 0; }      if ($arg_stay = 1)    { set $go_mobile 0; }      if ($force_ver = m)   { set $go_mobile 1; }      if ($force_ver = d)   { set $go_mobile 0; }      if ($pc_only)         { set $go_mobile 0; }      if ($skip_endpoints)  { set $go_mobile 0; }      if ($switch_on = 0)   { set $go_mobile 0; }      if ($go_mobile = 1)   { return 302 https://m.example.com$request_uri; }spec:ingressClassName: nginxrules:    - host: www.example.comhttp:paths:          - path: /pathType: Prefixbackend:service:name: web-pcport:number80
⚠️ 官方文档明确:server-snippet 注解每个 host 只能用一次,且对该 Ingress 的全部 host 生效。多 host 场景请拆成多个 Ingress。

5.5 Helm 改配置的正确姿势

如果是 Helm 管理的控制器,不要用 kubectl edit cm:改动会在下次 helm upgrade 被还原;更糟的是,若 values.yaml 与现网已有漂移,升级会把现网覆盖回旧值

规范流程:改 values.yaml → 渲染比对 → helm upgrade

bash
# 渲染出 ConfigMap 片段helm template <rel> <chart> -n <ns> -f values.yaml 2>&1 \  | sed-n "/kind: ConfigMap/,/^---/p" > /tmp/rendered-cm.yaml# 拉现网 ConfigMapkubectl-n <ns> get cm <name> -o yaml > /tmp/live-cm.yaml# 只比顶层键,确认「只多出预期的新键」diff <(grep-E "^  [a-z].:" /tmp/live-cm.yaml     | sort) \     <(grep-E "^  [a-z].:" /tmp/rendered-cm.yaml | sort)

——◆——

六、五个真实踩过的坑

坑 1:unknown "xxx" variable

自定义变量只写了 server{} 里的 if 引用,忘了在 http{} 里 map 声明。map 只能在 http 上下文(官方 Context 明确)。

自检一行命令:

bash
nginx -T | grep-c '^map '     # 数一数 map 到底被加载了几个

坑 2:/switch 切换端点被 server 级跳转抢走

nginx rewrite 模块的官方执行顺序是:先执行 server 级的 rewrite 指令,再去找 location

所以 server{} 里那句 if (... ) { return 302 ...; } 会先于location = /switch 命中,切换链路直接失效。

解法:用 $skip_endpoints 把 /switch/stay-pc 排除在跳转判定之外。

坑 3:CDN 缓存了 302

比浏览器缓存更难查——你本地怎么测都对,线上就是有人被错跳。必须要求 CDN 遵循源站、不缓存 302。

坑 4:CDN 剥离了 Set-Cookie

版本记忆直接失效,用户每次访问都被跳一遍。CDN 侧必须放行 Set-Cookie

坑 5:爬虫被跳走,收录掉了

判定顺序写成了「先设备、后爬虫」。记住红线 2:爬虫必须最先判。

——◆——

七、回滚开关

兜底原则一句话:宁可全站 PC,不可全站乱跳。

nginx
map $http_user_agent $switch_on { default 1; }

判定链最后判断它;故障时把 1 改成 0 并 reload/upgrade,一秒钟全站回 PC,不需要回滚任何代码或镜像。

在 Ingress 方案里,它对应改 http-snippet 里的那一行 + helm upgrade

——◆——

八、14 条验证清单(可照做)

上线前请在本地/测试环境用真实 nginx 跑一遍。用 curl 逐条打(-A 指定 UA):

bash
# 手机 UAcurl-sI-A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15" \  https://www.example.com/ | grep-iE "^HTTP|^location"# 百度 PC 爬虫(注意验证不被跳)curl-sI-A "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" \  https://www.example.com/ | grep-iE "^HTTP|^location"
#
用例
期望结果
1
手机 UA 访问 PC 站
302 → 移动站
2
桌面 UA 访问移动站
302 → PC 站
3
平板 UA(有 Android、无 Mobile)
200 留在 PC
4
百度 PC 爬虫
200 不跳
5
百度移动爬虫(UA 含 iPhone
200 不跳
6
Googlebot Smartphone
200 不跳
7
带路径 + 参数访问
302 且 Location 保留完整路径参数
8
手机访问 robots.txt / 静态资源
200 不跳
9
/switch?v=mobile
302 + Set-Cookie
10
选过电脑版后,再用手机 UA 访问
200 不跳
11
/stay-pc?p=/xxx.html
302 + pc_stay Cookie
12
/stay-pc?p=https://evil.com/x.html
302 只回本站首页(防开放重定向)
13
PC 专用页(/course/detail,手机访问)
200 不跳
14
switch_on=0
 后 reload
全站回 PC(含手机)

本次落地前,PC 侧 + 移动侧配置在 nginx 1.24.0 上完整跑通,30 个子用例全部 PASS。目的就是避免上机后反复试错——首次上机最容易踩的正是坑 1 的 unknown "no_redirect" variable

8.1 本文配置的复现验证(nginx 1.30.5)

写这篇文章时,我把正文 §4 的配置原样搬进 nginx.conf,用 Docker 起真实 nginx 1.30.5 复现了一遍:

bash
# 语法校验docker run --rm-v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" \  nginx:1.30.5 sh -c 'mkdir -p /tmp/nginx-test && nginx -t'# → syntax is ok / test is successful# 起服务(PC=8082,移动站=8081)docker run -d--name ngx-test-p 18081:8081 -p 18082:8082 \-v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" nginx:1.30.5 \  sh -c 'mkdir -p /tmp/nginx-test && nginx -g "daemon off;"'# 跑行为矩阵PC_PORT=18082 M_PORT=18081 bash run_tests.sh

实测结果:

code
TOTAL=18  PASS=18  FAIL=0✅ 全部通过

覆盖:手机/桌面/平板 UA、百度 PC 爬虫、百度移动爬虫(UA 含 iPhone)、Googlebot Smartphone、路径参数保留、robots.txt 与静态资源白名单、Cookie 偏好(电脑版/手机版)、/switch 双分支、/stay-pc 路径保留、开放重定向拦截。

两点提示:1. 用 Docker 跑时,nginx 的 pid / 日志 / temp 目录必须显式指定到可写路径(如 /tmp/nginx-test/)并 mkdir -p,否则会报 open() "/tmp/nginx-test/nginx.pid" failed——这是环境问题,不是配置问题。2. 主机端口别选 8081:本机常被其他服务(如 llama-server)占用,会静默把请求打到别的服务上,测试结果全错。用 lsof -nP -iTCP:8081 -sTCP:LISTEN 先确认,或干脆映射到 18081/18082。

——◆——

九、版本与信源

组件
使用/核对版本
来源
nginx
1.30.5
(stable)/ mainline 1.31.6
nginx.org 官网下载页 + CHANGES(2026-09-15)
ingress-nginx
controller-v1.15.1
,Helm chart 4.15.1
GitHub Releases(2026-03-19)
$is_mobile
 等 map 语义
Context 仅 httpdefault/hostnames/volatile
nginx.org ngx_http_map_module
if
 / return 语义与执行顺序
Context server/location/if;server 级先于 location
nginx.org ngx_http_rewrite_module
$request_uri
full original request URI (with arguments)
nginx.org ngx_http_core_module
add_header ... always
默认仅 200/201/204/206/301/302/303/304/307/308 生效
nginx.org ngx_http_headers_module
allow-snippet-annotations
默认 false
ingress-nginx ConfigMap 文档
annotations-risk-level
默认 High,接受 Critical/High/Medium/Low
ingress-nginx ConfigMap 文档
annotation-value-word-blocklist
默认 "",官方给出建议值
ingress-nginx ConfigMap 文档
server-snippet
每 host 仅一次,全 host 生效
ingress-nginx Annotations 文档
CVE-2021-25742
影响 v1.0.0 与 <= v0.49.0>= v0.49.1 / >= v1.0.1 可缓解
kubernetes/ingress-nginx #7837

安全提醒(CVE-2021-25742)

放开 allow-snippet-annotations 后,任何能创建/更新 Ingress 对象的用户,都可能借 snippet 注入 Nginx 配置,进而读取集群内 Secret。官方评级 High,明确写着:

Multitenant environments where non-admin users have permissions to create Ingress objects are most affected by this issue.

落地前务必评估 RBAC:多租户集群里,不要让普通用户有创建 Ingress 的权限;单租户/受信集群再开。配套把 annotation-value-word-blocklist 按官方建议值收紧。

——◆——

十、小结

  1. 先实测再选载体——「一台 Nginx 两个 server 块」是假设,不是事实。

  2. 302 不是 301——包括别照抄官方示例里的 return 301

  3. 爬虫判定最先——百度移动爬虫 UA 含 iPhone,顺序错了就掉收录。

  4. map 只能在 http;ingress 侧用 http-snippet 放 mapserver-snippet 放判定。

  5. snippet 两个开关缺一不可allow-snippet-annotations: true + annotations-risk-level: Critical

  6. 留回滚开关——宁可全站 PC,不可全站乱跳。

  7. 多租户慎开 snippet(CVE-2021-25742 + RBAC)。

——◆——

延伸阅读:

K8s 证书翻车合集:apiserver/kubelet/etcd 三处证书各自过期,症状报错 + 5 分钟定位法

K8s 1.37 把 kube-proxy IPVS 判了死刑:还在用 ipvs 的集群,这份迁移 + 避坑清单趁早看

内网穿透怎么选?Tailscale、ngrok、frp、ZeroTier 六方案对比,附选型决策图

——◆——

你遇到过「配置看起来全对、就是有人被错跳」的情况吗?留言说说你的排查经历,一起交流 👇

——◆——

🤔 互动话题

关于同一域名,手机和电脑该看哪个站?Nginx/Ingress 设备分发跳转完整配置 + 14 条验证清单,你有什么踩坑经历或心得?评论区聊聊~

📖 阅读原文 👈 底部查看

👍 点赞 + 在看 + 转发 是对我最大的支持!

本文首发于「不怕慢」

📂 查看本系列更多文章 →

相关学习资料

返回首页浏览学习资料