Автор выбрал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
в своем браузере. Вы увидите следующее:
Второй вариант (hw2.example.com
) покажет другое сообщение:
Благодаря этому вы убедились, что 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.