K8s 有任何负载均衡吗?

K8s ANY load balancing?

我越来越喜欢 k8s,我正在尝试一些个人 VPS 的东西。 我已经创建了一个在内部使用另一个服务的 POD 部署。 我很想验证这两项服务是否在某种程度上实现了负载平衡。

这是我尝试创建的: 我有一个简单的服务,我称之为 metric-test,它只有一个端点计算它被调用的次数,记录它并 returns 此信息。 为此,我使用了微框架jooby,因为我熟悉它并且可以快速入门。

这个简单应用的代码可以是found on github

我还在存储库中添加了 deployment.yaml 文件,我用它来将它推送到我的本地版本 minikube(模拟我的 k8s 环境)。

采取的步骤:

  1. 使用此 cmd 将 docker 映像编译到 minikube 存储库中:eval $(minikube docker-env)
  2. 我现在使用 docker build . -t metric-test1
  3. 构建项目的 docker 图像
  4. 然后我使用 kubectl apply -f deployment.yaml 应用部署文件(该文件也在 github link

这给了我一个 ClusterIP 类型的服务(这是我想要的,因为它不应该从外部访问)和 2 个 PODS 包含 jooby 代码。这是 deployment.yaml 文件:

apiVersion: v1
kind: Service
metadata:
  name: metric-test
  labels:
    run: metric-test
spec:
  ports:
    - port: 3000
      protocol: TCP
  selector:
    run: metric-test

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metric-test
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      run: metric-test
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        run: metric-test
    spec:
      containers:
        - image: metric-test1
          imagePullPolicy: Never
          name: data-api
          ports:
            - containerPort: 3000
              protocol: TCP
              name: 3000tcp
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30

好的,一切正常!我刚刚设置了一个端口转发,所以我可以访问该服务: kubectl port-forward service/metric-test 3000:3000

并使用此脚本在服务中触发大量请求:

#!/bin/bash
target=${1:-http://localhost:3000}
while true # loop forever, until ctrl+c pressed.
do
        for i in $(seq 100) # perfrom the inner command 100 times.
        do
                curl $target > /dev/null & # send out a curl request, the & indicates not to wait for the response.
        done

        wait # after 100 requests are sent out, wait for their processes to finish before the next iteration.
done

我现在看到 ALL 的请求仅由一个 pods 处理,而另一个只是闲置在那里。

我浏览了文档 (here),但老实说,实际上我提出的问题多于答案。这就是为什么我试图创建一个简化的场景来测试这些东西。

问题

  1. 谁能帮帮我?
  2. 我错过了什么?如何在不通过 Internet 公开服务的情况下实现这种负载平衡。我只希望集群中的其他 pods 可以使用它。
  3. (奖励)Ingress 提供的前端服务都应该适当地进行负载平衡(对吗?)

注意:据我了解,使用 LoadBalancerIngress 您实际上可以实现负载平衡,但是,它也会暴露给外部。

编辑 1

有关部署的更多信息: kubectl get po

的结果
NAME                          READY   STATUS    RESTARTS   AGE
metric-test-f89bfbf86-ccrj8   1/1     Running   0          16h
metric-test-f89bfbf86-kl7qg   1/1     Running   0          16h

这是 运行 稍微使用 curl 脚本后两者的日志图片:

编辑解决方案

正如 m303945 所说,当我们使用端口转发时,负载平衡不起作用。

为了验证这一点,以及我可能想做的任何未来测试,我做了以下事情:

我在我的终端中 运行 以下命令:

kubectl run -it --rm --restart=Never --image=alpine handytools -n ${1:-default} -- /bin/ash

它创建了一个基于 alpine 的容器并为我提供了 shell 访问权限。但是,那时我无法使用 curl,因为它尚未安装。所以为此我 运行:

一旦我有了它,我就将我之前的 bash 脚本从上面修改为此 pod 上的 运行 并尝试访问我设置的服务:

#!/bin/ash
target=${1:-http://metric-test:3000}
for i in $(seq 5) # loop 5 times to generate 500 calls.
do
        for i in $(seq 100) # perfrom the inner command 100 times.
        do
                curl $target > /dev/null & # send out a curl request, the & indicates not to wait for the response.
        done

        wait # after 100 requests are sent out, wait for their processes to finish before the next iteration.
done

修改包括指向服务而不是“本地主机”,并且不需要端口。此外,alpine 使用 ash 而不是 bash shell。我也 运行 500 个请求而不是无穷大。

如您所见,运行以上(您可以在 alpine 中使用 vi 创建)我得到了一个很好的均匀负载分布!!!

再次感谢用户 m303945 为我指明了正确的方向

如果我没记错的话,TCP 负载平衡在使用端口转发时不起作用。尝试从 k8s 中的容器 运行 脚本而不是进行端口转发。