题目与适用场景
你负责一个裸机 Kubernetes 集群,团队用 Service.spec.externalIPs 让外部地址直接路由到 Service。集群升级到 v1.36 后出现弃用警告,安全团队担心租户可以声明任意地址并拦截流量。请设计迁移:先发现真实依赖,再按业务选择 LoadBalancer 控制器或 Gateway API,最后阻断新增使用并验证回滚。
Kubernetes 官方说明指出,externalIPs 不由 Kubernetes 分配或所有权校验;v1.36 将其标记为 deprecated,未来版本会先停止 kube-proxy 支持,再完全移除。因此答案要区分当前兼容窗口与长期目标,不能把弃用误述为立即删除。
背景与边界
本题聚焦 Service 网络入口、RBAC、准入策略、迁移顺序和可观测性。云厂商负载均衡器、裸机网络设备和 DNS 由平台团队提供,候选人应说明接口契约、地址所有权证明、双写窗口和故障回退条件。
面试官考察点
- 能否解释
externalIPs是 Service spec 字段,与 Node 的ExternalIP地址或 LoadBalancer 展示字段不同。 - 能否从审计、流量、权限、控制器和 DNS 追踪迁移闭环。
- 能否用
DenyServiceExternalIPs阻断新增写入,同时不误删既有业务。 - 能否比较 LoadBalancer、MetalLB 类控制器和 Gateway API 的所有权与回滚边界。
- 能否用指标和分阶段切换证明没有流量黑洞或 IP 抢占。
30 秒回答框架
“我先扫描 Service spec、审计日志、DNS、节点路由和真实流量,建立 externalIP 到租户、端口和后端的映射。迁移前开启 DenyServiceExternalIPs 只阻断新增值,不修改既有对象;对每个入口选择管理员控制的 LoadBalancer 控制器或 Gateway API,先并行验证健康检查、源地址和连接排空,再切 DNS/上游。确认旧流量为零后删除 externalIPs,保留回滚窗口,并用审计、5xx、连接失败和地址冲突指标控制放量。”
分步骤深入解答
- 建立资产清单。 列出所有使用
externalIPs的 Service、地址、端口、命名空间、所有者、DNS TTL、入口协议、EndpointSlice、externalTrafficPolicy 和最近流量。区分外部地址字段与 Node.status.addresses的ExternalIP,避免误报。
- 识别安全风险。
externalIPs由用户写入 spec,而 Kubernetes 不负责分配地址或保证唯一性。低信任租户可以声明别人的地址,造成流量拦截或中间人风险。审计创建、更新、删除和 kube-proxy 规则,按地址和租户关联异常。
- 先挡新增、后迁移存量。 启用
DenyServiceExternalIPs,它拒绝新建或新增 externalIPs,但允许删除既有值。先在审计模式或低风险集群验证误伤,再切到强制模式;存量对象由迁移控制器或人工审批处理。
- 选择替代入口。 云环境优先使用管理员控制的
type: LoadBalancer;裸机可用具备地址池和冲突检查的负载均衡控制器。需要角色分离、共享入口或路由规则时使用 Gateway API,让平台管理员持有 Gateway,应用团队仅管理 HTTPRoute 等受限对象。
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
spec:
gatewayClassName: platform-public
addresses:
- type: IPAddress
value: 192.0.2.4这段只表达管理员持有地址的示意;实际 GatewayClass、控制器能力、证书和 IP 池必须按部署实现验证。
- 设计双入口验证。 新入口先用独立 hostname 或低 TTL DNS 灰度,比较连接成功率、TLS、源地址、长连接、健康检查和 EndpointSlice 收敛。若必须复用旧 IP,先确认新控制器完成地址所有权登记,再切换上游,避免两个实现同时宣告同一地址。
- 排空与删除。 观察旧入口无新连接并等待最大连接寿命后,移除 externalIPs,保留审计记录和回滚快照。删除顺序应让 DNS、负载均衡、Service 和后端之间始终至少有一条可验证路径。
- 版本与回滚。 v1.36 先产生警告;官方时间表预计最早 v1.40 在 kube-proxy 禁用行为,最早 v1.43 完全移除。回滚只恢复经过地址所有权校验的旧入口,不重新开放任意租户写 externalIPs;若新入口失败,临时回退 DNS 或控制器配置并持续阻断新增风险。
高质量示范回答
我先把每个 externalIP 当作待迁移资产,而不是直接批量替换字段。通过 API 清单、审计、DNS、节点规则和流量日志确认地址、租户、端口、连接寿命和所有权。externalIPs 是用户可写的 Service spec 字段,Kubernetes 不负责分配或冲突检查,这正是 CVE-2020-8554 类流量拦截风险的根源。
在迁移期间启用 DenyServiceExternalIPs,只拒绝新增或追加地址,保留删除存量的能力。替代方案由入口需求决定:云环境使用管理员控制的 LoadBalancer;裸机使用有地址池和冲突检测的控制器;需要角色分离和共享路由则使用 Gateway API。新入口通过独立 hostname 或低 TTL 灰度,比较连接、TLS、源地址和健康检查,确认旧连接排空后再删除 externalIPs。
我会把 v1.36 的弃用警告、最早 v1.40 的 kube-proxy 行为变化和最早 v1.43 的完全移除写入迁移计划。回滚只恢复已验证的管理员入口,不恢复任意租户写入;指标包括地址冲突、5xx、连接失败、DNS 生效延迟和残留 Service 数量。
常见错误
- 错误表现: 把弃用理解成升级后立即删除 → 失败原因: 误判兼容窗口,导致无计划停机 → 修正方法: 按 v1.36 警告、后续行为禁用和最终移除分阶段安排。
- 错误表现: 直接把
externalIPs改成loadBalancerIP→ 失败原因: 仍可能绕过地址池和冲突检查 → 修正方法: 让管理员控制的 LoadBalancer 控制器分配并写入 status。 - 错误表现: 开启准入控制后批量删除所有旧字段 → 失败原因: 没有流量和连接排空证据 → 修正方法: 先挡新增、灰度新入口、等待连接寿命,再按资产删除。
- 错误表现: 只检查 Service,不检查 DNS、节点规则和真实流量 → 失败原因: 可能留下隐性入口或黑洞 → 修正方法: 建立端到端迁移清单和观测窗口。
- 错误表现: 让租户继续管理 Gateway 地址 → 失败原因: 替代入口复现相同权限问题 → 修正方法: Gateway 由平台持有,应用只管理受限路由。
追问及应对
DenyServiceExternalIPs 会影响已有 Service 吗?
官方行为是拒绝新建 Service 使用该字段,以及向已有 Service 追加新值;删除既有值仍可进行。上线前应核对当前版本实现并观察拒绝事件,不能把它当作自动迁移器。
裸机集群为什么不直接手工填 LoadBalancer IP?
手工填写仍缺少地址池、冲突检查、健康状态和审计。使用具备管理员地址池的控制器,可以让分配、回收和唯一性成为平台责任;特殊固定 IP 也应经过显式审批。
Gateway API 如何保持应用团队自助?
平台团队创建 Gateway 和 GatewayClass,限制 addresses、监听器和跨命名空间引用;应用团队提交 HTTPRoute,并通过引用策略、策略对象和审计控制可达范围。
如何处理长连接和 WebSocket?
在 DNS 或入口切换前测量连接寿命,使用连接排空和双入口重试策略。旧入口只停止新连接,保留足够时间让现有连接完成;指标要区分新连接失败和旧连接自然结束。
什么时候可以关闭回滚开关?
当旧入口流量为零、所有 Service 已移除字段、地址冲突检查通过、DNS TTL 窗口结束且新入口连续观察达标后,再删除快照并保留审计证据。时间表不能替代数据证据。
参考资料
- Kubernetes v1.36 Service ExternalIPs 弃用公告(Kubernetes Blog)
- Service 文档(Kubernetes Documentation)
- Admission Control 文档(Kubernetes Documentation)
- Gateway API 文档(Kubernetes Documentation)
面试作答要点
先区分字段语义和安全风险,再给出盘点、阻断新增、替代入口、双入口验证、排空、删除与回滚的顺序。
一句话总结
迁移 externalIPs 的关键是把任意用户可写入口改成管理员拥有、可审计、可验证的地址分配链路。
继续练习
如果集群同时使用 Gateway API、MetalLB 和云 LoadBalancer,请设计统一入口目录、地址所有权模型和跨环境回滚协议。