Как создать API-шлюз с помощью Ambassador на DigitalOcean Kubernetes

Автор выбралFree and Open Source Fund для получения пожертвования в рамках программыWrite for DOnations.

Вступление

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

Envoy - это прокси-сервер службы с открытым исходным кодом, предназначенный для облачных приложений. В Kubernetes Ambassador можно использовать для установки и управления настройками Envoy. Ambassador поддерживает изменение конфигурации с нулевым временем простоя и интеграцию с другими функциями, такими как аутентификация, обнаружение сервисов иservices meshes.

В этом руководстве вы настроите шлюз Ambassador API в кластере Kubernetes с помощью Helm и сконфигурируете его для маршрутизации входящего трафика в различные службы на основе правил маршрутизации. Вы настроите эти правила для маршрутизации трафика на основе имени хоста или пути к соответствующим сервисам.

Предпосылки

Прежде чем начать это руководство, вам потребуется следующее:

  • Кластер DigitalOcean Kubernetes с настроеннымkubectl. Чтобы создать кластер Kubernetes в DigitalOcean, см. НашKubernetes Quickstart.

  • Менеджер пакетов Helm установлен на вашем локальном компьютере, а Tiller установлен на вашем кластере. Завершите шаги 1 и 2How To Install Software on Kubernetes Clusters with the Helm Package Manager

  • Полностью зарегистрированное доменное имя с минимум двумя настроенными записями. В этом руководстве будут использоватьсяsvc1.your-domain,svc2.your-domain иsvc3.your-domain. Вы можете следить заDNS Quickstart, чтобы установить свои рекорды в DigitalOcean.

[[step-1 -—- install-ambassador]] == Шаг 1. Установка Ambassador

В этом разделе вы будете устанавливать Ambassador в свой кластер Kubernetes. Амбассадор может быть установлен с использованием диаграммы Helm или путем передачи файла конфигурации YAML командеkubectl.

[.note] #Note: DigitalOcean Kubernetes включаетRBAC по умолчанию, поэтому при использовании файла конфигурации YAML для установки необходимо убедиться, что вы используете файл с активированным RBAC. Более подробную информацию о развертывании Amabassador в Kubernetes через YAML можно найти вdocumentation.
от Ambassador #

В рамках этого руководства вы будете использовать диаграммуHelm для установки Ambassador в свой кластер. Выполнив необходимые условия, Helm будет установлен в ваш кластер.

Для начала выполните следующую команду, чтобы установить Ambassador через Helm:

helm upgrade --install --wait ambassador stable/ambassador

Вы увидите вывод, похожий на следующий:

OutputRelease "ambassador" does not exist. Installing it now.
NAME:   ambassador
LAST DEPLOYED: Tue Jun 18 02:15:00 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        READY  UP-TO-DATE  AVAILABLE  AGE
ambassador  3/3    3           3          2m39s

==> v1/Pod(related)
NAME                         READY  STATUS   RESTARTS  AGE
ambassador-7d55c468cb-4gpq9  1/1    Running  0         2m38s
ambassador-7d55c468cb-jr9zr  1/1    Running  0         2m38s
ambassador-7d55c468cb-zhm7l  1/1    Running  0         2m38s

==> v1/Service
NAME               TYPE          CLUSTER-IP      EXTERNAL-IP    PORT(S)                     AGE
ambassador         LoadBalancer  10.245.183.114  139.59.52.164  80:30001/TCP,443:31557/TCP  2m40s
ambassador-admins  ClusterIP     10.245.46.43             8877/TCP                    2m41s

==> v1/ServiceAccount
NAME        SECRETS  AGE
ambassador  1        2m43s

==> v1beta1/ClusterRole
NAME        AGE
ambassador  2m41s

==> v1beta1/ClusterRoleBinding
NAME        AGE
ambassador  2m41s

==> v1beta1/CustomResourceDefinition
NAME                                          AGE
authservices.getambassador.io                 2m42s
consulresolvers.getambassador.io              2m41s
kubernetesendpointresolvers.getambassador.io  2m42s
kubernetesserviceresolvers.getambassador.io   2m43s
mappings.getambassador.io                     2m41s
modules.getambassador.io                      2m41s
ratelimitservices.getambassador.io            2m42s
tcpmappings.getambassador.io                  2m41s
tlscontexts.getambassador.io                  2m42s
tracingservices.getambassador.io              2m43s

. . .

Это создаст развертывание Ambassador, сервис и балансировщик нагрузки с подключенными узлами кластера Kubernetes. Вам потребуется IP-адрес балансировщика нагрузки, чтобы сопоставить его с записями А. вашего домена.

Чтобы получить IP-адрес вашего посла Load Balancer, выполните следующее:

kubectl get svc --namespace default ambassador

Вы увидите вывод, похожий на:

OutputNAME         TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
ambassador   LoadBalancer   your_cluster_IP   your-IP-address   80:30001/TCP,443:31557/TCP   8m4s

Обратите внимание на внешний IP-адресyour-IP-address на этом этапе и сопоставьте домены (через вашего поставщика домена)svc1.your-domain,svc2.your-domain иsvc3.your-domain, чтобы они указывали на этот IP-адрес.

Вы можете включить HTTPS с помощью балансировщика нагрузки DigitalOcean, выполнив действия, указанные вHow to Configure SSL Termination. Рекомендуется настроить завершение TLS через балансировщик нагрузки. Другой способ настройки завершения TLS - использоватьAmbassador’s TLS Support

Вы установили Ambassador в своем кластере Kubernetes, используя Helm, который создал развертывание Ambassador с тремя репликами в пространстве имен по умолчанию. Это также создало балансировщик нагрузки с общедоступным IP-адресом для маршрутизации всего трафика к шлюзу API. Затем вы создадите развертывания Kubernetes для трех разных сервисов, которые вы будете использовать для тестирования этого шлюза API.

[[step-2 -—- setting-up-web-server-deployments]] == Шаг 2. Настройка развертывания веб-сервера

В этом разделе вы создадите три развертывания для запуска трех разных контейнеров веб-сервера. Вы создадите файлы YAML с определениями развертываний Kubernetes для трех различных контейнеров веб-серверов и развернете их с помощьюkubectl.

Откройте предпочитаемый текстовый редактор, чтобы создать первое развертывание для веб-сервера Nginx:

nano svc1-deploy.yaml

Введите следующую конфигурацию yaml в свой файл:

svc1-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      name: svc1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        name: svc1
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - name: http
          containerPort: 80

Здесь вы определили KubernetesDeployment с образом контейнераnginx:latest, который будет развернут с репликой1, называемойsvc1. Deployment определен для предоставления доступа внутри кластера через порт80.

Сохраните и закройте файл.

Затем выполните следующую команду, чтобы применить эту конфигурацию:

kubectl apply -f svc1-deploy.yaml

Вы увидите вывод, подтверждающий создание:

Outputdeployment.extensions/svc1 created

Теперь создайте второе развертывание веб-сервера. Откройте файл с именемsvc2-deploy.yaml с помощью:

nano svc2-deploy.yaml

Введите следующую конфигурацию YAML в файл:

svc2-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
      name: svc2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpd
        name: svc2
    spec:
      containers:
      - name: httpd
        image: httpd:latest
        ports:
        - name: http
          containerPort: 80

Здесь вы определили KubernetesDeployment с образом контейнераhttpd, который будет развернут с репликой1, называемойsvc2.

Сохраните и закройте файл.

Выполните следующую команду, чтобы применить эту конфигурацию:

kubectl apply -f svc2-deploy.yaml

Вы увидите этот вывод:

Outputdeployment.extensions/svc2 created

Наконец, для третьего развертывания откройте и создайте файлsvc3-deploy.yaml:

nano svc3-deploy.yaml

Добавьте следующие строки в файл:

svc3-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      name: svc3
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpbin
        name: svc3
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        ports:
        - name: http
          containerPort: 80

Здесь вы определили KubernetesDeployment с образом контейнераhttpbin, который будет развернут с репликой1, называемойsvc3.

Сохраните и закройте файл.

Наконец, выполните следующую команду для применения:

kubectl apply -f svc3-deploy.yaml

И вы увидите следующий вывод:

Outputdeployment.extensions/svc3 created

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

[[step-3 -—- exposing-apps-using-services-with-ambassador-annotations]] == Шаг 3. Раскрытие приложений, использующих сервисы, с аннотациями Ambassador

В этом разделе вы откроете свои веб-приложения для Интернета, создав службы Kubernetes сAmbassador annotations, чтобы настроить правила для маршрутизации к ним трафика. Аннотации в Kubernetes - это способ добавления метаданных к объектам. Посол использует эти значения аннотаций из сервисов для настройки своих правил маршрутизации.

Напоминаем, что ваши домены (например:svc1.your-domain,svc2.your-domain иsvc3.your-domain) должны быть сопоставлены с общедоступным IP-адресом балансировщика нагрузки в ваших записях DNS.

Определите сервис Kubernetes для развертыванияsvc1 с аннотациями Ambassador, создав и открыв этот файл:

nano svc1-service.yaml

[.note] #Note: Имя отображения должно быть уникальным для каждого блока аннотации Ambassador. Сопоставление действует как идентификатор для каждого блока аннотации, и при повторении оно будет перекрывать более старый блок аннотации.
#

svc1-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc1-service_mapping
      host: svc1.your-domain
      prefix: /
      service: svc1:80
spec:
  selector:
    app: nginx
    name: svc1
  ports:
  - name: http
    protocol: TCP
    port: 80

В этом коде YAML вы определили службу Kubernetessvc1 с аннотациями Ambassador для сопоставления имени хостаsvc1.your-domain этой службе.

Сохраните и выйдите изsvc1-service.yaml, а затем выполните следующие действия, чтобы применить эту конфигурацию:

kubectl apply -f svc1-service.yaml

Вы увидите этот вывод:

Outputservice/svc1 created

Создайте вторую службу Kubernetes для развертыванияsvc2 с аннотациями Ambassador. Это еще один пример маршрутизации на основе хоста с Ambassador:

svc2-service.yaml

Добавьте следующую конфигурацию в файл:

svc2-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc2-service_mapping
      host: svc2.your-domain
      prefix: /
      service: svc2:80
spec:
  selector:
    app: httpd
    name: svc2
  ports:
  - name: http
    protocol: TCP
    port: 80

Сохраните это какsvc2-service.yaml. Здесь вы определили другой сервис Kubernetes с аннотациями Ambassador для маршрутизации трафика наsvc2, когда посол получает любой запрос со значением заголовкаhost какsvc2.your-domain. Следовательно, эта маршрутизация на основе хоста позволит вам отправить запрос в поддоменsvc2.your-domain, который направит трафик на службуsvc2 и обслужит ваш запрос с веб-сервераhttpd.

Чтобы создать этот сервис, выполните следующее:

kubectl apply -f svc2-service.yaml

Вы увидите следующий вывод:

Outputservice/svc2 created

Создайте третью службу Kubernetes для развертыванияsvc3 и обслуживайте ее по путиsvc2.your-domain/bin. Это настроит маршрутизацию на основе пути для Ambassador:

svc3-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc3
spec:
  selector:
    app: httpbin
    name: svc3
  ports:
  - name: http
    protocol: TCP
    port: 80

Сохраните это какsvc3-service.yaml и запустите следующее, чтобы применить конфигурацию:

kubectl apply -f svc3-service.yaml

Ваш вывод будет:

Outputservice/svc3 created

Отредактируйтеsvc2-service.yaml, чтобы добавить второй блок аннотации Ambassador для маршрутизации/bin в службуsvc3:

nano svc2-service.yaml

svc2-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc2-service_mapping
      host: svc2.your-domain
      prefix: /
      service: svc2:80
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc3-service_mapping
      host: svc2.your-domain
      prefix: /bin
      service: svc3:80
spec:
  selector:
    app: httpd
    name: svc2
  ports:
  - name: http
    protocol: TCP
    port: 80

Вы добавили второй блок аннотации Ambassador, чтобы настроить пути, начинающиеся с/bin, для сопоставления с вашим сервисом Kubernetessvc3. Чтобы направлять запросы дляsvc2.your-domain/bin вsvc3, вы добавили здесь второй блок аннотации в качестве значения хостаsvc2.your-domain, которое одинаково для обоих блоков. Следовательно, маршрутизация на основе пути позволит вам отправить запросsvc2.your-domain/bin, который будет получен службойsvc3 и обслуживается приложениемhttpbin в этом руководстве.

Теперь выполните следующее, чтобы применить изменения:

kubectl apply -f svc2-service.yaml

Вы увидите этот вывод:

Outputservice/svc2 configured

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

[[step-4 -—- advanced-ambassador-configurations-for-routing]] == Шаг 4. Расширенные настройки посланника для маршрутизации

В этом разделе вы настроите службы с дополнительными аннотациями Ambassador дляmodify headers иconfigure redirection.

curl доменsvc1.your-domain и проверьте заголовки ответа:

curl -I svc1.your-domain

Ваш вывод будет похож на следующее:

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 21:41:00 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 21 May 2019 14:23:57 GMT
etag: "5ce409fd-264"
accept-ranges: bytes
x-envoy-upstream-service-time: 0

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

Чтобы добавить настраиваемые заголовки в ответ службы, удалите заголовокx-envoy-upstream-service-time из ответа и добавьте новый заголовок ответаx-geo-location: India дляsvc1. (Вы можете изменить этот заголовок в соответствии с вашими требованиями.)

Отредактируйте файлsvc1-service.yaml:

nano svc1-service.yaml

Обновите аннотацию следующими выделенными строками:

svc1-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc1-service_mapping
      host: svc1.example.com
      prefix: /
      remove_response_headers:
      - x-envoy-upstream-service-time
      add_response_headers:
        x-geo-location: India
      service: svc1:80
spec:
  selector:
    app: nginx
    name: svc1
  ports:
  - name: http
    protocol: TCP
    port: 80

Здесь вы изменили службуsvc1, чтобы удалитьx-envoy-upstream-service-time, и добавили заголовокx-geo-location: India в ответ HTTP.

Примените изменения, которые вы сделали:

kubectl apply -f svc1-service.yaml

Вы увидите следующий вывод:

Outputservice/svc1 configured

Теперь запуститеcurl, чтобы проверить обновленные заголовки в ответе службы:

curl -I svc1.your-domain

Вывод будет похож на это:

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 21:45:26 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 21 May 2019 14:23:57 GMT
etag: "5ce409fd-264"
accept-ranges: bytes
x-geo-location: India

Теперь отредактируйтеsvc3-service.yaml, чтобы перенаправить запросы для вашего имени хостаsvc3.your-domain на путьsvc2.your-domain/bin:

nano svc3-service.yaml

Добавьте блок аннотации Ambassador, как показано в следующем YAML, и сохраните его:

svc3-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc3
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind:  Mapping
      name:  redirect_mapping
      host: svc3.your-domain
      prefix: /
      service: svc2.your-domain
      host_redirect: true
      path_redirect: /bin
spec:
  selector:
    app: httpbin
    name: svc3
  ports:
  - name: http
    protocol: TCP
    port: 80

Вы добавилиhost_redirect: true, чтобы настроить ответ перенаправления 301 дляsvc3 наsvc2.your-domain/bin для имени хостаsvc3.your-domain. Параметрhost_redirect отправляет клиенту ответ перенаправления 301. Если не установлено, запросы будут получать 200 HTTP-ответов, а не 301 HTTP-ответы.

Теперь выполните следующую команду, чтобы применить эти изменения:

kubectl apply -f svc3-service.yaml

Вы увидите похожий вывод:

Outputservice/svc3 configured

Теперь вы можете проверить ответ дляsvc3.your-domain с помощьюcurl:

curl -I svc3.your-domain

Ваш вывод будет похож на следующее:

OutputHTTP/1.1 301 Moved Permanently
location: http://svc2.your-domain/bin
date: Mon, 17 Jun 2019 21:52:05 GMT
server: envoy
transfer-encoding: chunked

Результатом является HTTP-заголовок для ответа на запрос службы.svc3.your-domain+`showing that the configuration of `+host_redirect: true в аннотации службы правильно предоставил код состояния HTTP:301 Moved Permanently.

Вы настроили службу с аннотациями Ambassador для изменения заголовков HTTP и настройки перенаправлений. Далее вы добавите глобальную конфигурацию к сервису Ambassador API Gateway.

[[step-5 -—- setting-up-ambassador-global-configurations]] == Шаг 5 - Настройка глобальных конфигураций Ambassador

В этом разделе вы отредактируете сервис Ambassador, добавив глобальную конфигурацию сжатия GZIP. Сжатие GZIP сожмет размер активов HTTP и уменьшит требования к пропускной способности сети, что приведет к более быстрому времени отклика для веб-клиентов. Эта конфигурация влияет на весь трафик, маршрутизируемый через шлюз Ambassador API. Аналогично, вы можете настроить другие глобальные модули с помощью Ambassador, что позволит вам включить специальное поведение для Ambassador на глобальном уровне. Эти глобальные конфигурации могут применяться с использованием аннотаций к сервису Ambassador. Вы можете обратиться к документацииAmbassador’s Global Configuration для получения дополнительной информации.

Следующая командаkubectl edit откроет редактор по умолчанию, которым является vim. Например, чтобы использовать nano, вы можете установить для переменной окруженияKUBE_EDITOR значение nano:

export KUBE_EDITOR="nano"

Отредактируйте сервис послов:

kubectl edit service ambassador

Теперь добавьте выделенные строки в новый блок аннотаций для сжатия GZIP:

Редактирование Посол Сервис

apiVersion: v1
kind: Service
metadata:
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Module
      name: ambassador
      config:
        service_port: 8080
      ---
      apiVersion: ambassador/v0
      kind:  Module
      name:  ambassador
      config:
        gzip:
          memory_level: 5
          min_content_length: 256
          compression_level: BEST
          compression_strategy: DEFAULT
          content_type:
          - application/javascript
          - application/json
          - text/html
          - text/plain
          disable_on_etag_header: false
          remove_accept_encoding_header: false
  creationTimestamp: "2019-06-17T20:45:04Z"
  labels:
    app.kubernetes.io/instance: ambassador
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: ambassador
    helm.sh/chart: ambassador-2.8.2
  name: ambassador
  namespace: default
  resourceVersion: "2153"
  . . .

Вы добавили блок аннотации Ambassador в службу Ambassador и глобально настроили GZIP для шлюза API. Здесь вы включили конфигурацию для управления объемом внутренней памяти, используемой сmemory_level, который может быть значением от 1 до 9. compression_level, установленный наBEST, обеспечивает более высокую степень сжатия за счет более высокой задержки. С помощьюmin_content_length вы настроили минимальную длину ответа в байтах256. Дляcontent_type вы специально включили наборmedia types (ранее MIME-типы), обеспечивающий сжатие. Наконец, вы добавили две последние конфигурации какfalse, чтобы обеспечить сжатие.

Вы можете узнать больше о сжатии GZIP наEnvoy’s GZIP page.

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

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

Outputservice/ambassador edited

Проверьтеsvc1.your-domain с помощьюcurl для заголовкаcontent-encoding, имеющего значениеgzip:

curl --compressed -i http://svc1.example.com

Вывод будет похож на это:

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 22:25:35 GMT
content-type: text/html
last-modified: Tue, 21 May 2019 14:23:57 GMT
accept-ranges: bytes
x-geo-location: India
vary: Accept-Encoding
content-encoding: gzip
transfer-encoding: chunked




Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

Здесь вы можете увидеть HTML-страницу Nginx по умолчанию с заголовком ответа, показывающим, чтоcontent-encoding полученного ответа сжатgzip.

Вы добавили глобальную конфигурацию в Ambassador, чтобы включить настройку GZIP для ответов выбранного типа контента через шлюз API.

Заключение

Вы успешно настроили API-шлюз для своего кластера Kubernetes с помощью Ambassador. Теперь вы можете предоставлять свои приложения, используя маршрутизацию на основе хоста и пути, настраиваемые заголовки и глобальное сжатие GZIP.

Для получения дополнительной информации об аннотациях Ambassador и параметрах конфигурации прочтитеAmbassador’s official documentation.

Related