K8S Service 适配多VPC

发布于:2025-06-16 ⋅ 阅读:(27) ⋅ 点赞:(0)

01


背景

当同一集群中有多个 VPC 时,就会存在不同的 Pod 使用相同的 IP。虽然 IP 间具有不同的 VXLAN 属性,但 K8S 组件层面是无法识别和区分出这种属性。这显然破坏了 K8S 的网络平面设计,所以需要解决一些额外的问题。

其一需要解决的是,K8S Service 的连通性问题。

众所周知,Kube-proxy 会在节点上增加 IPVS/IPTables 规则,以实现 K8S Service 功能。但由于 VPC 场景中 PodIP 的重复,则会导致 Kube-proxy 加的规则无效。

02


方案

经过深入讨论,我们决定使用 司内既有的 LVS服务 实现 K8S Service 功能,并对 Kube-proxy 进行替换。

使用司内 LVS 方案的原因,有以下几点:

  • 一是司内 LVS 已经经过改造,对 VPC 场景早已适配支持,拿过来就可以用,无需容器侧再自行实现一番 VPC 的逻辑,降低成本和复杂度。

  • 二是既有的容器 LB 功能,就是基于 LVS 实现的,此设计的可靠性和性能已经历过线上的考验。并且其很多设计和实现可以复用,无需重复造轮子。

  • 三是相较于修改 Kube-proxy 源码而言,这种不破坏 k8s 原生组件的方式,更便于集群的维护和升级。

此方案需 LB 组件增加对 Service 资源的适配支持,将之 IP+Port 映射到 LVS 侧,以及 Service 所关联的 Pod 管理。另外,CNI 组件,也需要在节点侧拦截所有访问 Service 的流量,路由给 VPC 网络处理。

由此可解 多 VPC 场景下的 Service 连通性问题。

03


实现

角色及职责

云平台:UI 层、屏蔽细节

K8S:容器编排、提供状态驱动的系统

CNI:Pod网络路由管理

LBController:调协集群状态、对接及实现

虚拟化(VPC/LVS 等):底层实现

流量路径示意图

流程图

创建 Service

集群 Service CIDR 规划

众所周知,K8S 集群中 Service 的 IP 地址,由控制组件进行分配。二控制组件具体从哪个网段中分配及管理,可由管理员在搭建集群时进行配置。

因此,需要提前规划好 K8S 集群所使用的 Service CIDR。

对于当前场景,有以下要求:

  1. Service CIDR 多集群间唯一,不能重复;

  2. Service CIDR 由虚拟化 VPC 侧提供,并 配置好打通规则 以及 关闭DHCP(防止地址被DHCP占用) 等;

Service 的隔离性

在 K8S 中的 Service,可按照 用户类型 和 系统类型 对 Service 进行区分,不同类型的 Service 对隔离性的要求是不同的。

例如,用户类型 Service,要求实现 VPC 维度的隔离,仅能允许放行同一 VPC 中 Client 发起的请求访问。不通 VPC 之间的网络资源,一定要由强隔离性。

但系统类型的 Service 则不然,系统类型 Service 要求所有 VPC 的 Client 皆可访问。以 K8S 集群中的 KubeDNS/CoreDNS 服务为例,它通过 Service IP 为集群中 Pod 提供 DNS 服务,这就一定所有 Pod 都能访问到,才能维持 集群/业务 功能正常。

因此我们规定,携带业务属性的 Service 为业务 Service,反之则为系统 Service。以此对隔离性要求进行区分实现。

Service 对象设计

需要给 Service 附加上业务相关 VPC 的属性,用以标识出此 Service 所属。另外为了支持 LBC 进行 GC,所以需要增加 finalizer 字段,保证无资源泄露。

apiVersion: v1kind: Servicemetadata:  annotations:    # Region,例如 beijing、shanghai    k8s.hulk.qihoo.net/region: "xxxx"    # 平台维度的 项目 ID    k8s.hulk.qihoo.net/relate-id: "xxxx"    # VPC 维度的网络信息 - NetworkID    k8s.hulk.qihoo.net/network-id: "xxxx"    # VPC 维度的网络信息 - SubnetID    k8s.hulk.qihoo.net/subnet-id: "xxxx"  finalizers:    # LBC 的 finalizer  - containercloud.qihoo.net/finalizer  labels:    app: nginx-cpf  name: nginx-cpf  namespace: defaultspec:  internalTrafficPolicy: Cluster  ipFamilies:  - IPv4  ipFamilyPolicy: SingleStack  ports:  - name: http    port: 80    protocol: TCP    targetPort: 80  selector:    app: nginx-cpf  sessionAffinity: None  type: ClusterIP

Service 功能兼容

TargetPort

Service 中的 targetPort 除了可以写具体端口号外,还允许用户填入 端口名。

LBC 组件需要根据用户输入的端口名,去 Pod 模板中进行查找,然后转换为具体的端口号进行处理。

apiVersion: v1kind: Servicespec:  ports:  - name: https    port: 443    protocol: TCP    targetPort: https
apiVersion: v1kind: Podspec:  containers:  - name: metrics-server    ports:    - containerPort: 4443      hostPort: 4443      name: https      protocol: TCP

如上,示例 Service 中的 targetPort 为 https,对应到 Pod 中的 端口号为 4443。

Service Kubernetes

apiVersion: v1kind: Servicemetadata:  name: kubernetes  namespace: defaultspec:  clusterIP: 100.101.0.1  clusterIPs:  - 100.101.0.1  internalTrafficPolicy: Cluster  ipFamilies:  - IPv4  ipFamilyPolicy: SingleStack  ports:  - name: https    port: 443    protocol: TCP    targetPort: 443  sessionAffinity: None  type: ClusterIP

可以看到,这个 Service 是 ClusterIP 类型,但不存在 selector 字段,需要根据 Endpoint 做特殊处理。

依赖方

容器云平台

虚拟化 VPC、LVS

04


总结

我们通过以上的设计及实现,成功落地了 多 VPC 场景下的 K8S 集群 Service 功能,为用户提供有效支撑。但是,在功能和性能上还存在进步空间,例如 Service 的 session affinity 功能未支持等。后续仍需继续保持演进。

云服务器和专有网路VPC服务,也可以咨询我们~


更多技术干货,

请关注“360智汇云开发者”👇

360智汇云官网:https://zyun.360.cn(复制在浏览器中打开)

更多好用又便宜的云产品,欢迎试用体验~

添加工作人员企业微信👇,get更快审核通道+试用包哦~

图片


网站公告

今日签到

点亮在社区的每一天
去签到