kubectl端口转发会忽略loadBalance服务吗?

时间:2020-01-28 00:38:32

标签: 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

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

部署:

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
myproj-app-deployment   3/3     3            3           79m

服务:

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

豆荚:

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

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

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

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

2 个答案:

答案 0 :(得分:3)

kubernetes API仅提供Pod port forward operationsCREATEGET)。服务端点不存在类似的API操作。

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

kubectl代码

kubectl代码中的一些流程似乎可以证明这一点(我只是补充说Go不是我的主要语言)

portforward.go Complete functionkubectl portforward首先通过AttachablePodForObjectFn从选项中查找广告连播的地方:

this interface中将AttachablePodForObjectFn定义为attachablePodForObject,然后是attachablePodForObject function

对我(经验不足)的人来说,看来attachablePodForObjectkubectl用来从命令行上定义的服务中查找Pod的东西。

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

答案 1 :(得分:0)

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