【问题标题】:Connecting to a Kubernetes service resulted in connection refused连接到 Kubernetes 服务导致连接被拒绝
【发布时间】:2021-01-12 16:57:54
【问题描述】:

我正在尝试使用 Kubernetes 部署我的 Web 应用程序。我使用 Minikube 创建集群并使用 ingress 成功公开了我的前端 react 应用程序。然而,当我在前端的 deployment.yaml 的“env”字段中附加后端服务的 URL 时,它不起作用。当我尝试通过前端 pod 连接到后端服务时,连接被拒绝。

前端部署yaml

kind: Deployment
apiVersion: apps/v1
metadata:
 name: frontend
spec:
 replicas: 1
 selector:
   matchLabels:
     app: frontend
 template:
   metadata:
     labels:
       app: frontend
   spec:
     containers:
       - name: frontend
         image: <image_name>
         imagePullPolicy: Never
         ports:
           - containerPort: 80
         env:
         - name: REACT_APP_API_V1_ENDPOINT
           value: http://backend-svc
     restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
 name: frontend-svc
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 80
 selector:
   app: frontend

前端入口

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: front-ingress
 namespace: default
 annotations:
   kubernetes.io/ingress.class: "nginx"
   nginx.ingress.kubernetes.io/rewrite-target: /
   nginx.ingress.kubernetes.io/proxy-read-timeout: "12h"
   nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
 rules:
   - host: front-testk.info
     http:
       paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: frontend-svc
               port:
                 number: 80

后端部署yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: backend
  labels:
    name: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: <image_name>
        ports:
        - containerPort: 80
        imagePullPolicy: Never
      restartPolicy: Always
---
kind: Service
apiVersion: v1
metadata:
  name: backend-svc
  labels:
    app: backend
spec:
  selector:
    app: backend
  ports:
    - name: http
      port: 80
      targetPort: 80

% kubectl get svc backend-svc -o wide
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE   SELECTOR
backend-svc   ClusterIP   10.109.107.145   <none>        80/TCP    21h   app=backend

在前端 pod 内部连接并尝试使用部署期间创建的 ENV 连接到后端:

❯ kubectl exec frontend-75579c8499-x766s -it sh
/app # apk update && apk add curl
OK: 10 MiB in 20 packages

/app # env
REACT_APP_API_V1_ENDPOINT=http://backend-svc

/app # curl $REACT_APP_API_V1_ENDPOINT
curl: (7) Failed to connect to backend-svc port 80: Connection refused

/app # nslookup backend-svc
Server:         10.96.0.10
Address:        10.96.0.10:53

Name:   backend-svc.default.svc.cluster.local
Address: 10.109.107.145

** server can't find backend-svc.cluster.local: NXDOMAIN

执行到我的后端 pod

# netstat -tulpn
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:8080            0.0.0.0:*               LISTEN      1/node

# netstat -lnturp
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG        0 0          0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 eth0

【问题讨论】:

  • 你能把kubectl get svc backend-svc -o wide的输出也加在这里吗?
  • @vishal 感谢您的建议,我刚刚添加了。
  • 检查控制平面 pod、core-dns pod 的状态。查看控制平面 pod 日志中是否有任何有用的信息。检查是否存在任何拒绝 pod 之间通信的网络策略。
  • 你的后端命名空间是什么?如果命名空间是默认的,dns 应该是 backend-svc.default.cluster.local ?
  • @ThanhNguyenVan 根据他发布的yamls,他没有在元数据中提到任何命名空间,这意味着它将自动部署在默认的ns中。

标签: kubernetes kubernetes-pod amazon-eks kubernetes-service


【解决方案1】:

我怀疑您的应用程序侦听端口 8080。如果您仔细查看netstat 的输出,您会注意到Local Address0.0.0.0:8080

# netstat -tulpn

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0     ? 0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1/node

为了解决这个问题,您必须在服务中更正您的 targetPort

kind: Service
apiVersion: v1
metadata:
  name: backend-svc
  labels:
    app: backend
spec:
  selector:
    app: backend
  ports:
    - name: http
      port: 80
      targetPort: 8080 # ? change this to 8080

由于containerPort 主要用于提供信息,因此无需更改部署端的端口。不指定端口不会阻止该端口被暴露。任何监听容器内默认"0.0.0.0" 地址的端口都可以访问。

【讨论】:

  • 感谢剩下的。修改后的部署 yaml 仍然导致连接被拒绝。
  • 这真的很奇怪。我用不同的图像检查了你的 yaml 文件,前端应用程序能够连接支持的。所以问题肯定出在您支持的应用程序方面。只是为了确认一下,您修改了部署或服务?
  • 我已按照您的建议修改了服务的 targetPort。感谢您的验证,我会尝试使用另一个图像作为后端,看看它是否有效
  • 我使用的是mendhak/http-https-echo。它非常适合测试。
  • 我已经部署了一个与link 建议的配置相同的测试 pod,运行nslookup backend-svc.defaultnslookup kubernetes.default 没有问题。我的前端 pod 使用的是 Alpine 映像,您认为这是这里建议的问题吗link
猜你喜欢
  • 2019-06-01
  • 2021-09-13
  • 2018-10-19
  • 1970-01-01
  • 2016-05-02
  • 2021-05-25
  • 2019-05-06
  • 2020-11-08
  • 1970-01-01
相关资源
最近更新 更多