Серия практических занятий Kubernetes по сервису облачных контейнеров Alibaba — Ingress

Kubernetes

Автор: Ронг Бин, внутренний архитектор Kuzha Online, специализирующийся на управлении микросервисами, технологии контейнеризации, Service Mesh и других технических областях.

Рекомендация проекта с открытым исходным кодом

Pepper Metricsэто инструмент с открытым исходным кодом, разработанный мной и моими коллегами (GitHub.com/live-actioncool/pep…), который собирает текущую статистику производительности jedis/mybatis/httpservlet/dubbo/motan и предоставляет ее для основных данных, совместимых с базой данных временных рядов, таких как prometheus, и отображает тенденции через grafana. Его подключаемая архитектура также очень удобна для пользователей, позволяющих расширять и интегрировать другие компоненты с открытым исходным кодом.
Пожалуйста, поставьте звезду и пригласите всех стать разработчиками и отправить PR, чтобы вместе улучшить проект.

Задний план

статус кво

Предыдущая статья в основном посвящена исследованию и тестированию производительности основных сетевых компонентов перед внедрением контейнеризации.Для заинтересованных студентов, пожалуйста, обратитесь к:Тест производительности сети Aliyun K8S CNI с открытым исходным кодом

В настоящее время серверная архитектура компании представляет собой модель микросервисной архитектуры, как показано на рисунке ниже. Весь входящий трафик поступает во внутреннюю службу через шлюз API. Шлюз API действует как «защитник» и контролирует весь входящий трафик, запросы и имеет важные функции, такие как защита от кистей, мониторинг производительности интерфейса и оповещение.После того, как трафик проходит через шлюз, вызовы между сервисами — это все вызовы RPC.

переходный период

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

  • Разделение сервисов приводит к увеличению количества машин
  • Чтобы сократить потери ресурсов, стоимость управления портами, вызванная развертыванием нескольких служб на одном хосте.
  • Несогласованная среда доставки, что приводит к затратам на устранение неполадок

Чтобы решить вышеуказанные проблемы, после исследования мы сосредоточимся на контейнерной службе Kubernetes для решения наших проблем.Эта статья в основном посвящена части nginx-ingress-controller (далее именуемой NGINX IC), поэтому следующая архитектура в основном выделяет шлюз API и IC. На картинке ниже показан наш план перехода: Путем введения внутрисетевого SLB для решения проблемы обнаружения сервисов, когда IC является вышестоящим по отношению к нашему шлюзу API. Кроме того, эффекта постепенной миграции можно добиться за счет постепенного переключения интерфейса на SLB, а гранулярность может быть на уровне интерфейс+процент. Схема архитектуры в переходный период выглядит следующим образом:

конечное состояние

После завершения всех миграций все машины перезапускаются, как показано на следующем рисунке:

На самом деле, два слоя SLB будут расточительны, но поскольку наш API-шлюз в настоящее время играет важную роль, мы должны найти альтернативу его удалению. Мы также попытались исследовать решение Istio с пользовательской архитектурой IC или Service Mesh.Поскольку Istio 1.1 еще не был выпущен в то время, а масштабных вариантов использования было слишком мало, мы консервативно выбрали текущее компромиссное решение.Это не очень хлопотно перейти на Istio в будущем.

Групповые интеграторы по направлениям деятельности

По умолчанию весь трафик Kubernetes ложится на набор IC по умолчанию, мы с самого начала отказались от этого решения, поэтому необходимо добиться определенной изоляции, развернув несколько наборов IC. Это закончится в форме, показанной выше.

Упражняться

Как включить Multi-IC

Глядя на параметры команды запуска ИС, можно найти:

Это означает, что нужно обращать внимание только на определение Ingress с аннотацией «kubernetes.io/ingress.class» и тем же значением, что и параметр параметра запуска IC --ingress-class, если он не совпадает, он будет проигнорирован. , так что достигается несколько групп IC. , изоляция между определениями Ingress. Например:

containers:
  - args:
    - /nginx-ingress-controller
    - --ingress-class=xwz #看这里
    - --configmap=$(POD_NAMESPACE)/xwz-nginx-configuration
    - --tcp-services-configmap=$(POD_NAMESPACE)/xwz-tcp-services
    - --udp-services-configmap=$(POD_NAMESPACE)/xwz-udp-services
    - --annotations-prefix=nginx.ingress.kubernetes.io
    - --publish-service=$(POD_NAMESPACE)/xwz-nginx-ingress-lb
    - --v=2

так же как

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "xwz" #看这里
  labels:
    app: tap-revision-ing
    wayne-app: tap-revision
    wayne-ns: coohua
  name: tap-revision-ing
  namespace: coohua
spec:
  rules:
  - host: staging.coohua.com
    http:
      paths:
      - backend:
          serviceName: tap-revision-stable
          servicePort: 80
        path: /

Далее давайте взглянем на структуру ресурсов IC, развернутых в Kubernetes, как показано на рисунке:

Видно, что группа ИС фактически состоит из следующих частей:

  • ServiceAccount, ClusterRole, ClusterRoleBinding: определение разрешений RBAC
  • Развертывание: управляет развертыванием контроллера и зависит от ServiceAccount, Configmap, Service
  • ConfigMap: три карты конфигурации используются для сохранения пользовательских конфигураций контроллера.
  • Служба: здесь используется svc, тип которого LoadBalancer, в основном использует функцию автоматической привязки к экземпляру SLB, реализованную базовыми службами Alibaba Cloud.

Наш сценарий не требует специальной настройки разрешений, поэтому мы просто копируем несколько ресурсов в красное поле и изменяем несколько конфигураций (например, --ingress-class=xwz), а затем напрямую ссылаемся на значение по умолчанию. ServiceAccount IC завершает развертывание. нового набора микросхем и изолирован от микросхем, поставляемых с Kubernetes. Здесь я помещаю конфигурацию, которую написал на своем github, читатели могут обратиться к:ingress resources

После создания новой ИС, если вы обнаружите, что ИС имеет следующие ошибки

E0416 11:31:50.831279       6 leaderelection.go:304] Failed to update lock: configmaps "ingress-controller-leader-xwz" is forbidden: User "system:serviceaccount:kube-system:nginx-ingress-controller" cannot update resource "configmaps" in API group "" in the namespace "kube-system"

Ссылаться наissue, вам нужно изменить кластерную роль: nginx-ingress-controller, добавить следующее содержимое

...
- apiGroups:
  - ""
  resourceNames:
  - ingress-controller-leader-nginx
  - ingress-controller-leader-xwz #将新增加的configmap增加进来,不然会报上面提到的错误
  resources:
  - configmaps
...

Как автоматически добавить расширенный экземпляр IC в список серверных служб SLB

Способ 1 externalTrafficPolicy=Cluster

Когда spec.externalTrafficPolicy of Service имеет значение Cluster: Каждый хост в кластере может действовать как маршрутизатор уровня 3, выполняя роль балансировки нагрузки и пересылки, но поскольку он выполняет операцию SNAT для пакета запроса, как показано на рисунке:

Таким образом, клиентский ip, полученный в POD IC, будет IP рабочего узла, который переслал пакет, поэтому в этом режиме мы не можем получить реальный IP клиента.Если мы не заботимся о реальном IP-адрес клиента, который мы можем использовать. Таким образом, все IP-адреса рабочих узлов могут быть добавлены в список серверных служб SLB.

Метод 2 externalTrafficPolicy=Local

Когда spec.externalTrafficPolicy службы является локальной: Узел будет пересылать запрос только на POD IC в узле.Поскольку IC не проходит операцию SNAT, IC может получить реальный IP клиента.Если узел не имеет POD, ошибка будет сообщено. Таким образом, нам нужно вручную поддерживать связь между IC POD, узлом и серверной службой SLB. Так есть ли способ автоматически управлять и поддерживать эти отношения? На самом деле это так.Alibaba Cloud Container Service сделал все это за нас.Поскольку следующие аннотации добавлены к сервису, тип которого LoadBalancer, он может автоматически добавить порт и IP рабочего узла, который запустил POD, в В серверной службе SLB расширение и сокращение емкости обновляются автоматически, как показано ниже (обратите внимание, что мы используем внутрисетевой SLB, тип — интранет, вы можете изменить его в соответствии с реальной ситуацией):

metadata:
  annotations:
    service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet
    service.beta.kubernetes.io/alicloud-loadbalancer-force-override-listeners: "true"
    service.beta.kubernetes.io/alicloud-loadbalancer-id: lb-2zec8x×××××××××965vt
Режим 1 (кластер) и режим 2 (локальный)
В сравнении Cluster Local
преимущество Простой, стандартный способ K8S Уменьшите переадресацию сети, хорошую производительность и можете получить реальный IP-адрес клиента.
недостаток Маскировка адреса SNAT добавляет к сети один переход, производительность снижается, и реальный IP-адрес клиента не может быть получен. Вам нужно проверить, открыт ли порт узла, и вам нужно настроить обнаружение службы (Alibaba Cloud уже интегрировалась с SLB)

Вокруг ямы

Проблема количества рабочих процессов nginx

Мы знаем, что когда конфигурация worker_processes по умолчанию для nginx установлена ​​​​автоматически, она будет автоматически рассчитываться в соответствии с текущей информацией о процессоре хоста, но nginx не является приложением, поддерживающим контрольные группы, поэтому он будет слепо «высокомерен», что доступно «много» процессоров. , здесь Нам нужно указать его, мы можем задать параметры в конфигмапе:

apiVersion: v1
data:
  worker-processes: "8"
kind: ConfigMap
metadata:
  annotations:
  labels:
    app: ingress-nginx
  name: xwz-nginx-configuration
  namespace: kube-system

Настройки параметров ядра

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

initContainers:
- command:
  - /bin/sh
    - -c
    - |
      sysctl -w net.core.somaxconn=65535
      sysctl -w net.ipv4.ip_local_port_range="1024 65535"
      sysctl -w fs.file-max=1048576
      sysctl -w fs.inotify.max_user_instances=16384
      sysctl -w fs.inotify.max_user_watches=524288
      sysctl -w fs.inotify.max_queued_events=16384

Проблема с реальным IP клиента

В период низкого трафика в оттенках серого студенты-бизнесмены сообщили, что сторонние античитерские службы обнаружили, что интерфейс, который мы им назвали, был ненормальным.После анализа выяснилось, что IP-адрес клиента содержался в запросе, отправленном третьему -party был записан как IP-адрес хоста нашего API-шлюза. Помните приведенную ранее архитектурную диаграмму?

Причина этой проблемы в том, что наша ИС находится за OpenResty, а кодовая часть настройки X-REAL-IP в шаблоне ИС выглядит следующим образом:
Откуда взялся этот the_real_ip?
Видно, что по умолчанию он получается из переменной remote_addr.В нашем сценарии remote_addr будет IP-адресом хоста API-шлюза, поэтому нам нужно изменить его для заголовка с именем X_REAL_IP, который API-шлюз установил для нас. . Наш подход заключается в том, чтобы экспортировать и изменить файл шаблона и смонтировать его в образ в виде configmap, перезаписав исходную конфигурацию.Конфигурация выглядит следующим образом:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  ...
spec:
  template:
    spec:
      containers:
        name: nginx-ingress-controller
        ...
        volumeMounts:
        - mountPath: /etc/nginx/template
          name: nginx-template-volume
          readOnly: true
      ....
      volumes:
      - name: nginx-template-volume
        configMap:
          name: xwz-nginx-template
          items:
          - key: nginx.tmpl
            path: nginx.tmpl

Пока проблема решена

Мониторинг статей

На существующем API-шлюзе CooHua уже ведется подробный мониторинг различных показателей.Поскольку ingress-контроллер также выставляет метрики prometheus, также очень просто напрямую развернуть версию панели управления для сообщества и выполнить простую модификацию, т.к. показано ниже:

Справочная документация по мониторингу развертываний включает:пожалуйста, нажмите на меняПользовательская панель инструментов загружена на мой личный github:пожалуйста, нажмите на меня

Поиск проблемы

дамп файла nginx.conf

Пожалуйста, обратитесь к этой статьеdocs.Nginx.com/Nginx/admin…

Refs

Особенно Aliyun.com/articles/69… Особенно Aliyun.com/articles/64… Богдан-Али by.blogspot.com/2017/09/guest… Daniel FM: Что /posts/ отправило вас на… Woohoo.a, так что Kim.com/blog/deep- of…