kubectl port-forward 会忽略 loadBalance 服务吗?

Jas*_*enX 4 kubernetes minikube

我的环境:带有最新 Minikube/Docker 的 Mac 开发机器

我用一个简单的 Django REST API“hello world”(在本地)构建了一个简单的 docker 镜像。我正在运行一个具有 3 个副本的部署。这是我yaml定义它的文件:

apiVersion: v1
kind: Service
metadata:
  name: myproj-app-service
  labels:
    app: myproj-be
spec:
  type: LoadBalancer
  ports:
    - port: 8000
  selector:
    app: myproj-be
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myproj-app-deployment
  labels:
    app: myproj-be
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myproj-be
  template:
    metadata:
      labels:
        app: myproj-be
    spec:
      containers:
        - name: myproj-app-server
          image: myproj-app-server:4
          ports:
            - containerPort: 8000
          env:
            - name: DATABASE_URL
              value: postgres://myname:@10.0.2.2:5432/myproj2
            - name: REDIS_URL
              value: redis://10.0.2.2:6379/1
Run Code Online (Sandbox Code Playgroud)

当我应用yaml它时,它会正确生成东西。- 一次部署 - 一项服务 - 三个 Pod

部署:

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
myproj-app-deployment   3/3     3            3           79m
Run Code Online (Sandbox Code Playgroud)

服务:

NAME               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes         ClusterIP      10.96.0.1     <none>        443/TCP          83m
myproj-app-service   LoadBalancer   10.96.91.44   <pending>     8000:31559/TCP   79m
Run Code Online (Sandbox Code Playgroud)

豆荚:

NAME                                   READY   STATUS    RESTARTS   AGE
myproj-app-deployment-77664b5557-97wkx   1/1     Running   0          48m
myproj-app-deployment-77664b5557-ks7kf   1/1     Running   0          49m
myproj-app-deployment-77664b5557-v9889   1/1     Running   0          49m
Run Code Online (Sandbox Code Playgroud)

有趣的是,当我SSH进入Minikube, 并使用curl 10.96.91.44:8000它点击服务时,会尊重服务的LoadBalancer类型,并在我一次又一次地点击端点时在所有三个 pod 之间轮换。我可以在返回的结果中看到,我已确保包含 pod 的 HOSTNAME。

但是,当我尝试从我的 Hosting Mac 访问服务时 -- 使用kubectl port-forward service/myproj-app-service 8000:8000-- 每次我点击端点时,我都会得到相同的 pod 进行响应。它没有负载平衡。当我kubectl logs -f <pod>打开所有三个吊舱时,我可以清楚地看到这一点,只有其中一个正在处理命中,而另外两个则闲置……

这是kubectl port-forward限制还是问题?还是我在这里错过了更大的东西?

Mat*_*att 6

kubernetes API 仅提供Pod 端口转发操作CREATEGET)。服务端点不存在类似的 API 操作。

所以我会说kubectl从命令行提供的服务信息中查找 Pod 并直接转发到 Pod,而不是转发到 ClusterIP/Service 端口并允许集群像常规服务流量一样对服务进行负载平衡。

kubectl 代码

下面是一些kubectl似乎支持这一点的代码流程(我将补充一点,Go 不是我的主要语言)

portforward.goComplete功能就是kubectl portforward不先看看了从通过选项荚AttachablePodForObjectFn

AttachablePodForObjectFn被定义为attachablePodForObject该界面,那么这里就是attachablePodForObject功能

在我(没有经验的)Go 眼里,它似乎attachablePodForObjectkubectl用来从命令行上定义的服务中查找 Pod的东西。

然后从那里开始所有处理填充特定于 Pod PortForwardOptions(不包括服务)并传递给 kubernetes API。

  • 看来您也可能总是转发到[第一个活动 Pod](https://github.com/kubernetes/kubectl/blob/3874cf79897cfe1e070e592391792658c44b78d4/pkg/polymorphichelpers/attachablepodforobject.go#L51-L52),即使您尝试再次附加。 (2认同)

Jas*_*enX 0

原因是,由于容器中残留有 Python *.pyc 文件,我的 Pod 随机处于崩溃状态。当 Django 在多 Pod Kubernetes 部署中运行时,这会导致问题。一旦我解决了这个问题并且所有 Pod 都成功运行,循环就开始工作。