繁体   English   中英

在 Kubernetes 中连接前端和后端

[英]Connecting Frontend and Backend in Kubernetes

我的前端设置为:

this.http.post<any>(`${environment.apiUrl}/auth/login`, {email, password})

其中apiUrl: 'http://backend/api'

我在一个容器中构建了前端并将其暴露给负载均衡器服务,我试图通过 ClusterIP 服务将它连接到端口 3000 上的后端。

前端 YAML:

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    tier: frontend
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      tier: frontend
  replicas: 1
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: frontend
        image: <Image>
        imagePullPolicy: Always
        ports:
        - containerPort: 80

后端 YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: app
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: app
        tier: backend
    spec:
      containers:
      - name: frontend-container
        image: <Image>
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: app
    tier: backend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

正如这里的文档中所解释的那样。

但是当我尝试从浏览器访问它时它不起作用,我收到未知错误!

在此处输入图像描述

在此处输入图像描述

这是前端内部的屏幕截图,确保它能够在内部到达后端。

在此处输入图像描述

我不明白我在哪里出错了。 我认为设置为 http://backend 的 apiUrl var 未正确翻译,因为如果我将其更改为负载均衡器 IP 并重建图像,将后端暴露给 LB 服务而不是 ClusterIP。 它确实有效。

但显然我不想将我的后端暴露给 LB 服务。

任何想法?

请看以下内容:

outside world  | k8s cluster
               | 
Browser  -->   | Nginx-pod --> backend-pod
               |
               |

url http://backend/api只能在集群内解析,但是你的浏览器在外面,所以不知道这个url是什么。

理想情况下,您将使用ingress来管理集群 pod 的路由。

正如@Elgarni 所说,客户端的浏览器无法访问您的集群,因此http://backend/api无法在集群外部解析。
如果您定义了入口,请使用kubectl get ingress命令并了解您的外部 IP。 然后将您的${environment.apiUrl}替换为http://$EXTERNAL_IP/api/或为您的外部 IP 定义 DNS 记录并通过您定义的域进行访问。

我们也可以使用 nginx 反向代理。 其中后端服务不需要使用入口或负载均衡器公开。 以下步骤对我来说很好

  1. 例如:将 http://api-service/api/getsomething 替换为
    /api/getsomething

    /api/getsomething - 这将告诉浏览器它将请求发送到为您的前端应用程序提供服务的同一服务器(在这种情况下为 nginx)

    然后通过 nginx 服务器,呼叫可以使用 K8S 转发到您的 api
    DNS。 (称为反向代理)

  2. 样品 docker 文件:

     ### STAGE 1: Build ### FROM node:16 as build # Create app directory WORKDIR /app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json./ RUN npm install # Bundle app source COPY. . RUN npm run build ###STAGE 2: Run ### FROM nginx:alpine RUN rm -rf /usr/share/nginx/html/* && rm -rf /etc/nginx/conf.d/default.conf && rm -rf /etc/nginx/nginx.conf COPY nginx.conf /etc/nginx COPY --from=build /app/dist/angular-frontend /usr/share/nginx/html #Optional to mention expose as it will be taken by nginx sever, port 80 wil be taken from nginx server EXPOSE 80
  3. 示例 nginx 配置文件:

     worker_processes 1; events { worker_connections 1024; } http { #upstream local { #server localhost:5000; #} upstream backend { server backend-service:80; } server { listen 80; #server_name localhost; server_name backend-service; root /usr/share/nginx/html; index index.html index.htm; include /etc/nginx/mime.types; gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend; } #location /api/v1/ { #proxy_pass http://local; #} }

    }

注意:这适用于 k8s 集成。 但是对于本地测试,我在 windows 机器中使用了 wsl2,并且曾经用 localhost 后端容器替换了 k8s 后端服务配置。 我收到以下错误:*3 connect() failed (111: Connection refused) while connection to upstream, client: 172.17.0.1,

我认为这里提到的 wsl2 集成存在问题。 https://github.com/Budibase/budibase/issues/4996

但适用于 k8s。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM