【问题标题】:Load balancing to multiple containers of same app in a pod对 Pod 中同一应用的多个容器进行负载均衡
【发布时间】:2019-07-21 04:17:23
【问题描述】:

我有一个场景,我需要在同一个 pod 中运行一个应用容器的两个实例。 我将它们设置为侦听不同的端口。下面是部署清单的样子。 Pod 以预期的容器数量正常启动。 我什至可以从其他 pod 连接到 podIP 上的两个端口。

kind: Deployment
metadata:
  labels:
    service: app1-service
  name: app1-dep
  namespace: exp
spec:
  template:
    spec:
      contianers:
        - image: app1:1.20
          name: app1
          ports:
          - containerPort: 9000
            protocol: TCP
        - image: app1:1.20
          name: app1-s1
          ports:
          - containerPort: 9001
            protocol: TCP

我什至可以为容器的每个端口创建两个不同的服务,而且效果也很好。 我可以单独访问这两个服务并最终访问 Pod 中的相应容器。

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9000
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

---
apiVersion: v1
kind: Service
metadata:
  name: app1-s1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9001
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

我希望容器的两个实例都在一个服务后面,即两个容器之间的循环。 我怎样才能做到这一点?在服务领域内可能吗?或者我是否需要探索入口以获得类似的东西?

【问题讨论】:

  • 为什么要这样设置,而不是让 Deployment 管理多个 Pod 副本,每个副本都有一个容器副本? (...在这种情况下,普通服务将在副本之间循环,无需特殊配置。)
  • 多个 pod 副本是我们目前拥有的方式。但是,有一个应用程序消耗大约 50G 左右的 RAM 用于映射到内存中的数据,但只有系统 CPU 的十分之一。我正在尝试在 pod 与 pod 副本中获取更多容器实例,以更好地利用集群资源。这样,两个应用程序实例使用相同的共享内存,因为它们最终都希望可以访问 50G 的一部分。所有这一切都无需触及应用程序以实际利用更多的 CPU 资源和吞吐量。
  • 但是为什么不让它们成为具有不同副本数的单独部署或副本集呢?通过这种方式,它为不同大小的节点提供了不同的节点注释的可能性,然后您可以为不同的部署制定关联规则,以将较高内存使用率的 Pod 固定在较高内存节点上,反之亦然。
  • 我们确实使用单独的部署,每个部署都有多个副本。我要解决的问题是减少内存占用。如果我有 5 个副本,例如将创建 5 个 50Gb pod,并且可能/可能不在单个节点上。因此,如果我有两个可以使用 50Gb 共享内存的应用容器实例,我可能会减少副本数并减少集群上的资源使用。我将研究的一个选项是尝试通过关联规则将这些应用程序 pod 固定到单个节点上,并查看 interpod IPC 共享。

标签: kubernetes kubernetes-service


【解决方案1】:

Kubernetes 服务具有三种代理模式:iptables(默认)、userspaceIPVS

  • Userspace: 是较旧的方式,它以循环方式分发是唯一的方式。
  • Iptables: 是默认值,随机选择一个 pod 并坚持下去。
  • IPVS:有多种分配流量的方法,但首先你必须在你的节点上安装它,例如在 centos 节点上使用这个命令: yum install ipvsadm 然后使其可用。

就像我说的,Kubernetes 服务默认没有循环。 要激活IPVS,您必须向 kube-proxy 添加一个参数

--proxy-mode=ipvs

--ipvs-scheduler=rr(选择循环)

【讨论】:

  • Ipvs 是我们默认设置的。是的,ipvs 是为了实现更好的负载平衡。但是我上面谈到的情况是需要一种将一个源端口映射到多个目标端口的方法。到目前为止,我可以找到一个可行的解决方案。
  • 服务连接到端点,端点由地址和端口定义,因此使用多个具有相同地址的端点应该没有问题。
【解决方案2】:

可以使用单个服务公开多个端口。在 Kubernetes 服务清单中,spec.ports[] 是一个数组。因此,可以在其中指定多个端口。例如,见下文:

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9000
  - name: http-s1
    port: 81
    protocol: TCP
    targetPort: 9001
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

现在,除了端口,主机名相同,默认情况下,kube-proxy 在用户空间模式下通过 round-robin 算法选择后端。

【讨论】:

  • 我应该澄清一下,我需要一个包含两个容器实例的单一 IP 和端口。我已经尝试了你的建议,但是有了这个,我需要像入口这样的东西,可以在两个服务端口之间进行负载平衡。我想看看服务区是否有什么东西。可能是一项特殊的服务和端点设置,可以让我开始工作。
【解决方案3】:

我要做的是将应用程序分隔在两个不同的部署中,每个部署中都有一个容器。我会为这两个部署设置相同的标签,并使用一个服务攻击它们。

这样,您甚至不必在不同的端口上运行它们。

稍后,如果您希望其中一个获得更多流量,我会考虑每个部署的副本数量。

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 2020-05-26
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2021-12-07
    • 2014-12-13
    相关资源
    最近更新 更多