Как настроить Nginx Ingress на DigitalOcean Kubernetes с помощью шлема

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

Вступление

KubernetesIngresses предлагает вам гибкий способ маршрутизации трафика из-за пределов вашего кластера во внутренние службы Kubernetes. IngressResources - это объекты в Kubernetes, которые определяют правила маршрутизации трафика HTTP и HTTPS к Сервисам. Чтобы они работали, должен присутствовать IngressController; его роль заключается в реализации правил путем приема трафика (скорее всего, через балансировщик нагрузки) и его маршрутизации в соответствующие службы. Большинство контроллеров входа используют только один глобальный балансировщик нагрузки для всех входов, что более эффективно, чем создание балансировщика нагрузки для каждой службы, которую вы хотите предоставить.

Helm - это менеджер пакетов для управления Kubernetes. Использование Helm Charts с Kubernetes обеспечивает возможность конфигурирования и управления жизненным циклом для обновления, отката и удаления приложения Kubernetes.

В этом руководстве вы настроитеNginx Ingress Controller, поддерживаемые Kubernetes, с помощью Helm. Затем вы создадите входной ресурс для маршрутизации трафика из ваших доменов в пример внутренних служб Hello World. После настройки Ingress вы установитеCert-Manager в свой кластер, чтобы иметь возможность автоматически предоставлять сертификаты Let's Encrypt TLS для защиты ваших Ingress.

Предпосылки

  • Кластер DigitalOcean Kubernetes с вашей конфигурацией подключения, настроенной какkubectl по умолчанию. Инструкции по настройкеkubectl показаны под этапомConnect to your Cluster, показанным при создании кластера. Чтобы узнать, как создать кластер Kubernetes в DigitalOcean, см.Kubernetes Quickstart.

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

  • Полностью зарегистрированное доменное имя с двумя доступными записями А. В этом руководстве будут использоватьсяhw1.example.com иhw2.example.com. Вы можете приобрести доменное имя наNamecheap, получить его бесплатно наFreenom или воспользоваться услугами регистратора доменов по вашему выбору.

[[step-1 -—- setting-up-hello-world-deployments]] == Шаг 1. Настройка развертываний Hello World

В этом разделе перед развертыванием Nginx Ingress вы развернете приложение Hello World с именемhello-kubernetes, чтобы иметь некоторые службы, к которым вы будете маршрутизировать трафик. Чтобы убедиться, что Nginx Ingress работает правильно на следующих шагах, вы должны развернуть его дважды, каждый раз с другим приветственным сообщением, которое будет отображаться при доступе к нему из браузера.

Вы будете хранить конфигурацию развертывания на своем локальном компьютере. Первая конфигурация развертывания будет в файле с именемhello-kubernetes-first.yaml. Создайте его с помощью текстового редактора:

nano hello-kubernetes-first.yaml

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

hello-kubernetes-first.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-first
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-first
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-first
  template:
    metadata:
      labels:
        app: hello-kubernetes-first
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the first deployment!

Эта конфигурация определяет Развертывание и Сервис. Развертывание состоит из трех реплик образаpaulbouwer/hello-kubernetes:1.5 и переменной среды с именемMESSAGE - вы увидите ее значение при доступе к приложению. Служба здесь определена для предоставления доступа к развертыванию в кластере на порту80.

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

Затем создайте этот первый вариант приложенияhello-kubernetes в Kubernetes, выполнив следующую команду:

kubectl create -f hello-kubernetes-first.yaml

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

Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created

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

kubectl get service hello-kubernetes-first

Вывод будет выглядеть так:

OutputNAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
hello-kubernetes-first   ClusterIP   10.245.85.236           80:31623/TCP   35s

Вы увидите, что недавно созданному Сервису назначен ClusterIP, что означает, что он работает правильно. Весь отправленный на него трафик будет перенаправлен в выбранное развертывание на порту8080. Теперь, когда вы развернули первый вариант приложенияhello-kubernetes, вы будете работать над вторым.

Откройте файл с именемhello-kubernetes-second.yaml для редактирования:

nano hello-kubernetes-second.yaml

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

hello-kubernetes-second.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-second
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-second
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-second
  template:
    metadata:
      labels:
        app: hello-kubernetes-second
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the second deployment!

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

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

Теперь создайте его в Kubernetes с помощью следующей команды:

kubectl create -f hello-kubernetes-second.yaml

Выход будет:

Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created

Убедитесь, что вторая служба запущена и работает, перечислив все ваши службы:

kubectl get service

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

OutputNAME                            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
hello-kubernetes-first          ClusterIP      10.245.85.236              80:31623/TCP                 54s
hello-kubernetes-second         ClusterIP      10.245.99.130              80:30303/TCP                 12s
kubernetes                      ClusterIP      10.245.0.1                 443/TCP                      5m

В списке указаны какhello-kubernetes-first, так иhello-kubernetes-second, что означает, что Kubernetes успешно их создал.

Вы создали два развертывания приложенияhello-kubernetes с соответствующими службами. Каждый из них имеет свой набор сообщений в спецификации развертывания, что позволяет различать их во время тестирования. На следующем шаге вы установите сам Nginx Ingress Controller.

[[step-2 -—- install-the-kubernetes-nginx-ingress-controller]] == Шаг 2 - Установка Kubernetes Nginx Ingress Controller

Теперь вы установите поддерживаемый KubernetesNginx Ingress Controller с помощью Helm. Обратите внимание, что есть несколькоNginx Ingresses.

Контроллер входа Nginx состоит из модуля и службы. Pod запускает контроллер, который постоянно опрашивает конечную точку/ingresses на сервере API вашего кластера на предмет обновлений доступных ресурсов Ingress. Служба относится к типу LoadBalancer, и поскольку вы развертываете ее в кластере DigitalOcean Kubernetes, кластер автоматически создаетDigitalOcean Load Balancer, через который весь внешний трафик будет поступать на контроллер. Контроллер затем направит трафик к соответствующим Сервисам, как определено в Ingress Resources.

Только служба LoadBalancer знает IP-адрес автоматически созданного балансировщика нагрузки. Некоторым приложениям (например,ExternalDNS) необходимо знать его IP-адрес, но они могут только читать конфигурацию Ingress. Контроллер можно настроить для публикации IP-адреса на каждом входе, установив для параметраcontroller.publishService.enabled значениеtrue в течениеhelm install. Рекомендуется включить этот параметр для поддержки приложений, которые могут зависеть от IP-адреса балансировщика нагрузки.

Чтобы установить Nginx Ingress Controller в ваш кластер, выполните следующую команду:

helm install stable/nginx-ingress --name nginx-ingress --set controller.publishService.enabled=true

Эта команда устанавливает контроллер Nginx Ingress из репозитория диаграммstable, называет выпуск Helmnginx-ingress и устанавливает для параметраpublishService значениеtrue.

Вывод будет выглядеть так:

OutputNAME:   nginx-ingress
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: DEPLOYED

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

==> v1/Pod(related)
NAME                                            READY  STATUS             RESTARTS  AGE
nginx-ingress-controller-7658988787-npv28       0/1    ContainerCreating  0         0s
nginx-ingress-default-backend-7f5d59d759-26xq2  0/1    ContainerCreating  0         0s

==> v1/Service
NAME                           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
nginx-ingress-controller       LoadBalancer  10.245.9.107       80:31305/TCP,443:30519/TCP  0s
nginx-ingress-default-backend  ClusterIP     10.245.221.49         80/TCP                      0s

==> v1/ServiceAccount
NAME           SECRETS  AGE
nginx-ingress  1        0s

==> v1beta1/ClusterRole
NAME           AGE
nginx-ingress  0s

==> v1beta1/ClusterRoleBinding
NAME           AGE
nginx-ingress  0s

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

==> v1beta1/Role
NAME           AGE
nginx-ingress  0s

==> v1beta1/RoleBinding
NAME           AGE
nginx-ingress  0s

NOTES:
...

Хелм зарегистрировал, какие ресурсы в Kubernetes он создал как часть установки диаграммы.

Вы можете увидеть, как Load Balancer станет доступным, запустив:

kubectl get services -o wide -w nginx-ingress-controller

Вы установили Nginx Ingress, поддерживаемый сообществом Kubernetes. Он будет направлять трафик HTTP и HTTPS от балансировщика нагрузки к соответствующим внутренним службам, настроенным в Ingress Resources. На следующем шаге вы раскроете развертывание приложенийhello-kubernetes с помощью ресурса Ingress.

[[step-3 -—- exing-the-app-using-an-ingress]] == Шаг 3. Раскрытие приложения с помощью Ingress

Теперь вы собираетесь создать ресурс Ingress и использовать его для демонстрации развертываний приложенийhello-kubernetes в желаемых доменах. Затем вы протестируете его, открыв его через браузер.

Вы сохраните Ingress в файле с именемhello-kubernetes-ingress.yaml. Создайте его, используя ваш редактор:

nano hello-kubernetes-ingress.yaml

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

hello-kubernetes-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: hw1.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
  - host: hw2.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-second
          servicePort: 80

В приведенном выше коде вы определяете входящий ресурс с именемhello-kubernetes-ingress. Затем вы указываете два правила хоста, так чтоhw1.example.com направляется в службуhello-kubernetes-first, аhw2.example.com направляется в службу из второго развертывания (hello-kubernetes-second).

Не забудьте заменить выделенные домены своими собственными, затем сохраните и закройте файл.

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

kubectl create -f hello-kubernetes-ingress.yaml

Затем вам необходимо убедиться, что ваши два домена указаны в Балансировщике нагрузки через записи А. Это делается через вашего провайдера DNS. Чтобы настроить записи DNS в DigitalOcean, см.How to Manage DNS Records.

Теперь вы можете перейти кhw1.example.com в своем браузере. Вы увидите следующее:

Hello Kubernetes - First Deployment

Второй вариант (hw2.example.com) покажет другое сообщение:

Hello Kubernetes - Second Deployment

Благодаря этому вы убедились, что Ingress Controller правильно маршрутизирует запросы; в этом случае от двух ваших доменов до двух разных Сервисов.

Вы создали и настроили ресурс Ingress для обслуживания развертываний приложенийhello-kubernetes в ваших доменах. На следующем шаге вы настроите Cert-Manager, чтобы иметь возможность защитить свои входящие ресурсы с помощью бесплатных сертификатов TLS от Let’s Encrypt.

[[step-4 -—-securing-the-ingress-using-cert-manager]] == Шаг 4. Защита входящего трафика с помощью Cert-Manager

Чтобы защитить свои ресурсы Ingress, вы должны установить Cert-Manager, создать ClusterIssuer для производства и изменить конфигурацию вашего Ingress, чтобы использовать преимущества сертификатов TLS. ClusterIssuers - это ресурсы Cert-Manager в Kubernetes, которые предоставляют сертификаты TLS. После установки и настройки ваше приложение будет работать за HTTPS.

Перед установкой Cert-Manager в свой кластер через Helm вы вручную примените необходимыеCRDs (пользовательские определения ресурсов) из репозитория jetstack / cert-manager, выполнив следующую команду:

kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

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

Outputcustomresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created

Это показывает, что Kubernetes применил пользовательские ресурсы, необходимые для cert-manager.

[.Примечание]##

Note: Если вы следовали этому руководству и предварительным условиям, вы не создали пространство имен Kubernetes с именемcert-manager, поэтому вам не нужно запускать команду из этого блока заметок. Однако, если это пространство имен существует в вашем кластере, вам нужно будет сообщить Cert-Manager, чтобы оно не проверялось с помощью следующей команды:

kubectl label namespace cert-manager certmanager.k8s.io/disable-validation="true"

The Webhook component of Cert-Manager требует сертификатов TLS для безопасной связи с сервером Kubernetes API. Чтобы Cert-Manager сгенерировал сертификаты для него в первый раз, проверка ресурса должна быть отключена в пространстве имен, в котором она развернута. В противном случае он застрянет в бесконечном цикле; невозможно связаться с API и создать сертификаты TLS.

Выход будет:

Outputnamespace/cert-manager labeled

Затем вам нужно добавитьJetstack Helm repository в Helm, в котором размещается диаграмма Cert-Manager. Для этого выполните следующую команду:

helm repo add jetstack https://charts.jetstack.io

Хелм покажет следующий результат:

Output"jetstack" has been added to your repositories

Наконец, установите Cert-Manager в пространство именcert-manager:

helm install --name cert-manager --namespace cert-manager jetstack/cert-manager

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

OutputNAME:   cert-manager
LAST DEPLOYED: ...
NAMESPACE: cert-manager
STATUS: DEPLOYED

RESOURCES:
==> v1/ClusterRole
NAME                                    AGE
cert-manager-edit                       3s
cert-manager-view                       3s
cert-manager-webhook:webhook-requester  3s

==> v1/Pod(related)
NAME                                     READY  STATUS             RESTARTS  AGE
cert-manager-5d669ffbd8-rb6tr            0/1    ContainerCreating  0         2s
cert-manager-cainjector-79b7fc64f-gqbtz  0/1    ContainerCreating  0         2s
cert-manager-webhook-6484955794-v56lx    0/1    ContainerCreating  0         2s

...

NOTES:
cert-manager has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://docs.cert-manager.io/en/latest/reference/issuers.html

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://docs.cert-manager.io/en/latest/reference/ingress-shim.html

Вывод показывает, что установка прошла успешно. Как указано вNOTES в выходных данных, вам необходимо настроить эмитента для выпуска сертификатов TLS.

Теперь вы создадите тот, который выдает сертификаты Let's Encrypt, и сохраните его конфигурацию в файле с именемproduction_issuer.yaml. Создайте его и откройте для редактирования:

nano production_issuer.yaml

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

production_issuer.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your_email_address
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

Эта конфигурация определяет ClusterIssuer, который связывается с Let's Encrypt для выдачи сертификатов. Вам нужно будет заменитьyour_email_address на свой адрес электронной почты, чтобы получать возможные срочные уведомления о безопасности и истечении срока действия ваших сертификатов.

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

Разверните его с помощьюkubectl:

kubectl create -f production_issuer.yaml

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

Outputclusterissuer.certmanager.k8s.io/letsencrypt-prod created

Установив Cert-Manager, вы готовы представить сертификаты входному ресурсу, определенному на предыдущем шаге. Откройтеhello-kubernetes-ingress.yaml для редактирования:

nano hello-kubernetes-ingress.yaml

Добавьте выделенные строки:

hello-kubernetes-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - hw1.example.com
    - hw2.example.com
    secretName: letsencrypt-prod
  rules:
  - host: hw1.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
  - host: hw2.example.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-second
          servicePort: 80

Блокtls вspec определяет, в каком секрете сертификаты для ваших сайтов (перечисленные в разделеhosts) будут хранить свои сертификаты, которые выдает ClusterIssuerletsencrypt-prod. Это должно отличаться для каждого Ingress, который вы создаете.

Не забудьте заменитьhw1.example.com иhw2.example.com своими собственными доменами. Когда вы закончите редактирование, сохраните и закройте файл.

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

kubectl apply -f hello-kubernetes-ingress.yaml

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

Outputingress.extensions/hello-kubernetes-ingress configured

Вам нужно подождать несколько минут, чтобы серверы Let Encrypt выпустили сертификат для ваших доменов. В то же время вы можете отслеживать его прогресс, проверив вывод следующей команды:

kubectl describe certificate letsencrypt-prod

Конец вывода будет выглядеть примерно так:

OutputEvents:
  Type    Reason              Age   From          Message
  ----    ------              ----  ----          -------
  Normal  Generated           56s   cert-manager  Generated new private key
  Normal  GenerateSelfSigned  56s   cert-manager  Generated temporary self signed certificate
  Normal  OrderCreated        56s   cert-manager  Created Order resource "hello-kubernetes-1197334873"
  Normal  OrderComplete       31s   cert-manager  Order "hello-kubernetes-1197334873" completed successfully
  Normal  CertIssued          31s   cert-manager  Certificate issued successfully

Когда ваша последняя строка вывода будет читатьCertificate issued successfully, вы можете выйти, нажавCTRL + C. Перейдите к одному из ваших доменов в вашем браузере для тестирования. Вы увидите замок слева от адресной строки в своем браузере, показывая, что ваше соединение безопасно.

На этом этапе вы установили Cert-Manager с помощью Helm и создали Let Encrypt ClusterIssuer. После этого вы обновили свой входящий ресурс, чтобы воспользоваться преимуществами эмитента для создания сертификатов TLS. В конце вы подтвердили, что HTTPS работает правильно, перейдя на один из ваших доменов в браузере.

Заключение

Теперь вы успешно настроили Nginx Ingress Controller и Cert-Manager в своем кластере DigitalOcean Kubernetes, используя Helm. Теперь вы можете открывать свои приложения в Интернете, на своих доменах, защищенных с помощью сертификатов Let Encrypt TLS.

Для получения дополнительной информации о диспетчере пакетов Helm прочтите этотintroduction article.

Related