Kubernetes pod 获取另一个 pod 失败

问题描述 投票:0回答:1

我有一个应用程序正在尝试部署到 Kubernetes(使用 Docker Desktop)。

该应用程序有 2 个 pod,每个 pod 都有一个组件:

API 窗格

  • 具有 POST API 的 Node.js Express 应用程序
  • 监听端口8000

网络窗格

  • 提供静态网页的 Node.js Express 应用程序
  • 监听8080端口
  • 网页有一个按钮,可以获取WEB组件上的api
  • Web 应用程序上的 api 反过来会获取 API 组件

我的想法是我希望 WEB pod 暴露给外界,但我不想将任何其他 pod 暴露给集群中其他 pod 之外的任何人。最终我将添加数据库、工作组件、队列和 Redis,这些都应该隐藏在集群中,远离外部。架构没什么特别的。

网页服务正常,对 Web 服务器上的 api 的调用也很好。

从 WEB pod 到 API pod 的调用给我带来了麻烦:

我正在尝试的 URL 是:http://localhost:8000

我得到的错误是:

TypeError: fetch failed
    at node:internal/deps/undici/undici:12618:11
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /app/server.js:51:17 {
cause: Error: connect ECONNREFUSED 10.107.140.254:8000
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16) {
    errno: -111,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '10.107.140.254',
    port: 8000

除了localhost之外,我还尝试过:

  • 0.0.0.0
  • 127.0.0.1
  • 主机.docker.内部
  • k8s-api(API pod 的服务名称,请参阅下面的 yaml)
  • server-cluster-ip-service(我尝试过的集群的服务名称)

我发现一个页面表明 Web Node.js 可能正在解析为 ipv6,因此我将其添加到我的 WEB NodeJS 应用程序的顶部,但没有成功:

var dns = require('node:dns');
dns.setDefaultResultOrder('ipv4first');

我能够使用以下命令成功地卷曲 API(从 MacOS 主机):

curl -d '{"x": 1}' -H "Content-Type: application/json" -X POST http://localhost:8000

所以我相信 API 正在运行。

这是 WEB Nodejs api 中尝试获取 API pod 的代码:

await fetch('http://localhost:8000', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
        body: JSON.stringify({}}) })
        .then(r => Promise.all([r, r.status !== 200 ? r.text() : r.json()]))
        .then(([r, json]) => {
                if (r.status !== 200) {
                        console.log(r); console.log(json);
                        }
                })
        .catch(e => {
                console.log(e);
                }
        );

这是我的清单 yaml:

api.deployment.yml

apiVersion: v1
kind: Service
metadata:
  name: k8s-api
  labels:
    app: k8s-api
spec:
  type: LoadBalancer
  ports:
  - port: 8000
    name: "api"
    targetPort: 8000
  selector:
    app: k8s-api
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-api-deployment
spec:
  replicas: 1
  minReadySeconds: 10
  selector:
    matchLabels:
      app: k8s-api
  template:
    metadata:
      labels:
        app: k8s-api
        yada: booyah
    spec:
      containers:
      - image: k8s-sample-api
        name: k8s-api
        imagePullPolicy: Never

web.deployment.yml

apiVersion: v1
kind: Service
metadata:
  name: k8s-web
  labels:
    app: k8s-web
spec:
  type: LoadBalancer
  ports:
  - port: 8080
    name: "web"
    targetPort: 8080
  selector:
    app: k8s-web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-web-deployment
spec:
  replicas: 1
  minReadySeconds: 10
  selector:
    matchLabels:
      app: k8s-web
  template:
    metadata:
      labels:
        app: k8s-web
        yada: booyah
    spec:
      containers:
      - image: k8s-sample-web
        name: k8s-web
        imagePullPolicy: Never

我还尝试使用将它们放在集群服务中(使用基于 yada: booyah 标签的选择器) 集群.deployment.yml

apiVersion: v1
kind: Service
metadata:
  name: server-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    yada: booyah
  ports:
    - name: "8000"
      port: 8000
      targetPort: 8000
    - name: "8080"
      port: 8080
      targetPort: 8080

这就是

kubectl get all
显示的内容:

NAME                                      READY   STATUS    RESTARTS   AGE
pod/k8s-api-deployment-8cf4dcd8c-p7gbz    1/1     Running   0          2m38s
pod/k8s-web-deployment-7cdf999d48-mx76j   1/1     Running   0          4s

NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/k8s-api                     LoadBalancer   10.108.64.186   localhost     8000:30825/TCP      2m38s
service/k8s-web                     LoadBalancer   10.106.86.200   localhost     8080:32391/TCP      4s
service/kubernetes                  ClusterIP      10.96.0.1       <none>        443/TCP             36h
service/server-cluster-ip-service   ClusterIP      10.109.42.57    <none>        8000/TCP,8080/TCP   4s

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/k8s-api-deployment   1/1     1            1           2m38s
deployment.apps/k8s-web-deployment   1/1     1            0           4s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/k8s-api-deployment-8cf4dcd8c    1         1         1       2m38s
replicaset.apps/k8s-web-deployment-7cdf999d48   1         1         1       4s

有什么建议吗?

node.js docker express kubernetes
1个回答
0
投票

您已从前端服务器添加了 localhost:8000,相反,您应该定义服务的原始值,在您的情况下为

http://k8s-api:8000
,也可用于内部连接使用 ClusterIP。

另外,通过暴露Host Port来检查后端服务是否给出200响应。

此外,您可以创建永久静态的服务 DNS:

serviceName.namespaceName.svc.cluster.local

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.