kubectl port-forward 是否忽略 loadBalance 服务?
Does kubectl port-forward ignore loadBalance services?
我的环境:Mac 具有最新 Minikube/Docker
的开发机
我(在本地)使用简单的 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
时,它会正确生成内容。
- 一次部署
- 一项服务
- 三个 pods
部署:
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
Pods:
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
类型并在两者之间轮换当我一次又一次到达终点时,所有三个 pods。我可以在返回的结果中看到,我确保包含 pod 的主机名。
但是,当我尝试从我的主机 Mac 访问服务时——使用 kubectl port-forward service/myproj-app-service 8000:8000
——每次我到达端点时,我都会得到相同的 pod 响应。它没有负载平衡。我可以清楚地看到,当我 kubectl logs -f <pod>
所有三个 pods 并且其中只有一个正在处理命中,因为其他两个是空闲的...
这是 kubectl port-forward
限制或问题吗?还是我在这里遗漏了更重要的东西?
kubectl port-forward
从命令行提供的Service信息中查找第一个Pod,直接转发到一个Pod,而不是转发到ClusterIP/Service端口。集群没有机会像常规服务流量一样对服务进行负载平衡。
kubernetes API只提供Pod port forward operations(CREATE
和GET
)。服务端点不存在类似的 API 操作。
kubectl
代码
这里有一些来自 kubectl
代码的流程似乎支持了这一点(我只是补充说 Go 不是我的主要语言)
portforward.go Complete
function is where kubectl portforward
does the first look up for a pod from options via AttachablePodForObjectFn
:
AttachablePodForObjectFn
在this interface, then here is the attachablePodForObject
function中定义为attachablePodForObject
。
在我(没有经验的)Go 看来,attachablePodForObject
似乎是 kubectl
用来从命令行上定义的服务查找 Pod 的东西。
然后从那里开始,所有内容都涉及填充 Pod 特定 PortForwardOptions
(不包括服务)并传递给 kubernetes API.
原因是由于 Python *.pyc 文件留在容器中,我的 pods 运行domly 处于崩溃状态。当 Django 在多 pod Kubernetes 部署中 运行 时,这会导致问题。一旦我解决了这个问题并且所有 pods 运行 成功,循环法就开始工作了。
我的环境:Mac 具有最新 Minikube/Docker
的开发机我(在本地)使用简单的 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
时,它会正确生成内容。
- 一次部署
- 一项服务
- 三个 pods
部署:
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
Pods:
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
类型并在两者之间轮换当我一次又一次到达终点时,所有三个 pods。我可以在返回的结果中看到,我确保包含 pod 的主机名。
但是,当我尝试从我的主机 Mac 访问服务时——使用 kubectl port-forward service/myproj-app-service 8000:8000
——每次我到达端点时,我都会得到相同的 pod 响应。它没有负载平衡。我可以清楚地看到,当我 kubectl logs -f <pod>
所有三个 pods 并且其中只有一个正在处理命中,因为其他两个是空闲的...
这是 kubectl port-forward
限制或问题吗?还是我在这里遗漏了更重要的东西?
kubectl port-forward
从命令行提供的Service信息中查找第一个Pod,直接转发到一个Pod,而不是转发到ClusterIP/Service端口。集群没有机会像常规服务流量一样对服务进行负载平衡。
kubernetes API只提供Pod port forward operations(CREATE
和GET
)。服务端点不存在类似的 API 操作。
kubectl
代码
这里有一些来自 kubectl
代码的流程似乎支持了这一点(我只是补充说 Go 不是我的主要语言)
portforward.go Complete
function is where kubectl portforward
does the first look up for a pod from options via AttachablePodForObjectFn
:
AttachablePodForObjectFn
在this interface, then here is the attachablePodForObject
function中定义为attachablePodForObject
。
在我(没有经验的)Go 看来,attachablePodForObject
似乎是 kubectl
用来从命令行上定义的服务查找 Pod 的东西。
然后从那里开始,所有内容都涉及填充 Pod 特定 PortForwardOptions
(不包括服务)并传递给 kubernetes API.
原因是由于 Python *.pyc 文件留在容器中,我的 pods 运行domly 处于崩溃状态。当 Django 在多 pod Kubernetes 部署中 运行 时,这会导致问题。一旦我解决了这个问题并且所有 pods 运行 成功,循环法就开始工作了。