Pod 到 Pod 通信不适用于 k8s 中的 Python 套接字
Pod-to-pod communication doens't work with Python socket in k8s
问题
在我们的项目中,我们需要两个 pods 作为服务器-客户端通过 Python socket
库进行通信。这两个容器都是使用 docker build
在本地构建的,通过 yaml 文件上的 imagePullPolicy: IfNotPresent
和 k8s 集群的同一节点上的 运行 在本地拉取(我是 运行ning kubernetes vanilla ,如果这很重要的话)。
当我们
时,沟通效果很好
- 运行 命令行中的两个 python 脚本
- 运行 两个脚本都使用
docker build
和 docker run
作为容器
- 服务器应用程序容器部署在 K8s 集群中,客户端应用程序 运行 在命令行上或作为 docker 容器。
服务端和客户端都部署在K8s中时通信失败。 kubectl logs client -f
returns :
Traceback (most recent call last):
File "client.py", line 7, in <module>
client_socket.connect((IP_Server,PORT_Server))
TimeoutError: [Errno 110] Connection timed out
我怀疑客户端脚本在集群上部署时发出的请求有问题,但我找不到问题所在。
代码
server.py
import socket
IP = "0.0.0.0"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen()
...
server.yaml
apiVersion: v1
kind: Service
metadata:
name: server
labels:
app: server
spec:
ports:
- port: 1234
targetPort: 1234
protocol: TCP
selector:
app: server
---
apiVersion: v1
kind: Pod
metadata:
name: server
labels:
app: server
spec:
containers:
- name: server
image: server:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 1234
client.py
import socket
IP_Server = # the IP of the server service, obtained from "kubectl get svc"
PORT_Server = 1234
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP_Server,PORT_Server)) # fails here
...
client.yaml
apiVersion: v1
kind: Pod
metadata:
name: client
labels:
app: client
spec:
containers:
- name: client
image: client:latest
imagePullPolicy: IfNotPresent
在 默认 设置中 - 不应该有任何东西阻止您在 2 pods 之间进行连接。但是,您不应依赖 IP 地址在集群内进行通信。尝试使用服务名称:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
server ClusterIP 10.98.48.92 <none> 80/TCP 9m39s
server
通常应该对同一命名空间内的所有 pods 运行 可用。
您解析服务器 IP 地址的方式可能有问题,但服务器创建的“服务”应该可以通过 DNS 隐式访问(例如 server:1234),如here,所以也许您可以改用它?
万一以后有人来这里,我找到了一个对我有用的解决方案,方法是执行
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
然后删除所有 coredns pods.
参考:https://github.com/kubernetes/kubernetes/issues/86762#issuecomment-836338017
问题
在我们的项目中,我们需要两个 pods 作为服务器-客户端通过 Python socket
库进行通信。这两个容器都是使用 docker build
在本地构建的,通过 yaml 文件上的 imagePullPolicy: IfNotPresent
和 k8s 集群的同一节点上的 运行 在本地拉取(我是 运行ning kubernetes vanilla ,如果这很重要的话)。
当我们
时,沟通效果很好- 运行 命令行中的两个 python 脚本
- 运行 两个脚本都使用
docker build
和docker run
作为容器
- 服务器应用程序容器部署在 K8s 集群中,客户端应用程序 运行 在命令行上或作为 docker 容器。
服务端和客户端都部署在K8s中时通信失败。 kubectl logs client -f
returns :
Traceback (most recent call last):
File "client.py", line 7, in <module>
client_socket.connect((IP_Server,PORT_Server))
TimeoutError: [Errno 110] Connection timed out
我怀疑客户端脚本在集群上部署时发出的请求有问题,但我找不到问题所在。
代码
server.py
import socket
IP = "0.0.0.0"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen()
...
server.yaml
apiVersion: v1
kind: Service
metadata:
name: server
labels:
app: server
spec:
ports:
- port: 1234
targetPort: 1234
protocol: TCP
selector:
app: server
---
apiVersion: v1
kind: Pod
metadata:
name: server
labels:
app: server
spec:
containers:
- name: server
image: server:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 1234
client.py
import socket
IP_Server = # the IP of the server service, obtained from "kubectl get svc"
PORT_Server = 1234
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP_Server,PORT_Server)) # fails here
...
client.yaml
apiVersion: v1
kind: Pod
metadata:
name: client
labels:
app: client
spec:
containers:
- name: client
image: client:latest
imagePullPolicy: IfNotPresent
在 默认 设置中 - 不应该有任何东西阻止您在 2 pods 之间进行连接。但是,您不应依赖 IP 地址在集群内进行通信。尝试使用服务名称:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
server ClusterIP 10.98.48.92 <none> 80/TCP 9m39s
server
通常应该对同一命名空间内的所有 pods 运行 可用。
您解析服务器 IP 地址的方式可能有问题,但服务器创建的“服务”应该可以通过 DNS 隐式访问(例如 server:1234),如here,所以也许您可以改用它?
万一以后有人来这里,我找到了一个对我有用的解决方案,方法是执行
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
然后删除所有 coredns pods.
参考:https://github.com/kubernetes/kubernetes/issues/86762#issuecomment-836338017