-l 'env!=prod' 会选中什么?Deployment 的 selector 为什么改不了?标签值有什么限制?改一个 Pod 的标签会发生什么?这篇用六个不同标签的对象,把选择器语法、控制器的限制和实时影响都跑一遍。
-l env=prod → ['a', 'b'] (等值) -l env!=prod → ['c', 'd', 'e', 'f'] (不等于:包括没有 env 标签的) -l env=prod,tier=web → ['a'] (逗号 = 与(AND)) -l env in (prod,staging) → ['a', 'b', 'c'] (集合:在其中) -l env notin (prod) → ['c', 'd', 'e', 'f'] (notin:同样包括没有 env 标签的) -l env → ['a', 'b', 'c', 'd'] (存在这个键) -l !env → ['e', 'f'] (不存在这个键) -l env=dev,!tier → ['d'] (组合:env=dev 且没有 tier) 注意:没有“或”的写法能跨键:env=prod OR tier=web 只能分两次查;同一个键内的“或”用 in (a,b)
六个 ConfigMap:a=prod/web,b=prod/db,c=staging/web,d=dev,e=只有 tier=web,f=无标签。-l env=prod → a、b;env!=prod → c、d、e、f(不等于包括没有 env 标签的);env=prod,tier=web(逗号是 AND)→ a;env in (prod,staging) → a、b、c;env notin (prod) 同样包含没有 env 的;env(存在)→ a、b、c、d;!env(不存在)→ e、f;env=dev,!tier → d。跨键的“或”没有一次查完的写法,同一个键内的“或”用 in。
matchExpressions(app In [frontend,backend] 且 tier 不存在),模板标签 app: frontend:退出码 0;['deployment.apps/d-expr created']
选择器 app=backend 但模板标签是 app: frontend:退出码 1;['The Deployment "d-mismatch" is invalid: spec.template.metadata.labels: Invalid value: {"app":"frontend"}: `selector` does not match template `labels`']
选择器写成 {}(空):退出码 1;['The Deployment "d-empty" is invalid: spec.selector: Invalid value: {}: empty selector is invalid for deployment']
创建后把 spec.selector 从 app=frontend 改成 app=backend:退出码 1;['The Deployment "d-fix" is invalid: spec.selector: Invalid value: {"matchLabels":{"app":"backend"}}: field is immutable']
Service 不写 selector(空):不会去选 Pod,endpoints 由人手工管理;读出的 spec.selector=None
NetworkPolicy 的 podSelector: {} 则是“选中命名空间里的全部 Pod”(同样是空选择器,含义相反)Deployment 的 matchExpressions(app In [frontend,backend] 且 tier DoesNotExist)配模板标签 app: frontend 创建成功;选择器 app=backend 但模板标签是 app: frontend 被拒(`selector` does not match template `labels`);选择器写成 {} 被拒(empty selector is invalid for deployment);创建后把 spec.selector 改成 app=backend 被拒(field is immutable)。Service 不写 selector 就不会选 Pod;NetworkPolicy 里的 podSelector: {} 却是“选中命名空间里全部 Pod”——同样是空选择器,含义因资源而异。(实验中还踩到一个 YAML 坑:app: y 的 y 会被解析成布尔值。)
值 63 个字符 → 退出码 0 值 64 个字符 → 退出码 1;The ConfigMap "lab-test" is invalid: metadata.labels: Invalid value: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": must be no more than 63 bytes 值带空格 → 退出码 1;The ConfigMap "lab-test" is invalid: metadata.labels: Invalid value: "a b": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(( 值以 - 开头 → 退出码 1;The ConfigMap "lab-test" is invalid: metadata.labels: Invalid value: "-ab": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(( 值为空串 → 退出码 0 键带前缀 example.com/name → 退出码 0 键名部分 64 个字符 → 退出码 1;The ConfigMap "lab-test" is invalid: metadata.labels: Invalid value: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": name part must be no more than 63 bytes 键前缀带大写 Example.com/name → 退出码 1;The ConfigMap "lab-test" is invalid: metadata.labels: Invalid value: "Example.com/name": prefix part a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is
值 63 个字符通过、64 个字符被拒(must be no more than 63 bytes);值带空格或以 - 开头被拒(要求空串,或字母数字开头结尾,中间可含 - _ .);空串允许;带前缀的键 example.com/name 通过;键名部分 64 个字符被拒;前缀写成大写 Example.com/name 被拒(前缀必须是小写的 RFC 1123 子域名)。
Deployment web 3 个副本,Service web 的 endpoint 数 3 给一个 Pod 加新标签 env=debug:pod/web-679886b487-8djjf labeled 再改同一个键 env=other(不加 --overwrite):退出码 1;["error: 'env' already has a value (debug), and --overwrite is false"] 加 --overwrite:pod/web-679886b487-8djjf labeled 把 app 标签改成 web-quarantine:0.0 秒后 Service 的 endpoint 从 3 变成 2(Pod 被踢出 Service) Deployment 补了一个新 Pod:app=web 的 Pod 数 3;命名空间里总共 4 个 Pod;被改标签的那个还在运行(True),但已脱离 ReplicaSet 和 Service——这是“隔离故障 Pod 留着排查”的常用手法
Deployment web 3 个副本,Service web 有 3 个 endpoint。给一个 Pod 加标签 env=debug 成功;再改 env=other 不加 --overwrite 失败('env' already has a value (debug), and --overwrite is false)。把它的 app 标签改成 web-quarantine:0.1 秒后 Service 的 endpoint 从 3 变成 2;Deployment 补了一个新 Pod(app=web 的 Pod 仍是 3 个,命名空间里共 4 个);被改标签的那个还在运行,但脱离了 ReplicaSet 和 Service——隔离问题 Pod 留着排查的常用手法。