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

Независимое тестирование масштабированных развертываний в Kubernetes

Я пытаюсь придумать подход для достижения следующего.

  1. У меня есть несколько развертываний для нескольких компонентов, которые вместе завершают мое приложение. Для простоты предположим, что есть интерфейс, бэкэнд и база данных.
  2. Когда я развертываю (с 1 модулем каждый) все компоненты и освобождаю интерфейс за внешним IP-адресом, я могу получить доступ к приложению. Внутренние сетевые подключения следующие. Frontend 1 -> Backend 1 -> Database 1
  3. Мое требование масштабирования таково, что при создании второй копии развертываний я хочу получить доступ к полностью независимому (от первого развертывания) сценарию, например Frontend 2 -> Backend 2 -> Database 2. Вариант использования - поддержка нескольких параллельных тестов на разных данных в базе данных. Например, если Test A продолжается и Test B требуется, раскручиваем приложение и запускаем независимое тестирование.

Как я могу этого добиться?

С помощью того, что я пробовал до сих пор, служба балансировки нагрузки, открывающая интерфейс для внешнего IP-адреса, будет балансировать трафик либо на Frontend 1 или Frontend 2 и так же для серверной части и базы данных, к которой они подключаются. Я также могу добавить все контейнеры в один модуль как единое развертывание, чтобы серверная часть и база данных были отделены от других развертываний через соединения localhost, но интерфейс, к которому я подключаюсь, все равно не будет таким, как хотелось бы.

Могу ли я настроить отображение 1-1 в службе балансировки нагрузки? Я упустил что-то важное?

Балансировщик нагрузки не предназначен для балансировки вашего трафика между разными Deployments но между набором Pods в пределах одного Deployment. Если у вас только один Pod в каждом из них действительно нечего балансировать. Если ваш Frontend1 Deployment состоит скажем из 3 Pods, Loadbalancer заботится о том, чтобы равномерно распределять ваш трафик между этими 3 Pods. Насколько я понимаю ваш Frontend1 и Frontend2 это два отдельных развертывания, и вы хотите иметь возможность гибко переключать свой трафик, не только его часть, но и весь трафик между Frontend1 и Frontend2, право ?

Это можно сделать довольно легко, однако гораздо лучше было бы использовать два отдельных LoadBalancers для Frontend1 и Frontend2 Deployments. Предположим, у вас есть внешний LoadBalancer определено в lb.yaml файл:

apiVersion: v1
kind: Service
metadata:
  name: example-loadbalancer-service
spec:
  selector:
    app: nginx-prod
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

Как видите, он использует app: nginx-prod селектор, что означает, что он выбирает только Pods который имеет app этикетка с nginx-prod значение определено. Чтобы переключить ваш трафик на nginx-dev Поды, которые являются частью вашего Frontend2 Deployment вам нужно только обновить этот файл, изменив nginx-prod к nginx-dev и примените новую конфигурацию с помощью следующей команды:

kubectl apply -f lb.yaml

Ваш внешний трафик будет немедленно направлен на Pods управляется вашим Frontend2 Deployment. Вы можете легко протестировать это, используя два следующих манифеста yaml:

Развертывание 1 (это может быть твой Frontend1):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-prod
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-prod
  template:
    metadata:
      labels:
        app: nginx-prod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        volumeMounts:
        - name: workdir
          mountPath: /usr/share/nginx/html
      initContainers:
      - name: install
        image: busybox
        command: ["/bin/sh","-c"]
        args: ["echo Welcome on Prod! > /work-dir/index.html"]
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
      volumes:
      - name: workdir
        emptyDir: {}

Развертывание 2 (это может быть твой Frontend2):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-dev
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-dev
  template:
    metadata:
      labels:
        app: nginx-dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        volumeMounts:
        - name: workdir
          mountPath: /usr/share/nginx/html
      initContainers:
      - name: install
        image: busybox
        command: ["/bin/sh","-c"]
        args: ["echo Welcome on Dev! > /work-dir/index.html"]
        volumeMounts:
        - name: workdir
          mountPath: "/work-dir"
      volumes:
      - name: workdir
        emptyDir: {}

Когда дело доходит до балансировки запросов, исходящих от вашего интерфейса Pods на ваш сервер Pods это можно сделать очень похожим образом, но в этом нет необходимости LoadBalancer но просто ClusterIP Обслуживание (ClusterIP можно опустить в Service определение, поскольку это тип по умолчанию), как показано ниже:

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

Обратите внимание, что в нем app: prod-backend селектор. Представьте, что ваш dev набор модулей, управляемых Backend2 Deployment имеет другое значение этой метки. Это может быть, например, dev-backend. Как только вы измените селектор в своем Service из app: prod-backend к app: dev-backend, весь ваш трафик идет так далеко от вашего интерфейса Pods к Backend1 будет перенаправлен на ваш Backend2 Pods (помечены как dev-backend). Я делюсь этим только для того, чтобы показать вам, что это тоже возможно, но такой подход не имеет смысла. Что касается LoadBalancer, Я согласен, что создание дополнительных LoadBalancer требует дополнительных затрат, но это не относится к простым ClusterIP Services. Итак, в этом случае вы должны определить два разных Services, каждый из которых использует свой селектор. Затем используйте полное доменное имя службы, которое будет другим для Backend1 и Backend2 Service вы можете направить свой трафик соответственно из Frontend1 и Frontend2.

Надеюсь, это немного проясняет использование LoadBalancer и ClusterIP Service. Если что-то не совсем понятно, не стесняйтесь обращаться и задавать дополнительные вопросы.