Установка Stackland на виртуальные машины в Yandex Cloud
В этом руководстве описана установка Yandex Cloud Stackland на виртуальные машины в Yandex Cloud из пользовательского загрузочного образа.
Note
Основные сценарии развертывания Stackland поверх виртуальных машин в Yandex Cloud — демонстрация, прототипирование и тестовые стенды.
Для production-нагрузок в зонах, где доступны управляемые сервисы Yandex Cloud, рекомендуем использовать эти сервисы.
Введение
Для развертывания минимального кластера потребуется:
- Один бастионный хост на Ubuntu 22.04 или выше. На нем запускается
sladm, выполняется доступ к кластеру и обеспечивается выход узлов в интернет. - Не менее трех виртуальных машин для будущего кластера Stackland. Все машины должны находиться в одной облачной сети и одной подсети.
- Пользовательский образ диска, созданный из raw-образа Stackland.
- На каждой виртуальной машине: один загрузочный диск из пользовательского образа и один отдельный диск для данных.
- Сервисный аккаунт с правами на управление Network Load Balancer и использование облачной сети.
Рекомендуемые ресурсы для узлов кластера см. в разделе Инфраструктура.
Note
В ссылках на релизные артефакты используется переменная $VERSION. Замените ее на актуальную версию Stackland.
В примерах CLI ниже используются переменные. Перед выполнением команд задайте их значения:
export VERSION=26.1.5
export ZONE=ru-central1-d
export NETWORK_NAME=stackland-network
export SUBNET_NAME=stackland-subnet
export SUBNET_CIDR=10.130.0.0/24
export SECURITY_GROUP_NAME=stackland-sg
export DNS_ZONE_NAME=stackland-internal
export BASE_DOMAIN=stackland.internal
export CLUSTER_NAME=main
Подготовьте облачную сеть
Создайте облачную сеть и подсеть, в которой будут размещены бастионный хост и виртуальные машины кластера.
При подготовке сети учитывайте следующие требования:
- Все виртуальные машины кластера должны находиться в одной подсети. Это упрощает работу Network Load Balancer и целевой группы.
- Виртуальные машины кластера должны иметь стабильные внутренние IP-адреса.
- Бастионный хост должен иметь доступ в интернет и сетевой доступ к виртуальным машинам кластера.
- Узлы кластера должны иметь доступ в интернет через бастионный хост, NAT или другой сетевой механизм вашей инфраструктуры.
Создайте DNS-зону для будущего кластера. В примерах ниже используется домен stackland.internal.
Если вы используете CLI, выполните команды:
yc vpc network create --name $NETWORK_NAME
yc vpc subnet create \
--name $SUBNET_NAME \
--zone $ZONE \
--range $SUBNET_CIDR \
--network-name $NETWORK_NAME
NETWORK_ID=$(yc vpc network get $NETWORK_NAME --format json | jq -r '.id')
yc dns zone create \
--name $DNS_ZONE_NAME \
--zone $BASE_DOMAIN. \
--private-visibility \
--network-ids $NETWORK_ID
Если для виртуальных машин используются группы безопасности, создайте группу и разрешите трафик, необходимый для установки и работы кластера:
yc vpc security-group create \
--name $SECURITY_GROUP_NAME \
--network-name $NETWORK_NAME
SECURITY_GROUP_ID=$(yc vpc security-group get $SECURITY_GROUP_NAME --format json | jq -r '.id')
yc vpc security-group update-rules $SECURITY_GROUP_ID \
--add-rule "direction=ingress,protocol=any,predefined=self_security_group" \
--add-rule "direction=ingress,protocol=tcp,port=22,v4-cidrs=<ip_адрес_администратора>/32" \
--add-rule "direction=ingress,protocol=tcp,from-port=30000,to-port=32767,v4-cidrs=0.0.0.0/0" \
--add-rule "direction=egress,protocol=any,v4-cidrs=0.0.0.0/0"
Правило для диапазона 30000-32767 нужно для доступа Network Load Balancer к NodePort-портам системного ingress. В примере указан стандартный диапазон NodePort в Kubernetes. Если в вашей конфигурации задан другой диапазон, укажите его в правиле группы безопасности. Для production-стендов ограничьте источник трафика в этом правиле согласно сетевой политике вашей организации.
Подготовьте сервисный аккаунт
Создайте сервисный аккаунт, который будет привязан к виртуальным машинам кластера. Назначьте ему роли:
load-balancer.admin— для создания и удаления сетевых балансировщиков и целевых групп.vpc.user— для работы с ресурсами облачной сети.
Выполните команды:
yc iam service-account create --name stackland-yc-lb
SA_ID=$(yc iam service-account get stackland-yc-lb --format json | jq -r '.id')
FOLDER_ID=$(yc config get folder-id)
yc resource-manager folder add-access-binding "$FOLDER_ID" \
--role load-balancer.admin \
--subject serviceAccount:"$SA_ID"
yc resource-manager folder add-access-binding "$FOLDER_ID" \
--role vpc.user \
--subject serviceAccount:"$SA_ID"
Создайте образ диска
Создайте пользовательский образ диска из raw-образа Stackland. Raw-образ доступен по адресу:
https://storage.yandexcloud.net/stackland-public/stackland/$VERSION/images/stackland-amd64-$VERSION.raw
Создать образ можно по инструкции Загрузить свой образ.
Если вы используете CLI, выполните команду:
yc compute image create \
--name stackland-$VERSION \
--source-uri https://storage.yandexcloud.net/stackland-public/stackland/$VERSION/images/stackland-amd64-$VERSION.raw \
--os-type linux \
--min-disk-size 150GB
Дождитесь, пока образ перейдет в состояние READY.
Создайте бастионный хост
Создайте виртуальную машину с Ubuntu 22.04 или выше в той же подсети, где будут размещены узлы кластера.
На бастионном хосте установите необходимые утилиты:
sudo apt update
sudo apt install unzip jq curl wget -y
Установите kubectl: он понадобится для проверки состояния кластера после установки. Например:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
Установите и настройте CLI для Yandex Cloud.
Если узлы кластера выходят в интернет через бастионный хост, включите IPv4-маршрутизацию и NAT. Пример настройки NAT приведен в руководстве Установка Stackland на Yandex BareMetal.
Создайте виртуальные машины кластера
Создайте не менее трех виртуальных машин для кластера Stackland.
Для каждой виртуальной машины задайте следующие параметры:
- Загрузочный диск — из пользовательского образа
stackland-$VERSION. - Дополнительный диск для данных — не менее требуемого объема по минимальным требованиям.
- Сервисный аккаунт — созданный ранее сервисный аккаунт.
- Подсеть — та же подсеть, где находится бастионный хост.
- Внутренний IP-адрес — статический.
- Публичный IP-адрес — не назначайте, если доступ к узлам выполняется через бастионный хост.
- Метка
cluster-name— значение должно совпадать сmetadata.nameв ресурсеStacklandClusterConfig. В примере ниже этоmain.
Если вы используете CLI, добавьте параметр --labels cluster-name=$CLUSTER_NAME при создании виртуальных машин.
Если виртуальные машины уже созданы, добавьте метку отдельно:
yc compute instance add-labels node1 --labels cluster-name=$CLUSTER_NAME
yc compute instance add-labels node2 --labels cluster-name=$CLUSTER_NAME
yc compute instance add-labels node3 --labels cluster-name=$CLUSTER_NAME
Warning
Метка cluster-name обязательна для компонента yandexcloud-lb. Без нее оператор балансировщика не сможет получить имя кластера из metadata-сервиса Yandex Cloud и будет перезапускаться с ошибкой failed to get cluster name from metadata: metadata service returned status 404.
Пример создания первого узла с помощью CLI:
yc compute instance create \
--name node1 \
--zone $ZONE \
--hostname node1.$BASE_DOMAIN \
--platform standard-v3 \
--cores 32 \
--memory 64GB \
--core-fraction 100 \
--labels cluster-name=$CLUSTER_NAME \
--create-boot-disk name=node1-boot,image-name=stackland-$VERSION,type=network-ssd,size=150,auto-delete=true \
--create-disk name=node1-data,type=network-ssd,size=400,device-name=data,auto-delete=true \
--network-interface subnet-name=$SUBNET_NAME,ipv4-address=10.130.0.11,security-group-ids=$SECURITY_GROUP_ID \
--service-account-name stackland-yc-lb
Создайте остальные узлы по этому примеру, изменив имена, FQDN, IP-адреса и имена дисков.
После создания виртуальных машин запишите для каждого узла:
- FQDN или имя, которое будет использоваться в конфигурации Stackland.
- Внутренний IP-адрес.
- MAC-адрес сетевого интерфейса.
- Имя загрузочного диска внутри гостевой ОС. Обычно это
/dev/vda, но проверьте значение для вашей конфигурации. - Имя диска для данных внутри гостевой ОС. Обычно это
/dev/vdb, если к виртуальной машине подключен один дополнительный диск.
Настройте DNS
Настройте DNS-записи для домена кластера.
Для узлов кластера создайте A-записи, которые указывают на внутренние IP-адреса виртуальных машин:
node1.stackland.internal. A 10.130.0.11
node2.stackland.internal. A 10.130.0.12
node3.stackland.internal. A 10.130.0.13
Если вы используете CLI, выполните команду:
yc dns zone add-records $DNS_ZONE_NAME \
--record "node1 300 A 10.130.0.11" \
--record "node2 300 A 10.130.0.12" \
--record "node3 300 A 10.130.0.13"
Также подготовьте записи для системных эндпоинтов:
api.sys.$baseDomain— на адрес сетевого балансировщика, который вы используете для доступа к API Kubernetes, либо на внутренние IP-адреса узловcombinedилиcontrol-plane.*.sys.$baseDomain— на адрес, который будет назначен сетевому балансировщику после установки.
Если адрес сетевого балансировщика неизвестен заранее, создайте или обновите wildcard-запись после завершения установки и создания Network Load Balancer.
До установки создайте запись для API Kubernetes:
yc dns zone add-records $DNS_ZONE_NAME \
--record "api.sys 300 A 10.130.0.11" \
--record "api.sys 300 A 10.130.0.12" \
--record "api.sys 300 A 10.130.0.13"
После установки получите внешний IP-адрес Network Load Balancer и добавьте wildcard-запись:
INGRESS_IP=$(kubectl get svc -n stackland-ingress ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
yc dns zone add-records $DNS_ZONE_NAME \
--record "*.sys 300 A $INGRESS_IP"
Подготовьте конфигурацию Stackland
Создайте на бастионном хосте папку config/ и сохраните в ней конфигурационные файлы кластера.
Note
Для балансировщика yandex-nlb не указывайте ipPools. Этот параметр не поддерживается Network Load Balancer.
Пример конфигурации кластера:
apiVersion: v1alpha1
kind: StacklandClusterConfig
metadata:
name: main
spec:
platform:
type: yandexcloud
loadBalancer:
type: yandex-nlb
cluster:
baseDomain: stackland.internal
networking:
hostsNetwork:
- cidr: 10.130.0.0/24
clusterNetwork:
- cidr: 172.16.0.0/16
servicesNetwork:
- cidr: 10.96.0.0/12
storage:
defaultStorageClass: stackland-other
genericHostConfig:
disksConfig:
- installDisk:
name: /dev/vda
- dataDisk:
name: /dev/vdb
networkConfig:
routes:
- to: 0.0.0.0/0
via: 10.130.0.1
iface: eth0
resolvers:
- 10.130.0.2
timeservers:
- 10.130.0.2
В Compute Cloud сетевые диски виртуальных машин отображаются как VirtIO-устройства. Stackland относит такие диски к Storage Class stackland-other, поэтому для этого сценария укажите defaultStorageClass: stackland-other.
Если указать stackland-ssd, постоянные тома для системных компонентов могут остаться в состоянии Pending, а в событиях подов будет сообщение did not have enough free storage.
Пример конфигурации хостов:
apiVersion: v1alpha1
kind: StacklandHostsList
metadata:
name: main
spec:
hosts:
- hostname: node1.stackland.internal
role: combined
networkConfig:
interfaces:
- macaddress: d0:0d:20:97:18:17
name: eth0
addresses:
- interface: eth0
ip: 10.130.0.11/24
- hostname: node2.stackland.internal
role: combined
networkConfig:
interfaces:
- macaddress: d0:0d:1f:a3:b5:05
name: eth0
addresses:
- interface: eth0
ip: 10.130.0.12/24
- hostname: node3.stackland.internal
role: combined
networkConfig:
interfaces:
- macaddress: d0:0d:1a:c5:b7:a5
name: eth0
addresses:
- interface: eth0
ip: 10.130.0.13/24
Замените IP-адреса, MAC-адреса, DNS-серверы, NTP-серверы и имена хостов на значения вашей инфраструктуры.
Скачайте sladm
На бастионном хосте скачайте и распакуйте sladm:
wget https://storage.yandexcloud.net/stackland-public/stackland/$VERSION/sladm-$VERSION-linux-amd64.zip
unzip sladm-$VERSION-linux-amd64.zip
chmod +x sladm
Подготовьте секреты
Сгенерируйте ресурс StacklandSecretsConfig:
./sladm secrets add --out config/secrets.yaml --license-key key.json
Где key.json — файл с лицензионным ключом Stackland.
Установите кластер
Проверьте конфигурацию перед установкой:
./sladm validate --config config/
Запустите установку:
./sladm install --config config/ --installation-timeout 2h 2>&1 | tee install-$(date +%y%m%d-%H%M).log
Процесс установки занимает примерно час. Лог установки сохраните до окончания проверки: в нем есть сообщения о переходах узлов и компонентов между состояниями, а после успешной установки — адрес консоли управления, логин и пароль администратора.
Warning
Лог установки содержит пароль администратора. Не публикуйте его и не передавайте третьим лицам.
Если установка не завершилась за отведенное время или остановилась с ошибкой, см. раздел Устранение неполадок.
Проверьте установку
После завершения установки в логе sladm должно появиться сообщение:
✓ Your Stackland cluster is ready
Также sladm выведет адрес консоли управления, логин и пароль по умолчанию.
На бастионном хосте проверьте состояние установки вручную.
Если sladm еще не скопировал kubeconfig в домашнюю директорию пользователя, укажите файл kubeconfig явно:
export KUBECONFIG=./_out/kubeconfig
-
Проверьте, что Kubernetes API доступен и все узлы находятся в состоянии
Ready:kubectl get nodes -o wide -
Проверьте, что начальная установка платформы завершена:
kubectl get platformconfig main -o jsonpath='{.status.initialInstall.state}{"\n"}'Ожидаемое значение:
Installed -
Проверьте состояния компонентов:
kubectl get componentinstallations -o wideВсе компоненты должны быть в состоянии
Ready. -
Проверьте, что нет зависших PVC и PVC с неверным Storage Class:
kubectl get pvc -A kubectl get pvc -A | grep -E 'Pending|Lost|stackland-ssd' || trueДля этого сценария PVC системных компонентов должны использовать
stackland-other. -
Проверьте, что нет подов c ошибками:
kubectl get pod -A --field-selector=status.phase!=Succeeded | grep -E 'Pending|Error|CrashLoop|Init|0/|ContainerCreating' || trueЕсли команда выводит поды, проверьте их события и логи:
kubectl describe pod <имя_пода> -n <пространство_имен> kubectl logs <имя_пода> -n <пространство_имен> --previous --tail=100 -
Проверьте системные ingress-ресурсы:
kubectl get ingress -A kubectl get svc -n stackland-ingress ingress-controller -o wideВ поле
ADDRESSу ingress-ресурсов должен быть внешний IP-адрес Network Load Balancer.
Проверьте, что доступны системные эндпоинты:
https://console.sys.$baseDomain— консоль управления кластером.https://dashboard.sys.$baseDomain— дашборд кластера.https://grafana.sys.$baseDomain— графики кластера в Grafana.https://prometheus.sys.$baseDomain— метрики кластера в Prometheus.https://alertmanager.sys.$baseDomain— алерты кластера в Alertmanager.
Если wildcard-запись *.sys.$baseDomain еще не указывает на адрес Network Load Balancer, получите адрес созданного балансировщика и обновите DNS-запись.
Например:
INGRESS_IP=$(kubectl get svc -n stackland-ingress ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
yc dns zone add-records $DNS_ZONE_NAME \
--record "*.sys 300 A $INGRESS_IP"
Если вы проверяете доступ с рабочей станции и не используете публичную DNS-зону, добавьте записи в файл hosts на вашем компьютере:
<ip_балансировщика> console.sys.stackland.internal auth.sys.stackland.internal kubeconfig.sys.stackland.internal grafana.sys.stackland.internal docs.sys.stackland.internal
Note
Если открыть IP-адрес Network Load Balancer напрямую в браузере, ingress вернет ответ default backend - 404. Это ожидаемое поведение: маршрутизация выполняется по имени хоста. Открывайте консоль по адресу https://console.sys.$baseDomain.
Проверьте доступ к консоли управления:
curl -I --max-time 10 -H "Host: console.sys.$BASE_DOMAIN" http://$INGRESS_IP
curl -kI --max-time 10 \
--resolve console.sys.$BASE_DOMAIN:443:$INGRESS_IP \
https://console.sys.$BASE_DOMAIN
Ожидаемый результат:
- HTTP-запрос возвращает редирект на HTTPS.
- HTTPS-запрос возвращает редирект на страницу входа или саму страницу входа с кодом
200.
Проверьте состояние целевой группы балансировщика:
yc load-balancer network-load-balancer list
yc load-balancer target-group list
yc load-balancer network-load-balancer target-states <имя_или_id_балансировщика> \
--target-group-id <id_целевой_группы>
Все узлы должны перейти в состояние HEALTHY.
Если узлы остаются в состоянии UNHEALTHY, проверьте доступность NodePort-порта ingress с бастионного хоста:
INGRESS_HTTP_NODEPORT=$(kubectl get svc -n stackland-ingress ingress-controller -o jsonpath='{.spec.ports[?(@.port==80)].nodePort}')
for ip in <ip_узла_1> <ip_узла_2> <ip_узла_3>; do
timeout 3 bash -c "</dev/tcp/$ip/$INGRESS_HTTP_NODEPORT" && \
echo "$ip:$INGRESS_HTTP_NODEPORT open" || \
echo "$ip:$INGRESS_HTTP_NODEPORT closed"
done
Если NodePort доступен из подсети, но целевая группа остается в состоянии UNHEALTHY, проверьте:
- правила групп безопасности для входящего трафика от Network Load Balancer к NodePort-портам узлов;
- сетевые ACL, маршруты и NAT-правила, которые могут влиять на обратный трафик от узлов к проверкам состояния Network Load Balancer;
- что в целевой группе указаны внутренние IP-адреса всех узлов;
- что сервис
stackland-ingress/ingress-controllerиспользует те же NodePort-порты, что и Network Load Balancer.
Для дополнительной проверки ingress из подсети выполните с бастионного хоста:
curl -I --max-time 10 -H "Host: console.sys.$BASE_DOMAIN" \
http://<ip_любого_узла>:$INGRESS_HTTP_NODEPORT
Ожидаемый ответ — HTTP-редирект на HTTPS или страницу входа.
Устранение неполадок
В этом разделе приведены проблемы, характерные для установки Stackland на виртуальные машины в Yandex Cloud. Общие проблемы установки см. в разделе Диагностика и устранение неполадок.
yandexcloud-lbперезапускается с ошибкой metadata-сервиса
Если установка останавливается на компонентах load-balancer или ingress, проверьте поды компонента балансировщика:
kubectl get pod -n stackland-load-balancer
kubectl logs -n stackland-load-balancer deploy/yandexcloud-lb --tail=100
Если в логах есть ошибка failed to get cluster name from metadata: metadata service returned status 404, проверьте, что у всех виртуальных машин кластера есть метка cluster-name, совпадающая с metadata.name в ресурсе StacklandClusterConfig:
yc compute instance add-labels node1 --labels cluster-name=$CLUSTER_NAME
yc compute instance add-labels node2 --labels cluster-name=$CLUSTER_NAME
yc compute instance add-labels node3 --labels cluster-name=$CLUSTER_NAME
После добавления метки перезапустите под yandexcloud-lb:
kubectl delete pod -n stackland-load-balancer -l app.kubernetes.io/name=yandexcloud-lb
PVC остаются в состоянии Pending
Если установка останавливается на компонентах iam, logging или storage, а в событиях подов есть сообщение did not have enough free storage, проверьте Storage Class и емкость TopoLVM:
kubectl get nodes -o custom-columns=NAME:.metadata.name,OTHER:.status.capacity.capacity\.topolvm\.io/stackland-other,SSD:.status.capacity.capacity\.topolvm\.io/stackland-ssd
kubectl get pvc -A
Для виртуальных машин в Compute Cloud емкость должна быть доступна в capacity.topolvm.io/stackland-other. В конфигурации установки должен быть указан параметр:
storage:
defaultStorageClass: stackland-other
Если PVC уже созданы с stackland-ssd, измените конфигурацию и перезапустите установку. На тестовом стенде без пользовательских данных можно удалить только те PVC, которые находятся в состоянии Pending, чтобы операторы пересоздали их с правильным Storage Class.