2017-07-18 686 views
2

对于本地开发,我有一个工作的minikube。我们有不同的服务部署。现在我想将前端连接到后端。Kubernetes前端和后端之间的通信

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

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

当我首次启动具有类型NodePort的后端服务并将url和端口复制到前端目标URL时,唯一的工作状态被接近。我认为这对我来说很不洁净。有没有另一种方法将后端请求的URL加入前端?

我知道当我们在类型=“LoadBalancer”的生产系统上部署一项服务时,该服务通过外部IP公开,我可以从那里访问该服务。并且外部IP在pod更新等情况下将是永久的。我也看到的问题是,需要通过额外的提交将后端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 
+0

你揭露你服务后台?如果是的话,你应该已经定义了服务定义中的端口,并且你应该得到DNS解析说http:// backend:80/

+0

@SebastienGoasguen我已经添加了后端服务定义。所以我已经为后端定义了端口3000,并且它也不可访问。我认为角度应用程序不知道如何解决DNS名称'后端'。 – Lunero

+0

你可以用这个'backend.default.svc.cluster.local'来尝试fqn。您可能需要将默认值替换为您的名称空间。 – sfgroups

回答

3

这要看情况。

您是通过前端服务器还是通过Angular(在用户浏览器上运行)代理所有后端调用,直接击中真正的后端?你是否在使用API​​网关等任何模式?

如果您通过前端的服务器端路由(或愿意路由)所有微服务/后端调用,并且如果将同一个k8s群集中的前端和后端部署在相同的名称空间中,那么您可以使用KubeDNS附加组件(如果它尚未在k8s群集中提供,则可以使用k8s admin进行检查)将后端服务名称解析为IP。从您的前端服务器,您的后端服务将始终可以通过名称解析。

只是好奇 - 为您的前端提供什么服务(哪种服务器技术将您的index.html提供给用户的浏览器)?它是像nginx或apache httpd这样的静态服务器,还是你在这里使用nodejs?

编辑

溶液:既然你在你的K8S有kubeDNS集群,既前端和后端服务驻留在同一集群K8S和相同的命名空间,我们可以利用的K8S'内置的服务发现机制;后端服务和前端服务应该可以通过名称相互发现。这意味着,您可以简单地使用DNS名称“后端”从前端窗格中访问后端服务。所以,只需通过前端nginx将所有后端请求代理到您的上游后端服务即可。在前端nginx pod中,后端服务的IP可以解析为域名“后端”。这也将为您节省CORS头痛。这种设置是可移植的,也就是说,无论您是在dev还是stage或prod中进行部署都无关紧要,名称“后端”将始终解析为相应的后端。

这种方法的潜在缺陷是,您的后端可能无法独立于前端进行缩放。在我的愚见中,这不是什么大问题;在k8s环境中,如果需要的话,这只是旋转更多吊舱的问题。

+0

对不起,我目前没有提到在它前面有一个nginx服务来处理后端和前端。 所以我的后端,前端和nginx位于相同的命名空间。 Kubedns也被定义。 – Lunero

+0

不用担心。因此,实现它非常容易,可以通过前端nginx将所有后端请求代理到上游后端服务。在前端nginx中,后端服务的IP可以解析域名“后端”。这也将为您节省CORS头痛。这种设置是可移植的,也就是说,无论您是在dev还是stage或prod中进行部署都无关紧要,名称“后端”将始终解析为相应的后端。 –

+0

非常感谢帮助。结合Marc Sl​​uiter的回答,我将它运用起来。提前致谢。 – Lunero

0

我会sugest使用Kubernetes拥有使用Ingress/IngressController灵活调用tarffic的方式。 Havin入口控制器部署在您的集群中,您可以轻松创建Ingress定义,告诉控制器在特定URL下公开服务。所有你需要做的就是在DNS中将该名称指向Ingress Controllers负载均衡器(在大多数将使用CNAME指向LB fqdn的云设置中)。

https://kubernetes.io/docs/concepts/services-networking/ingress/ https://github.com/kubernetes/ingress

2

我们使用的方法不同于so-random-dude(这是一个很好的解决方案)的答案:我们让后端服务器为前端文件提供服务。我们为两者分隔了泊坞窗图像,但仅使用1个吊舱。前端作为init容器运行并将文件复制到emptydir卷。后端也安装该卷并在/上提供该服务(所有后端资源都在其他路径上提供服务)。这样前端和后端在同一台主机上提供服务。

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

在开发本地开发机器的过程中,我们在自己分离的服务器上运行前端和后端。因此,我们必须为获得正确的后端的网址在所有情况下的小帮手功能:

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; 
    } 
} 

(有2种方法,因为我们有:第二个部分的测试)