前端和后端之间的Kubernetes通信

前端和后端之间的Kubernetes通信,kubernetes,Kubernetes,为了当地的发展,我有一个工作的minikube。在那里,我们部署了不同的服务。现在我想连接前端和后端 前端是一个有角度的应用程序,它提供自己的服务。 后端是node.js应用程序,也使用单独的服务,并使用DNS连接到其他内部服务,如mongodb 现在我想从前端与后端进行通信。DNS不工作,因为前端不知道如何解析命名路由。问题是告诉前端应该使用哪个后端URL和端口向其发送请求 当我第一次启动类型为NodePort的后端服务并将url和端口复制到前端目标url时,就接近了唯一的工作状态。我觉得这对

为了当地的发展,我有一个工作的minikube。在那里,我们部署了不同的服务。现在我想连接前端和后端

前端是一个有角度的应用程序,它提供自己的服务。 后端是node.js应用程序,也使用单独的服务,并使用DNS连接到其他内部服务,如mongodb

现在我想从前端与后端进行通信。DNS不工作,因为前端不知道如何解析命名路由。问题是告诉前端应该使用哪个后端URL和端口向其发送请求

当我第一次启动类型为NodePort的后端服务并将url和端口复制到前端目标url时,就接近了唯一的工作状态。我觉得这对我很不干净。是否有其他方法将后端请求的url获取到前端

我知道,当我们使用type=“LoadBalancer”在生产系统上部署服务时,该服务是由外部IP公开的,我可以从那里访问该服务。在pod更新时,外部IP将是永久的,等等。我还看到的问题是,后端IP需要通过额外的提交注入docker容器

编辑(1):后端服务

apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: some-app
    tier: backend
spec:
  type: NodePort
  ports:
  - port: 3000
  selector:
    app: some-app
    tier: backend
编辑(2):当我从具有fqn的客户端请求时,也会得到此响应:

OPTIONS http://backend.default.svc.cluster.local:3000/signup/ net::ERR_NAME_NOT_RESOLVED

我建议使用Kubernetes自己的方式,通过Ingress/IngressController灵活地摄入tarffic。在集群中部署了入口控制器之后,您可以轻松创建入口定义,告诉控制器在特定URL下公开服务。然后,您需要做的就是将DNS中的名称指向入口控制器loadbalancer(在大多数云设置中,将CNAME指向LB fqdn)


首先,我将尝试回答您的具体问题

当我第一次启动后端时,唯一的工作状态已经接近 类型为NodePort的服务,并将url和端口复制到 前端目标URL。我觉得这对我很不干净。有 另一种将后端请求的url获取到 前端

这里有两个选项1)如您所说,使用type=“LoadBalancer”。或者2)通过前端服务器代理所有后端调用

我知道在生产系统上部署服务时 type=“LoadBalancer”表示服务由外部IP公开,并且 我可以从那里访问服务。而外部IP 在pod更新时将是永久性的,等等。我也看到的问题是 后端IP需要通过以下方式注入docker容器: 额外的提交

  • 通过将配置从您的代码移到平台(比如k8s configmap或外部KV注册表,如Concur/eureka),使其成为12因素应用程序(或更接近12因素应用程序:))
  • 即使它留在代码中,正如您所说,外部IP将是可引用的,除非您这样做,否则它不会改变。我不明白你为什么需要另一个部署
  • 通过前端服务器代理所有后端调用 如果您通过前端的服务器端路由(或愿意路由)所有微服务/后端呼叫,并且在同一命名空间的同一k8s群集中部署前端和后端,那么您可以使用KubeDNS附加组件(如果k8s群集中还没有,您可以与k8s管理员联系)将后端服务名称解析为其IP。从您的前端服务器,您的后端服务将始终可以通过其名称进行解析

    由于k8s集群中有kubeDNS,并且前端和后端服务都位于同一k8s集群和同一命名空间中,因此我们可以利用k8s内置的服务发现机制。后端服务和前端服务将通过名称相互发现。这意味着,您只需使用DNS名称“backend”即可从前端吊舱访问后端服务。因此,只需通过前端nginx将所有后端请求代理到上游后端服务。在前端nginxpods中,后端服务的IP将可解析为域名“后端”。这也会帮你省去CORS的头痛。此设置是可移植的,这意味着,无论您是在dev、stage还是prod中部署,名称“backend”将始终解析为相应的后端

    这种方法的一个潜在缺陷是,您的后端可能无法独立于前端进行扩展;依我拙见,这没什么大不了的;在k8s环境中,如果需要,只需旋转更多的吊舱即可


    只是好奇-什么服务于您的前端(哪种服务器技术将index.html交付给用户的浏览器)?是像nginx或apachehttpd这样的静态服务器,还是您在这里使用nodejs?

    我们使用了一种不同于随机dude(这是一个不错的解决方案)的方法:我们让后端服务器为前端文件服务。我们已经为这两个单独的docker图像,但只使用一个pod。前端作为init容器运行,并将文件复制到emptydir卷。后端还装载该卷并在
    /
    上提供服务(所有后端资源都在其他路径上提供)。这样,前端和后端服务于同一主机

    您可以使用
    window.location.protocol+'/'+window.location.host
    在Angular代码中获取当前主机(现在也是后端主机)

    在本地开发人员机器上进行开发期间,我们在其各自独立的服务器上运行前端和后端。因此,我们有一个小助手函数,用于在所有情况下获取正确的后端url:

    public getBackendUrl(): string {
      return this.getBackendUrlInternal(window.location.protocol, window.location.host);
    }
    
    private getBackendUrlInternal(protocol: string, host: string): string {
      if (host === 'localhost:3000') {
        // running in local dev server, connect to local dev backend
        return 'http://localhost:8585';
      } else {
        // running in docker compose or on k8s, backend is on same host and port as we are
        return protocol + '//' + host;
      }
    }
    

    (有两种方法,因为我们对第二种方法进行了一些测试)

    这就是我如何配置Ingress以使用服务名称将前端应用程序连接到后端的方法

    BankendapiVersion: v1 kind: Service metadata: name: student-app-api spec: selector: app: student-app-api ports: - port: 8080 protocol: TCP targetPort: 8080
    const get = id => {
      return http.get(`api/students/`);
    };
    
    apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
    kind: Ingress
    metadata:
      name: student-app-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$1
    spec:
      rules:
      - http:
          paths:
            - path: /?(.*)
              backend:
                serviceName: student-app-client-service
                servicePort: 80
            - path: /api/?(.*)   //Redirect all request to backend (backend service name)
              backend:
                serviceName: student-app-api
                servicePort: 8080