Files
talos-kurs/talos-k8s/generate.sh

786 lines
26 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
### Дефолты ###
IMAGE=factory.talos.dev/metal-installer/956b9107edd250304169d2e7a765cdd4e0c31f9097036e2e113b042e6c01bb98:v1.10.4
DEFAULT_K8S_VERSION=1.33.2
CONFIG_DIR="config"
# Цвета для вывода
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# функции ask_yes_no, check_command, detect_os и т.д.
ask_yes_no() {
local prompt="$1"
local default="$2"
local answer
while true; do
read -p "$prompt" answer
answer=${answer:-$default}
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') # convert to lowercase
case "$answer" in
y|yes)
echo "y"
return 0
;;
n|no)
echo "n"
return 0
;;
*)
echo -e "${YELLOW}Некорректный ввод. Введите 'y'/'yes' или 'n'/'no'.${NC}"
;;
esac
done
}
# Функция для определения ОС
detect_os() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "$ID"
elif [[ -f /etc/redhat-release ]]; then
echo "rhel"
elif [[ -f /etc/debian_version ]]; then
echo "debian"
else
echo "linux"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macos"
else
echo "unknown"
fi
}
# Функция для проверки установки утилиты
check_command() {
local cmd="$1"
local name="$2"
if command -v "$cmd" &> /dev/null; then
echo -e "${GREEN}$name установлен${NC}"
return 0
else
echo -e "${RED}$name не установлен${NC}"
return 1
fi
}
# Функция для проверки установки brew (для macOS)
check_brew() {
if ! command -v brew &> /dev/null; then
echo -e "${RED}✗ brew не установлен${NC}"
echo -e "${YELLOW}Установите Homebrew командой:/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"${NC}"
exit 1
fi
}
# Функция для установки talosctl
install_talosctl() {
local os=$(detect_os)
echo -e "\n${YELLOW}Установка talosctl...${NC}"
case "$os" in
"ubuntu"|"debian")
echo "Для Ubuntu/Debian:"
echo "curl -Lo /usr/local/bin/talosctl https://github.com/siderolabs/talos/releases/latest/download/talosctl-linux-amd64"
echo "chmod +x /usr/local/bin/talosctl"
;;
"rhel"|"centos"|"fedora"|"rocky"|"alma")
echo "Для RHEL/CentOS/Fedora:"
echo "curl -Lo /usr/local/bin/talosctl https://github.com/siderolabs/talos/releases/latest/download/talosctl-linux-amd64"
echo "chmod +x /usr/local/bin/talosctl"
;;
"macos")
check_brew
echo "Для macOS:"
echo "brew install talosctl"
echo "Или вручную:"
echo "curl -Lo /usr/local/bin/talosctl https://github.com/siderolabs/talos/releases/latest/download/talosctl-darwin-amd64"
echo "chmod +x /usr/local/bin/talosctl"
;;
*)
echo "Скачайте talosctl с https://github.com/siderolabs/talos/releases"
;;
esac
}
# Функция для установки kubectl
install_kubectl() {
local os=$(detect_os)
echo -e "\n${YELLOW}Установка kubectl...${NC}"
case "$os" in
"ubuntu"|"debian")
echo "Для Ubuntu/Debian:"
echo "sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl"
echo "sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg"
echo "echo \"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main\" | sudo tee /etc/apt/sources.list.d/kubernetes.list"
echo "sudo apt-get update && sudo apt-get install -y kubectl"
;;
"rhel"|"centos"|"fedora"|"rocky"|"alma")
echo "Для RHEL/CentOS/Fedora:"
echo "cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo"
echo "[kubernetes]"
echo "name=Kubernetes"
echo "baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64"
echo "enabled=1"
echo "gpgcheck=1"
echo "repo_gpgcheck=1"
echo "gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg"
echo "EOF"
echo "sudo yum install -y kubectl"
;;
"macos")
check_brew
echo "Для macOS:"
echo "brew install kubectl"
;;
*)
echo "Скачайте kubectl с https://kubernetes.io/docs/tasks/tools/install-kubectl/"
;;
esac
}
# Проверка необходимых утилит
echo -e "${GREEN}--- Проверка необходимых утилит ---${NC}"
TALOSCTL_INSTALLED=false
KUBECTL_INSTALLED=false
if check_command "talosctl" "talosctl"; then
TALOSCTL_INSTALLED=true
else
if [[ $(ask_yes_no "Установить talosctl автоматически? (y/n) [y]: " "y") == "y" ]]; then
install_talosctl
else
echo -e "${YELLOW}Установка talosctl отменена пользователем. Скрипт завершён.${NC}"
exit 1
fi
fi
if check_command "kubectl" "kubectl"; then
KUBECTL_INSTALLED=true
else
if [[ $(ask_yes_no "Установить kubectl автоматически? (y/n) [y]: " "y") == "y" ]]; then
install_kubectl
else
echo -e "${YELLOW}Установка kubectl отменена пользователем. Скрипт завершён.${NC}"
exit 1
fi
fi
# Если что-то не установлено, предлагаем установить
if [[ "$TALOSCTL_INSTALLED" == "false" || "$KUBECTL_INSTALLED" == "false" ]]; then
echo -e "\n${YELLOW}Для продолжения необходимо установить недостающие утилиты.${NC}"
echo -e "${YELLOW}Выполните команды установки выше, затем запустите скрипт снова.${NC}"
exit 1
fi
echo -e "\n${GREEN}Все необходимые утилиты установлены!${NC}\n"
# Helper function for checking uniqueness in an array
contains_element () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
echo -e "${GREEN}--- Интерактивный конфигуратор Talos K8s ---${NC}"
# --- Вопросы пользователю ---
# Список вопросов для прогресса
QUESTIONS=(
"Введите имя кластера [talos-demo]: "
"Введите версию Kubernetes [${DEFAULT_K8S_VERSION}]: "
"Введите имя сетевого адаптера (например, ens18 или eth0) [ens18]: "
"Введите количество control plane (нечетное, макс 7) [1]: "
"Введите количество worker-нод (макс 15, мин 0) [3]: "
"Введите общий gateway (например, 192.168.23.1): "
"Введите маску сети (например, 24) [24]: "
"Введите первый DNS сервер: (например, 8.8.8.8) [8.8.8.8]: "
"Введите второй DNS сервер: (например, 8.8.4.4) [8.8.4.4]: "
"Введите первый NTP сервер [1.ru.pool.ntp.org]: "
"Введите второй NTP сервер [2.ru.pool.ntp.org]: "
"Введите третий NTP сервер [3.ru.pool.ntp.org]: "
"Нужен ли VIP адрес? (y/n) [y]: "
"Введите VIP адрес (например, 192.168.23.20): "
"Нужен ли внешний балансировщик? (y/n) [n]: "
"Введите IP адрес внешнего балансировщика: "
"Введите диск для установки базовой ос [/dev/sda]: "
"Нужна ли поддержка drbd? (y/n) [y]: "
"Нужна ли поддержка zfs? (y/n) [n]: "
"Нужна ли поддержка spl? (y/n) [n]: "
"Нужна ли поддержка vfio_pci? (y/n) [n]: "
"Нужна ли поддержка vfio_iommu_type1? (y/n) [n]: "
"Нужна ли поддержка openvswitch? (y/n) [n]: "
"Хотите ли вы использовать зеркала timeweb.cloud и gcr.io для docker.io? (y/n) [y]: "
"Нужно ли установить maxPods: 512? (110 подов на ноду по умолчанию) (y/n) [n]: "
)
QUESTION_IDX=0
QUESTION_TOTAL=${#QUESTIONS[@]}
# Функция для вывода вопроса с прогрессом
ask_with_progress() {
local prompt="$1"
((QUESTION_IDX++))
read -p "[$QUESTION_IDX из $QUESTION_TOTAL] $prompt" "$2"
}
ask_yes_no_progress() {
local prompt="$1"
local default="$2"
local varname="$3"
((QUESTION_IDX++))
local answer
while true; do
read -p "[$QUESTION_IDX из $QUESTION_TOTAL] $prompt" answer
answer=${answer:-$default}
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]')
case "$answer" in
y|yes)
eval "$varname=\"y\""
return 0
;;
n|no)
eval "$varname=\"n\""
return 0
;;
*)
echo -e "${YELLOW}Некорректный ввод. Введите 'y'/'yes' или 'n'/'no'.${NC}"
;;
esac
done
}
# Имя кластера
ask_with_progress "Введите имя кластера [talos-demo]: " CLUSTER_NAME
CLUSTER_NAME=${CLUSTER_NAME:-talos-demo}
# Версия Kubernetes
ask_with_progress "Введите версию Kubernetes [${DEFAULT_K8S_VERSION}]: " K8S_VERSION
K8S_VERSION=${K8S_VERSION:-${DEFAULT_K8S_VERSION}}
# Имя сетевого адаптера
ask_with_progress "Введите имя сетевого адаптера (например, ens18 или eth0) [ens18]: " INTERFACE_NAME
INTERFACE_NAME=${INTERFACE_NAME:-ens18}
# Количество control plane
while true; do
ask_with_progress "Введите количество control plane (нечетное, макс 7) [1]: " CP_COUNT
CP_COUNT=${CP_COUNT:-1}
if (( CP_COUNT % 2 != 0 && CP_COUNT > 0 && CP_COUNT <= 7 )); then
break
else
echo -e "${YELLOW}Некорректное значение. Введите нечетное число от 1 до 7.${NC}"
fi
done
# Количество worker-нод
while true; do
ask_with_progress "Введите количество worker-нод (макс 15, мин 0) [3]: " WORKER_COUNT
WORKER_COUNT=${WORKER_COUNT:-3}
if (( WORKER_COUNT >= 0 && WORKER_COUNT <= 15 )); then
break
else
echo -e "${YELLOW}Некорректное значение. Введите число от 0 до 15.${NC}"
fi
done
# Общий шлюз
while true; do
ask_with_progress "Введите общий gateway (например, 192.168.23.1): " GATEWAY
if [[ -n "$GATEWAY" ]]; then
USED_IPS+=("$GATEWAY")
break
else
echo -e "${YELLOW}Gateway не может быть пустым.${NC}"
fi
done
# Маска сети
while true; do
ask_with_progress "Введите маску сети (например, 24) [24]: " NETMASK
NETMASK=${NETMASK:-24}
if [[ -n "$NETMASK" ]]; then
break
else
echo -e "${YELLOW}Маска сети не может быть пустой.${NC}"
fi
done
# DNS-серверы
while true; do
ask_with_progress "Введите первый DNS сервер: (например, 8.8.8.8) [8.8.8.8]: " DNS1
DNS1=${DNS1:-8.8.8.8}
if [[ -n "$DNS1" ]]; then
break
else
echo -e "${YELLOW}DNS сервер не может быть пустым.${NC}"
fi
done
while true; do
ask_with_progress "Введите второй DNS сервер: (например, 8.8.4.4) [8.8.4.4]: " DNS2
DNS2=${DNS2:-8.8.4.4}
if [[ -n "$DNS2" ]]; then
break
else
echo -e "${YELLOW}DNS сервер не может быть пустым.${NC}"
fi
done
# NTP-серверы
ask_with_progress "Введите первый NTP сервер [1.ru.pool.ntp.org]: " NTP1
NTP1=${NTP1:-1.ru.pool.ntp.org}
ask_with_progress "Введите второй NTP сервер [2.ru.pool.ntp.org]: " NTP2
NTP2=${NTP2:-2.ru.pool.ntp.org}
ask_with_progress "Введите третий NTP сервер [3.ru.pool.ntp.org]: " NTP3
NTP3=${NTP3:-3.ru.pool.ntp.org}
# VIP адрес
VIP_IP=""
USE_VIP="n"
if (( CP_COUNT > 1 )); then
ask_yes_no_progress "Нужен ли VIP адрес? (y/n) [y]: " "y" USE_VIP
if [[ "$USE_VIP" == "y" ]]; then
while true; do
ask_with_progress "Введите VIP адрес (например, 192.168.23.20): " VIP_IP
if [[ -z "$VIP_IP" ]]; then
echo -e "${YELLOW}VIP адрес не может быть пустым.${NC}"
continue
fi
if contains_element "$VIP_IP" "${USED_IPS[@]}"; then
echo -e "${YELLOW}Этот IP адрес уже используется. Введите уникальный адрес.${NC}"
else
USED_IPS+=("$VIP_IP")
break
fi
done
fi
fi
# Внешний балансировщик
EXT_BALANCER_IP=""
ask_yes_no_progress "Нужен ли внешний балансировщик? (y/n) [n]: " "n" USE_EXT_BALANCER
if [[ "$USE_EXT_BALANCER" == "y" ]]; then
while true; do
ask_with_progress "Введите IP адрес внешнего балансировщика: " EXT_BALANCER_IP_INPUT
if [[ -z "$EXT_BALANCER_IP_INPUT" ]]; then
echo -e "${YELLOW}IP адрес не может быть пустым.${NC}"
continue
fi
if contains_element "$EXT_BALANCER_IP_INPUT" "${USED_IPS[@]}"; then
echo -e "${YELLOW}Этот IP адрес уже используется. Введите уникальный адрес.${NC}"
else
EXT_BALANCER_IP=$EXT_BALANCER_IP_INPUT
USED_IPS+=("$EXT_BALANCER_IP")
break
fi
done
fi
# Диск
ask_with_progress "Введите диск для установки базовой ос [/dev/sda]: " DISK
DISK=${DISK:-/dev/sda}
# Вопросы по модулям ядра
ask_yes_no_progress "Нужна ли поддержка drbd? (y/n) [y]: " "y" USE_DRBD
ask_yes_no_progress "Нужна ли поддержка zfs? (y/n) [n]: " "n" USE_ZFS
ask_yes_no_progress "Нужна ли поддержка spl? (y/n) [n]: " "n" USE_SPL
ask_yes_no_progress "Нужна ли поддержка vfio_pci? (y/n) [n]: " "n" USE_VFIO_PCI
ask_yes_no_progress "Нужна ли поддержка vfio_iommu_type1? (y/n) [n]: " "n" USE_VFIO_IOMMU_TYPE1
ask_yes_no_progress "Нужна ли поддержка openvswitch? (y/n) [n]: " "n" USE_OPENVSWITCH
# Использовать зеркало mirror.gcr.io?
ask_yes_no_progress "Хотите ли вы использовать зеркала timeweb.cloud и gcr.io для docker.io? (y/n) [y]: " "y" USE_MIRROR_GCR
# Вопрос: нужен ли maxPods: 512 для kubelet?
ask_yes_no_progress "Нужно ли установить maxPods: 512? (110 подов на ноду по умолчанию) (y/n) [n]: " "n" USE_KUBELET_MAXPODS
# --- Генерация конфигурационных файлов ---
mkdir -p "$CONFIG_DIR"
PATCH_FILE="$CONFIG_DIR/patch.yaml"
# --- Создание patch.yaml ---
# Записываем первую часть файла
cat > "$PATCH_FILE" << EOF
machine:
EOF
# Добавляем certSANs если есть внешний балансировщик
if [[ -n "$EXT_BALANCER_IP" ]]; then
cat >> "$PATCH_FILE" << EOF
certSANs:
- ${EXT_BALANCER_IP}
EOF
fi
# Добавляем блок kernel для drbd, если нужно
if [[ "$USE_DRBD" == "y" ]] && (( WORKER_COUNT == 0 )); then
cat >> "$PATCH_FILE" << EOF
kernel:
modules:
- name: drbd
parameters:
- usermode_helper=disabled
- name: drbd_transport_tcp
- name: dm-thin-pool
EOF
if [[ "$USE_ZFS" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
- name: zfs
EOF
fi
if [[ "$USE_SPL" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
- name: spl
EOF
fi
if [[ "$USE_VFIO_PCI" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
- name: vfio_pci
EOF
fi
if [[ "$USE_VFIO_IOMMU_TYPE1" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
- name: vfio_iommu_type1
EOF
fi
if [[ "$USE_OPENVSWITCH" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
- name: openvswitch
EOF
fi
fi
# Добавляем основную часть machine и начало cluster
cat >> "$PATCH_FILE" << EOF
network:
nameservers:
- ${DNS1}
- ${DNS2}
install:
disk: ${DISK}
image: ${IMAGE}
EOF
if [[ "$USE_MIRROR_GCR" == "y" ]]; then
cat >> "$PATCH_FILE" << EOF
registries:
mirrors:
docker.io:
endpoints:
- https://dockerhub.timeweb.cloud
- https://mirror.gcr.io
EOF
fi
cat >> "$PATCH_FILE" << EOF
time:
servers:
- ${NTP1}
- ${NTP2}
- ${NTP3}
cluster:
EOF
# Добавляем allowSchedulingOnControlPlanes и финальную часть
if (( WORKER_COUNT == 0 )); then
echo -e "\n${YELLOW}Воркеры отсутствуют. Разрешение на запуск подов на control plane...${NC}"
cat >> "$PATCH_FILE" << EOF
allowSchedulingOnControlPlanes: true
network:
cni:
name: none
proxy:
disabled: true
EOF
else
cat >> "$PATCH_FILE" << EOF
network:
cni:
name: none
proxy:
disabled: true
EOF
fi
CP_IPS=()
# Генерация патчей для control plane
echo -e "\n${GREEN}--- Настройка Control Plane нод ---${NC}"
for i in $(seq 1 $CP_COUNT); do
while true; do
read -p "Введите IP адрес для control plane $i (например, 192.168.23.5${i}): " CP_IP
if [[ -z "$CP_IP" ]]; then
echo -e "${YELLOW}IP адрес не может быть пустым.${NC}"
continue
fi
if contains_element "$CP_IP" "${USED_IPS[@]}"; then
echo -e "${YELLOW}Этот IP адрес уже используется. Введите уникальный адрес.${NC}"
else
CP_IPS+=("$CP_IP")
USED_IPS+=("$CP_IP")
break
fi
done
HOSTNAME="cp-$i"
FILENAME="$CONFIG_DIR/cp$i.patch"
# Создание базового патча
cat > "$FILENAME" << EOF
machine:
EOF
if [[ "$USE_KUBELET_MAXPODS" == "y" ]]; then
cat >> "$FILENAME" << EOF
kubelet:
extraConfig:
maxPods: 512
EOF
fi
cat >> "$FILENAME" << EOF
network:
hostname: $HOSTNAME
interfaces:
- interface: $INTERFACE_NAME
dhcp: false
addresses:
- $CP_IP/$NETMASK
EOF
# Добавление VIP, если он используется
if [[ "$USE_VIP" == "y" && -n "$VIP_IP" ]]; then
cat >> "$FILENAME" << EOF
vip:
ip: $VIP_IP
EOF
fi
# Добавление маршрутов
cat >> "$FILENAME" << EOF
routes:
- network: 0.0.0.0/0
gateway: $GATEWAY
EOF
echo "Создан файл: $FILENAME"
done
# Генерация патчей для worker-нод
if (( WORKER_COUNT > 0 )); then
echo -e "\n${GREEN}--- Настройка Worker нод ---${NC}"
WORKER_IPS=()
for i in $(seq 1 $WORKER_COUNT); do
while true; do
read -p "Введите IP адрес для worker $i (например, 192.168.23.10${i}): " WORKER_IP
if [[ -z "$WORKER_IP" ]]; then
echo -e "${YELLOW}IP адрес не может быть пустым.${NC}"
continue
fi
if contains_element "$WORKER_IP" "${USED_IPS[@]}"; then
echo -e "${YELLOW}Этот IP адрес уже используется. Введите уникальный адрес.${NC}"
else
USED_IPS+=("$WORKER_IP")
WORKER_IPS+=("$WORKER_IP")
break
fi
done
HOSTNAME="worker-$i"
FILENAME="$CONFIG_DIR/worker$i.patch"
cat > "$FILENAME" << EOF
machine:
network:
hostname: $HOSTNAME
interfaces:
- deviceSelector:
physical: true
dhcp: false
addresses:
- $WORKER_IP/$NETMASK
routes:
- network: 0.0.0.0/0
gateway: $GATEWAY
EOF
# Добавляем drbd если выбрано
if [[ "$USE_DRBD" == "y" ]]; then
cat >> "$FILENAME" << EOF
kernel:
modules:
- name: drbd
parameters:
- usermode_helper=disabled
- name: drbd_transport_tcp
- name: dm-thin-pool
EOF
if [[ "$USE_ZFS" == "y" ]]; then
cat >> "$FILENAME" << EOF
- name: zfs
EOF
fi
if [[ "$USE_SPL" == "y" ]]; then
cat >> "$FILENAME" << EOF
- name: spl
EOF
fi
if [[ "$USE_VFIO_PCI" == "y" ]]; then
cat >> "$FILENAME" << EOF
- name: vfio_pci
EOF
fi
if [[ "$USE_VFIO_IOMMU_TYPE1" == "y" ]]; then
cat >> "$FILENAME" << EOF
- name: vfio_iommu_type1
EOF
fi
if [[ "$USE_OPENVSWITCH" == "y" ]]; then
cat >> "$FILENAME" << EOF
- name: openvswitch
EOF
fi
fi
echo "Создан файл: $FILENAME"
done
fi
# --- Вывод команд для выполнения ---
echo -e "\n${YELLOW}--------------------------------------------------${NC}"
echo -e "${GREEN}Конфигурация завершена. Собираю файлы в кучу:${NC}"
echo -e "${YELLOW}--------------------------------------------------${NC}"
# Генерация секретов
talosctl gen secrets -o $CONFIG_DIR/secrets.yaml
# Определение эндпоинта
ENDPOINT_IP=""
if [[ "$USE_VIP" == "y" && -n "$VIP_IP" ]]; then
ENDPOINT_IP=$VIP_IP
else
FIRST_CP_FULL_IP=${CP_IPS[0]}
ENDPOINT_IP=$(echo "$FIRST_CP_FULL_IP" | cut -d'/' -f1)
fi
# Генерация основной конфигурации
cd $CONFIG_DIR
talosctl gen config --kubernetes-version $K8S_VERSION --with-secrets secrets.yaml $CLUSTER_NAME https://${ENDPOINT_IP}:6443 --config-patch @patch.yaml
# Применение патчей к control plane
for i in $(seq 1 $CP_COUNT); do
talosctl machineconfig patch controlplane.yaml --patch @cp$i.patch --output cp$i.yaml
echo "Создан файл: $CONFIG_DIR/cp$i.yaml"
done
# Применение патчей к worker-нодам
if (( WORKER_COUNT > 0 )); then
for i in $(seq 1 $WORKER_COUNT); do
WORKER_IP=${WORKER_IPS[$((i-1))]}
talosctl machineconfig patch worker.yaml --patch @worker${i}.patch --output worker${i}.yaml
echo "Создан файл: $CONFIG_DIR/worker${i}.yaml"
done
fi
# Обновление talosconfig с endpoints
echo -e "\n${GREEN}--- Обновление talosconfig ---${NC}"
# Создаем массив endpoints
ENDPOINTS=()
# Добавляем все control plane IPs
for cp_ip in "${CP_IPS[@]}"; do
ENDPOINTS+=("$cp_ip")
done
# Добавляем VIP если есть
if [[ "$USE_VIP" == "y" && -n "$VIP_IP" ]]; then
ENDPOINTS+=("$VIP_IP")
fi
# Добавляем внешний балансировщик если есть
if [[ "$USE_EXT_BALANCER" == "y" && -n "$EXT_BALANCER_IP" ]]; then
ENDPOINTS+=("$EXT_BALANCER_IP")
fi
# Объединяем endpoints через запятую с пробелом
ENDPOINTS_STRING=$(IFS="," ; echo "${ENDPOINTS[*]}")
# Обновляем talosconfig
if [[ -f "talosconfig" ]]; then
TMP_CONFIG=$(mktemp)
while IFS= read -r line; do
if [[ "$line" == *"endpoints: []"* ]]; then
echo "${line/endpoints: []/endpoints: [$ENDPOINTS_STRING]}" >> "$TMP_CONFIG"
else
echo "$line" >> "$TMP_CONFIG"
fi
done < "talosconfig"
mv "$TMP_CONFIG" "talosconfig"
echo -e "${GREEN}Обновлен talosconfig с endpoints: [$ENDPOINTS_STRING]${NC}"
else
echo -e "${YELLOW}Файл talosconfig не найден${NC}"
fi
# --- Применение конфигов и bootstrap ---
echo -e "\n${GREEN}--- Применение конфигов и bootstrap ---${NC}"
cd ..
FIRST_CP_IP=${CP_IPS[0]}
FIRST_CP_IP_CLEAN=$(echo "$FIRST_CP_IP" | cut -d'/' -f1)
read -p "Применить конфиг на первом control-plane ($FIRST_CP_IP_CLEAN)? [Enter для продолжения]"
talosctl apply-config --insecure -n $FIRST_CP_IP_CLEAN --file config/cp1.yaml
echo -e "${GREEN}Применен конфиг на первом control-plane ($FIRST_CP_IP_CLEAN)${NC}"
echo -e "${YELLOW}--------------------------------------------------${NC}"
echo -e "${RED} Обязательно дождитесь ребута и предложения в логе о bootstrap ${NC}"
echo -e "${GREEN}--------------------------------------------------${NC}"
read -p "Выполнить bootstrap на первом control-plane ($FIRST_CP_IP_CLEAN)? [Enter для продолжения]"
talosctl bootstrap --nodes $FIRST_CP_IP_CLEAN --endpoints $FIRST_CP_IP_CLEAN --talosconfig=config/talosconfig
echo -e "${GREEN}Выполнен bootstrap на первом control-plane ($FIRST_CP_IP_CLEAN)${NC}"
echo -e "${YELLOW}--------------------------------------------------${NC}"
echo -e "${RED}Обазятельно дождитесь полного завершения bootstrap${NC}"
echo -e "${YELLOW}--------------------------------------------------${NC}"
echo "Остальные ноды можно применять без ожидания"
echo -e "${GREEN}--------------------------------------------------${NC}"
if (( CP_COUNT > 1 )); then
for i in $(seq 2 $CP_COUNT); do
CP_IP_CLEAN=$(echo "${CP_IPS[$((i-1))]}" | cut -d'/' -f1)
read -p "Применить конфиг на control-plane $i ($CP_IP_CLEAN)? [Enter для продолжения]"
talosctl apply-config --insecure -n $CP_IP_CLEAN --file config/cp${i}.yaml
done
fi
if (( WORKER_COUNT > 0 )); then
for i in $(seq 1 $WORKER_COUNT); do
WORKER_IP=${WORKER_IPS[$((i-1))]}
read -p "Применить конфиг на worker-$i ($WORKER_IP)? [Enter для продолжения]"
talosctl apply-config --insecure -n $WORKER_IP --file config/worker${i}.yaml
done
fi
# Выгрузка kubeconfig
KUBECONFIG_ENDPOINT=""
if [[ "$USE_VIP" == "y" && -n "$VIP_IP" ]]; then
KUBECONFIG_ENDPOINT=$VIP_IP
else
KUBECONFIG_ENDPOINT=$FIRST_CP_IP_CLEAN
fi
talosctl kubeconfig ~/.kube/${CLUSTER_NAME}.yaml --nodes $KUBECONFIG_ENDPOINT --endpoints $KUBECONFIG_ENDPOINT --talosconfig config/talosconfig
echo "Работа скрипта завершена"