美文网首页
K8S Pod 如何实现 Service 切流

K8S Pod 如何实现 Service 切流

作者: _晓__ | 来源:发表于2024-01-16 10:34 被阅读0次

前言

在云原生环境中,Pod 是部署应用程序的基本单位,而 Service 将符合指定条件的 Pod 作为可通过网络访问的服务提供给服务调用者。在某些情况下,可能需要将某个 Pod 的流量从 Service 中切走,使其不再接收 Service 的请求。这可能是因为 Pod 出现故障需要保留现场人工排查。

目标

使能够灵活地将 Pod 的流量从 Service 中切走,同时确保在切走流量时,其他 Pod 仍然能够正常工作,并且对用户请求的影响最小化。

概述

  1. 基本概念和原理
    在 Kubernetes 中,Service 通过 Label 选择器来将请求流量分发到对应的 Pod 上。因此,要切走某个 Pod 的流量,可以通过修改 Label 选择器来实现。我们可以为需要切走的 Pod Label 进行修改,使其 Service Label 选择器不再包含该 Pod 的 Label。
# Service 通过 Label 选择器绑定 Deployment
---
apiVersion: v1
kind: Service
metadata:
  name: test
spec:
  ports:
    - name: port-xxxx
      nodePort: xxxxx
      port: xxxx
      protocol: TCP
      targetPort: xxxx
  selector:
    app: test
  type: NodePort

# Deployment Label
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  selector:
    matchLabels:
      app: test   # 与 Pod Label一致
  template:
    metadata:
      labels:
        app: test  # 与 Service selector 一致
        
# Pod Label
---
apiVersion: v1
kind: Pod
metadata:
  generateName: test-8495787574-
  labels:
    app: test
  name: test-8495787574-rssvq
  1. 实现流程
    (1)准备阶段:确定需要切走流量的 Pod,并修改成特定 Label,如原 Label:app=test,修改后 Label:app=test-offline。
    (2)修改 Pod 的 Label 后,Deployment 会检测发现同 Label 实例与副本数实例不一致,通过扩容将 Pod 个数与副本数一致。
    (3)验证流量切分:通过 Service 调用时,使用工具或监控系统验证流量是否成功切分,确保其他 Pod 能够正常接收请求和被切流的 Pod 不再接收请求。
    (4)恢复流量:在需要恢复流量时,将切走流量的 Pod 的 Label 恢复为原始状态,Deployment 会检测发现同 Label 实例与副本数实例不一致,通过缩容将 Pod 个数与副本数一致。
    (5)再次验证流量:确认流量是否成功恢复,确保切走流量的 Pod 重新接收请求。

针对于第4、5点,实际情况如排查完问题,没必要恢复该 Pod 流量,而是直接销毁该 Pod,因为第2点已将切流的 Pod 个数扩容了回来,所以无须保留切流的 Pod

具体实现步骤

  1. 准备阶段
  • 确定需要切走流量的 Pod:确定需要切走流量的 Pod 的名称或标识。
  • 修改 Pod Label:使用 K8S API 进行修改
public V1Pod patchPodLabel(String namespace, String name, String key, String value) throws ApiException {
    CoreV1Api api = new CoreV1Api(client);
    V1Patch v1Patch = new V1Patch(JSONUtil.toJsonStr(CollUtil.newArrayList(new PatchPodLabelsParam(key, value))));
    return api.patchNamespacedPod(name, namespace, v1Patch, null, null, null, null);
}

@Getter
public static class PatchPodLabelsParam {
    private final String op = "replace";
    private final String path;
    private final String value;

    public PatchPodLabelsParam(String key, String value) {
        this.path = StrFormatter.format("/metadata/labels/{}", key);
        this.value = value;
    }
}

@Test
public void patchPodLabel() throws ApiException {
    Kube kube = Kube.init(dev_KubeConfig);
    kube.patchPodLabel("default","test-8495787574-nz58d", "app", "test-offline");
}
  1. 验证流量切分
# 到 Pod 中执行命令安装 arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# 通过 watch 监控方法是否被调用
watch 包名.类名 方法名 '{params,returnObj,throwExp}'
// 模拟通过 NodePort 进行调用
for (int i = 0; i < 100; i++) {
    CompletableFuture.runAsync(() -> HttpUtil.get("http://测试接口"));
}
ThreadUtil.sleep(10000);
  1. 处理切流的 Pod
    修改了 Label 的 Pod 则脱离了 Deployment 的管理,也无法通过 Deployment 来查看,该 Pod 则无法自动销毁,只能人工销毁。

总结和注意事项

本方案提供了一种将 Pod 的流量从 Service 中切走的方法。通过修改 Pod Label,可以灵活地控制流量的分发,确保在进行维护或升级时,对用户请求的影响最小化。在实际应用中,需要根据具体业务需求和环境进行适当的调整和测试,以确保方案的可行性和稳定性。

相关文章

  • K8S 创建资源的两种方式

    K8S 的资源有 Pod、Service、Volume、Namespace、ReplicaSet、Deployme...

  • k8s中service和endpoint

    K8s提供了service对象来访问pod。 为什么没有直接访问pod?一是k8s中pod不是持久性的,宕机重建将...

  • k8s资源类型

    k8s资源关系k8s资源类型主要有Deployment、Service、Pod、ReplicaSet,它们之间的关...

  • k8s的网络发现

    k8s网络场景 容器与容器之间的通信 pod与pod之间的通信 pod到service之间的通信 集群外部与集群内...

  • k8s之service account

    service account是k8s为pod内部的进程访问apiserver创建的一种用户。其实在pod外部也可...

  • 11.5 服务是如何实现的

    11.5 服务是如何实现的 在第5 章中学习过Service,Service允许长时间对外暴露一系列pod、稳定的...

  • Kubernetes编排文件里的各种Port

    最近在搞K8s里的编排文件,对于Deployment Pod里的containerPort,Service文件里的...

  • k8s-servcie

    Service pod是k8s中的最小调度单元,但是pod是有生命周期的,pod的ip是不稳定的,这样就不能提供稳...

  • k8s kubeDNS

    k8s DNS 参考: dns-pod-service kubernetes-dns dns name 同一个na...

  • Sateful和Operator

    Sateful 和 Operator Pod: k8s最小的逻辑单元service:提供注册服务和服务发现功能(通...

网友评论

      本文标题:K8S Pod 如何实现 Service 切流

      本文链接:https://www.haomeiwen.com/subject/undkodtx.html