关于apaas中pod隔离的实现方案

关于apaas中pod隔离的实现方案

1. 目标

将目标pod逻辑隔离开来、确保pod不会重启、流量成功切换、不会破坏rs对pod的管理,在隔离之后能够顺利恢复

2. 支持范围

支持OAM模型以及Apaas自研模型的应用关联的部署单元

隔离只针对由 ReplicaSet 管理的 Pod,排除 DaemonSet 和 StatefulSet

3. 实现步骤

3.1 前置检查

在隔离pod之前校验网络(ip是否充足)和资源(cpu、内存是否充足),避免新pod无法顺利Running

  • 校验网络(默认IP资源充足):通过模版中是否启用了flatNetworkEnabled(扁平化网络)来判断,如果没有启用,默认IP充足
    如果启用,通过一下步骤来判断
    • 通过解析模版中的ip以及副本数来判断是否自动分配ip:如果解析结果ip字段的值是AUTO或者解析出来的ip数量大于副本数,就是自动分配ip
    • 调用 Rancher provider的API 获取命名空间下的 macvlan IP 列表
    • 计算子网总可用 IP 数量,判断是否充足
  • 资源信息获取:
    • OAM模型:oam模型不能通过模版获取资源的限制与请求
      • 通过k8s接口获取pod的yaml信息
      • 获取yaml中所有容器的资源信息,对请求的资源以及限制的资源进行相加组合,获取最终的资源信息
    • Apaas模型:通过模版获取资源信息
  • 校验资源:
    • 获取命名空间下的资源信息,并且统计剩余可用的资源值
    • 判断命名空间下剩余的资源值,是否满足当前请求的限制值
    • 判断命名空间下对pod的限制值,至少满足剩余可用pod数大于1

3.2 流量切换

  • 流量查看:
    • 通过 k8s接口获取当前命名空间所有的 Pod 列表,并找到指定 podName 的 Pod。
    • 获取该命名空间下所有的 SVC 列表。
    • 对每个 Service,获取对应的 Endpoints。
    • 遍历 Endpoints 的地址列表,判断是否有 Endpoint 指向当前的 Pod
  • 流量切换:
    • 当原pod的label修改了之后rs会认为pod不符合要求,因此会创建新pod,流量的切换会自动进行svc的endpoints的更新
    • kube-proxy 会同步更新 iptables/ipvs 规则,将流量路由到新的 Pod IP。

3.3 进行隔离/恢复操作

  • 判断pod是否由rs控制,目前只支持rs控制的pod进行隔离操作
  • 隔离操作:
    • 修改pod的label,使其失去rs的满足需求,使得rs进行新的pod创建操作
    • 在数据库中保存旧的pod的拓扑图信息,并且在查询argocd资源树的时候进行插入操作
  • 恢复操作:
    • 校验服务是否成功启动(新pod是否成功启动),如果成功启动,默认不支持恢复操作,因为我们更希望通过删除功能,对旧的pod进行删除而保留新pod(安信用户手册中指出,pod隔离的目的在于在发现服务故障的时候能够快速恢复服务,同时保留现场数据,为故障排查提供有力支持)
    • 恢复旧pod的label,使其满足rs的需求,从而使得rs删除掉创建失败的pod,实现恢复操作
    • 在数据库中删除拓补图查询关联,删除掉进行隔离操作时存入的关联信息

4. 修改pod的yaml中的哪些字段,pod不会重启/删除重建

  • 一般来说,修改yaml中的label标签或者annotations,不会导致重启
  • 如果修改环境变量env,会导致重建(一般k8s不允许直接修改pod的spec,会被拒绝)
  • 如果修改容器的信息(如镜像、端口、env、资源限制)、pod的亲和性、挂载卷、SA、网络等等都会导致重建

5. 参考文档