Назад | Перейти на главную страницу

Использование kubernetes ingress для предоставления доступа к нескольким службам без раскрытия служб с помощью NodePort

Я пытаюсь настроить такой кластер:

+--------------+  +---------------+
|              |  |               |
| Express API  |  | Front End     |
|              |  | Static Assets |
|              |  |               |
+------+-------+  +--------+------+
       ^                   ^
       |                   |
       |                   |
+------+-------------------+------+
|  /api/..                 /      |
|            Ingress              |
+--------------+------------------+
               ^
               +
            Internet

А пока делаю это на Minikube.

Я просмотрел эти два руководства:

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

https://medium.com/@Oskarr3/setting-up-ingress-on-minikube-6ae825e98f82

Во втором руководстве он раскрывает свои развертывания с помощью служб NodePort, а затем настраивает свой входящий трафик для использования этих служб.

Это также означает, что к этим сервисам можно получить доступ напрямую через IP-адрес.

Однако я понимаю, что в этом нет необходимости - вы можете просто объявить неэкспонированный сервис и позволить Ingress раскрыть их. (аналогично тому, как они это сделали в этой официальной документации).

то есть:

kind: Service
apiVersion: v1
metadata:
  name: template-frontend-service
  labels:
    app: template
spec:
  selector:
    app: template
    type: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

kind: Service
apiVersion: v1
metadata:
  name: template-api-service
  labels:
    app: template
spec:
  selector:
    app: template
    type: api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3001

Но здесь я столкнулся с проблемой:

Вход:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend-service
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api-service
              servicePort: 80

Я получил:

Служба 503 временно недоступна nginx / 1.13.12

С другой стороны, если я просто выставлю свои развертывания напрямую с помощью:

kubectl expose deploy template-api --type=NodePort
kubectl expose deploy template-frontend --type=NodePort

(это даст мне две услуги template-api и template-frontend)

тогда эта конфигурация будет работать:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api
              servicePort: 80

Что мне здесь не хватает?

Служба 503 временно недоступна

Я получаю эту ошибку в двух случаях:

  • служба, указанная во входящем входе, не существует
  • служба существует, но не существует модуля, соответствующего селектору службы.

Контроллер Nginx Ingress может получить доступ к сервису без необходимости указывать type=NodePort за услугу. Я протестировал конфигурацию, очень близкую к вашей, и она отлично работает с сервисом. type=ClusterIP.
Версия Miniube - v0.30.0 (добавлен входящий аддон)

Сервис Ingress настроен как NodePort, потому что мы должны получить к нему доступ с хост-машины:

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
  namespace: kube-system
  labels:
    app.kubernetes.io/name: nginx-ingress-controller
    app.kubernetes.io/part-of: kube-system
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app.kubernetes.io/name: nginx-ingress-controller
    app.kubernetes.io/part-of: kube-system

Вот протокол эксперимента:
Я создал два развертывания для внешнего интерфейса и API и проверил, работает ли он:

$ kubectl run template-frontend --image=hashicorp/http-echo --labels=app=template,type=frontend -- -listen=:80 -text="Frontend"
$ kubectl run template-api --image=hashicorp/http-echo --labels=app=template,type=api -- -listen=:80 -text="API"
$ kubectl get pods -o wide

Я выставил их через службу ClusterIP и проверил их адреса:

$ kubectl expose deployment template-frontend --port=80
$ kubectl expose deployment template-api --port=80
$ kubectl get svc -o wide

Я проверил доступность модулей через службы, используя их ClusterIP:

$ kubectl run ubuntu --rm -it --image ubuntu --restart=Never --command -- bash -c 'apt-get update && apt-get -y install curl less net-tools && bash'

root@ubuntu:/# curl http://10.96.101.51
API
root@ubuntu:/# curl http://10.107.165.156
Frontend

Я применил к кластеру файл ingress.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: template-ingress
  labels:
    app: template
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
    - host: template.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: template-frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: template-api
              servicePort: 80

Теперь мне нужно проверить IP-адрес узла minikube:

$ minikube ip
192.168.99.100

и порт узла обслуживания:

$ kubectl get svc --all-namespaces | grep ingress

Обычно номер порта находится в диапазоне от 30000 до 33000.

kube-system   nginx-ingress          NodePort    10.99.220.242    <none>        80:32462/TCP,443:32318/TCP   1h        app.kubernetes.io/name=nginx-ingress-controller,app.kubernetes.io/part-of=kube-system

Наконец, я проверяю, могут ли модули обслуживать запросы через вход:

$ curl -H "Host:template.example.com" http://192.168.99.100:32462/api/
API
$ curl -H "Host:template.example.com" http://192.168.99.100:32462/
Frontend