Kubernetes в миниатюре для локального запуска: k0s, MicroK8s, kind, k3s и Minikube

в 7:51, , рубрики: devops, k0s, k3s, kind, kubernetes, MicroK8s, Minikube, open source, Блог компании Флант, системное администрирование
Kubernetes в миниатюре для локального запуска: k0s, MicroK8s, kind, k3s и Minikube - 1

Тех, кто работал с Kubernetes, вряд ли удивит ситуация, когда внезапно пришла идея по автоматизации, унификации, преобразованию чего-либо в кластере, но так, чтобы не волноваться за конечный результат. Когда возникает потребность в какой-то песочнице, чтобы провести тестирование, проверить гипотезу «на коленке», не используя рабочий Kubernetes-кластер.

В таких случаях приходят на помощь «мини-кластеры». Их можно запустить на рабочем ПК, «поиграться» с примитивами, построить новую структуру, а после завершения эксперимента — безвозвратно удалить (ведь это уже отработанный материал).

Отвечая на эту потребность, разработчики со всего мира пришли со своими решениями для быстрого запуска облегчённого варианта Kubernetes. Все они по-разному организованы и, конечно, обладают разными возможностями. Чем пользоваться, зависит от нужд и предпочтений. Чтобы получше разобраться в них или вообще понять, с чего стоит начать, предлагаем результаты нашего беглого знакомства с некоторыми популярными решениями. Благо, все они достаточно хорошо документированы (как на сайтах, так и в CLI), что существенно ускоряет первое погружение и взаимодействие с ними. В конце статьи будет сводная таблица с основными особенностями решений.

Обзор

1. k0s

  • Сайт: k0sproject.io

  • Основной GitHub: k0sproject/k0s

  • GH-звёзды: ~4000

  • Контрибьюторы: 30+

  • Первый коммит: июнь 2020

  • Основной разработчик: Mirantis

  • Поддерживаемые версии K8s: 1.20 и 1.21

Название проекта (произносится как «kziros») говорит само за себя: тяжело придумать систему меньше, т.к. настройку и дальнейшую работу с кластером обеспечивает самодостаточный (собранный статически) бинарный файл, а его установка состоит в получении актуальной версии из репозитория проекта. Файл скомпилирован под Linux — соответственно, работа кластера возможна только в этой системе (подробнее о поддерживаемых хост-системах см. в конце обзора). Для полноценного запуска необходимо обладать правами суперпользователя.

После незатейливой установки файла (он помещается в /usr/local/bin) вспомогательным скриптом нужно запустить службу, которая позволит нашей системе выполнять функцию узла кластера (по умолчанию это master):

k0s install controller ; systemctl start k0scontroller.service

Взаимодействие с Kubenetes API осуществляется с помощью встроенного kubectl:

k0s kubectl get nodes

Таким же образом, через k0s kubectl ..., можно создавать желаемые объекты: namespaces, Deployments и т.д. Для добавления в кластер других узлов нужно подготовить систему по соседству (запуск нескольких кластеров на одной физической системе не предусмотрен) и с помощью токена, полученного на существующем master, подключить её в качестве master- или worker-узла. Необходимой «соседней» системой может быть ОС в контейнере или виртуальной машине: главное — обеспечить сетевую доступность сервера API для возможности регистрации узла в кластере.

После прекращения работы узла кластера (k0s stop) нужно произвести остановку задействованных контейнеров командой k0s reset.

За работу контейнеров в Pod’ах отвечает containerd. К Pod’ам можно подключить тома типа HostPath. В качестве CNI по умолчанию используется Calico, на выбор из коробки также предлагается и kube-router, но можно настроить любой другой: ограничений на настройку собственно Kubernetes нет.

Для удобства работы в консоли предусмотрены готовые наборы для автодополнения в разных оболочках: Bash, zsh, fish, PowerShell (через WSL).

k0s максимально аскетичен: это ванильный Kubernetes без каких-либо готовых модулей и плагинов. По умолчанию в нём нет поддержки облачных провайдеров, но её можно добавить при запуске. Устанавливать ПО нужно по аналогии с обычным кластером Kubernetes — через объявление необходимых примитивов (возможно, с применением Helm и подобных инструментов).

2. MicroK8s

  • Сайт: microk8s.io

  • Основной репозиторий на GitHub: ubuntu/microk8s

  • GH-звёзд: ~5600

  • Контрибьюторов: 120+

  • Первый коммит: май 2018

  • Основной разработчик: Canonical

  • Поддерживаемые версии K8s: 1.19—1.21

Этот вариант кластера от Canonical очень похож на предыдущий: узлы кластера нужно готовить самостоятельно (это могут быть любые экземпляры ОС Linux, имеющие связность по TCP/IP с первым узлом кластера в роли master’а), подключать новые — с помощью токена, а для работы с API доступен встроенный kubectl.

В качестве CNI по умолчанию также используется Calico. Для запуска потребуются права суперпользователя. Но поставляется продукт в виде пакета snap и официально поддерживает работу в 42 разновидностях Linux:

# snap install microk8s --classic

После установки остаётся только запустить кластер:

# microk8s start
# microk8s kubectl get nodes
NAME            STATUS   ROLES    AGE    VERSION
thinkpad        Ready    <none>   2m     v1.20.7-34+df7df22a741dbc

Весьма полезным может оказаться набор дополнений, который позволяет с помощью одной команды установить, например, Kubernetes dashboard:

# microk8s enable dashboard
# microk8s status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dashboard            # The Kubernetes dashboard
    ...

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

Еще одна интересная возможность — команда microk8s inspect, которая проводит анализ состояния кластера и готовит отчёт о его компонентах в виде архива для дальнейшего изучения:

$ ls inspection-report/
apparmor
args
juju
k8s
kubeflow
network
snap.microk8s.daemon-apiserver
snap.microk8s.daemon-apiserver-kicker
snap.microk8s.daemon-cluster-agent
snap.microk8s.daemon-containerd
snap.microk8s.daemon-controller-manager
snap.microk8s.daemon-control-plane-kicker
snap.microk8s.daemon-kubelet
snap.microk8s.daemon-proxy
snap.microk8s.daemon-scheduler
sys
$ ls inspection-report/k8s/
cluster-info
cluster-info-dump
get-all
get-pv
get-pvc
version
$ cat inspection-report/k8s/version 
Client Version: version.Info{Major:"1", Minor:"20+", GitVersion:"v1.20.7-34+df7df22a741dbc", GitCommit:"df7df22a741dbc18dc3de3000b2393a1e3c32d36", GitTreeState:"clean", BuildDate:"2021-05-12T21:08:20Z", GoVersion:"go1.15.10", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"20+", GitVersion:"v1.20.7-34+df7df22a741dbc", GitCommit:"df7df22a741dbc18dc3de3000b2393a1e3c32d36", GitTreeState:"clean", BuildDate:"2021-05-12T21:09:51Z", GoVersion:"go1.15.10", Compiler:"gc", Platform:"linux/amd64"}

3. kind

  • Сайт: kind.sigs.k8s.io

  • Основной репозиторий на GitHub: kubernetes-sigs/kind

  • GH-звёзд: ~8300

  • Контрибьюторов: 200+

  • Первый коммит: сентябрь 2018

  • Основной разработчик: Kubernetes SIG

  • Поддерживаемые версии K8s: 1.21

Название этого дистрибутива представляет собой аббревиатуру: Kubernetes in Docker. Установка совершенно бесхитростна: нужно просто скачать выполняемый файл.

Для создания кластера достаточно обладать правами на создание контейнеров и сетей Docker. После установки и создания кластера (kind create cluster)* появляется узел, представляющий собой контейнер Docker, внутри которого находятся другие контейнеры:

$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                       NAMES
fee30f6d4b73        kindest/node:v1.21.1   "/usr/local/bin/entr…"   2 minutes ago       Up About a minute   127.0.0.1:45331->6443/tcp   kind-control-plane
$ kind get nodes
kind-control-plane
$ kubectl get nodes
NAME                 STATUS   ROLES                  AGE   VERSION
kind-control-plane   Ready    control-plane,master   2m    v1.21.1
$ docker exec -it kind-control-plane bash
root@kind-control-plane:/# crictl ps
CONTAINER           IMAGE               CREATED             STATE               NAME                      ATTEMPT             POD ID
2a0dfe12a5810       296a6d5035e2d       2 minutes ago       Running             coredns                   0                   e13acbf529288
38ef0ad97090a       296a6d5035e2d       2 minutes ago       Running             coredns                   0                   3460cf0419c19
ec11cbc0e9795       e422121c9c5f9       2 minutes ago       Running             local-path-provisioner    0                   a9ffa60dcc12d
fa8057bbf0df6       6de166512aa22       3 minutes ago       Running             kindnet-cni               0                   4f8481acba5fc
e341ce4c5cdfd       ebd41ad8710f9       3 minutes ago       Running             kube-proxy                0                   1b1755819c40a
88c6185beb5c5       0369cf4303ffd       3 minutes ago       Running             etcd                      0                   da01c1b2b0cdc
5cdf1b4ce6deb       d0d10a483067a       3 minutes ago       Running             kube-controller-manager   0                   a0b2651c06136
b704a102409e1       6401e478dcc01       3 minutes ago       Running             kube-apiserver            0                   c2119c740fff2
a5da036de5d10       7813cf876a0d4       3 minutes ago       Running             kube-scheduler            0                   92a22aa99ad29

* При установке создаётся сеть Docker. В случае, если установка не удалась из-за ошибки:

ERROR: failed to create cluster: failed to ensure docker network: command "docker network create -d=bridge -o com.docker.network.bridge.enable_ip_masquerade=true -o com.docker.network.driver.mtu=1500 --ipv6 --subnet fc00:f853:ccd:e793::/64 kind" failed with error: exit status 1
Command Output: Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

... следует проверить наличие в системе процесса OpenVPN и остановить его на время установки. После завершения установки можно запустить вновь.

Также во время создания кластера производится настройка конфига kubectl для доступа к API. Настройка кластера более сложной конфигурации может быть осуществлена только в момент создания с помощью конфига. Например, для создания кластера, состоящего из трёх узлов:

kind create cluster --config=three-node-conf.yaml

… где three-node-conf.yaml:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

После удаления кластера (kind delete cluster) удаляется также информация о нём из конфига kubectl. Поддерживается автодополнение для Bash, zsh, fish.

Поскольку узел представляет собой Docker-контейнер, объявление томов HostPath в Pod’ах приведёт к использованию файловой системы контейнера, каталог на которой, в свою очередь, можно пробросить на ФС родительской ОС. Есть возможность загружать Docker-образы с управляющего хоста на узлы кластера. Плагинов, дополнений нет.

В качестве CNI по умолчанию — собственное решение kindnetd, — но возможно и использование других плагинов. Хотя поддержка этой фичи называется ограниченной, «многие популярные CNI-манифесты работают, например, Calico».

Дальнейшая настройка выполняется при помощи kubectl. Например, установить Ingress NGINX можно командой:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml

4. k3s (и k3d)

  • Сайт: k3s.io k3d.io)

  • Основной репозиторий на GitHub: k3s-io/k3s (rancher/k3d)

  • GH-звёзд: ~17600 (~2700)

  • Контрибьюторов: 1750+ (50+)

  • Первый коммит: январь 2019 (апрель 2019)

  • Основной разработчик: CNCF (Rancher)

  • Поддерживаемые версии K8s: 1.17—1.21

k3s — дистрибутив от Rancher, название которое сделали «меньше», чем K8s, чтобы подчеркнуть его легковесность и простоту (пусть и с меньшим функционалом). Общая идея схожа с k0s и MicroK8s. После запуска в системе k3s он становится узлом кластера с одной из двух возможных ролей:

  • сервер, выполняющий функции master’а: API server, scheduler и controller manager, — с БД в виде SQLite;

  • агент, выполняющий функции рядового узла Kubernetes: kubelet и containerd, управляющий запуском контейнеров CRI-O.

С целью уменьшения размера исполняемого файла при сборке исключены большинство драйверов для работы с дисками и драйверы облачных провайдеров. За счёт того, что он содержит в себе сразу несколько составляющих классического Kubernetes, более экономно расходуется оперативная память.

В «вырожденном» случае для запуска кластера в составе единственного узла можно использовать Docker Desktop без систем полноценной виртуализации.

Помимо собственно дистрибутива существует также k3d — утилита, управляющая узлами k3s, каждый из которых помещён в контейнер Docker. Она устанавливается на систему с Linux с помощью Bash-скрипта.

Для запуска кластера достаточно обладать правами на создание контейнеров и сетей Docker.

Кластер создаётся одной командой**:

$ k3d cluster create mycluster --servers 1 --agents 2
$ kubectl get nodes
NAME                  STATUS   ROLES                  AGE   VERSION
k3d-mycluster-agent-0    Ready    <none>                 30s   v1.20.6+k3s1
k3d-mycluster-agent-1    Ready    <none>                 22s   v1.20.6+k3s1
k3d-mycluster-server-0   Ready    control-plane,master   39s   v1.20.6+k3s1

** См. выше примечание про создание сети Docker при установке и возможную ошибку из-за процесса OpenVPN. Только текст ошибки в данном случае будет другим:

Failed Cluster Preparation: Failed Network Preparation: Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

Под каждый узел кластера выделяется свой контейнер плюс ещё один — служебный с nginx, который выполняет роль балансировщика нагрузки. В качестве CNI используется Flannel, а ingress — Traefik. Предусмотрена возможность выбора других CNI — например, в документации есть особые инструкции для Calico и Canal. Поддерживается автодополнение для Bash, zsh, fish, PowerShell.

Предусмотрена возможность управления репозиториями образов: создавать свои репозитории в кластере, импортировать образы из основной системы. Это может сыграть хорошую службу при локальной разработке образов Docker, т.к. они будут доступны в кластере сразу после сборки.

5. Minikube

  • Сайт: minikube.sigs.k8s.io

  • Основной репозиторий на GitHub: kubernetes/minikube

  • GH-звёзд: ~21500

  • Контрибьюторов: 650+

  • Первый коммит: апрель 2016

  • Основной разработчик: Kubernetes SIG

  • Поддерживаемые версии K8s: 1.11—1.22

Инсталляция Minikube в Linux-дистрибутивах, базирующихся на Debian и Red Hat, сводится к установке соответствующего пакета. Пользователь, который не обязан быть root (но должен обладать правами, достаточными для настройки выбранной системы виртуализации), может создать кластер одной командой:

$ minikube start
* minikube v1.20.0 on Ubuntu 18.04
* Automatically selected the docker driver. Other choices: kvm2, ssh
…
* Preparing Kubernetes v1.20.2 on Docker 20.10.6 ...
…
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
$ kubectl get nodes
NAME       STATUS   ROLES                  AGE    VERSION
minikube   Ready    control-plane,master   48s    v1.20.2

После этого доступен конфиг kubectl, дополненный данными доступа к новому кластеру. Поддерживается автодополнение для Bash, zsh, fish.

В рамках локальной ОС Minikube создаёт систему smth1-in-smth2, где:

  • smth1 — одно из значений: docker, cri-o, containerd;

  • smth2 — одно из: virtualbox, vmwarefusion, kvm2, vmware, none, docker, podman, ssh.

Также можно выбрать CNI:

minikube help start
Starts a local Kubernetes cluster

Options:
...    
      --cni='': CNI plug-in to use. Valid options: auto, bridge, calico, cilium, flannel, kindnet, or path to a CNI manifest (default: auto)
      --container-runtime='docker': The container runtime to be used (docker, cri-o, containerd).
...
      --driver='': Driver is one of: virtualbox, vmwarefusion, kvm2, vmware, none, docker, podman, ssh (defaults to auto-detect)

Можно добавить необходимое количество узлов на той же физической машине:

$ minikube node add
* Adding node m02 to cluster minikube

А посмотреть текущее состояние кластера — командой minikube status:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

minikube-m02
type: Worker
host: Running
kubelet: Running

Для облегчения подключения ФС родительской системы доступна команда minikube mount. После её выполнения содержимое каталога-источника, благодаря протоколу 9P, будет доступно на ФС внутри узла кластера. Использование в Pod’ах тома HostPath позволит, таким образом, работать с файлами без выполнения docker cp (хотя и использование этой команды тоже допустимо).

При необходимости подключения внешних каталогов с большим количеством файлов 9P может работать нестабильно. Выйти из этого положения помогут возможности подключения ФС, предоставляемые системами виртуализации (VirtualBox, KVM, VMware).

В minikube есть дополнения, которые легко активировать в кластере:

$ minikube addons enable dashboard
…
* The 'dashboard' addon is enabled
$ minikube addons list
…
| dashboard                   | minikube | enabled ​   |
…
$ kubectl -n kubernetes-dashboard get pod
NAME                                        READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-f6647bd8c-rrxq6   1/1     Running   0          29s
kubernetes-dashboard-968bcb79-tk5qt         1/1     Running   0          29s

Аналогично можно включить registry, ingress, Istio и многие другие компоненты.

Поддерживается параллельная работа с несколькими кластерами, использующими разные профили:

$ minikube start -p minik2
* [minik2] minikube v1.20.0 on Ubuntu 18.04
* Automatically selected the docker driver. Other choices: kvm2, ssh
* Starting control plane node minik2 in cluster minik2
…
$ minikube profile list
|----------|-----------|---------|--------------|------|---------|---------|-------|
| Profile  | VM Driver | Runtime |      IP      | Port | Version | Status  | Nodes |
|----------|-----------|---------|--------------|------|---------|---------|-------|
| minik2   | docker    | docker  | 192.168.58.2 | 8443 | v1.20.2 | Running |     1 |
| minikube | docker    | docker  | 192.168.49.2 | 8443 | v1.20.2 | Running |     2 |
|----------|-----------|---------|--------------|------|---------|---------|-------|

6. Альтернативные решения

Существуют также и некоторые другие проекты, не попавшие в этот обзор из-за их меньшей популярности или по другим причинам. Например, есть проект Red Hat CRC (CodeReady Containers; ~750 звёзд на GitHuB), пришедший на смену Minishift для запуска минимального кластера OpenShift 4.x на лаптопе/десктопе.

По-своему интересен Firekube от Weaveworks — Kubernetes-кластер, работающий в виртуальной машине Firecracker. Однако его разработка больше не выглядит активной.

Где всё это запускать

Все упомянутые дистрибутивы работают в Linux. Но если в распоряжении находится другая ОС, можно обойтись виртуализацией:

  • В общем случае это могут быть Multipass и VirtualBox.

  • В частных случаях — другие средства виртуализации, такие как, например, WSL на Windows.

Для kind, k3d, Minikube в минимальном варианте будет достаточно создания одной ВМ с Linux, а для k0s, Microk8s, k3s — по числу узлов кластера.

Итоги с таблицей-сравнением

Систематизирую полученный опыт:

k0s

MicroK8s

kind

k3s + k3d

Minikube

Управление созданием/удалением узлов

Система управления узлами

Docker

Docker

virtualbox, vmwarefusion, kvm2, vmware, none, docker, podman, ssh

Система запуска контейнеров

containerd

containerd

containerd, CRI-O

CRI-O

Docker, CRI-O, containerd

CNI по умолчанию

Calico

Calico

kindnet

Flannel

bridge

Возможность подключения ФС родительской ОС

HostPath

HostPath

HostPath + docker mount

HostPath + docker mount

HostPath + … (зависит от системы виртуализации)

Наличие дополнений

Возможность создания кластера непривилегированным пользователем

Vanilla Kubernetes

Сравнение проводилось в рамках конкретной задачи (песочницы, локального запуска), однако некоторые из рассмотренных продуктов формально ориентированы на иное применение. Например, MicroK8s от Canonical и K3s от Rancher позиционируются как решения для IoT и edge. Поэтому вдвойне полезно напомнить, что окончательный выбор будет сильно зависеть от задачи с оглядкой на требования к доступным ресурсам и сетевой инфраструктуре. Надеюсь, изложенная информация поможет осуществить его правильно.

Полезные ссылки

P.S.

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

Автор:
zevssneg

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js