首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从Kubernetes的前端服务到达后端服务

无法从Kubernetes的前端服务到达后端服务
EN

Stack Overflow用户
提问于 2020-04-20 15:49:21
回答 1查看 1.3K关注 0票数 0

在Kubernetes中,我很难从前端应用程序到后端应用程序进行Http调用。

因此,基本上我对前端和后端应用程序都有部署、服务和入口规则,而前端服务不能连接到后端服务。

这是我收到的错误信息

net::ERR_NAME_NOT_RESOLVED GET http://spring-boot-vuejs:8080/api/courses

我试图创建一个简单的web应用程序,使用Vuejs作为前端,Spring引导作为后端。后端公开REST的on /api/courses/*终结点,前端使用它。

我已经部署了两个单独的吊舱,一个用于前端,另一个用于裸金属Kubernetes集群上的后端。我还安装了Nginx入口控制器

如果我在本地机器上运行两个对接映像,一切都会很好,因为我使用"http://localhost:8080“作为后端点,但是当我在Kubernetes上部署应用程序时,它就不能工作了,因为它可以解析服务名"http://spring-boot-vuejs:8080”。

我已经提到了提到的这里这里这里等问题,但没有一个问题对我有帮助。

下面是各自的yaml文件。如果我在yaml文件或入口规则中出错,请纠正我。

后端:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-vuejs
  labels:
    app: spring-boot-vuejs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-vuejs
  template:
    metadata:
      labels:
        app: spring-boot-vuejs
    spec:
      containers:
        - name: spring-boot-vuejs
          imagePullPolicy: ifNotPresent
          image: <my docker hub username>/spring-boot-vuejs:0.0.1
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-vuejs
  labels:
    app: spring-boot-vuejs
spec:
  clusterIP: None
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: spring-boot-vuejs
  selector:
    app: spring-boot-vuejs

入口规则

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: spring-boot-vuejs
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80

  rules:
    - host: spring-boot-vuejs
    - http:
        paths:
          - path: /api/.*
            backend:
              serviceName: spring-boot-vuejs
              servicePort: 8080

用于前端的Yaml文件

部署和服务

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vuejs-frontend
  labels:
    app: vuejs-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vuejs-frontend
  template:
    metadata:
      labels:
        app: vuejs-frontend
    spec:
      containers:
        - name: vuejs-frontend
          imagePullPolicy: ifNotPresent
          image: <my dockerhub username>/vuejs-frontend:0.0.1
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: vuejs-frontend
  labels:
    app: vuejs-frontend
spec:
  clusterIP: None
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: vuejs-frontend
  selector:
    app: vuejs-frontend

入口规则

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: vuejs-frontend
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /

spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: spring-boot-vuejs
    - http:
        paths:
          - path: /
            backend:
              serviceName: vuejs-frontend
              servicePort: 8080
EN

回答 1

Stack Overflow用户

发布于 2020-04-21 14:03:04

如果我正确地理解了您,问题是vuejs-frontend无法在端口8080上到达spring-boot-vuejs

我看到您已经创建了一个headless Service (带有clusterIP: None的服务)。此外,该服务没有yaml中指定的选择器,因此没有创建EndPoinds )

关于专题的正式文件说:

有时,您不需要负载平衡,而是需要单一的服务IP。在这种情况下,您可以通过为集群IP ( "None" )显式指定"None"来创建所谓的“无头”服务。 对于无头Services,不分配集群IP,kube不处理这些服务,也没有平台为它们进行负载平衡或代理。如何自动配置DNS取决于服务是否定义了选择器。 对于不定义选择器的无头服务,端点控制器不创建Endpoints记录。但是,DNS系统查找并配置:

  • ExternalName-type服务的CNAME记录。
  • 与服务共享名称的任何Endpoints的记录,用于所有其他类型

这里有一些解决办法。

  • 手动创建EP。
代码语言:javascript
复制
apiVersion: v1  
kind: Endpoints  
metadata:  
  name: spring-boot-vuejs  
  namespace: default  
subsets:  
- addresses:  
  - ip: IP_spring-boot-vuejs_pod 
  ports:  
  - name: http  
    port: 8080  
    protocol: TCP

因此,DNS将被正确地配置。

  • 若要创建其他类型的服务,或至少向当前服务添加选择器,请执行以下操作。

下面您可以看到它是如何在我的k8s安装上工作的。我使用的所有文件都来自我的GitHub回购。

代码语言:javascript
复制
$ kubectl create -f  deployment.yaml
deployment.apps/server-go-deploy created

$ kubectl get deployments
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
server-go-deploy      1/1     1            1           9s

$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

$ kubectl get pods -o wide 
NAME                         READY   STATUS  AGE     IP           
nginx-65f88748fd-vzgxx       1/1     Running 9m16s   10.52.3.13
server-go-6c84bbd44d-r5bsb   1/1     Running 14m     10.52.3.12

$ kubectl create -f service.yaml 
service/hello-go created

$ kubectl get services   -o wide 
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE    SELECTOR
hello-go     ClusterIP   None          <none>        8180/TCP   13s    <none>
kubernetes   ClusterIP   10.0.0.1      <none>        443/TCP    123d   <none>

$ kubectl exec -it nginx-65f88748fd-vzgxx -- curl hello-go:8180
curl: (6) Could not resolve host: hello-go
command terminated with exit code 6

## As you can see K8s knows nothing that request to 'hello-go' should be routed to 'hello-go' Pod. 

$ kubectl create -f ep.yaml 
endpoints/hello-go created

$ kubectl get ep  -o wide 
NAME         ENDPOINTS            AGE
hello-go     10.52.3.12:8180      3s
kubernetes   35.234.103.244:443   123d

kiwi@kiwi-dv7:~/PycharmProjects/innovative-solutions/61326587-svc$ kubectl exec -it nginx-65f88748fd-vzgxx -- curl hello-go:8180/whoo-hoo
Hello from ServerGo. You requested: /whoo-hoo 

#And now it works.

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61326587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档