Невозможно получить доступ к бэкэнд-сервису из внешнего сервиса в Кубернетесе - PullRequest
0 голосов
/ 20 апреля 2020

Я изо всех сил пытаюсь сделать Http-вызовы из внешнего интерфейса в бэкэнд-приложение в Кубернетесе.

Так что в основном у меня есть правила развертывания, обслуживания и доступа как для внешнего, так и для внутреннего приложения, а служба внешнего интерфейса может ' t подключиться к бэкэнд-сервису.

Это сообщение об ошибке, которое я получаю

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

Я пытаюсь создать простое веб-приложение, используя Vuejs в качестве внешнего интерфейса и загрузку Spring в качестве внутреннего интерфейса. Бэкэнд предоставляет конечную точку API REST для / api / courses / *, а внешний интерфейс потребляет ее.

Я развернул два отдельных модуля: один для внешнего интерфейса и один для внутреннего интерфейса в голометаллическом кластере Kubernetes . Я также установил Nginx входной контроллер .

, если я запускаю оба docker образа на локальном компьютере, все работает нормально, потому что я использую "http://localhost: 8080"как конечная точка бэкэнда, но как только я разверну приложения в Kubernetes, они больше не будут работать, поскольку могут разрешать имя службы" http://spring-boot-vuejs: 8080"

I уже упоминалось о проблемах, упомянутых здесь , здесь , здесь но ни одна из них не помогла мне.

Ниже приведены соответствующие файлы yaml. Пожалуйста, исправьте меня, если я делаю ошибку в любых файлах yaml или правилах входа.

Backend:

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

Правила входа

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 для интерфейса

Развертывание и обслуживание

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

Входные правила

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

1 Ответ

0 голосов
/ 21 апреля 2020

Если я правильно вас понял, проблема в том, что vuejs-frontend не может достичь spring-boot-vuejs на порту 8080.

. Я вижу, что вы создали headless Service (Служба с clusterIP: None). Более того, у этой службы нет селекторов, указанных в yaml, поэтому EndPoinds не было создано)

Официальная документация по topi c гласит:

Иногда вам не нужна балансировка нагрузки, а только один IP-адрес службы. В этом случае вы можете создать так называемые «безголовые» службы, явно указав "None" для IP-адреса кластера (.spec.clusterIP).

Для безголовых Services IP-адрес кластера не выделяется, kube-proxy не обрабатывает эти Сервисы, и платформа не выполняет для них балансировку нагрузки или прокси. Способ автоматической настройки DNS зависит от того, определены ли в службе селекторы.

Для автономных служб, которые не определяют селекторы, контроллер конечных точек не создает Endpoints записей. Однако система DNS ищет и настраивает:

  • CNAME-записи для ExternalName -типа служб.
  • A-записи для любых Endpoints, которые поделиться именем со Службой для всех других типов

Здесь есть несколько решений.

  • для создания EP вручную.
В результате
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 .

$ 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.

Надеюсь, это поможет.

...