Собираю единомышленников в телеге
Присоединяйся

Если с оффлайн установкой всё очевидно и просто, то с оффлайн приходится разбираться кропотливо и детально. Спросишь: “Зачем устанавливать в оффлайне?”.
Отвечаю: Многие компании имеют закрытые контура, в которых размещаются сервера. По типу Air Gapped. Интернета у таких серверов нет и не будет никогда. Сделано это с целью безопасности серверов и данных.
Поэтому нужно выкачать пакеты и образы, упаковать, занести их в закрытый периметр и указать “программе”, что установка будет из локального репозитория.
Поехали.
Требования:
Online установка: HELM, Kubernetes cluster
Offline установка: Хост с инетом, HELM, Docker/Nerdctl, Harbor, Kubernetes cluster
Онлайн установка Longhorn
Создаём файл с переменными:
1
| nano longhorn-values.yaml
|
Здесь пишем количество количество воркер нод defaultReplicaCount у меня две:
1
2
3
4
5
6
7
| defaultSettings:
defaultReplicaCount: 2
replicaSoftAntiAffinity: true
storageOverProvisioningPercentage: 200
storageMinimalAvailablePercentage: 10
longhornUI:
replicas: 1
|
Устанавливаем:
1
2
3
| helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn -n longhorn-system --create-namespace -f longhorn-values.yaml
|
Если нет ingress в кластере, то прокинуть порт:
1
| kubectl port-forward service/longhorn-frontend 8080:80 -n longhorn-system
|
Если есть, то написать манифест:
1
| nano ingress-longhorn.yaml
|
Вставить:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: longhorn-ui
namespace: longhorn-system
spec:
ingressClassName: nginx
rules:
- host: longhorn.k8s.domain.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: longhorn-frontend
port:
number: 80
|
Применить
1
| kubectl apply -f ingress-longhorn.yaml
|
Входим по IPНоды:80 если port-forward или по имени, которое нужно добавить в DNS для резолва longhorn.k8s.domain.local

Установка завершена
Offline установка Longhorn
Шаг 1. Подготовка образов
На машине с инетом ставим HELM и docker.
1
2
| apt update -y
apt install helm docker.io -y
|
Забираем файлы, чтобы вытащить имена образов.
Вместо v1.11.0 укажите актуальную версию.
Взять здесь. URL https://github.com/longhorn/longhorn/releases
1
2
3
| helm repo add longhorn https://charts.longhorn.io
helm repo update
helm pull longhorn/longhorn --version v1.11.0 --untar
|
Переходим в директорию:
Получить список образов (из values.yaml)
Поскольку в чарте образы задаются как repository: + tag:, мы достаём их из ./longhorn/values.yaml:
1
2
3
4
| awk '
$1 ~ /repository:/ { repo=$2 }
$1 ~ /tag:/ { tag=$2; if (repo != "" && tag != "") { print repo ":" tag; repo=""; tag="" } }
' ./longhorn/values.yaml | sort -u > lh-images.txt
|
Спулить образы:
Если в lh-images.txt строки вида longhornio/xxx:vX.Y.Z, то:
1
2
3
| while read -r img; do
docker pull "${img}"
done < lh-images.txt
|
Сохранить для переноса:
1
2
3
4
5
| mkdir -p lh-tars
while read -r img; do
safe=$(echo "$img" | tr '/:' '_')
docker save -o "lh-tars/${safe}.tar" "${img}"
done < lh-images.txt
|
Упаковать HELM чарт:
1
| tar -cvf longhorn-helm.tar longhorn
|
Перенести lh-tars и longhorn-helm.tar в закрытый контур.
Шаг 2. Пуш образов в приватный репозиторий
В закрытом контуре кубера.
У меня создан публичный проект в Harbor с названием helm.
Логинимся в репозитории:
1
| helm login harbor.domain.local
|

Пушим HELM в репозиторий:
1
| helm push longhorn-helm.tgz oci://harbor.domain.local/helm
|
Загрузить образы из tar:
1
2
3
| for f in lh-tars/*.tar; do
docker load -i "$f"
done
|
Я создал project в harbor с именем platform.
Запушить в Harbor. Изменив переменные HARBOR и имя проекта PROJECT на свои:
1
2
3
4
5
6
7
8
9
| HARBOR="harbor.domain.local"
PROJECT="platform"
docker login "$HARBOR"
while read -r img; do
new="${HARBOR}/${PROJECT}/${img}"
docker tag "${img}" "$new"
docker push "$new"
done < lh-images.txt
|

Подготовить longhorn-values.yaml под Harbor + 2 ноды. Ключевые настройки:
1
2
3
| defaultReplicaCount: 2 (реплика на каждую из 2 нод)
anti-affinity
registry на Harbor
|
Создаём файл:
1
| nano longhorn-values.yaml
|
Вставляем. Здесь меняем только количество количество воркер нод defaultReplicaCount, imageRegistry и repository на свой:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| global:
imageRegistry: harbor.domain.local
defaultSettings:
defaultReplicaCount: 2
replicaSoftAntiAffinity: true
storageOverProvisioningPercentage: 200
storageMinimalAvailablePercentage: 10
longhornUI:
replicas: 1
image:
registry: harbor.domain.local
longhorn:
manager:
repository: platform/longhorn/longhorn-manager
engine:
repository: platform/longhorn/longhorn-engine
ui:
repository: platform/longhorn/longhorn-ui
instanceManager:
repository: platform/longhorn/longhorn-instance-manager
shareManager:
repository: platform/longhorn/longhorn-share-manager
backingImageManager:
repository: platform/longhorn/backing-image-manager
supportBundleKit:
repository: platform/longhorn/support-bundle-kit
csi:
attacher:
repository: platform/longhorn/csi-attacher
provisioner:
repository: platform/longhorn/csi-provisioner
nodeDriverRegistrar:
repository: platform/longhorn/csi-node-driver-registrar
resizer:
repository: platform/longhorn/csi-resizer
snapshotter:
repository: platform/longhorn/csi-snapshotter
livenessProbe:
repository: platform/longhorn/livenessprobe
|
Шаг 3. Установка Longhorn
Запускаем установку из Heml чарта в нашем репозитории, с объявленными нами переменными.
1
| helm install longhorn oci://harbor.domain.local/helm/longhorn --version v1.11.0 -n longhorn-system --create-namespace -f longhorn-values.yaml
|
Проверка:
1
2
| kubectl get pods -n longhorn-system
kubectl get storageclass
|
Поды должны успешно запуститься.
Далее настраиваем nginx.
1
| nano ingress-longhorn.yaml
|
Вставить:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: longhorn-ui
namespace: longhorn-system
spec:
ingressClassName: nginx
rules:
- host: longhorn.k8s.domain.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: longhorn-frontend
port:
number: 80
|
Применить:
1
| kubectl apply -f ingress-longhorn.yaml
|
Если Nginx нет, то port-forward:
1
| kubectl port-forward service/longhorn-frontend 8080:80 -n longhorn-system
|
Если есть, то создать DNS запись с именем longhorn.k8s.domain.local и адресом ingress ноды и войти в веб-интерфейс.

Установка завершена