连接到 Kubernetes 服务导致连接被拒绝

Connecting to a Kubernetes service resulted in connection refused

我正在尝试使用 Kubernetes 部署我的 Web 应用程序。我使用 Minikube 创建集群并使用入口成功公开了我的前端 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

我怀疑您的应用程序在端口 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" 地址的端口都可以访问。