[Перевод] Деплой Elasticsearch на AWS с помощью Kubernetes за 10 шагов
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
Как вариант, можно сделать то же самое и из 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
Если вы толком не знакомы с Kubernetes, я рекомендую интерактивный тренинг по k8s.
На данный момент в K8S кластере мы создали: главную ноду и две ноды-агента. Роль главной ноды заключается в передаче команд развертывания приложениям, запущенным в подах нод-агентов.
Развертывания приложений в K8S являются декларативными и настраиваются через файлы JSON / YAML. Выбирайте контроллер в зависимости от типа приложения или системы, которую вы разворачиваете. Поскольку Elasticsearch — это приложение, сохраняющее состояние, мы будем использовать контроллер StatefulSet.
6. Развертывание через StatefulSet. StatefulSet управляет подами, основанными на спецификации идентичных контейнеров. Он управляет развертыванием и масштабированием набора подов и гарантирует порядок и уникальность этих подов. Контроллер StatefulSet также упрощает связь приложения с persistent volume, что важно для Elasticsearch.
Создайте файл с именем es-stateful set.и yaml
. Он будет содержать спецификацию Elasticsearch. Смело изменяйте конфигурацию. Список переменных среды, которые можно передать в используемый образ Elasticsearch, смотрите здесь.
7. Сервисы: Service
Kubernetes — абстракция, которая определяет логический набор подов
и доступ к ним. Это помогает контейнерному приложению идентифицировать другое контейнерное приложение или свой собственный экземпляр в другом поде.
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
. Вы увидите это:
Вы можете проверить работоспособность нодов Elasticsearch, добавив : 9200/_cluster /health?pretty
к внешнему IP-адресу.
10. Тестирование Kubernetes Healing: У StatefulSets есть функция сохранения указанного числа реплик. Таким образом, если под падает, StatefulSet будет запускать новые поды.
Мы проверим его, имитируя сбой (удаляя все поды, на которых работают наши экземпляры ES), чтобы увидеть, может ли наш кластер ES автоматически создавать резервные копии с неповрежденными данными.
Так как StatefulSet запускает по одному поду за раз, на восстановление всех контейнеров потребуется время.
Мы видим, что после восстановления подов нам доступна проиндексированная запись в состоянии до сбоя ES.
Рекомендуем следующие шаги
Прежде чем использовать эти настройки в продакшн, обратите внимание:
- Настройка резервных копий. Помогает восстановить потерянные данные. Этот процесс лучше автоматизировать.
- Настройка авторизации. Мы хотим защитить кластер Elasticsearch. Настройка обычной проверки подлинности или авторизации на основе токен носителя обеспечит безопасность.
- Сертификаты TLS. Настройте LetsEncrypt / другие поставщики TLS сертификатов сопоставления личного домена для нашего ES кластера и защиты всех передаваемых ему запросов.
Хоть статья не о том, но знайте: Kubernetes все это умеет.
Оригинал: Deploy Elasticsearch with Kubernetes on AWS in 10 steps