K8s v1.36升级实战指南——UserNS GA与Ingress NGINX退役

版本概览

Kubernetes v1.36 是2026年上半年最重要的版本之一,包含18项增强毕业GA、25项进入Beta。对运维团队而言,本次升级的核心关注点包括:User Namespaces GA带来的安全隔离增强、Fine-Grained Kubelet API Authorization GA的精细化权限控制,以及 Ingress NGINX 退役后的 Gateway API 迁移方案。

User Namespaces GA:容器隔离新范式

核心原理

User Namespaces(用户命名空间)是 Linux 内核提供的一项安全特性。在 v1.36 之前,它一直处于 Alpha 状态,许多生产环境因兼容性考虑而不敢启用。GA 之后,Kubernetes 正式支持将容器内的 root 用户映射为宿主机上的非特权用户,从根本上消除了容器逃逸导致 root 权限的风险。

映射原理如下:

容器内 uid=0 (root)  →  宿主机 uid=65534 (nobody)
容器内 uid=1000      →  宿主机 uid=65535
容器内 uid=N         →  宿主机 uid=65534+N

启用步骤

# 检查内核版本(需要 >= 5.8)
uname -r

# 检查 user namespace 支持
cat /proc/sys/kernel/unprivileged_userns_clone
# 输出应为 1

# 检查 cgroup v2 状态(UserNS 需要 cgroup v2)
stat -fc %T /sys/fs/cgroup
# 输出应为 cgroup2fs
# /etc/kubernetes/kubelet-config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
userNamespace: true
# 容器 root UID 映射到宿主机的非特权 UID
staticPods:
  mapping:
    rootUID: 65534
    rootGID: 65534
# 编辑 /etc/default/grub,添加
GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"

# 更新 grub
update-grub

# 重启节点
reboot
# 查看节点状态
kubectl describe node| grep -A5 "UserNS"

# 部署测试 Pod
apiVersion: v1
kind: Pod
metadata:
  name: userns-test
  annotations:
    # 显式启用 UserNS
    security.alpha.kubernetes.io/userns: "true"
spec:
  containers:
  - name: test
    image: ubuntu:22.04
    command: ["sleep", "3600"]
    securityContext:
      runAsUser: 0
      runAsNonRoot: false
# 验证映射关系
kubectl exec userns-test -- cat /etc/passwd
kubectl exec -it userns-test -- bash -c "id && ls -la /root"

注意事项

  1. 现有 Pod 不受影响:UserNS 是节点级配置,新部署的 Pod 才会使用新的映射规则。

  2. 特权容器排除privileged: true 的 Pod 不会启用 UserNS。

  3. Volume 挂载限制:某些 hostPath 类型的 Volume 在 UserNS 下可能无法正确挂载。

Ingress NGINX 退役与 Gateway API 迁移

退役背景

Ingress NGINX 项目已于 2026 年 3 月 24 日正式退役,这意味着:
- 不再有新的功能开发
- 不再有安全补丁发布
- 不再有 bug 修复

对于仍在使用的 Ingress NGINX 集群,立即启动迁移是运维团队的当务之急。

迁移工具:ingress2gateway 1.0

Kubernetes 社区提供了官方迁移工具 ingress2gateway,支持从 Ingress NGINX、Traefik、Contour 等 Ingress 控制器迁移到 Gateway API。

# 安装 ingress2gateway
go install sigs.k8s.io/gateway-api-inference-extension/cmd/ingress2gateway@latest

# 导出当前 Ingress 资源
kubectl get ingress --all-namespaces -o yaml > ingress-resources.yaml

# 执行迁移
ingress2gateway --input-file ingress-resources.yaml \
                --output-file gateway-resources.yaml

# 查看生成的 Gateway API 资源
cat gateway-resources.yaml

迁移后的资源配置

# Gateway 资源(替代 Ingress 资源)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: external-http
  namespace: ingress-nginx
spec:
  gatewayClassName: nginx
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: Same
    - name: https
      protocol: HTTPS
      port: 443
      allowedRoutes:
        namespaces:
          from: All
      tls:
        mode: Terminate
        options:
          cert-manager.io/cluster-issuer: letsencrypt-prod
# HTTPRoute 资源(替代 Ingress Rule)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: api-gateway
  namespace: default
spec:
  parentRefs:
    - name: external-http
      sectionName: https
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/v1
      backendRefs:
        - name: api-server
          port: 8080
      filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
            statusCode: 301
# TLS 证书管理
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: api-example-com
  namespace: default
spec:
  secretName: api-example-com-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: api.example.com
  dnsNames:
    - api.example.com

迁移验证步骤

# 1. 检查 Gateway 状态
kubectl get gateway external-http -n ingress-nginx

# 2. 检查 HTTPRoute 状态
kubectl get httproute api-gateway -n default

# 3. 测试流量转发
curl -H "Host: api.example.com" https:///api/v1/healthz

# 4. 检查证书状态
kubectl get certificate api-example-com -n default

kube-proxy 向 nftables 过渡

nftables 优势

kube-proxy 的 nftables 模式相比 iptables 具有显著优势:
- 性能提升:nftables 使用更高效的数据结构,减少了规则匹配开销。
- 原子性更新:规则集可以原子性地替换,避免临时性断流。
- IPv6 原生支持:nftables 对 IPv6 的支持更加完善。

配置步骤

# /var/lib/kube-proxy/config.conf
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "nftables"
# nftables 模式特有配置
nftables:
  # 跳过已经由 CNI 处理的流量
  skipUnicastNodePort: false
  # 对于 IPv6 集群启用
  enableIPv6: true
# 备份当前配置
kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-config-backup.yaml

# 更新配置
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "nftables"

# 滚动更新 Pod
kubectl rollout restart daemonset kube-proxy -n kube-system

# 验证更新
kubectl get pods -n kube-system -l app=kube-proxy -w
# 查看 nftables 表
nft list table inet kube-proxy

# 查看链规则
nft list chain inet kube-proxy KUBE-SERVICES

# 对比 iptables 规则(旧模式)
iptables-save | grep KUBE | head -20
# 如果发现 nftables 模式有问题,可以快速回滚
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "iptables"

kubectl rollout restart daemonset kube-proxy -n kube-system

Fine-Grained Kubelet API Authorization

权限控制背景

Fine-Grained Kubelet API Authorization GA 后,你可以对 Kubelet API 进行细粒度的权限控制,而不仅仅是完全禁用或完全开放。这对于多租户集群尤其重要。

配置示例

# KubeletConfiguration 中的授权配置
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authorization:
  mode: Webhook
  webhook:
    # 使用 Kubernetes TokenReview API 进行授权
    authorizedURLs:
      - /stats/summary
      - /metrics
      - /pods
    # 未授权请求的处理方式
    unauthorizedStatusCode: 403
# ClusterRole 定义
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubelet-api-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods"]
    verbs: ["get", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubelet-api-reader-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubelet-api-reader
subjects:
  - kind: ServiceAccount
    name: monitoring-agent
    namespace: monitoring

升级实战检查清单

# 1. 集群预检查
kubeadm upgrade plan

# 2. 备份 etcd
etcdctl snapshot save backup-$(date +%Y%m%d).db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# 3. 检查当前版本的所有组件
kubectl get nodes -o wide
kubectl get pods -A -o wide

# 4. 升级 kubeadm
apt-get update && apt-get install -y kubeadm=1.36.0-00

# 5. 执行升级
kubeadm upgrade apply v1.36.0

# 6. 升级 kubelet 和 kubectl
apt-get install -y kubelet=1.36.0-00 kubectl=1.36.0-00
systemctl daemon-reload
systemctl restart kubelet

# 7. 验证升级结果
kubectl version --short
kubectl get nodes
kubectl get pods -A | grep -v Running

User Namespaces在生产环境的应用案例

某电商平台的迁移实践:

# 迁移前的安全检查
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{" "}{.spec.securityContext.runAsUser}{"
"}{end}' | head -20

# 分批启用UserNS(先测试环境)
kubectl label node test-node-01 features.node.kubernetes.io/user-namespaces=true

# 验证Pod调度
kubectl run test-ns --image=nginx --restart=Never
kubectl get pod test-ns -o yaml | grep -A5 securityContext

迁移过程中发现的问题:
1. Volume挂载失败:某些hostPath Volume无法在UserNS下正确挂载
2. 日志收集异常:Fluentd无法读取容器日志文件
3. 监控Agent兼容:部分旧版监控Agent需要重新编译

解决方案:
- 使用emptyDir或PVC替代hostPath
- 升级Fluentd到v1.16+版本
- 使用新版监控Agent(如prometheus-node-exporter)

Ingress NGINX退役后的替代方案对比

特性Ingress NGINXGateway APIIstio
成熟度GABetaGA
性能中等中等
学习曲线中等
多集群支持有限
流量管理基础高级高级

User Namespaces在生产环境的迁移案例

某电商平台的迁移实践提供了有价值的参考经验。在迁移前,运维团队需要执行全面的安全检查:

# 检查所有Pod的安全上下文配置
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{" "}{.spec.securityContext.runAsUser}{"
"}{end}' | head -20

# 统计特权容器数量
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.securityContext.privileged}{" "}{.metadata.name}{"
"}{end}' | grep true | wc -l

# 检查哪些Pod使用了hostNetwork
kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.hostNetwork}{" "}{.metadata.name}{"
"}{end}' | grep true

迁移过程中的典型问题及解决方案:

  1. Volume挂载失败:某些hostPath Volume无法在UserNS下正确挂载。解决方案是使用emptyDir或PVC替代hostPath,或者配置适当的权限映射。

  2. 日志收集异常:Fluentd等日志收集组件可能无法读取容器日志文件。解决方案是升级Fluentd到v1.16+版本,或使用专门的日志收集Agent。

  3. 监控Agent兼容:部分旧版监控Agent需要重新编译以支持UserNS环境。建议选择支持UserNS的新版Agent,如prometheus-node-exporter。

Ingress NGINX退役后的替代方案对比

特性Ingress NGINXGateway APIIstio
成熟度GABetaGA
性能中等中等
学习曲线中等
多集群支持有限
流量管理基础高级高级
服务网格不支持不支持支持

对于大多数场景,推荐使用Gateway API作为Ingress NGINX的替代方案。Gateway API提供了更丰富的路由能力和更好的多租户支持。

kube-proxy nftables模式的性能优势

kube-proxy的nftables模式相比iptables模式具有显著的性能优势。根据基准测试,nftables模式在处理大量规则时,CPU使用率可降低30-40%,规则更新延迟可减少50%以上。

# 比较iptables和nftables规则数量
iptables-save | grep -c "KUBE"
nft list table inet kube-proxy | grep -c "rule"

# 监控规则更新性能
sudo nft monitor trace

对于大型集群(超过100个节点),建议优先切换到nftables模式,以获得更好的性能和可扩展性。

总结

Kubernetes v1.36 的升级虽然涉及多项重大变更,但通过合理的规划和灰度策略,可以将风险降到最低。核心要点包括:

  1. UserNS GA:从节点层面启用,为新 Pod 提供更强隔离,但需注意兼容性测试。

  2. Ingress NGINX 退役:立即启动 ingress2gateway 迁移,避免安全风险。

  3. kube-proxy nftables:平滑过渡,保留回滚方案。

  4. Fine-Grained Kubelet Authorization:在多租户环境中强化 API 访问控制。

建议运维团队先在测试环境完成全流程演练,再制定生产环境的灰度升级计划。