Skip to content

Установка в закрытом контуре

Развёртывание ALT Orchestra в закрытом контуре опирается на подготовленный инфраструктурный сервер: он находится в одной подсети с узлами кластера, не имеющими выхода в интернет, и выполняет служебные функции для их установки и работы.

ФункцияПрограммное обеспечениеТребуется
Выдача IP-адресов (DHCP)dhcp-serverнет: возможны статические адреса
Разрешение имён (DNS)bindнет: можно использовать IP-адреса
Синхронизация времени (NTP)chronyда: kubelet и etcd ждут синхронизации времени перед запуском
Реестр-прокси с кэшем — доступ к образам контейнеровdocker-registryда
Обнаружение узлов (Discovery Service RS)discovery-service-rsнет: без него не работают KubeSpan и KubePrism
Сетевая загрузка по iPXEdnsmasqнет: можно загрузить с ISO
Интернет-доступ реестранет: удобен только для первичной загрузки образов

KubeSpan и KubePrism — функции Talos Linux: KubeSpan — защищённое соединение узлов между сетями, KubePrism — высокодоступный доступ к API-серверу Kubernetes изнутри кластера.

Примечание: выход реестра в интернет нужен только для начальной загрузки образов: когда образы закэшированы прокси, сервер можно отключить от внешней сети, и кластер продолжит работу в закрытом контуре. Возможен и полностью офлайновый путь — не подключать сервер к интернету вовсе, а загрузить все необходимые образы в реестр вручную (например, через skopeo copy).

Примечание: все команды в этом разделе выполняются на инфраструктурном сервере от имени root.

Подготовка инфраструктурного сервера

Установка необходимых пакетов

console
apt-get update
apt-get dist-upgrade
apt-get install -y dhcp-server \
    bind \
    bind-utils \
    chrony \
    podman \
    docker-registry \
    containers-common \
    curl \
    jq \
    grpcurl \
    talosctl \
    kubernetes1.35-client \
    discovery-service-rs \
    helm

Настройка сетевых интерфейсов

Инфраструктурный сервер и узлы кластера должны находиться в одной подсети 192.168.1.0/24 и быть доступны друг другу. Узлы получают адреса по DHCP (см. следующий раздел), а серверу нужен стабильный статический адрес: по адресу 192.168.1.1 узлы обращаются ко всем его службам — DHCP, DNS, NTP, реестру и Discovery Service. Этот адрес используется во всех настройках ниже.

Способ назначения статического адреса зависит от системы управления сетью: etcnet (по умолчанию в части дистрибутивов ALT Linux) или systemd-networkd (по умолчанию в других; переключиться на неё можно и вручную). Выполните один из вариантов ниже.

Примечание: имя интерфейса ens20 в примерах — пример; замените его на фактическое (список: ip link).

etcnet

Создать каталог для конфигурации сетевого интерфейса:

console
IFACE="ens20" && mkdir -p /etc/net/ifaces/${IFACE}

Назначить статический IPv4-адрес и маску подсети для интерфейса:

console
echo 192.168.1.1/24 > /etc/net/ifaces/${IFACE}/ipv4address

Настроить параметры интерфейса (тип, протокол, автозагрузка):

console
cat > /etc/net/ifaces/${IFACE}/options <<EOF
TYPE=eth
CONFIG_WIRELESS=no
BOOTPROTO=static
SYSTEMD_BOOTPROTO=static
CONFIG_IPV4=yes
DISABLED=no
NM_CONTROLLED=no
SYSTEMD_CONTROLLED=no
ONBOOT=yes
EOF

Перезапустить сетевую службу и проверить назначенные адреса:

console
systemctl restart network && ip a

systemd-networkd

Создать каталог для конфигурации сетевого интерфейса:

console
IFACE="ens20" && mkdir -p /etc/systemd/network

Создать .network файл со статическим IPv4-адресом:

console
cat > /etc/systemd/network/20-${IFACE}.network <<EOF
[Match]
Name=${IFACE}
[Network]
Address=192.168.1.1/24
EOF

Перечитать конфигурацию и применить её к интерфейсу (networkctl reload перечитывает файлы и применяет изменения к подходящим интерфейсам):

console
networkctl reload

Проверить, что интерфейс настроен службой и адрес назначен:

console
networkctl status ${IFACE} && ip a

Настройка DHCP-сервера

Создать конфигурацию DHCP-сервера с диапазоном адресов и параметрами:

console
cat > /etc/dhcp/dhcpd.conf << EOF
option space altlinux;
option altlinux.keydata code 2 = string;
vendor-option-space altlinux;

subnet 192.168.1.0 netmask 255.255.255.0 {
    next-server 192.168.1.1;
    option routers 192.168.1.1;
    option domain-name-servers 192.168.1.1;
    option ntp-servers 192.168.1.1;
    default-lease-time 3600;
    max-lease-time 3600;
    range 192.168.1.2 192.168.1.100;
}
EOF

Включить автозапуск DHCP-сервера, запустить его и проверить статус:

console
systemctl enable --now dhcpd && sleep 5; systemctl status dhcpd --no-pager -l

Примечание: если на сервере есть интерфейсы с адресами вне подсети 192.168.1.0/24 (например, интернет-интерфейс), dhcpd выведет предупреждение No subnet declaration for eth0 и будет игнорировать запросы на них — это нормально, если сервер должен обслуживать только контур 192.168.1.0/24.

Настройка DNS

Указать адреса, на которых BIND будет принимать DNS-запросы:

console
sed -i 's|listen-on {.*|listen-on { 127.0.0.1; 192.168.1.0/24; };|g' \
    /etc/bind/options.conf

Добавить зоны прямого и обратного просмотра в конфигурацию BIND:

console
cat >> /etc/bind/local.conf <<'EOF'
zone "internal.local" {
    type master;
    file "/etc/bind/zone/db.internal.local";
    allow-update { 192.168.1.0/24; };
};

zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zone/db.192.168.1";
    allow-update { 192.168.1.0/24; };
};
EOF

Создать файл зоны прямого просмотра (A-записи):

console
cat > /etc/bind/zone/db.internal.local <<'EOF'
$TTL 604800
@       IN      SOA     ns1.internal.local. admin.internal.local. (
                                2025010101 ; Serial
                                604800     ; Refresh
                                86400      ; Retry
                                2419200    ; Expire
                                604800     ; Negative Cache TTL
                                )
        IN      NS      ns1.internal.local.
ns1     IN      A       192.168.1.1
EOF

Создать файл зоны обратного просмотра (PTR-записи):

console
cat > /etc/bind/zone/db.192.168.1 <<'EOF'
$TTL 604800
@       IN      SOA     ns1.internal.local. admin.internal.local. (
                                2025010101 ; Serial
                                604800     ; Refresh
                                86400      ; Retry
                                2419200    ; Expire
                                604800     ; Negative Cache TTL
                                )
        IN      NS      ns1.internal.local.
1       IN      PTR     ns1.internal.local.
EOF

Включить автозапуск BIND, запустить службу и проверить статус:

console
systemctl enable --now bind && sleep 5; systemctl status bind --no-pager -l

Настройка NTP

Настроить разрешение доступа для всех клиентов и указать NTP-пулы:

console
cat >> /etc/chrony.conf <<'EOF'
allow all
pool pool.ntp.org iburst
EOF

Включить автозапуск службы Chrony:

console
systemctl enable chronyd

Перезапустить службу Chrony и проверить её статус:

console
systemctl restart chronyd && sleep 5; systemctl status chronyd --no-pager -l

Настройка прокси и кэша для необходимых образов

Для каждого внешнего реестра запускается отдельный экземпляр Docker Registry:

РеестрУдалённый адресПорт
registry.altlinux.orghttps://registry.altlinux.org5000
altlinux.spacehttps://altlinux.space5001

Если потребуется зеркалировать другие реестры (например, для образов пользовательских нагрузок), добавьте их аналогично. Значения для распространённых реестров:

РеестрУдалённый адресПорт
factory.altlinux.spacehttps://factory.altlinux.space5002
ghcr.iohttps://ghcr.io5003
registry.k8s.iohttps://registry.k8s.io5004
docker.iohttps://registry-1.docker.io5005

Определить функцию, которая настраивает клиент Podman, сервер Docker Registry и systemd-службу для одного реестра:

console
setup_registry() {
    local registry_name="$1"
    local remote_url="$2"
    local registry_port="$3"

    # Настроить клиент Podman на использование прокси-кэша
    cat >> /etc/containers/registries.conf <<EOF
[[registry]]
location = "${registry_name}"

[[registry.mirror]]
location = "localhost:${registry_port}"
insecure = true
EOF

    # Создать конфигурацию сервера Docker Registry
    cat > /etc/docker-registry/config-${registry_name}.yml <<EOF
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/docker-registry/${registry_name}
http:
  addr: ":${registry_port}"
  headers:
    X-Content-Type-Options: [nosniff]
proxy:
  remoteurl: ${remote_url}
EOF

    # Создать и включить systemd-службу
    cp /lib/systemd/system/docker-registry.service \
        /etc/systemd/system/docker-registry-${registry_name}.service
    sed -i "s|config.yml|config-${registry_name}.yml|g" \
        /etc/systemd/system/docker-registry-${registry_name}.service
    systemctl daemon-reload
    systemctl enable --now docker-registry-${registry_name}.service && \
        sleep 5; systemctl status docker-registry-${registry_name}.service \
        --no-pager -l
}

Настроить прокси-кэши для всех реестров из таблицы:

console
setup_registry registry.altlinux.org https://registry.altlinux.org 5000
setup_registry altlinux.space https://altlinux.space 5001

Благодаря [[registry.mirror]] образы можно тянуть по исходному имени реестра (registry.altlinux.org/...) — клиент сначала обращается к локальному прокси-кэшу localhost:<порт>, который при необходимости скачивает образ из внешнего реестра.

Эта конфигурация читается только утилитами на базе библиотеки containers/image (podman, skopeo, buildah, cri-o); containerd и docker её не учитывают — для них зеркала настраиваются отдельно (hosts.toml и daemon.json соответственно).

Проверить, что все экземпляры слушают свои порты:

console
netstat -nlpt | grep -E ':(500[0-5])'

Проверить каталог образов на каждом порту:

console
for port in 5000 5001; do
    curl -s http://localhost:${port}/v2/_catalog | jq
done

Протестировать прокси-кэш (дополнительные проверки):

console
podman pull registry.altlinux.org/p11/kube-apiserver && \
    curl http://localhost:5000/v2/_catalog | jq && \
    curl http://localhost:5000/v2/p11/kube-apiserver/tags/list | jq && \
    podman pull localhost:5000/p11/kube-apiserver

Настройка Discovery Service RS

Запустить службу:

console
systemctl enable --now discovery-service-rs.service && \
    sleep 5; systemctl status discovery-service-rs.service --no-pager -l

Проверить, что порты прослушиваются:

console
netstat -tulnp | grep -E '2000|3000'

Служба запущена на портах 3000 и 2000:

text
tcp        0      0 0.0.0.0:2000                0.0.0.0:*                   LISTEN      1790/discovery-serv
tcp        0      0 0.0.0.0:3000                0.0.0.0:*                   LISTEN      1790/discovery-serv

Проверить работу службы тестовым запросом Hello:

Чтобы clientIp в ответе соответствовал переданному заголовку X-Real-IP (а не адресу клиента, подключившегося напрямую), включить чтение этого заголовка:

console
sed -i 's|# read_real_ip = false|read_real_ip = true|' \
    /etc/discovery-service-rs/discovery-service-rs.ini
systemctl restart discovery-service-rs

Создать proto-файл и выполнить запрос:

console
mkdir -p proto
cat > proto/cluster_grpc.proto << 'EOF'
syntax = "proto3";
package sidero.discovery.server;
import "google/protobuf/duration.proto";

service Cluster {
    rpc Hello(HelloRequest) returns (HelloResponse);
    rpc AffiliateUpdate(AffiliateUpdateRequest) returns (AffiliateUpdateResponse);
    rpc AffiliateDelete(AffiliateDeleteRequest) returns (AffiliateDeleteResponse);
    rpc List(ListRequest) returns (ListResponse);
    rpc Watch(WatchRequest) returns (stream WatchResponse);
}

message Affiliate {
    string id = 1;
    bytes data = 2;
    repeated bytes endpoints = 3;
}

message HelloRequest {
    string cluster_id = 1;
    string client_version = 2;
}

message RedirectMessage {
    string endpoint = 1;
}

message HelloResponse {
    optional RedirectMessage redirect = 1;
    bytes client_ip = 2;
}

message AffiliateUpdateRequest {
    string cluster_id = 1;
    string affiliate_id = 2;
    optional bytes affiliate_data = 3;
    repeated bytes affiliate_endpoints = 4;
    google.protobuf.Duration ttl = 5;
}

message AffiliateUpdateResponse {
}

message AffiliateDeleteRequest {
    string cluster_id = 1;
    string affiliate_id = 2;
}

message AffiliateDeleteResponse {
}

message ListRequest {
    string cluster_id = 1;
}

message ListResponse {
    repeated Affiliate affiliates = 1;
}

message WatchRequest {
    string cluster_id = 1;
}

message WatchResponse {
    repeated Affiliate affiliates = 1;
    bool deleted = 2;
}
EOF
grpcurl -proto cluster_grpc.proto -import-path ./proto -plaintext \
    -d '{"clusterId": "abc", "clientVersion": "11.0"}' \
    -H 'X-Real-IP: 1.2.3.4' 192.168.1.1:3000 \
    sidero.discovery.server.Cluster/Hello

Примерный вывод:

text
{
  "redirect": {},
  "clientIp": "AQIDBA=="
}

Установка кластера

Загрузочный ISO для узлов можно получить в Генераторе образов.

Получение дисков и подготовка образов

Для каждого узла ALT Orchestra получить название свободного диска, куда будет установлен дистрибутив:

console
for node in 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5 192.168.1.6; do
    talosctl --endpoints $node --nodes $node get disks --insecure
done

Примерный вывод:

text
NODE   NAMESPACE   TYPE   ID      VERSION   SIZE     READ ONLY   TRANSPORT   ROTATIONAL   WWID   MODEL           SERIAL
       runtime     Disk   loop0   2         4.1 kB   true
       runtime     Disk   loop1   2         98 MB    true
       runtime     Disk   sda     2         16 GB    false       virtio      true                QEMU HARDDISK
       runtime     Disk   sr0     2         377 MB   false       sata                            QEMU DVD-ROM

Получить версии образов:

console
REPO=p11 && \
KUBELET_VERSION="v1.34.8" && \
COREDNS_VERSION="$(curl -ks "https://registry.altlinux.org/v2/${REPO}/coredns/tags/list" | jq -r  '.tags | sort | .[]' | tail -1)" && \
ETCD_VERSION="$(curl -ks "https://registry.altlinux.org/v2/${REPO}/etcd/tags/list" | jq -r  '.tags | sort | .[]' | tail -1)" && \
PAUSE_VERSION="$(curl -ks "https://registry.altlinux.org/v2/${REPO}/pause/tags/list" | jq -r  '.tags | sort | .[]' | tail -1)"

Задать основные переменные:

console
DEVICE="/dev/sda" && \
INSTALLERIMAGE="altlinux.space/alt-orchestra/installer:v11.0-rc.1"

Значение /dev/sda заменить на имя диска из вывода get disks (например, /dev/vda для virtio-дисков).

Образ установщика также можно получить в Генераторе образов, а для особых случаев — собрать вручную.

Если нужно установить системные расширения, используйте образ установщика со встроенными расширениями — например, собранный в Генераторе образов.

Получить названия образов для основных контейнеров:

console
KUBELETIMAGE="registry.altlinux.org/${REPO}/kubelet:${KUBELET_VERSION}" && \
APISERVERIMAGE="registry.altlinux.org/${REPO}/kube-apiserver:${KUBELET_VERSION}" && \
CONTROLMANAGERIMAGE="registry.altlinux.org/${REPO}/kube-controller-manager:${KUBELET_VERSION}" && \
SHEDULERIMAGE="registry.altlinux.org/${REPO}/kube-scheduler:${KUBELET_VERSION}" && \
COREDNSIMAGE="registry.altlinux.org/${REPO}/coredns:${COREDNS_VERSION}" && \
ETCDIMAGE="registry.altlinux.org/${REPO}/etcd:${ETCD_VERSION}" && \
PAUSEIMAGE="registry.altlinux.org/${REPO}/pause:${PAUSE_VERSION}"

Скачать образы (pull):

console
for image in \
    ${KUBELETIMAGE} \
    ${APISERVERIMAGE} \
    ${CONTROLMANAGERIMAGE} \
    ${SHEDULERIMAGE} \
    ${COREDNSIMAGE} \
    ${ETCDIMAGE} \
    ${PAUSEIMAGE} \
    ${INSTALLERIMAGE}
do
    podman pull $image
done

Примечание: Предварительное скачивание образов через podman pull не обязательно, прокси-кэш скачает образ при первом обращении к нему.

Проверить их наличие в кэше:

console
curl http://localhost:5000/v2/_catalog | jq
curl http://localhost:5001/v2/_catalog | jq

Подготовка конфигурации кластера

Создать общий патч конфигурации:

console
cat > patch_common.yaml << PATCH
cluster:
  network:
    cni:
      name: none
  proxy:
    disabled: true
  discovery:
    enabled: true
    registries:
      kubernetes:
        disabled: true
      service:
        endpoint: http://192.168.1.1:3000
machine:
  time:
    servers:
      - 192.168.1.1
  network:
    nameservers:
      - 192.168.1.1
  install:
    disk: ${DEVICE}
    image: ${INSTALLERIMAGE}
  kubelet:
    image: ${KUBELETIMAGE}
  registries:
    mirrors:
      registry.altlinux.org:
        endpoints:
          - http://192.168.1.1:5000
      altlinux.space:
        endpoints:
          - http://192.168.1.1:5001
PATCH

Создать патч конфигурации controlplane:

console
cat > patch_controlplane.yaml << PATCH
machine:
  network:
    interfaces:
      - deviceSelector:
          physical: true
        dhcp: true
        vip:
          ip: 192.168.1.200
cluster:
  apiServer:
    image: ${APISERVERIMAGE}
  controllerManager:
    image: ${CONTROLMANAGERIMAGE}
  scheduler:
    image: ${SHEDULERIMAGE}
  etcd:
    image: ${ETCDIMAGE}
  coreDNS:
    image: ${COREDNSIMAGE}
PATCH

Сгенерировать конфигурацию ALT Orchestra с отключённым kube-proxy (патчи применяются при генерации):

console
talosctl gen config talos https://192.168.1.200:6443 \
    --config-patch @patch_common.yaml \
    --config-patch-control-plane @patch_controlplane.yaml

Endpoint кластера Kubernetes — виртуальный IP 192.168.1.200; подробнее см. Работа с Virtual (Shared) IP. Для доступа к API Talos (talosctl) виртуальный IP не используется — см. предостережения на этой странице.

Объединить talosconfig с конфигурацией по умолчанию:

console
talosctl config merge talosconfig

Установить текущий контекст talos и проверить конфигурацию:

console
talosctl config context talos
talosctl config info

Применение конфигурации и инициализация кластера

Применить конфигурацию на каждом узле controlplane:

console
talosctl apply-config --insecure --nodes 192.168.1.2 --file controlplane.yaml
talosctl apply-config --insecure --nodes 192.168.1.3 --file controlplane.yaml
talosctl apply-config --insecure --nodes 192.168.1.4 --file controlplane.yaml

Применить конфигурацию на каждом узле worker:

console
talosctl apply-config --insecure --nodes 192.168.1.5 --file worker.yaml
talosctl apply-config --insecure --nodes 192.168.1.6 --file worker.yaml

Инициализировать кластер (bootstrap, создание кластера etcd). Этот запрос отправляется только на один из controlplane узлов:

console
talosctl --endpoints 192.168.1.2 --nodes 192.168.1.2 bootstrap

Получить kubeconfig для кластера:

console
talosctl --endpoints 192.168.1.2 --nodes 192.168.1.2 kubeconfig

Установка Cilium

Установить Cilium через Helm:

console
curl https://altlinux.space/cloud/charts/raw/branch/master/cilium/sisyphus/1.18.2/values.yaml -o cilium-values.yaml
helm repo add cilium https://helm.cilium.io
helm repo update
helm install \
    cilium \
    cilium/cilium \
    --version 1.18.2 \
    --namespace kube-system \
    --set ipam.mode=kubernetes \
    --set kubeProxyReplacement=true \
    --set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \
    --set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \
    --set cgroup.autoMount.enabled=false \
    --set cgroup.hostRoot=/sys/fs/cgroup \
    --set k8sServiceHost=localhost \
    --set k8sServicePort=7445 \
    -f cilium-values.yaml

Проверка кластера

Убедиться, что узлы готовы:

console
kubectl get nodes

Примерный вывод:

text
NAME                    STATUS   ROLES           AGE   VERSION
alt-orchestra-2n9-fm5   Ready    <none>          69s   v1.34.8
alt-orchestra-4ty-xyj   Ready    control-plane   70s   v1.34.8
alt-orchestra-861-o83   Ready    <none>          61s   v1.34.8
alt-orchestra-9v7-0p2   Ready    control-plane   63s   v1.34.8
alt-orchestra-kus-sds   Ready    control-plane   67s   v1.34.8

Получить список всех подов в кластере:

console
kubectl get pods -A

Примерный вывод:

text
NAMESPACE     NAME                                            READY   STATUS    RESTARTS       AGE
kube-system   cilium-2jvb4                                    1/1     Running   0              112s
kube-system   cilium-4xrlg                                    1/1     Running   1 (52s ago)    112s
kube-system   cilium-9nspx                                    1/1     Running   0              112s
kube-system   cilium-9zb6v                                    1/1     Running   0              113s
kube-system   cilium-cp96k                                    1/1     Running   0              113s
kube-system   cilium-envoy-2m8wp                              1/1     Running   0              112s
kube-system   cilium-envoy-4mx5h                              1/1     Running   0              113s
kube-system   cilium-envoy-g8qh5                              1/1     Running   0              112s
kube-system   cilium-envoy-xffdn                              1/1     Running   0              113s
kube-system   cilium-envoy-z8xw6                              1/1     Running   0              113s
kube-system   cilium-operator-67f4b4f5fd-9djtg                1/1     Running   1 (82s ago)    112s
kube-system   cilium-operator-67f4b4f5fd-wkjdq                1/1     Running   1 (69s ago)    113s
kube-system   coredns-5966c6bdcd-2gxvq                        1/1     Running   0              3m43s
kube-system   coredns-5966c6bdcd-qfmn2                        1/1     Running   0              3m43s
kube-system   kube-apiserver-alt-orchestra-27m-03d            1/1     Running   0              3m30s
kube-system   kube-apiserver-alt-orchestra-gpg-qkl            1/1     Running   0              3m36s
kube-system   kube-apiserver-alt-orchestra-urk-gud            1/1     Running   0              2m59s
kube-system   kube-controller-manager-alt-orchestra-27m-03d   1/1     Running   0              3m30s
kube-system   kube-controller-manager-alt-orchestra-gpg-qkl   1/1     Running   1 (96s ago)    3m36s
kube-system   kube-controller-manager-alt-orchestra-urk-gud   1/1     Running   2 (4m3s ago)   2m59s
kube-system   kube-scheduler-alt-orchestra-27m-03d            1/1     Running   0              3m30s
kube-system   kube-scheduler-alt-orchestra-gpg-qkl            1/1     Running   0              3m36s
kube-system   kube-scheduler-alt-orchestra-urk-gud            1/1     Running   4 (58s ago)    2m58s

Вывести список всех ресурсов во всех пространствах имён кластера Kubernetes:

console
kubectl get all -A

Примерный вывод:

text
NAMESPACE     NAME                                                READY   STATUS    RESTARTS        AGE
kube-system   pod/cilium-2jvb4                                    1/1     Running   0               2m11s
kube-system   pod/cilium-4xrlg                                    1/1     Running   1 (71s ago)     2m11s
kube-system   pod/cilium-9nspx                                    1/1     Running   0               2m11s
kube-system   pod/cilium-9zb6v                                    1/1     Running   0               2m12s
kube-system   pod/cilium-cp96k                                    1/1     Running   0               2m12s
kube-system   pod/cilium-envoy-2m8wp                              1/1     Running   0               2m11s
kube-system   pod/cilium-envoy-4mx5h                              1/1     Running   0               2m12s
kube-system   pod/cilium-envoy-g8qh5                              1/1     Running   0               2m11s
kube-system   pod/cilium-envoy-xffdn                              1/1     Running   0               2m12s
kube-system   pod/cilium-envoy-z8xw6                              1/1     Running   0               2m12s
kube-system   pod/cilium-operator-67f4b4f5fd-9djtg                1/1     Running   1 (101s ago)    2m11s
kube-system   pod/cilium-operator-67f4b4f5fd-wkjdq                1/1     Running   1 (88s ago)     2m12s
kube-system   pod/coredns-5966c6bdcd-2gxvq                        1/1     Running   0               4m2s
kube-system   pod/coredns-5966c6bdcd-qfmn2                        1/1     Running   0               4m2s
kube-system   pod/kube-apiserver-alt-orchestra-27m-03d            1/1     Running   0               3m49s
kube-system   pod/kube-apiserver-alt-orchestra-gpg-qkl            1/1     Running   0               3m55s
kube-system   pod/kube-apiserver-alt-orchestra-urk-gud            1/1     Running   0               3m18s
kube-system   pod/kube-controller-manager-alt-orchestra-27m-03d   1/1     Running   0               3m49s
kube-system   pod/kube-controller-manager-alt-orchestra-gpg-qkl   1/1     Running   1 (115s ago)    3m55s
kube-system   pod/kube-controller-manager-alt-orchestra-urk-gud   1/1     Running   2 (4m22s ago)   3m18s
kube-system   pod/kube-scheduler-alt-orchestra-27m-03d            1/1     Running   0               3m49s
kube-system   pod/kube-scheduler-alt-orchestra-gpg-qkl            1/1     Running   0               3m55s
kube-system   pod/kube-scheduler-alt-orchestra-urk-gud            1/1     Running   4 (77s ago)     3m17s

NAMESPACE     NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes     ClusterIP   10.96.0.1      <none>        443/TCP                  5m32s
kube-system   service/cilium-envoy   ClusterIP   None           <none>        9964/TCP                 2m12s
kube-system   service/hubble-peer    ClusterIP   10.110.143.8   <none>        443/TCP                  2m12s
kube-system   service/kube-dns       ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP,9153/TCP   4m16s

NAMESPACE     NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/cilium         5         5         5       5            5           kubernetes.io/os=linux   2m12s
kube-system   daemonset.apps/cilium-envoy   5         5         5       5            5           kubernetes.io/os=linux   2m12s

NAMESPACE     NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/cilium-operator   2/2     2            2           2m12s
kube-system   deployment.apps/coredns           2/2     2            2           4m16s

NAMESPACE     NAME                                         DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/cilium-operator-67f4b4f5fd   2         2         2       2m12s
kube-system   replicaset.apps/coredns-5966c6bdcd           2         2         2       4m2s

Получить список сервисов во всех пространствах имён кластера Kubernetes:

console
kubectl get svc -A

Примерный вывод:

text
NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes     ClusterIP   10.96.0.1      <none>        443/TCP                  6m2s
kube-system   cilium-envoy   ClusterIP   None           <none>        9964/TCP                 2m42s
kube-system   hubble-peer    ClusterIP   10.110.143.8   <none>        443/TCP                  2m42s
kube-system   kube-dns       ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP,9153/TCP   4m46s
kube-system   hubble-relay   ClusterIP   10.109.3.163    <none>        80/TCP                   2m42s
kube-system   hubble-ui      ClusterIP   10.97.174.183   <none>        80/TCP                   2m42s

Изменить конфигурацию endpoint:

console
talosctl config endpoint 192.168.1.2 192.168.1.3 192.168.1.4

Вывести информацию о сервисах, работающих на узлах ALT Orchestra, включая их имена, состояние и конфигурацию:

console
talosctl --nodes 192.168.1.2 service
talosctl --nodes 192.168.1.3 service
talosctl --nodes 192.168.1.4 service
talosctl --nodes 192.168.1.5 service
talosctl --nodes 192.168.1.6 service

Примерный вывод для control-plane:

text
NODE          SERVICE      STATE     HEALTH   LAST CHANGE   LAST EVENT
192.168.1.4   apid         Running   OK       5m41s ago     Health check successful
192.168.1.4   auditd       Running   OK       5m52s ago     Health check successful
192.168.1.4   containerd   Running   OK       5m52s ago     Health check successful
192.168.1.4   cri          Running   OK       5m41s ago     Health check successful
192.168.1.4   dashboard    Running   ?        5m42s ago     Process Process(["/sbin/dashboard"]) started with PID 2204
192.168.1.4   etcd         Running   OK       3m37s ago     Health check successful
192.168.1.4   kubelet      Running   OK       5m35s ago     Health check successful
192.168.1.4   machined     Running   OK       5m52s ago     Health check successful
192.168.1.4   syslogd      Running   OK       5m51s ago     Health check successful
192.168.1.4   trustd       Running   OK       5m41s ago     Health check successful
192.168.1.4   udevd        Running   OK       5m43s ago     Health check successful

Примерный вывод для worker:

text
NODE          SERVICE      STATE     HEALTH   LAST CHANGE   LAST EVENT
192.168.1.5   apid         Running   OK       5m40s ago     Health check successful
192.168.1.5   auditd       Running   OK       5m48s ago     Health check successful
192.168.1.5   containerd   Running   OK       5m48s ago     Health check successful
192.168.1.5   cri          Running   OK       5m39s ago     Health check successful
192.168.1.5   dashboard    Running   ?        5m41s ago     Process Process(["/sbin/dashboard"]) started with PID 2094
192.168.1.5   kubelet      Running   OK       5m34s ago     Health check successful
192.168.1.5   machined     Running   OK       5m48s ago     Health check successful
192.168.1.5   syslogd      Running   OK       5m47s ago     Health check successful
192.168.1.5   udevd        Running   OK       5m42s ago     Health check successful

Получить информацию о членах кластера ALT Orchestra:

console
talosctl get members --nodes 192.168.1.2 --endpoints 192.168.1.2
talosctl get members --nodes 192.168.1.3 --endpoints 192.168.1.3
talosctl get members --nodes 192.168.1.4 --endpoints 192.168.1.4
talosctl get members --nodes 192.168.1.5 --endpoints 192.168.1.5
talosctl get members --nodes 192.168.1.6 --endpoints 192.168.1.6

Присутствуют все узлы кластера:

text
NODE          NAMESPACE   TYPE     ID                      VERSION   HOSTNAME                MACHINE TYPE   OS                        ADDRESSES
192.168.1.2   cluster     Member   alt-orchestra-4nl-pux   1         alt-orchestra-4nl-pux   controlplane   ALT Orchestra (v11.0)   ["192.168.1.2"]
192.168.1.2   cluster     Member   alt-orchestra-8vo-85l   1         alt-orchestra-8vo-85l   controlplane   ALT Orchestra (v11.0)   ["192.168.1.3"]
192.168.1.2   cluster     Member   alt-orchestra-hku-1uk   1         alt-orchestra-hku-1uk   worker         ALT Orchestra (v11.0)   ["192.168.1.5"]
192.168.1.2   cluster     Member   alt-orchestra-tab-x0d   1         alt-orchestra-tab-x0d   worker         ALT Orchestra (v11.0)   ["192.168.1.6"]
192.168.1.2   cluster     Member   alt-orchestra-y3q-ik2   1         alt-orchestra-y3q-ik2   controlplane   ALT Orchestra (v11.0)   ["192.168.1.4"]

Выполнить healthcheck для узлов control-plane:

console
talosctl health --nodes 192.168.1.2
talosctl health --nodes 192.168.1.3
talosctl health --nodes 192.168.1.4

Примерный вывод:

text
discovered nodes: ["192.168.1.2" "192.168.1.3" "192.168.1.4" "192.168.1.5" "192.168.1.6"]
waiting for etcd to be healthy: ...
waiting for etcd to be healthy: OK
waiting for etcd members to be consistent across nodes: ...
waiting for etcd members to be consistent across nodes: OK
waiting for etcd members to be control plane nodes: ...
waiting for etcd members to be control plane nodes: OK
waiting for apid to be ready: ...
waiting for apid to be ready: OK
waiting for all nodes memory sizes: ...
waiting for all nodes memory sizes: OK
waiting for all nodes disk sizes: ...
waiting for all nodes disk sizes: OK
waiting for no diagnostics: ...
waiting for no diagnostics: OK
waiting for kubelet to be healthy: ...
waiting for kubelet to be healthy: OK
waiting for all nodes to finish boot sequence: ...
waiting for all nodes to finish boot sequence: OK
waiting for all k8s nodes to report: ...
waiting for all k8s nodes to report: OK
waiting for all control plane static pods to be running: ...
waiting for all control plane static pods to be running: OK
waiting for all control plane components to be ready: ...
waiting for all control plane components to be ready: OK
waiting for all k8s nodes to report ready: ...
waiting for all k8s nodes to report ready: OK
waiting for coredns to report ready: ...
waiting for coredns to report ready: OK
waiting for all k8s nodes to report schedulable: ...
waiting for all k8s nodes to report schedulable: OK

Ручное обновление кластера

Получить текущую версию кластера:

console
kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.kubeletVersion}'

Вывод:

text
v1.34.8

Обновить кэш образами целевой версии Kubernetes (узлы в закрытом контуре скачивают образы только через прокси-кэш):

console
REPO=p11 && \
KUBELET_VERSION="v1.35.5" && \
KUBELETIMAGE="registry.altlinux.org/${REPO}/kubelet:${KUBELET_VERSION}" && \
APISERVERIMAGE="registry.altlinux.org/${REPO}/kube-apiserver:${KUBELET_VERSION}" && \
CONTROLMANAGERIMAGE="registry.altlinux.org/${REPO}/kube-controller-manager:${KUBELET_VERSION}" && \
SCHEDULERIMAGE="registry.altlinux.org/${REPO}/kube-scheduler:${KUBELET_VERSION}"

for image in ${KUBELETIMAGE} ${APISERVERIMAGE} ${CONTROLMANAGERIMAGE} ${SCHEDULERIMAGE}
do
    podman pull $image
done

Проверить их наличие в кэше:

console
podman images

Обновить кластер Kubernetes до версии 1.35.5 (upgrade-k8s выполняет переход на одну минорную версию за раз):

console
talosctl --nodes 192.168.1.2 upgrade-k8s --to 1.35.5

Поддерживаемые версии Kubernetes перечислены в матрице поддержки.

Примерный вывод во время обновления одной машины:

text
. . . . .
 > "192.168.1.4": starting update
 > update kube-scheduler: v1.34.8 -> 1.35.5
 > "192.168.1.4": machine configuration patched
 > "192.168.1.4": waiting for kube-scheduler pod update
 > "192.168.1.4": kube-scheduler: waiting, config version mismatch: got "1", expected "2"
 > "192.168.1.4": kube-scheduler: waiting, config version mismatch: got "1", expected "2"
 > "192.168.1.4": kube-scheduler: waiting, config version mismatch: got "1", expected "2"
 > "192.168.1.4": kube-scheduler: waiting, config version mismatch: got "1", expected "2"
 > "192.168.1.4": kube-scheduler: pod is not ready, waiting
 > "192.168.1.4": kube-scheduler: pod is not ready, waiting
 > "192.168.1.4": kube-scheduler: pod is not ready, waiting
 < "192.168.1.4": successfully updated
. . . . .

Кластер успешно обновился:

text
. . . . .
 > processing manifest v1.Secret/kube-system/bootstrap-token-u8gr7g
 < no changes
 > processing manifest rbac.authorization.k8s.io/v1.ClusterRoleBinding/system-bootstrap-approve-node-client-csr
 < no changes
 > processing manifest rbac.authorization.k8s.io/v1.ClusterRoleBinding/system-bootstrap-node-bootstrapper
 < no changes
 > processing manifest rbac.authorization.k8s.io/v1.ClusterRoleBinding/system-bootstrap-node-renewal
 < no changes
. . . . .
 < applied successfully
 > processing manifest v1.ServiceAccount/kube-system/coredns
 < no changes
 > processing manifest rbac.authorization.k8s.io/v1.ClusterRoleBinding/system:coredns
 < no changes
 > processing manifest rbac.authorization.k8s.io/v1.ClusterRole/system:coredns
 < no changes
 > processing manifest v1.ConfigMap/kube-system/coredns
 < no changes
 > processing manifest apps/v1.Deployment/kube-system/coredns
 < no changes
 > processing manifest v1.Service/kube-system/kube-dns
 < no changes
 > processing manifest v1.ConfigMap/kube-system/kubeconfig-in-cluster
 < no changes
waiting for all manifests to be applied

Получить текущую версию кластера:

console
kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.kubeletVersion}'

Вывод:

text
v1.35.5

Убедиться, что все узлы обновлены до версии v1.35.5:

text
# kubectl get nodes
NAME                    STATUS   ROLES           AGE    VERSION
alt-orchestra-4nl-pux   Ready    control-plane   139m   v1.35.5
alt-orchestra-8vo-85l   Ready    control-plane   139m   v1.35.5
alt-orchestra-hku-1uk   Ready    <none>          139m   v1.35.5
alt-orchestra-tab-x0d   Ready    <none>          139m   v1.35.5
alt-orchestra-y3q-ik2   Ready    control-plane   139m   v1.35.5

Вывести список всех ресурсов во всех пространствах имён кластера Kubernetes:

console
kubectl get all -A

Все поды в состоянии Running:

text
NAMESPACE     NAME                                                READY   STATUS    RESTARTS      AGE
kube-system   pod/cilium-2jvb4                                    1/1     Running   0             32m
kube-system   pod/cilium-4xrlg                                    1/1     Running   1 (31m ago)   32m
kube-system   pod/cilium-9nspx                                    1/1     Running   0             32m
kube-system   pod/cilium-9zb6v                                    1/1     Running   1 (24m ago)   32m
kube-system   pod/cilium-cp96k                                    1/1     Running   0             32m
kube-system   pod/cilium-envoy-2m8wp                              1/1     Running   0             32m
kube-system   pod/cilium-envoy-4mx5h                              1/1     Running   0             32m
kube-system   pod/cilium-envoy-g8qh5                              1/1     Running   0             32m
kube-system   pod/cilium-envoy-xffdn                              1/1     Running   0             32m
kube-system   pod/cilium-envoy-z8xw6                              1/1     Running   1 (24m ago)   32m
kube-system   pod/cilium-operator-67f4b4f5fd-9djtg                1/1     Running   3 (16m ago)   32m
kube-system   pod/cilium-operator-67f4b4f5fd-wkjdq                1/1     Running   2 (17m ago)   32m
kube-system   pod/coredns-5966c6bdcd-2gxvq                        1/1     Running   0             34m
kube-system   pod/coredns-5966c6bdcd-qfmn2                        1/1     Running   0             34m
kube-system   pod/kube-apiserver-alt-orchestra-27m-03d            1/1     Running   1 (17m ago)   17m
kube-system   pod/kube-apiserver-alt-orchestra-gpg-qkl            1/1     Running   0             16m
kube-system   pod/kube-apiserver-alt-orchestra-urk-gud            1/1     Running   1 (16m ago)   16m
kube-system   pod/kube-controller-manager-alt-orchestra-27m-03d   1/1     Running   2 (17m ago)   17m
kube-system   pod/kube-controller-manager-alt-orchestra-gpg-qkl   1/1     Running   0             16m
kube-system   pod/kube-controller-manager-alt-orchestra-urk-gud   1/1     Running   1 (16m ago)   16m
kube-system   pod/kube-scheduler-alt-orchestra-27m-03d            1/1     Running   2 (17m ago)   17m
kube-system   pod/kube-scheduler-alt-orchestra-gpg-qkl            1/1     Running   0             16m
kube-system   pod/kube-scheduler-alt-orchestra-urk-gud            1/1     Running   1 (16m ago)   16m

NAMESPACE     NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes     ClusterIP   10.96.0.1      <none>        443/TCP                  35m
kube-system   service/cilium-envoy   ClusterIP   None           <none>        9964/TCP                 32m
kube-system   service/hubble-peer    ClusterIP   10.110.143.8   <none>        443/TCP                  32m
kube-system   service/kube-dns       ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP,9153/TCP   34m

NAMESPACE     NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/cilium         5         5         5       5            5           kubernetes.io/os=linux   32m
kube-system   daemonset.apps/cilium-envoy   5         5         5       5            5           kubernetes.io/os=linux   32m

NAMESPACE     NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/cilium-operator   2/2     2            2           32m
kube-system   deployment.apps/coredns           2/2     2            2           34m

NAMESPACE     NAME                                         DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/cilium-operator-67f4b4f5fd   2         2         2       32m
kube-system   replicaset.apps/coredns-5966c6bdcd           2         2         2       34m

Выполнить healthcheck для узлов control-plane:

console
talosctl health --nodes 192.168.1.2
talosctl health --nodes 192.168.1.3
talosctl health --nodes 192.168.1.4

Healthcheck выполнен успешно:

text
discovered nodes: ["192.168.1.2" "192.168.1.3" "192.168.1.4" "192.168.1.5" "192.168.1.6"]
waiting for etcd to be healthy: ...
waiting for etcd to be healthy: OK
waiting for etcd members to be consistent across nodes: ...
waiting for etcd members to be consistent across nodes: OK
waiting for etcd members to be control plane nodes: ...
waiting for etcd members to be control plane nodes: OK
waiting for apid to be ready: ...
waiting for apid to be ready: OK
waiting for all nodes memory sizes: ...
waiting for all nodes memory sizes: OK
waiting for all nodes disk sizes: ...
waiting for all nodes disk sizes: OK
waiting for no diagnostics: ...
waiting for no diagnostics: OK
waiting for kubelet to be healthy: ...
waiting for kubelet to be healthy: OK
waiting for all nodes to finish boot sequence: ...
waiting for all nodes to finish boot sequence: OK
waiting for all k8s nodes to report: ...
waiting for all k8s nodes to report: OK
waiting for all control plane static pods to be running: ...
waiting for all control plane static pods to be running: OK
waiting for all control plane components to be ready: ...
waiting for all control plane components to be ready: OK
waiting for all k8s nodes to report ready: ...
waiting for all k8s nodes to report ready: OK
waiting for coredns to report ready: ...
waiting for coredns to report ready: OK
waiting for all k8s nodes to report schedulable: ...
waiting for all k8s nodes to report schedulable: OK

Опубликовано под лицензией GPL-3.0+. Содержание доступно по лицензии CC BY-SA 4.0, если не указано иное. Разработано участниками ALT Orchestra.