简体   繁体   English

如何使用服务名称访问kubernetes集群中的服务。

[英]How to access a service in a kubernetes cluster using the service name .

I am pretty new to kubernetes and I have successfully setup a cluster on google container engine . 我是kubernetes的新手,我已经在谷歌容器引擎上成功设置了一个集群。 In my cluster I have a backend api developed with dropwizard, front end developed with node js and a mysql database. 在我的集群中,我有一个用dropwizard开发的后端api,前端用节点js和一个mysql数据库开发。 All have been deployed to the cluster and are working .However my challenge is this after setting up an external ip for my node containers and backend I can access them remotely but I can't access my backed from my front end using the service name eg my backend is called backendapi within the cluster. 所有这些都已经部署到集群并且正在工作。但是我的挑战是在为我的节点容器和后端设置外部ip之后我可以远程访问它们但是我无法使用服务名称从我的前端访问我的支持,例如我的后端在集群中称为backendapi。 I can't do this http://backendapi:8080 to call my rest services when deployed to the cluster . 我不能这样做http:// backendapi:8080在部署到集群时调用我的休息服务。 The catch for me is when I deploy to the cluster I don't want my front end to hit my back end using the external ip, I want them to connect within the cluster without going via the external ip address. 对我来说,当我部署到集群时,我不希望我的前端使用外部IP命中我的后端,我希望它们在集群内连接,而无需通过外部IP地址。 When I connect to a pod and ping backendapi it returns a result but when I deploy my front end and use the label name it doesn't work .What could I be doing wrong ?. 当我连接到一个pod并ping backendapi时它会返回一个结果但是当我部署我的前端并使用标签名称时它不起作用。我可能做错了什么?

As long as kube-dns is running (which I believe is "always unless you disable it"), all Service objects have an in cluster DNS name of service_name +"."+ service_namespace + ".svc.cluster.local" so all other things would address your backendapi in the default namespace as (to use your port numbered example) http://backendapi.default.svc.cluster.local:8080 . 只要kube-dns正在运行(我相信“除非你禁用它”),所有服务对象都有一个群集 DNS名称service_name +"."+ service_namespace + ".svc.cluster.local"所以所有其他的东西会在default命名空间中将你的backendapi作为(使用你的端口编号的例子) http://backendapi.default.svc.cluster.local:8080 That fact is the very reason Kubernetes forces all identifiers to be a "dns compatible" name (no underscores or other goofy characters). 这个事实是Kubernetes迫使所有标识符成为“dns兼容”名称(没有下划线或其他愚蠢字符)的原因。

Even if you are not running kube-dns, all Service names and ports are also injected into the environment of Pods just like docker would do, so the environment variables ${BACKENDAPI_SERVICE_HOST}:${BACKENDAPI_SERVICE_PORT} would contain the Service's in-cluster IP (even though the env-var is named "host") and the "default" Service port (8080 in your example) if there is only one. 即使您没有运行kube-dns,所有服务名称和端口也会像${BACKENDAPI_SERVICE_HOST}:${BACKENDAPI_SERVICE_PORT}一样注入到${BACKENDAPI_SERVICE_HOST}:${BACKENDAPI_SERVICE_PORT}的环境中,因此环境变量${BACKENDAPI_SERVICE_HOST}:${BACKENDAPI_SERVICE_PORT}将包含服务的集群内IP (即使env-var命名为“host”)和“默认”服务端口(在您的示例中为8080)(如果只有一个)。

Whether you choose to use the DNS name or the environment-variable-ip is a matter of whether you like having the "readable" names for things in log output or error messages, versus whether you prefer to skip the DNS lookup and use the Service IP address for speed but less legibility. 您是否选择使用DNS名称或环境变量IP是一个问题,您是否希望在日志输出或错误消息中具有“可读”名称,而不是您是否希望跳过DNS查找并使用服务IP地址速度快但易读性差。 They behave the same. 他们的行为相同。

The whole story lives in the services-networking concept documentation 整个故事都存在于服务网络概念文档中

But the problem still persists when I change to this backendapi.default.svc.cluster.local:8080. 但是当我改为backendapi.default.svc.cluster.local:8080时,问题仍然存在。 I even tried using the other port that it is mapped to internally and my front end web page keeps saying backendapi.default.svc.cluster.local:32208/api/v1/auth/login net::ERR_NAME_NOT_RESOLVED. 我甚至尝试使用它内部映射到的另一个端口,我的前端网页一直在说backendapi.default.svc.cluster.local:32208 / api / v1 / auth / login net :: ERR_NAME_NOT_RESOLVED。 The funny thing is when I curl from my front end pod it works . 有趣的是,当我从我的前端吊舱卷曲时,它的工作原理。 But when I'm accessing it using my web browser it doesnt 但是当我使用我的网络浏览器访问它时,它并没有

Because it is resolvable only within the cluster. 因为它只能在群集中解析。 (Because only the K8s cluster with kube-dns add-on can translate the domain name backendapi.default.svc.cluster.local:8080 to it's corresponding IP address) (因为只有带有kube-dns附加组件的K8s群集才能将域名backendapi.default.svc.cluster.local:8080转换为相应的IP地址)

Could this be because i exposed an external ip for the service as well . 这可能是因为我也暴露了外部IP服务。 The external ip works though 外部ip工作

No, It is because domain name backendapi.default.svc.cluster.local is resolvable only within the cluster, not from a random browser in a random machine. 不,这是因为域名backendapi.default.svc.cluster.local只能在群集内解析,而不能从随机机器中的随机浏览器解析。

Solution

What you did is one of the solutions, exposing an external ip for the service. 你所做的是其中一个解决方案,为服务公开了一个外部ip。 If you don't want the IP to be used, you can Create an ingress (and use an ingress controller in your cluster) and expose your Microservice. 如果您不想使用IP,可以创建入口(并在群集中使用入口控制器)并公开您的微服务。 Since you are on GCP, you can make use of their API gateway rather than exposing a cryptic IP address. 由于您使用的是GCP,因此您可以使用其API网关,而不是暴露出神秘的IP地址。

Note : Remember to add the authentication/Authorization to lock down your microservice as it's getting exposed to the user. 注意 :请记住添加身份验证/授权以锁定您的微服务,因为它会暴露给用户。

Another Solution 另一种方案

Proxy all the backend calls through the server which serves your web app (nginx/nodejs etc) 代理所有后端调用通过服务器为您的Web应用程序服务(nginx / nodejs等)

Advantage of this approach is, you will avoid all the Same Origin Policy/CORS headaches, your microservice (express) authentication details will be abstracted out from user's browser. 这种方法的优点是,您将避免所有同源策略/ CORS头痛,您的微服务(快速)身份验证详细信息将从用户的浏览器中抽象出来。 (This is not necessarily an advantage). (这不一定是优势)。

Disadvantage of this approach is, your backend microservice will have a tight coupling with front end (or vice-versa depending on how you look at it), This will make the scaling of backend dependent on front end. 这种方法的缺点是,你的后端微服务将与前端紧密耦合(反之亦然,具体取决于你如何看待它),这将使后端的扩展依赖于前端。 Your Backend is not exposed. 您的后端未暴露。 So, if you have another consumer (let's just say an android app) it will not be able to access your service. 所以,如果你有另一个消费者(我们只是说一个Android应用程序),它将无法访问您的服务。

Hybrid Solution 混合解决方案

Proxy all the backend calls through the server which serves your web app (nginx/nodejs etc) so that your APIs will inherit your webapps domain. 代理所有后端调用通过服务器为您的Web应用程序(nginx / nodejs等)提供服务,以便您的API将继承您的webapps域。 And still expose the backend service (as and when required) so that other consumers (if any, in future) can make use of it. 并且仍然暴露后端服务(在需要时),以便其他消费者(如果有的话,将来)可以使用它。

Kind of similar question: https://stackoverflow.com/a/47043871/6785908 类似的问题: https//stackoverflow.com/a/47043871/6785908

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

相关问题 使用入口在远程Kubernetes集群中的访问服务 - Access service in remote Kubernetes cluster using ingress 如何按名称访问kubernetes中的服务IP? - How to access the service ip in kubernetes by name? 无法使用 NodePort 访问我本地 kubernetes 集群中的服务 - Can't access service in my local kubernetes cluster using NodePort Helm、Kube.netes、如何配置Pod访问集群外的服务? - Helm, Kubernetes, how to configure Pod to access a service outside the cluster? 如何在集群外访问/公开 kubernetes-dashboard 服务? - How to access/expose kubernetes-dashboard service outside of a cluster? 如何使用 docker 桌面 k8s 集群在本地主机/本地机器上部署和访问负载均衡器 kube.netes 服务? - how to deploy and access loadbalancer kubernetes service on localhost/local machine using docker desktop k8s cluster? Kubernetes中按服务名访问redis - Access redis by service name in Kubernetes 如何从 kubernetes 集群内提供的服务访问安装在 kubernetes 集群外的 kafka - How to access kafka installed outside kubernetes cluster from a service provisioned inside a kubernetes cluster 无法通过 kubernetes 上的服务名称访问服务 - Not able to access service by service name on kubernetes 无法访问 Kubernetes 集群外的 NodePort 服务 - Cannot access NodePort service outside Kubernetes cluster
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM