Чтобы попробовать Kubernetes-платформу Deckhouse в деле, придется найти мощный сервер, пространство у облачного провайдера или несколько машин и прокси-сервер. Но что делать, если хочется просто потестировать Deckhouse, а технических возможностей для этого нет? Конечно же, установить Deckhouse в kind (kubernetes in docker) — инструмент для запуска локальных K8s-кластеров, который использует в качестве узлов Docker-контейнеры. Вообще, утилита создана для тестирования Kubernetes разработчиками, но ее можно задействовать и для локальной разработки или CI.

Почему kind? Потому что тогда для наших задач сгодится даже ноутбук, а на выходе мы получим работающую инсталляцию Deckhouse, правда, с некоторыми ограничениями. Например, в kind не получится включить модули управления control-plane и узлами (хотя сам kind и поддерживает конфигурацию с несколькими узлами). Кроме того, есть сложности и по подключению внешних CNI, например того же Cilium. Встроенный в kind CNI можно отключить и поставить что-то другое (а для Cilium есть даже официальная инструкция), однако работоспособность в этом случае не гарантируется.

Итак, в этой статье мы установим Open Source-версию Deckhouse с помощью kind и попробуем платформу в деле — задеплоим небольшое приложение. 

В прошлых статьях мы рассматривали, как развернуть Kubernetes-кластер под управлением Deckhouse в Yandex Cloud, на bare-metal-сервере с виртуализацией и в закрытом контуре с отключенным доступом наружу.

Разворачиваем Deckhouse на рабочем ноутбуке

Системные требования и общая информация

Требований к компьютеру не так много:

  • не менее 4 ГБ оперативной памяти;

  • macOS или Linux (Windows не поддерживается);

  • установленный container runtime (Docker или containerd);

  • доступ в интернет (к хранилищу образов registry.deckhouse.io).

Весь процесс установки займет около 15 минут. Напомним, что Deckhouse будет развернут в минимальной конфигурации с включенным мониторингом на базе Grafana. При этом управление узлами или control-plane работать не будут.

Установка kind и Deckhouse

Убедитесь, что на вашем компьютере установлен container runtime: Docker (инструкция по установке) или containerd, — а также Docker-клиент.

В GitHub платформы есть заранее подготовленный скрипт — он установит все зависимости, включая сам kind, а затем развернет в нем кластер под управлением Deckhouse.

Запустим скрипт, взяв его напрямую с GitHub:

bash -c "$(curl -Ls https://raw.githubusercontent.com/deckhouse/deckhouse/main/tools/kind-d8.sh)"

С помощью этой команды мы устанавливаем Community-версию Deckhouse (CE). Если у вас есть лицензионный ключ для Enterprise-версии, воспользуйтесь другой командой:

bash -c "$(curl -Ls https://raw.githubusercontent.com/deckhouse/deckhouse/main/tools/kind-d8.sh)" -- --key <LICENSE_KEY>

<LICENSE_KEY> — это как раз лицензионный ключ.

Сразу после запуска скрипт проверит, установлены ли нужные утилиты:

Detected operating system as mac (arm64).
Checking for docker...
Detected docker...
Checking for kubectl...
Detected kubectl...
Checking for kind...
kind is not installed.
Install kind? y/[n]:

Если в системе не установлены зависимости (Docker или kubectl), скрипт завершится ошибкой, а в сообщении об ошибке вам порекомендуют установить необходимые зависимости. Если в системе еще нет kind, скрипт предложит установить его в автоматическом режиме. Соглашаемся с ним, указав y:

Install kind? y/[n]: y
kind installation directory [/Users/zhbert/.kind-d8]:

Установка в домашний каталог пользователя — стандартный подход, поэтому ничего не меняем и просто нажимаем Enter.

Теперь необходимо указать имя будущего кластера. Оставим вариант по умолчанию (d8) и просто еще раз нажмем Enter.

Specify kind cluster name [d8]:
No kind clusters found.
Creating kind config file (/Users/zhbert/.kind-d8/kind.cfg)...
Creating Deckhouse installation config file (/Users/zhbert/.kind-d8/config.yml)...
Creating Deckhouse resource file (/Users/zhbert/.kind-d8/resources.yml)...
Creating cluster "d8" ...
 ✓ Ensuring node image (kindest/node:v1.25.9) ????
 ✓ Preparing nodes ????
 ✓ Writing configuration ????
 ✓ Starting control-plane ????️
 ✓ Installing CNI ????
 ✓ Installing StorageClass ????
Set kubectl context to "kind-d8"
You can now use your cluster with:


kubectl cluster-info --context kind-d8


Thanks for using kind! ????

Кластер развернулся, теперь начнется установка Deckhouse — пройдет она автоматически.

Вывод большой, поэтому мы спрятали его под спойлером.
Running Deckhouse installation (the Stable release channel)...
stable: Pulling from deckhouse/ce/install
ca7dd9ec2225: Pull complete
bf0b3016f7b5: Pull complete
5f8350f83071: Pull complete
4461e5a6042e: Pull complete
70983edf3a15: Pull complete
4629b04f0170: Pull complete
2ff0309005dc: Pull complete
Digest: sha256:a01de23af3111fbe037beee0e1b70558636767aff92d2560425f0c158512f1aa
Status: Downloaded newer image for registry.deckhouse.io/deckhouse/ce/install:stable
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
┌ ???? ~ Common: Connect to Kubernetes API
│ ┌ Get Kubernetes API client
│ │ ???? Succeeded!
│ └ Get Kubernetes API client (0.05 seconds)
│
│ ┌ Waiting for Kubernetes API to become Ready
│ │ ???? Succeeded!
│ └ Waiting for Kubernetes API to become Ready (0.08 seconds)
└ ???? ~ Common: Connect to Kubernetes API (0.18 seconds)


┌ ⛵ ~ Bootstrap: Install Deckhouse
│ ┌ Create Manifests
│ │ Manifest for Namespace "d8-system"
│ │ Manifest for Admin ClusterRole "cluster-admin"
│ │ Admin ClusterRole "cluster-admin" already exists. Trying to update ... OK!
│ │ Manifest for ClusterRoleBinding "deckhouse"
│ │ Manifest for ServiceAccount "deckhouse"
│ │ Manifest for ConfigMap "deckhouse"
│ │ Manifest for Secret "deckhouse-registry"
│ │ Manifest for Deployment "deckhouse"
│ └ Create Manifests (0.13 seconds)
│
│ ┌ Waiting for Deckhouse to become Ready
│ │ Deckhouse pod found: deckhouse-6c6d8599c6-vfxhw (Pending)
│ │ Deckhouse pod found: deckhouse-6c6d8599c6-vfxhw (Running)
│ │ Running pod found! Checking logs...
│ │ Request failed. Probably pod was restarted during installation.
│ │ Deckhouse pod found: deckhouse-578db84d58-9dpc9 (Pending)
│ │ Deckhouse pod found: deckhouse-578db84d58-9dpc9 (Running)
│ │ Running pod found! Checking logs...
│ │ Deckhouse pod is Ready!
│ └ Waiting for Deckhouse to become Ready (73.57 seconds)
└ ⛵ ~ Bootstrap: Install Deckhouse (73.71 seconds)
┌ ⛵ ~ Bootstrap: Create resources
│ ┌ ???? ~ Common: Connect to Kubernetes API
│ │ ┌ Get Kubernetes API client
│ │ │ ???? Succeeded!
│ │ └ Get Kubernetes API client (0.04 seconds)
│ │
│ │ ┌ Waiting for Kubernetes API to become Ready
│ │ │ ???? Succeeded!
│ │ └ Waiting for Kubernetes API to become Ready (0.07 seconds)
│ └ ???? ~ Common: Connect to Kubernetes API (0.16 seconds)
│
│ Resources to create:
│ 	deckhouse.io/v1, Kind=IngressNginxController
│
...
│
│ Resources to create:
│ 	deckhouse.io/v1, Kind=IngressNginxController
│
│ ┌ Create deckhouse.io/v1, Kind=IngressNginxController resources
│ │ Manifest for IngressNginxController nginx
│ │ ???? Succeeded!
│ └ Create deckhouse.io/v1, Kind=IngressNginxController resources (2.52 seconds)
└ ⛵ ~ Bootstrap: Create resources (152.69 seconds)
Waiting for the Ingress controller to be ready.................................
Ingress controller is running.


You have installed Deckhouse Platform in kind!


Don't forget that the default kubectl context has been changed to 'kind-d8'.


Run 'kubectl --context kind-d8 cluster-info' to see cluster info.
Run '/Users/zhbert/.kind-d8/kind delete cluster --name d8' to delete the cluster.


Provide following credentials to access Grafana at http://grafana.127.0.0.1.sslip.io/ :


    Username: admin
    Password: Ta3hLkN9zElep0Q9Kz10


The information above is saved to /Users/zhbert/.kind-d8/info.txt file.


Good luck!

Deckhouse установлен. Теперь разберем, что у нас выводится в нижней части лога:

  • адрес кластера на базе сервиса sslip.io;

  • имя пользователя и пароль, с помощью которых можно зайти в Grafana.

Проверяем работоспособность Deckhouse

Откроем адрес из нижней части лога в браузере. Обратите внимание, что этот адрес локальный и работать будет только на вашем компьютере.

Вход в Grafana
Вход в Grafana

Теперь введем имя пользователя и пароль от Grafana и попадем на главную страницу с дашбордами:

Главная страница Grafana
Главная страница Grafana

Здесь отображается состояние кластера и включенных модулей, а также указаны версии компонентов. Например, сейчас мы установили актуальную на момент создания статьи Stable-версию Deckhouse 1.50.6 CE.

Кластер полностью рабочий, убедиться в этом можно с помощью kubectl, контекст для которой также был автоматически настроен на работу с kind:

$ kubectl get no
NAME               STATUS   ROLES                  AGE    VERSION
d8-control-plane   Ready    control-plane,master   138m   v1.25.9

Команда показала нам набор узлов в кластере — правда, сейчас у нас только один узел с установленным Deckhouse. Ура! Мы можем управлять модулями и пользоваться всеми возможностями платформы, чтобы ознакомиться с ней, — начать можно с официальной документации.

Кроме того, можно задеплоить в кластер простое приложение из нашего самоучителя по Kubernetes — так мы убедимся, что кластер способен выполнять базовые функции, и посмотрим на Deckhouse в деле. Итак, приступим. 

Развертываем приложение

Подготовка приложения

Для начала склонируем репозиторий с приложением, скопируем его в отдельный каталог и подготовим к развертыванию. Напомним, что мы будем брать уже готовое приложение из нашего самоучителя.

# Клонируем репозиторий с примерами в ~/werf-guide/guides.
test -e ~/werf-guide/guides || git clone https://github.com/werf/website ~/werf-guide/guides


# Скопируем файлы приложения (пока без изменений) в ~/werf-guide/app.
rm -rf ~/werf-guide/app
cp -rf ~/werf-guide/guides/examples/basic/001_build ~/werf-guide/app


# Сделаем из директории ~/werf-guide/app git-репозиторий.
cd ~/werf-guide/app
git init
git add .
git commit -m initial


# Чтобы увидеть, какие изменения мы собрались вносить далее в этой статье, заменим все файлы приложения в репозитории новыми, уже измененными файлами приложения, которые содержат описанные далее изменения.
git rm -r .
cp -rf ~/werf-guide/guides/examples/basic/002_deploy/. .
git add .
git commit -m WIP

Мы создали каталог ~/werf-guide/app, инициировали в нем Git-репозиторий и скопировали туда исходные файлы приложения. Это простое приложение на базе эхо-сервера, реализованного в виде bash-скрипта (start.sh):

#!/bin/sh


RESPONSE="pong"


while true; do
  printf "HTTP/1.1 200 OK\n\n$RESPONSE\n" | ncat -lp 8000
done

Собирать и развертывать приложение мы будем с помощью Open Source-утилиты werf, поэтому в корне проекта находится конфигурационный файл werf.yaml, в котором описано, как собирать образ будущего контейнера (там сразу указан нужный Dockerfile):

project: werf-guide-app
configVersion: 1


---
image: app
dockerfile: Dockerfile

Dockerfile, в котором описаны инструкции для сборки Docker-контейнера, также расположен в корне проекта и выглядит вот так:

FROM alpine:3.14
WORKDIR /app


# Устанавливаем зависимости приложения
RUN apk add --no-cache --update nmap-ncat


# Добавляем в образ скрипт для запуска эхо-сервера и устанавливаем разрешение на выполнение
COPY start.sh .
RUN chmod +x start.sh

Осталось подготовить Helm-чарты, описывающие ресурсы в кластере. Их будет три, и расположены они будут в каталоге ./helm/templates. Первый — Deployment, в котором описано само приложение (deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: werf-guide-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: werf-guide-app
  template:
    metadata:
      labels:
        app: werf-guide-app
    spec:
      imagePullSecrets:
      - name: registrysecret
      containers:
      - name: app
        image: {{ .Values.werf.image.app }}
        command: ["/app/start.sh"]
        ports:
        - containerPort: 8000

В разделе image указан образ, собираемый werf.

Чтобы контейнер был доступен внутри кластера, используется ресурс Service, описанный в service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: werf-guide-app
spec:
  selector:
    app: werf-guide-app
  ports:
  - name: http
    port: 8000

А для внешнего доступа (снаружи кластера) настроен Ingress (ingress.yaml):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: werf-guide-app
spec:
  rules:
  - host: werf-guide-app.127.0.0.1.sslip.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: werf-guide-app
            port:
              number: 8000

Здесь указано, что наше приложение доступно по адресу http://werf-guide-app.127.0.0.1.sslip.io/.

Не забудьте поменять адрес в исходном файле Ingress, загруженном из репозитория, и закоммитить изменения в локальный Git-репозиторий, созданный в ~/werf-guide/app.

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

Для хранения собранных образов воспользуемся Dockеr Hub. В нем необходимо создать приватный репозиторий с именем werf-guide-app.

Войдем в Docker Hub на компьютере:

$ docker login
# Введем ИМЯ ПОЛЬЗОВАТЕЛЯ DOCKER HUB.
Username: <ИМЯ ПОЛЬЗОВАТЕЛЯ DOCKER HUB>
# Введем ПАРОЛЬ ПОЛЬЗОВАТЕЛЯ DOCKER HUB.
Password: <ПАРОЛЬ ПОЛЬЗОВАТЕЛЯ DOCKER HUB>

Теперь создадим новое пространство имен в кластере, в котором будет разворачиваться приложение:

$ kubectl create namespace werf-guide-app
namespace/werf-guide-app created

Переключим контекст kubectl на кластер kind с использованием созданного пространства имен по умолчанию:

$ kubectl config set-context kind-d8 --namespace=werf-guide-app
Context "kind-d8" modified.

Создадим Secret с параметрами доступа в container registry:

$ kubectl create secret docker-registry registrysecret \
  --docker-server='https://index.docker.io/v1/' \
  --docker-username='<ИМЯ ПОЛЬЗОВАТЕЛЯ DOCKER HUB>' \
  --docker-password='<ПАРОЛЬ ПОЛЬЗОВАТЕЛЯ DOCKER HUB>'
secret/registrysecret created

Все готово для развертывания!

Процесс развертывания приложения

Как всегда при работе с werf, развертывание приложения производится одной командой:

werf converge --repo <ИМЯ ПОЛЬЗОВАТЕЛЯ DOCKER HUB>/werf-guide-app

Спустя пару минут увидим следующее сообщение:

Release "werf-guide-app" has been upgraded. Happy Helming!
NAME: werf-guide-app
LAST DEPLOYED: Wed Sep 20 15:58:26 2023
LAST PHASE: rollout
LAST STAGE: 0
NAMESPACE: werf-guide-app
STATUS: deployed
REVISION: 2
TEST SUITE: None
Running time 11.09 seconds

Ура! Приложение развернуто в кластере!

Проверим, что оно работает:

$ curl werf-guide-app.127.0.0.1.sslip.io
pong

Убираем за собой

Висящий в фоне кластер kind постоянно потребляет ресурсы компьютера, пусть и небольшие. Также он занимает 80-й порт, что может помешать работе с другими сервисами. Так что после тестирования Deckhouse необходимо будет удалить наш кластер. Делается это просто:

$ kind delete cluster --name d8
Deleting cluster "d8" ...
Deleted nodes: ["d8-control-plane"]

Теперь на компьютере не осталось ничего лишнего.

Заключение

В статье мы рассмотрели, как познакомиться с Deckhouse, установив его на рабочий компьютер в среде kind. После всех действий мы получили работоспособный кластер под управлением Deckhouse, в который можно деплоить свои приложения и выполнять различные действия с модулями кластера в соответствии с официальной документацией.

С любыми вопросами и предложениями ждем вас в комментариях к статье, а также в Telegram-чате deckhouse_ru, где разработчики платформы всегда готовы помочь и ответить на вопросы. Будем рады issues (и, конечно, звездам) в GitHub-репозитории Deckhouse.

P. S.

Читайте также в нашем блоге:

Комментарии (2)


  1. DonAlPAtino
    19.10.2023 09:23

    На маке можно пробовать или это только для Linux да еще и с графической оболочкой, учитывая что Grafana открывается только локально?


    1. TimurTukaev
      19.10.2023 09:23

      MacOS поддерживается, смотрите самое начало, где указаны требования к системе. Для самого Deckhouse GUI не нужны, просто именно в этой статье мы рассматриваем установку на личный ноутбук — а личные машинки обычно с GUI:)