任何帮助都将不胜感激。
我尝试在运行在亚马逊网络服务上的同一命名空间中的k8s集群中从pod发送一个请求到pod。
我已经添加了一个pod,它为来自端口5000的请求提供服务,在这个pod中,我成功地运行了curl命令:
curl -i \
--header "Content-Type: application/json" \
--request POST \
--data '[[5.1, 3.5, 1.4, 0.2]]' \
localhost:5000/predict我已经向pod添加了一个服务来公开一个端点,这样我就可以向它发送流量了:
apiVersion: v1
kind: Service
metadata:
annotations:
name: sklearn-iris-bentoml-deployment-sklearn-iris-example
namespace: bentoml
ownerReferences:
selfLink: /api/v1/namespaces/bentoml/services/sklearn-iris-bentoml-deployment-sklearn-iris-example
labels:
run: my-bentoml
spec:
ports:
- name: http
port: 5000
protocol: TCP
targetPort: 5000
selector:
run: my-bentoml
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}服务:
➜ kubectl get svc -n bentoml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sklearn-iris-bentoml-deployment-sklearn-iris-example ClusterIP 10.110.5.245 <none> 5000/TCP 5h6m端点:
➜ k get endpoints sklearn-iris-bentoml-deployment-sklearn-iris-example -n bentoml
NAME ENDPOINTS AGE
sklearn-iris-bentoml-deployment-sklearn-iris-example 10.110.115.108:5000 5h6m当我尝试通过telnet从同一命名空间中的不同pod进行连接时,连接失败:
root@my-shell:/# telnet 10.110.115.108 5000
Trying 10.110.115.108...
telnet: Unable to connect to remote host: Connection refused我不确定是否应该配置DNS,因为我无意从群集外部发送流量,因此网络主要集中在群集内部
发布于 2020-06-18 20:55:41
确保应用程序pod正在侦听0.0.0.0,而不是127.0.0.1或localhost。这通常可以在应用程序的代码中更改,并取决于应用程序的语言。
发布于 2020-06-19 06:16:55
这是netstat的-an输出: tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN - torpido 3小时前
它证实了@Arghya Sadhu怀疑的正确性,即您的问题与以下事实相关:您的应用程序被配置为仅侦听 localhost address,这意味着它只能在本地上访问。如果在netstat输出中粘贴描述每一列内容的标题,则会更清楚地看到这一点。
我们来看一个例子。为了说明我的想法,我部署了一组来自the example的nginx Pods,可以在k8s官方文档中找到。
在列出了可用的pod并通过kubectl exec连接到其中一个pod之后,我运行了netstat -ntlp命令:
root@nginx-deployment-pod1:/# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro如您所见,第三列中的输出与示例中的输出非常不同。0 0.0.0.0:80意味着nginx服务器监听分配给系统中所有网络接口的所有IPv4地址(在本例中为container或Pod)。您可以使用ip a或ifconfig命令列出所有可用的网络接口和地址。
看看你的命令:
curl -i \
--header "Content-Type: application/json" \
--request POST \
--data '[[5.1, 3.5, 1.4, 0.2]]' \
localhost:5000/predict您指定要在localhost上的端口5000上访问您的应用程序,但它在localhost上可用的事实并不意味着它也可以在Pod之外访问。让我们再看看您的netstat输出(这一次是头文件):
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN如您所见,您的应用程序侦听,或者换句话说,仅绑定到localhost地址(127.0.0.1)。正如@Arghya Sadhu提到的,它通常在应用程序代码或配置文件中的某个位置进行配置。
请记住,您可以通过Services和Endpoints进一步公开某些端口,但它们必须首先由Pod公开,这意味着使用Pod运行的应用程序必须配置为侦听所有本地IP地址。
回到我们的nginx示例,它监听0.0.0.0:80,因为它被配置为这样做。这是通过/etc/nginx/conf.d/default.conf配置文件中的以下指令完成的:
server {
listen 80;
server_name localhost;
...或者更具体地说,这一行:
listen 80;它相当于:
listen 0.0.0.0:80;它基本上意味着“监听所有IP地址/端口80上的所有网络接口”。如果我们将其更改为:
listen localhost:80;或
listen 127.0.0.1:80;nginx将仅侦听loclhost (127.0.0.1)地址,并且只能在本地(即从Pod内)到达。
每个应用程序都以自己的方式做到这一点。如果您在kubernetes上部署了一些自定义应用程序,而该应用程序没有提供能够让您查找、侦听或绑定IP地址的配置文件,则很可能它是硬编码在应用程序代码中的,因此您需要找到负责它的片段。专门查找包含localhost或127.0.0.1的条目,并将其更改为0.0.0.0,这意味着所有IP地址,搜索包含listen或bind关键字的行可能也会有所帮助。
https://stackoverflow.com/questions/62450172
复制相似问题