[Перевод] Деплой Elasticsearch на AWS с помощью Kubernetes за 10 шагов

rtnouda08zlh-unwdbcvqlb8fts.jpeg

Kubernetes aka k8s — это система с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнерными приложениями. В этой статье я расскажу как настроить кластер Kubernetes и развернуть на нем кластер Elasticsearch в AWS. Эти настройки также работают на GCE и Azure.


Конфигурирование Kubernetes на AWS

Для начала получите доступ с правами администратора к следующим AWS сервисам: S3, EC2, Route53, IAM и VPC.

1. Установка: я покажу установку CLI для Linux. Если у вас другая операционная система, переходите по ссылкам ниже, чтобы получить инструкции по установке для вашей ОС.

Во-первых, ставим AWS CLI для доступа к AWS через CLI. Если у вас уже есть Python и pip, запустите команду:

pip install awscli --upgrade --user

Потом используем Kops — инструмент командной строки, который ведет нас через настройку K8S-кластера продакшн-уровня.
Устанавливаем бинарники Kops прямо из github.

wget -O kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
chmod +x ./kops
sudo mv ./kops /usr/local/bin/

Наконец, используем kubectl — CLI для для управления кластером K8S (если вы использовали docker, это похоже на docker CLI). Последний релиз устанавливается командой:

wget -O kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

Примечание: можно запустить кластер Kubernetes и выполнить инструкции этой статьи на домашней машине с minikube.

2.Создание пользователей IAM: для создания кластеров в AWS мы создадим отдельного пользователя IAM для kops. Для kops нужна учетная запись API. Создайте пользователя и настройте учетную запись через пользовательский интерфейс AWS console. Пользователю kops понадобятся следующие разрешение IAM:


  • AmazonEC2FullAccess
  • AmazonRoute53FullAccess
  • AmazonS3FullAccess
  • IAMFullAccess
  • AmazonVPCFullAccess

93llzhkqarlmyjtluwo3xiqpjwa.jpeg

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

aws iam create-group --group-name kops

aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops

aws iam create-user --user-name kops

aws iam add-user-to-group --user-name kops --group-name kops

aws iam create-access-key --user-name kops

Обратите внимание на ключи SecretAccessKey и AccessKeyID в kops.

Настроим AWS CLI для использования учетной записи с помощью aws configure.

Убедитесь, что созданный пользователь находится в списке aws iam list-users.

Экспортируем учетную запись AWS в качестве следующих переменных среды, чтобы CLI kops мог их использовать.

export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)


Если вы используете Kops 1.6.2 или новее, настраивать DNS не обязательно. Можно создать госсип-кластер. Единственное требование: название кластера должно заканчиваться на .k8s.local.


Настройка DNS

Если вы уже разместили свой домен через AWS и планируете использовать его, ничего не нужно делать. Другой вариант: вы хотите использовать поддомен вашего домена, создайте вторую зону публичного хостинга для этого поддомена. В этой инструкции мы будем работать с зоной приватного хостинга. Установите зону под любым именем. Используйте это имя для создания кластеров Kubernetes. Подробности о настройке DNS читайте здесь.

3. Создание S3 bucket: чтобы сохранить состояние и вид нашего K8S кластера, нужно создать отдельный S3 bucket для kops. Этот bucket станет источником достоверных данных для конфигурационного кластера.

aws s3api create-bucket \
   --bucket  \
   --region us-east-1

Примечание: если вы вводите в эксплуатацию свой bucket в области отличной от us-east-1, в дополнение настройке - region переключитесь на нужную область и добавьте LocationConstraint к этой же области. Ниже показана команда создания bucket в регионе us-west-1.

aws s3api create-bucket \
   --bucket  \
   --region us-west-1 \
   --create-bucket-configuration LocationConstraint=us-west-1

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

aws s3api put-bucket-versioning \
   --bucket  \
   --versioning-configuration Status=Enabled

4. Создание первого кластера Kubernetes: Итак, вы готовы создать свой первый кластер! Сначала настроим переменные среды, чтобы упростить процесс. Если вы пропустили конфигурацию DNS (после шага 2), добавьте .k8s.local к значению NAME.

export NAME=myfirstcluster.example.com
export KOPS_STATE_STORE=s3://your-bucket-name

Не забывайте следить, какие региональные зоны вам доступны. В этом примере мы будем разворачивать кластер в регионе us-east-2.

aws ec2 describe-availability-zones --region us-east-2

Если используется зона публичного хостинга, создайте кластер с помощью следующей команды:

kops create cluster \
   --zones us-east-2c \
   --node-count 3 \
   ${NAME}

Если вы используете зону приватного хостинга, выполните:

kops create cluster \
   --zones us-east-2c \
   --node-count 3 \
   --dns private ${NAME}

Эта команда предоставит вам журнал настройки кластера K8S. Для запуска кластеру нужно время, так как он создает новые машины EC2 для мастер-нод миньонов.

[ec2-user@ip-172-31-35-145 test]$ kops create cluster \
>     --dns private \
>     --zones us-east-2c \
>     --node-count 3 \
>     ${NAME} --yes
I0306 09:45:29.636834   20628 create_cluster.go:439] Inferred --cloud=aws from zone "us-east-2c"
I0306 09:45:29.637030   20628 create_cluster.go:971] Using SSH public key: /home/ec2-user/.ssh/id_rsa.pub
I0306 09:45:29.850021   20628 subnets.go:184] Assigned CIDR 172.20.32.0/19 to subnet us-east-2c
I0306 09:45:31.118837   20628 dns.go:92] Private DNS: skipping DNS validation
I0306 09:45:46.986963   20628 executor.go:91] Tasks: 73 done / 73 total; 0 can run
I0306 09:45:46.987101   20628 dns.go:153] Pre-creating DNS records
I0306 09:45:47.668392   20628 update_cluster.go:248] Exporting kubecfg for cluster
kops has set your kubectl context to k8s.appbase
Cluster is starting.  It should be ready in a few minutes.

Вуаля! Кластер K8s уже должен работать.

5. Проверка кластера: все экземпляры, созданные kops, находятся в ASG (Auto Scaling Groups). На случай сбоя ведется проверка и автоматическая перестройка экземпляров ASG.

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

kops edit cluster ${NAME}

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

kops update cluster ${NAME} --yes

Вы увидите что-то подобное.

[ec2-user@ip-172-31-35-145 examples]$ kops update cluster --yes
Using cluster from kubectl context: k8s.appbase
I0216 05:09:06.074467    2158 dns.go:92] Private DNS: skipping DNS validation
I0216 05:09:07.699380    2158 executor.go:91] Tasks: 73 done / 73 total; 0 can run
I0216 05:09:07.699486    2158 dns.go:153] Pre-creating DNS records
I0216 05:09:07.961703    2158 update_cluster.go:248] Exporting kubecfg for cluster
kops has set your kubectl context to k8s.appbase
Cluster changes have been applied to the cloud.

Проверим кластер.

kops validate cluster

Убедимся, что кластер запущен и готов.

Using cluster from kubectl context: k8s.appbase
Validating cluster k8s.appbase
INSTANCE GROUPS
NAME   ROLE MACHINETYPE MIN MAX SUBNETS
master-us-east-2c Master t2.large 1 1 us-east-2c
nodes   Node t2.medium 3 3 us-east-2c
NODE STATUS
NAME      ROLE READY
ip-172-20-44-33.us-east-2.compute.internal master True
ip-172-20-52-48.us-east-2.compute.internal node True
ip-172-20-62-30.us-east-2.compute.internal node True
ip-172-20-64-53.us-east-2.compute.internal node True
Your cluster k8s.appbase is ready

Проверьте свой новый k8s!

Простым вызовом API Kubernetes можно проверить, находится ли API в сети и слушает ли. Используйте kubectl чтобы проверить ноды.

kubectl get nodes

Это даст информацию о ваших нодах и их текущем статусе.

[ec2-user@ip-172-31-35-145 elasticsearch]$ kubectl get nodes
NAME                                         STATUS    ROLES     AGE       VERSION
ip-172-20-44-33.us-east-2.compute.internal   Ready     master    1m       v1.8.6
ip-172-20-52-48.us-east-2.compute.internal   Ready     node      3m       v1.8.6
ip-172-20-62-30.us-east-2.compute.internal   Ready     node      2m       v1.8.6
ip-172-20-64-53.us-east-2.compute.internal   Ready     node      4m       v1.8.6

Под в Kubernetes — это абстракция, представляющая группу из одного или более контейнеров приложения (например Docker) и нескольких общих ресурсов для этих контейнеров. Под разворачивается на ноде. Если нужно масштабировать приложение, добавляйте ноды к развернутому K8S.

Чтобы узнать о доступных подах, выполните:

kubectl get pods

Эта команда даст список доступных подов в кластере.

[ec2-user@ip-172-31-35-145 ~]$ kubectl get pods
NAME                  READY     STATUS    RESTARTS   AGE
es-5967f5d99c-5vcpb   1/1       Running   0          3h
es-5967f5d99c-cqk88   1/1       Running   0          3h
es-5967f5d99c-lp789   1/1       Running   0          3h


Развертывание Elasticsearch в кластере K8S

ot1mhep0o9nltuo2ueq0puexg7g.png

Если вы толком не знакомы с Kubernetes, я рекомендую интерактивный тренинг по k8s.

На данный момент в K8S кластере мы создали: главную ноду и две ноды-агента. Роль главной ноды заключается в передаче команд развертывания приложениям, запущенным в подах нод-агентов.

Развертывания приложений в K8S являются декларативными и настраиваются через файлы JSON / YAML. Выбирайте контроллер в зависимости от типа приложения или системы, которую вы разворачиваете. Поскольку Elasticsearch — это приложение, сохраняющее состояние, мы будем использовать контроллер StatefulSet.

6. Развертывание через StatefulSet. StatefulSet управляет подами, основанными на спецификации идентичных контейнеров. Он управляет развертыванием и масштабированием набора подов и гарантирует порядок и уникальность этих подов. Контроллер StatefulSet также упрощает связь приложения с persistent volume, что важно для Elasticsearch.

Создайте файл с именем es-stateful set.и yaml. Он будет содержать спецификацию Elasticsearch. Смело изменяйте конфигурацию. Список переменных среды, которые можно передать в используемый образ Elasticsearch, смотрите здесь.

7. Сервисы: Service Kubernetes — абстракция, которая определяет логический набор подов и доступ к ним. Это помогает контейнерному приложению идентифицировать другое контейнерное приложение или свой собственный экземпляр в другом поде.

diwnyqsurqxa0813hatxpfhfgco.png

LoadBalancer — особый тип сервиса, который предоставляет поды внешним сетям и распределяет нагрузку. Мы будем использовать его для создания внешнего IP-адреса, через который любой под может связаться с кластером Elasticsearch. Мы будем использовать этот сервис для нодов ES как способ обнаружить друг друга.

Создайте файл с именем es-svc.yaml. Отредактируйте его и укажите сервис load balancer.

apiVersion: v1               #API Version of the resource
kind: Service                #Type of resource
metadata:                    #Contains metadata of this resource.
 name: elasticsearch        #Name of this resource
 labels:                    #Additional identifier to put on pods
   component: elasticsearch #puts component = elasticsearch
spec:                        #Specifications of this resource
 type: LoadBalancer         #type of service
 selector:                  #will distribute load on pods which
   component: elasticsearch #have label `component = elasticsearch`
 ports:                     #Port on which LoadBalancer will listen
 - name: http               #Name given to port
   port: 9200               #Port number
   protocol: TCP            #Protocol supported
 - name: transport          #Name given to port
   port: 9300               #Port number
   protocol: TCP            #Protocol supported

8. Создание приложения: это все, что нам нужно. Разворачиваем наш кластер Elasticsearch на K8S с помощью следующих команд.

kubectl create -f es-statefulset.yaml
kubectl create -f es-svc.yaml

'Create' — универсальная команда для создания любого ресурса в K8S.

Наш 3-нодный (помните replicas = 3 в конфиге StatefulSet?) кластер Elasticsearch будет запущен мгновенно.

Мы можем проверить поды Elasticsearch с помощью этой команды:

kubectl get pods
[ec2-user@ip-172-31-35-145 test]$ kubectl get pods,svc,deployment
NAME                  READY     STATUS    RESTARTS   AGE
es-0                  1/1       Running   0          23m
es-1                  1/1       Running   0          17m
es-2                  1/1       Running   0          23m

9.Тестирование кластера Elasticsearch: проверим, правильно ли настроен и работает ли Elasticsearch. Получите внешний IP-адрес для подключения к Elasticsearch. Он будет находиться в созданном нами сервисе LoadBalancer. Используйте следующую команду для описания LoadBalancer:

kubectl describe service elasticsearch
[ec2-user@ip-172-31-35-145 examples]$ kubectl describe service elasticsearch
Name:                     elasticsearch
Namespace:                default
Labels:                   component=elasticsearch
Annotations:              
Selector:                 component=elasticsearch
Type:                     LoadBalancer
IP:                       100.70.114.146
LoadBalancer Ingress:     http://a4d0c157d212811e898430af47d23da1-952261901.us-east-2.elb.amazonaws.com
Port:                     http  9200/TCP
TargetPort:               9200/TCP
NodePort:                 http  31358/TCP
Endpoints:                100.96.4.28:9200
Port:                     transport  9300/TCP
TargetPort:               9300/TCP
NodePort:                 transport  31767/TCP
Endpoints:                100.96.4.28:9300
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  1m    service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   1m    service-controller  Ensured load balancer
[ec2-user@ip-172-31-35-145 examples]$

Обратите внимание на значение LoadBalancer Ingress. Откройте браузер с URI и суффиксным номером внешнего порта Elasticsearch: 9200. Вы увидите это:

elb_zlrvyocf5b7phv5pd9zubri.jpeg

Вы можете проверить работоспособность нодов Elasticsearch, добавив : 9200/_cluster /health?pretty к внешнему IP-адресу.

hhyeaabyci4yvxnwqjkxacghek4.jpeg

10. Тестирование Kubernetes Healing: У StatefulSets есть функция сохранения указанного числа реплик. Таким образом, если под падает, StatefulSet будет запускать новые поды.

Мы проверим его, имитируя сбой (удаляя все поды, на которых работают наши экземпляры ES), чтобы увидеть, может ли наш кластер ES автоматически создавать резервные копии с неповрежденными данными.

l1vhnbrmqhhumqzqi1c7uczvdaa.gif

Так как StatefulSet запускает по одному поду за раз, на восстановление всех контейнеров потребуется время.

Мы видим, что после восстановления подов нам доступна проиндексированная запись в состоянии до сбоя ES.


Рекомендуем следующие шаги

Прежде чем использовать эти настройки в продакшн, обратите внимание:


  1. Настройка резервных копий. Помогает восстановить потерянные данные. Этот процесс лучше автоматизировать.
  2. Настройка авторизации. Мы хотим защитить кластер Elasticsearch. Настройка обычной проверки подлинности или авторизации на основе токен носителя обеспечит безопасность.
  3. Сертификаты TLS. Настройте LetsEncrypt / другие поставщики TLS сертификатов сопоставления личного домена для нашего ES кластера и защиты всех передаваемых ему запросов.

Хоть статья не о том, но знайте: Kubernetes все это умеет.

Оригинал: Deploy Elasticsearch with Kubernetes on AWS in 10 steps

© Habrahabr.ru