Как мне подключить один модуль к сети в другой модуль в Kubernetes? (ПРОСТО) - PullRequest
0 голосов
/ 06 мая 2018

Я бился головой об эту стену некоторое время. В Интернете много информации о Kubernetes, но все это предполагает столько знаний, что n00bs, таким как я, на самом деле особо нечем заняться.

Итак, кто-нибудь может поделиться простым примером следующего (в виде файла yaml)? Все, что я хочу, это

  • две капсулы
  • скажем, у одного модуля есть бэкэнд (я не знаю - node.js), а у другого - внешний интерфейс (скажем, React).
  • Способ связи между ними.

А затем пример вызова API-интерфейса от задней панели к передней.

Я начинаю изучать подобные вещи, и внезапно я попадаю на эту страницу - https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-achieve-this. Это супер бесполезно . Я не хочу и не нуждаюсь в расширенных сетевых политиках, и при этом у меня нет времени проходить через несколько разных уровней обслуживания, которые отображаются поверх kubernetes. Я просто хочу выяснить тривиальный пример сетевого запроса.

Надеемся, что если этот пример существует в стеке, он также будет полезен другим людям.

Любая помощь будет оценена. Спасибо.

EDIT; похоже, что самым простым примером может быть использование контроллера Ingress.

РЕДАКТИРОВАТЬ, РЕДАКТИРОВАТЬ;

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

Ниже приведен мой yaml файл:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/frontend_example
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend
  labels:
    app: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/backend_example
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: LoadBalancer
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend
spec:      
  rules:
  - host: www.kubeplaytime.example
    http:
      paths:
      - path: /
        backend:
          serviceName: frontend
          servicePort: 80
      - path: /api
        backend:
          serviceName: backend
          servicePort: 80

Я считаю, что это делает

  • Развертывание внешнего и внешнего приложений - я развернул patientplatypus/frontend_example и patientplatypus/backend_example в dockerhub, а затем потянул изображения вниз. Один открытый вопрос, который у меня есть: что, если я не хочу извлекать изображения из док-станции и, скорее, просто хочу загрузить их с моего локального хоста, это возможно? В этом случае я отправляю свой код на рабочий сервер, собираю образы докеров на сервере и затем загружаю их в kubernetes. Преимущество заключается в том, что мне не нужно полагаться на dockerhub, если я хочу, чтобы мои изображения были приватными.

  • Он создает две конечные точки службы, которые направляют внешний трафик из веб-браузера в каждое из развертываний. Эти сервисы относятся к типу loadBalancer, потому что они балансируют трафик между (в данном случае 3) репликациями, которые у меня есть в развертываниях.

  • Наконец, у меня есть входной контроллер, который предполагается , чтобы мои службы могли перенаправляться друг к другу через www.kubeplaytime.example и www.kubeplaytime.example/api. Однако это не работает.

Что происходит, когда я запускаю это?

patientplatypus:~/Documents/kubePlay:09:17:50$kubectl create -f kube-deploy.yaml
deployment.apps "frontend" created
service "frontend" created
deployment.apps "backend" created
service "backend" created
ingress.extensions "frontend" created
  • Итак, во-первых, создается впечатление, что все детали мне нужны без ошибок.

    patientplatypus:~/Documents/kubePlay:09:22:30$kubectl get --watch services

    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

    backend LoadBalancer 10.0.18.174 <pending> 80:31649/TCP 1m

    frontend LoadBalancer 10.0.100.65 <pending> 80:32635/TCP 1m

    kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 10d

    frontend LoadBalancer 10.0.100.65 138.91.126.178 80:32635/TCP 2m

    backend LoadBalancer 10.0.18.174 138.91.121.182 80:31649/TCP 2m

  • Во-вторых, если я смотрю сервисы, я в конечном итоге получаю IP-адреса, которые я могу использовать для перехода в своем браузере на эти сайты. Каждый из вышеперечисленных IP-адресов работает при маршрутизации меня к внешнему интерфейсу и внутреннему интерфейсу соответственно.

ОДНАКО

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

patientplatypus:~/Documents/kubePlay:09:24:44$kubectl get ingresses
NAME       HOSTS                      ADDRESS   PORTS     AGE
frontend   www.kubeplaytime.example             80        16m
  • Таким образом, у меня нет адреса, который я могу использовать, и www.kubeplaytime.example не работает.

Похоже, что мне нужно сделать, чтобы маршрутизировать к входному расширению, которое я только что создал, - это использовать службу и развертывание на it для получения IP-адреса, но это начинает выглядеть невероятно сложным очень быстро.

Например, взгляните на эту статью среднего размера: https://medium.com/@cashisclay/kubernetes-ingress-82aa960f658e.

Может показаться, что необходимый код, добавляемый только для маршрутизации службы к входу (т.е. то, что он называет Ingress Controller ), выглядит так:

---
kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
spec:
  type: LoadBalancer
  selector:
    app: ingress-nginx
  ports:
  - name: http
    port: 80
    targetPort: http
  - name: https
    port: 443
    targetPort: https
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: ingress-nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: ingress-nginx
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3
        name: ingress-nginx
        imagePullPolicy: Always
        ports:
          - name: http
            containerPort: 80
            protocol: TCP
          - name: https
            containerPort: 443
            protocol: TCP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/nginx-default-backend
---
kind: Service
apiVersion: v1
metadata:
  name: nginx-default-backend
spec:
  ports:
  - port: 80
    targetPort: http
  selector:
    app: nginx-default-backend
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nginx-default-backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-default-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        image: gcr.io/google_containers/defaultbackend:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP

Это, казалось бы, нужно добавить к моему другому yaml коду выше, чтобы получить точку входа в службу для моей входящей маршрутизации, и она, похоже, дает ip:

patientplatypus:~/Documents/kubePlay:09:54:12$kubectl get --watch services
NAME                    TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
backend                 LoadBalancer   10.0.31.209   <pending>     80:32428/TCP                 4m
frontend                LoadBalancer   10.0.222.47   <pending>     80:32482/TCP                 4m
ingress-nginx           LoadBalancer   10.0.28.157   <pending>     80:30573/TCP,443:30802/TCP   4m
kubernetes              ClusterIP      10.0.0.1      <none>        443/TCP                      10d
nginx-default-backend   ClusterIP      10.0.71.121   <none>        80/TCP                       4m
frontend   LoadBalancer   10.0.222.47   40.121.7.66   80:32482/TCP   5m
ingress-nginx   LoadBalancer   10.0.28.157   40.121.6.179   80:30573/TCP,443:30802/TCP   6m
backend   LoadBalancer   10.0.31.209   40.117.248.73   80:32428/TCP   7m

Так что ingress-nginx - это сайт, на который я хочу попасть. Переход к 40.121.6.179 возвращает сообщение 404 по умолчанию (default backend - 404) - оно не переходит к frontend, как /, что необходимо для маршрутизации. /api возвращает то же самое. Переход к моему пространству имен хоста www.kubeplaytime.example возвращает 404 из браузера - без обработки ошибок.

ВОПРОСЫ

  • Строго ли необходим контроллер входа, и если да, то есть ли менее сложная версия этого?

  • Я чувствую, что я рядом, что я делаю не так?

ПОЛНЫЙ ЯМЛ

Доступно здесь: https://gist.github.com/patientplatypus/fa07648339ee6538616cb69282a84938

Спасибо за помощь!

РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ

Я пытался использовать HELM . На первый взгляд это простой интерфейс, и я попытался его раскрутить:

patientplatypus:~/Documents/kubePlay:12:13:00$helm install stable/nginx-ingress
NAME:   erstwhile-beetle
LAST DEPLOYED: Sun May  6 12:13:30 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                                       DATA  AGE
erstwhile-beetle-nginx-ingress-controller  1     1s

==> v1/Service
NAME                                            TYPE          CLUSTER-IP   EXTERNAL-IP  PORT(S)                     AGE
erstwhile-beetle-nginx-ingress-controller       LoadBalancer  10.0.216.38  <pending>    80:31494/TCP,443:32118/TCP  1s
erstwhile-beetle-nginx-ingress-default-backend  ClusterIP     10.0.55.224  <none>       80/TCP                      1s

==> v1beta1/Deployment
NAME                                            DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
erstwhile-beetle-nginx-ingress-controller       1        1        1           0          1s
erstwhile-beetle-nginx-ingress-default-backend  1        1        1           0          1s

==> v1beta1/PodDisruptionBudget
NAME                                            MIN AVAILABLE  MAX UNAVAILABLE  ALLOWED DISRUPTIONS  AGE
erstwhile-beetle-nginx-ingress-controller       1              N/A              0                    1s
erstwhile-beetle-nginx-ingress-default-backend  1              N/A              0                    1s

==> v1/Pod(related)
NAME                                                             READY  STATUS             RESTARTS  AGE
erstwhile-beetle-nginx-ingress-controller-7df9b78b64-24hwz       0/1    ContainerCreating  0         1s
erstwhile-beetle-nginx-ingress-default-backend-849b8df477-gzv8w  0/1    ContainerCreating  0         1s


NOTES:
The nginx-ingress controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace default get services -o wide -w erstwhile-beetle-nginx-ingress-controller'

An example Ingress that makes use of the controller:

  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls

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

Файл:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: frontend
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/frontend_example
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend
  labels:
    app: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/backend_example
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: LoadBalancer
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /api
            backend:
              serviceName: backend
              servicePort: 80
          - path: /
            frontend:
              serviceName: frontend
              servicePort: 80

Развертывание этого в кластере, однако, приводит к этой ошибке:

patientplatypus:~/Documents/kubePlay:11:44:20$kubectl create -f kube-deploy.yaml
deployment.apps "frontend" created
service "frontend" created
deployment.apps "backend" created
service "backend" created
error: error validating "kube-deploy.yaml": error validating data: [ValidationError(Ingress.spec.rules[0].http.paths[1]): unknown field "frontend" in io.k8s.api.extensions.v1beta1.HTTPIngressPath, ValidationError(Ingress.spec.rules[0].http.paths[1]): missing required field "backend" in io.k8s.api.extensions.v1beta1.HTTPIngressPath]; if you choose to ignore these errors, turn validation off with --validate=false

Итак, возникает вопрос: ну что за хрень, как мне это отладить? Если вы выплевываете код, который производит helm, он в основном не читается человеком - нет никакого способа пойти туда и выяснить, что происходит.

Проверьте это: https://gist.github.com/patientplatypus/0e281bf61307f02e16e0091397a1d863 - более 1000 строк!

Если у кого-то есть лучший способ отладить развертывание руля, добавьте его в список открытых вопросов.

РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ

Для упрощения в крайнем случае Я пытаюсь позвонить из одного модуля в другой, используя только пространство имен.

Итак, вот мой код React, где я делаю http-запрос:

axios.get('http://backend/test')
.then(response=>{
  console.log('return from backend and response: ', response);
})
.catch(error=>{
  console.log('return from backend and error: ', error);
})

Я также пытался использовать http://backend.exampledeploy.svc.cluster.local/test без удачи.

Вот мой код узла, обрабатывающий get:

router.get('/test', function(req, res, next) {
  res.json({"test":"test"})
});

Вот мой yaml файл, который я загружаю в кластер kubectl:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: frontend
  namespace: exampledeploy
  labels:
    app: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/frontend_example
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: exampledeploy
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend
  namespace: exampledeploy
  labels:
    app: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: nginx
        image: patientplatypus/backend_example
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  namespace: exampledeploy
spec:
  type: LoadBalancer
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000

Загрузка в кластер работает, как я вижу в моем терминале:

patientplatypus:~/Documents/kubePlay:14:33:20$kubectl get all --namespace=exampledeploy 
NAME                            READY     STATUS    RESTARTS   AGE
pod/backend-584c5c59bc-5wkb4    1/1       Running   0          15m
pod/backend-584c5c59bc-jsr4m    1/1       Running   0          15m
pod/backend-584c5c59bc-txgw5    1/1       Running   0          15m
pod/frontend-647c99cdcf-2mmvn   1/1       Running   0          15m
pod/frontend-647c99cdcf-79sq5   1/1       Running   0          15m
pod/frontend-647c99cdcf-r5bvg   1/1       Running   0          15m

NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
service/backend    LoadBalancer   10.0.112.160   168.62.175.155   80:31498/TCP   15m
service/frontend   LoadBalancer   10.0.246.212   168.62.37.100    80:31139/TCP   15m

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/backend    3         3         3            3           15m
deployment.extensions/frontend   3         3         3            3           15m

NAME                                        DESIRED   CURRENT   READY     AGE
replicaset.extensions/backend-584c5c59bc    3         3         3         15m
replicaset.extensions/frontend-647c99cdcf   3         3         3         15m

NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/backend    3         3         3            3           15m
deployment.apps/frontend   3         3         3            3           15m

NAME                                  DESIRED   CURRENT   READY     AGE
replicaset.apps/backend-584c5c59bc    3         3         3         15m
replicaset.apps/frontend-647c99cdcf   3         3         3         15m

Однако, когда я пытаюсь сделать запрос, я получаю следующую ошибку:

return from backend and error:  
Error: Network Error
Stack trace:
createError@http://168.62.37.100/static/js/bundle.js:1555:15
handleError@http://168.62.37.100/static/js/bundle.js:1091:14
App.js:14

Поскольку вызов axios осуществляется из браузера, мне интересно, если просто невозможно использовать этот метод для вызова бэкэнда, даже если бэкэнд и внешний интерфейс находятся в разных модулях. Я немного растерялся, так как думал, что это самый простой из возможных способов объединения сетевых модулей.

РЕДАКТИРОВАТЬ X5

Я определил, что можно свернуть серверную часть из командной строки, выполнив код в модуле так:

patientplatypus:~/Documents/kubePlay:15:25:25$kubectl exec -ti frontend-647c99cdcf-5mfz4 --namespace=exampledeploy -- curl -v http://backend/test
* Hostname was NOT found in DNS cache
*   Trying 10.0.249.147...
* Connected to backend (10.0.249.147) port 80 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.38.0
> Host: backend
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: application/json; charset=utf-8
< Content-Length: 15
< ETag: W/"f-SzkCEKs7NV6rxiz4/VbpzPnLKEM"
< Date: Sun, 06 May 2018 20:25:49 GMT
< Connection: keep-alive
< 
* Connection #0 to host backend left intact
{"test":"test"}

Что это означает, без сомнения, потому что код переднего плана выполняется в браузере, ему необходим Ingress для получения доступа к модулю, так как запросы http от внешнего интерфейса - это то, что ломает простую сеть под модулем. Я не был уверен в этом, но это означает, что необходим вход.

Ответы [ 3 ]

0 голосов
/ 06 мая 2018

Чтобы использовать входной контроллер, у вас должен быть действительный домен (DNS-сервер настроен для указания IP-адреса вашего входного контроллера). Это происходит не из-за какой-то «магии» kubernetes, а из-за того, как работают vhosts ( здесь является примером для nginx - очень часто используется в качестве входного сервера, но любая другая реализация входа будет работать так же капот).

Если вы не можете настроить свой домен, самый простой способ для этой цели - создать сервис kubernetes. Есть хороший способ сделать это, используя kubectl expose

kubectl expose pod frontend-pod --port=444 --name=frontend
kubectl expose pod backend-pod --port=888 --name=backend
0 голосов
/ 07 мая 2018

Как оказалось, я слишком усложнял вещи. Вот файл Kubernetes, который работает, чтобы делать то, что я хочу. Вы можете сделать это, используя два развертывания (внешний и внутренний) и одну точку входа службы. Насколько я могу судить, сервис может балансировать нагрузку на множество (не только на 2) различных развертываний, а это означает, что для практического развития это должно стать хорошим началом для развития микросервиса. Одним из преимуществ метода доступа является возможность использовать имена путей, а не номера портов, но, учитывая сложность, он не кажется практичным при разработке.

Вот файл yaml:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: frontend
  labels:
    app: exampleapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: exampleapp
  template:
    metadata:
      labels:
        app: exampleapp
    spec:
      containers:
      - name: nginx
        image: patientplatypus/kubeplayfrontend
        ports:
        - containerPort: 3000
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: backend
  labels:
    app: exampleapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: exampleapp
  template:
    metadata:
      labels:
        app: exampleapp
    spec:
      containers:
      - name: nginx
        image: patientplatypus/kubeplaybackend
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: entrypt
spec:
  type: LoadBalancer
  ports:
  - name: backend
    port: 8080
    targetPort: 5000
  - name: frontend
    port: 81
    targetPort: 3000
  selector:
    app: exampleapp

Вот команды bash, которые я использую, чтобы ускорить его (вам, возможно, придется добавить команду входа в систему - docker login - для отправки в dockerhub):

#!/bin/bash

# stop all containers
echo stopping all containers
docker stop $(docker ps -aq)
# remove all containers
echo removing all containers
docker rm $(docker ps -aq)
# remove all images
echo removing all images
docker rmi $(docker images -q)

echo building backend
cd ./backend
docker build -t patientplatypus/kubeplaybackend .
echo push backend to dockerhub
docker push patientplatypus/kubeplaybackend:latest

echo building frontend
cd ../frontend
docker build -t patientplatypus/kubeplayfrontend .
echo push backend to dockerhub
docker push patientplatypus/kubeplayfrontend:latest

echo now working on kubectl
cd ..
echo deleting previous variables
kubectl delete pods,deployments,services entrypt backend frontend
echo creating deployment
kubectl create -f kube-deploy.yaml
echo watching services spin up
kubectl get services --watch

Фактический код - это просто приложение взаимодействия с внешним интерфейсом, выполняющее HTTP-запрос axios к маршруту внутреннего узла на componentDidMount начальной страницы приложения.

Вы также можете увидеть рабочий пример здесь: https://github.com/patientplatypus/KubernetesMultiPodCommunication

Еще раз спасибо всем за помощь.

0 голосов
/ 06 мая 2018

Прежде всего, давайте проясним некоторые очевидные заблуждения. Вы упомянули, что ваш интерфейс - это приложение React, которое, вероятно, будет запускаться в браузере пользователей. Чтобы это работало, ваша настоящая проблема не в том, что ваши серверные и интерфейсные модули взаимодействуют друг с другом , но браузер должен иметь возможность подключаться к обоим этим модулям ( в интерфейсный модуль для загрузки приложения React и во внутренний модуль приложения React для выполнения вызовов API).

Для визуализации:

                                                 +---------+
                                             +---| Browser |---+                                                 
                                             |   +---------+   |
                                             V                 V
+-----------+     +----------+         +-----------+     +----------+
| Front-end |---->| Back-end |         | Front-end |     | Back-end |
+-----------+     +----------+         +-----------+     +----------+
      (what you asked for)                     (what you need)

Как уже говорилось, самое простое решение для этого будет использовать Ingress controller . Я не буду вдаваться в подробности о том, как настроить контроллер Ingress здесь; в некоторых облачных средах (например, GKE) вы сможете использовать контроллер Ingress, предоставленный вам облачным провайдером. В противном случае вы можете настроить NGINX Ingress controller . Обратитесь к руководству по развертыванию контроллеров NGINX для получения дополнительной информации.

Определение услуг

Начните с определения Сервисных ресурсов как для внешнего, так и для внутреннего приложения (они также позволят вашим модулям взаимодействовать друг с другом). Определение сервиса может выглядеть так:

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Убедитесь, что ваши модули имеют меток , которые могут быть выбраны ресурсом службы (в этом примере я использую app=backend и app=frontend в качестве меток).

Если вы хотите установить соединение Pod-to-Pod, все готово. В каждом модуле вы теперь можете использовать backend.<namespace>.svc.cluster.local (или backend в качестве сокращения) и frontend в качестве имен хостов для подключения к этому модулю.

Define Ingresses

Далее вы можете определить ресурсы Ingress; поскольку обеим службам потребуется подключение извне кластера (пользовательский браузер), вам понадобятся определения Ingress для обеих служб.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend
spec:      
  rules:
  - host: www.your-application.example
    http:
      paths:
      - path: /
        backend:
          serviceName: frontend
          servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: backend
spec:      
  rules:
  - host: api.your-application.example
    http:
      paths:
      - path: /
        backend:
          serviceName: backend
          servicePort: 80

В качестве альтернативы, вы также можете объединить интерфейс и бэкэнд с одним ресурсом Ingress (здесь нет «правильного» ответа, просто вопрос предпочтения):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend
spec:      
  rules:
  - host: www.your-application.example
    http:
      paths:
      - path: /
        backend:
          serviceName: frontend
          servicePort: 80
      - path: /api
        backend:
          serviceName: backend
          servicePort: 80

После этого убедитесь, что и www.your-application.example, и api.your-application.example указывают на внешний IP-адрес контроллера Ingress, и все готово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...