Вводная часть


Kubernetes, также известный как k8s — это портативная расширяемая платформа с открытым исходным кодом для управления контейнеризованными рабочими нагрузками и сервисами, которая облегчает как декларативную настройку, так и автоматизацию. Kubernetes можно настроить как в локальной, так и в облачной инфраструктуре. Однако, кластер Kubernetes немного сложен в настройке и требует значительных ресурсов, что затрудняет развертывание на локальной машине для обучения или разработки. Это приводит к тому, что не для каждого бизнеса перейти на полноценный k8s представляется возможным. К счастью, на этот случай есть более легкое решение в виде k3s.


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


Немного истории о k3s


Во время создания Rio (одна из разработок для kubernetes от Rancher Labs), разработчик Даррен Шепард был разочарован тем, что для тестирования данного продукта, постоянно требовалось запускать новый кластер Kubernetes. Он знал, что это занимает всегда много времени и если он сможет запускать кластер быстрее, он сможет выделять больше времени на написание кода и быстрее выпускать новые фичи. Так как Даррен был хорошо знаком с исходным кодом Kubernetes, он начал его разбирать, удаляя все ненужные компоненты, чтоб обеспечить быстрый запуск.


Вот таким образом в 2019 году компания Rancher Labs объявила о запуске своего нового проекта с открытым исходным кодом k3s, который представлял собой легкий и простой в установке дистрибутив k8s, предназначенный для разработчиков и операторов, ищущих способ запуска Kubernetes на платформах с ограниченными ресурсами. 


Чтоб адаптировать kubernetes к слабому железу Rancher Labs потребовалось  следующее:


  • Удалить старый и неиспользуемый код. По словам разработчиков из кода было вырезано порядка 1000 строк.
  • Вместо Docker использовать conteinerd.
  • Добавить поддержку Kine, в качестве хранилища по умолчанию. 
  • Удалить драйвера облачных провайдеров.

Дистрибутив k3s поддерживает множество архитектур, включая AMD64, ARM64 и ARMv7-8. Благодаря последовательному процессу установки k3s может работать на Raspberry Pi Zero, NVIDIA Jetson Nano, Intel NUC или на экземпляре Amazon EC2 a1.4xlarge.


Отличия от k8s


Давайте для начала разберем, чем k3s отличается от полноценного k8s. Если сравнивать с традиционным кластером Kubernetes, то в k3s нет четкого различия между мастер и воркер нодами. Управление подами происходит на любой ноде, независимо от роли, которую они играют. Таким образом, понятия мастер и воркер нод не применимы к кластеру k3s.


Rancher Labs избавились от множества необязательных компонентов Kubernetes, например, от плагинов объема хранилища и API-интерфейсов облачных провайдеров, которые, как они посчитали, не будут критичны для запуска кластера k3s.


Затем были добавлены некоторые важные элементы, включая containerd, Flannel, CoreDNS, CNI, ingress controller Traefik, локальное хранилище данных, встроенный сервис Load Balancer. Все эти элементы упакованы в один бинарный файл и выполняются в рамках одного процесса. Помимо этого, дистрибутив также поддерживает Helm-charts из коробки. K3s не имеет внешних зависимостей. Это означает, что вам не нужно ничего устанавливать, чтобы запустить его.


Другое ключевое отличие k3s от k8s заключается в способе управления состоянием кластера. Kubernetes полагается на распределенную базу данных «ключ-значение» etcd для хранения всего состояния кластера. Изначально разработчики k3s заменили etcd облегченной базой данных под названием SQLite. Однако позже команда создала (они называют его революционным) проект под названием Kine, что означает «Kine is not etcd». Kine предоставляет прокладку API, которая позволяет k3s поддерживать различные серверные части баз данных, включая MySQL, Postgres и SQLite. Он принимает запросы etcd v3 от Kubernetes, преобразовывает их в SQL-запросы и отправляет в серверную часть вашей базы данных.


Также выделяется еще одна отличительная особенность от старшего брата — автоматическое развертывание. Оно позволяет развертывать манифесты Kubernetes и Helm-чарты, помещая их в определенный каталог. То есть k3s отслеживает изменения и заботится об их применении без дальнейшего взаимодействия. Просто создайте/обновите свою конфигурацию, и k3s обеспечит актуальность ваших deployments .


Архитектура


image


На приведенном выше рисунке показана разница между сервером k3s и узлами агента k3s. (Источник здесь)


Если копнуть глубже, то k3s упакован и развернут в виде одного бинарного файла размером приблизительно 60 МБ, представляющего из себя самодостаточный инкапсулированный объект, который запускает почти все компоненты кластера Kubernetes.


На рисунке мы наблюдаем две ноды, на одной из которых работает k3s service, а на второй агент k3s. API server проверяет и настраивает данные для объектов API — например pods, services и т.д. Controller Manager наблюдает за общим состоянием кластера через API-сервер, вносит в него изменения и переводит из текущего состояния в желаемое. Scheduler назначает модули узлам в соответствии с их текущим состоянием, ограничениями и доступными ресурсами. Kubelet как основной агент узла в кластере, работающий на каждой ноде. Kine, где в качестве хранилища по умолчанию используется SQLite. Containerd как исполняемая среда для запуска контейнеров. Связь между агентом и сервером осуществляется через туннельный прокси.


Теперь, когда мы разобрались с архитектурой, давайте рассмотрим, как на самом деле можно развернуть k3s. Для k3s существует несколько архитектур развертывания. Давайте рассмотрим основные(картинки взяты из официальной документации k3s):


  • Кластер из одной ноды:

Этот самый упрощенный метод для разворачивания кластера k3s, который оптимизирован для пограничных устройств. Вы просто запускаете команду установки при помощи команды curl, и она разворачивает полноценный кластер Kubernetes. Но стоит сразу обратить внимание, что данная архитектура развертывания не сможет обеспечить вам отказоустойчивость.


  • Один кластер с несколькими агентами:
    image

Этот метод также использует один сервер к которому вы можете добавить агентов в кластер. Агенты безопасно подключаются с помощью токена, который сервер создает при запуске. В этой конфигурации каждый узел агента регистрируется на одном и том же узле сервера. Пользователь k3s может управлять ресурсами Kubernetes, вызывая API k3s на узле сервера.


  • Высокодоступный сервер k3s с внешней БД:

image


Этот метод можно использовать, если вам важно настроить отказоустойчивый кластер. Данный кластер k3s состоит из:


  • Двух или более серверных узлов, которые будут обслуживать API Kubernetes и запускать другие службы плоскости управления.
  • Внешнего хранилища данных (вместо встроенного хранилища данных SQLite, которое используется в конфигурациях с одним сервером по умолчанию).

В данной статье мы на примере рассмотрим установку однонодового кластера и подключим агента к основному серверу.


Практика “Быстрый старт”


Наша цель быстро запустить кластер k3s на виртуальной машине для демонстрации.
Рекомендуемые требования, заявленные разработчиками следующие:


  • RAM: 512MB минимум (рекомендовано 1GB)
  • CPU: минимум 1 ядро
    Для нашей демонстрации мы подготовили 2 виртуальные машины со следующими характеристиками:
  • k3s server с hostname k3s_server: debian 10, cpu 1, ram 1gb
  • k3s agent c hostname worker1: debian 10, cpu 1, ram 1gb

Для начала развернем кластер из одной ноды:
Установка происходит в одну команду
curl -sfL https://get.k3s.io | sh -
При успешной установке в терминале выводится следующее:


[INFO]  Finding release for channel stable
[INFO]  Using v1.22.6+k3s1 as release
[INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.22.6+k3s1/sha256sum-amd64.txt
[INFO]Downloading binary  https://github.com/k3s-io/k3s/releases/download/v1.22.6+k3s1/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Skipping installation of SELinux RPM
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

real    0m0m32,577s
user    0m0,838s
sys     0m0,399s

Установка k3s заняла 32 сек.
Из вывода также были установлены другие важные утилиты:


  • kubectl
  • crictl
  • k3s-killall.sh
  • k3s-uninstall.sh

Как вы можете наблюдать в приведенной выше команде мы использовали дополнительный флаг, --write-kubeconfig-mode. По умолчанию файл KUBCECONFIG, расположенный по адресу /etc/rancher/k3s/k3s.yaml, имеет права только на чтение для пользователя root. Поэтому нам нужно сделать его читаемым и для других пользователей.
Если мы попытаемся выполнить следующую команду без флага, то мы получим ошибку загрузки kubeconfig:


WARN[0000] Unable to read /etc/rancher/k3s/k3s.yaml, please start server with --write-kubeconfig-mode to modify kube config permissions  
error: error loading config file "/etc/rancher/k3s/k3s.yaml": open /etc/rancher/k3s/k3s.yaml: permission denied

Исправить данную ошибку можно следующими методами:


  • экспортировать KUBECONFIG в переменную среду путем выполнения следующей команды:
    k3s_server:~$ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
  • вызвать флаг --kubeconfig с указанием расположения файла с последующим выводом:
    k3s_server:~$ kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml get pods --all-namespaces

Теперь мы можем просмотреть статус запущенной службы службы:


● k3s.service - Lightweight Kubernetes
   Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2022-03-17 20:56:59 +07; 1min 19s ago
     Docs: https://k3s.io
  Process: 456 ExecStartPre=/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service (code=exited, status=0/SUCCESS)
  Process: 458 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
  Process: 459 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 460 (k3s-server)
    Tasks: 84
   Memory: 532.6M
   CGroup: /system.slice/k3s.service
           ├─ 460 /usr/local/bin/k3s server
           ├─ 479 containerd  
           ├─1271 /coredns -conf /etc/coredns/Corefile
           ├─1453 traefik traefik --global.check        
           ├─1484 /metrics-server                     
           ├─1806 /bin/sh /usr/bin/entry
           ├─1842 /bin/sh /usr/bin/entry
           └─2023 local-path-provisioner start --config /etc/config/config.json

Проверяем установленную версию k3s:


k3s version v1.22.6+k3s1 (3228d9cb)
go version go1.16.10

Теперь пробуем подключиться к нашему кластеру:


k3s_server:~$ sudo k3s kubectl get node
NAME         STATUS        ROLES                  AGE      VERSION
k3s_server   Ready    control-plane,master        82s   v1.22.6+k3s1

Как мы видим у нас запущена мастер нода по имени k3s_server c указанием ролей, статуса, времени и т.д


k3s_server:~# kubectl get no -o wide
NAME           STATUS   ROLES                  AGE   VERSION        INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
k3s_server     Ready    control-plane,master   32s   v1.22.6+k3s1   192.168.1.127   <none>        Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.5.9-k3s1

Выводим список всех namespace:


NAME                    STATUS AGE
default                 Active 8m42s
kube-system             Active 8m42s
kube-public             Active 8m42s
kube-node-lease         Active 8m42s

Смотрим какие service доступны для пространства имен kube-system:


k3s_server:~$ kubectl -n kube-system get svc
NAME                   TYPE            CLUSTER-IP      EXTERNAL-IP    PORT(S)                        AGE
kube-dns               ClusterIP      10.43.0.10         <none>       53/UDP,53/TCP,9153/TCP         83m
metrics-server         ClusterIP      10.43.150.20       <none>       443/TCP                        83m
traefik                LoadBalancer   10.43.190.199   192.168.1.112   80:32738/TCP,443:31552/TCP     82m

Также мы можем посмотреть все наши запущенные поды в пространстве имен kube-system:


k3s_server:~$ k3s kubectl -n kube-system get pods
NAME                                              READY        STATUS           RESTARTS          AGE
local-path-provisioner-5ff76fc89d-c4lwm            1/1         Running             0              19d
metrics-server-86cbb8457f-cc4fp                    1/1         Running             0              19d
helm-install-traefik-crd-7nbxl                     0/1         Completed           0              19d
helm-install-traefik-hk9d4                         0/1         Completed           1              19d
svclb-traefik-2jn6j                                2/2         Running             0              19d
traefik-97b44b794-p2cpk                            1/1         Running             0              19d
coredns-7448499f4d-mh8lm                           1/1         Running             0              19d
svclb-traefik-7rxjr                                2/2         Running             0              19d
svclb-traefik-dspv9                                2/2         Running             0              19d

И ознакомится с остальной информацией по ноде:


k3s_server:~$ k3s kubectl get endpoints -n kube-system
NAME                    ENDPOINTS                                                   AGE
kube-dns               10.42.0.19:53,10.42.0.19:53,10.42.0.19:9153                  19d
traefik                10.42.0.21:8000,10.42.0.21:8443                              19d
metrics-server         10.42.0.20:4443                                              19d

k3s_server:~$ k3s kubectl cluster-info 
Kubernetes master is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

Вот и все, мы успешно установили наш однонодовый кластер k3s. Теперь приступим к настройке одного кластера с несколькими агентами:
Для подключения worker1 ноды к кластеру необходимо получить токен на k3s_server сервере:


sudo cat /var/lib/rancher/k3s/server/node-token
K10796db3814d90a12ad4be159bbf3891268b0a3af5888ca7c8853e82cdc4290a6d::server:*****

Получив токен, устанавливаем k3s на worker1 ноде:


root@worker1:~# curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.127:6443 K3S_TOKEN=K10796db3814d90a12ad4be159bbf3891268b0a3af5888::server:228c42c3fb5d5ef6424a168bf1a86105 sh

Как вы видите, для подключения worker1 ноды к k3s_server, необходимо дополнительно еще указать url c ip адресом, портом ноды k3s server


[INFO]  Finding release for channel stable
[INFO]  Using v1.22.6+k3s1 as release
[INFO]  Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.22.6+k3s1/sha256sum-amd64.txt
[INFO]  Skipping binary downloaded, installed k3s matches hash
[INFO]  Skipping installation of SELinux RPM
[INFO]  Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO]  Skipping /usr/local/bin/crictl symlink to k3s, already exists
[INFO]  Skipping /usr/local/bin/ctr symlink to k3s, already exists
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s-agent.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s-agent.service
[INFO]  systemd: Enabling k3s-agent unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service → /etc/systemd/system/k3s-agent.service.
[INFO]  systemd: Starting k3s-agent

k3s-agent нода установлена
Проверяем статус, что служба k3s-agent успешно запустилась:


root@worker1:~# systemctl status k3s-agent
● k3s-agent.service - Lightweight Kubernetes
  Loaded: loaded (/etc/systemd/system/k3s-agent.service; enabled; vendor preset: enabled)
  Active: active (running) since Thu 2022-03-17 21:16:25 +07; 1min 19s ago
  Docs: https://k3s.io
  Process: 426 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
  Process: 427 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 428 (k3s-agent)
    Tasks: 31
   Memory: 184.7M
   CGroup: /system.slice/k3s-agent.service
           ├─1008 /usr/local/bin/k3s agent
           └─1029 containerd 

И смотрим на ноде k3s_server, что агент успешно к ней подключился:


k3s_server:~$ kubectl get no -o wide
NAME         STATUS   ROLES                  AGE   VERSION        INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
k3s_server   Ready    control-plane,master   16m   v1.22.6+k3s1   192.168.1.127   <none>        Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.5.9-k3s1
worker1      Ready    <none>                 44s   v1.22.6+k3s1   192.168.1.157   <none>        Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.5.9-k3s1

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


Удаление k3s


Удаление k3s также происходит быстро, как его установка. Так как при установке k3s создается скрипт для удаления k3s из вашей системы, достаточно выполнить следующие команды в терминале вашего сервера:


sudo /usr/local/bin/k3s-uninstall.sh для удаления k3s с сервера/главного узла
sudo /usr/local/bin/k3s-agent-uninstall.sh для удаления k3s с агента/рабочего узла.


Заключение


На этом наше знакомство с k3s завершаем, и, подводя итог, скажу для кого использование k3s будет полезным:


  1. Для предприятий со средней капитализацией, где могут решить использовать как k3s, так и k8s, что сэкономит бизнесу много денег, сохраняя при этом обычную работу.
  2. Для предприятий с небольшой капитализацией, у которых нет опыта работы с крупными приложениями и которое дает шанс познакомится с kubernetes при помощи k3s, так как он очень быстр при развертывании приложений с небольшими рабочими нагрузками, а также прост в установке, запуске и обновлении.

Напоследок предоставим немного интересных фактов о k3s


  • Это полностью сертифицированный CNCF(Сloud Native Computing Foundation) дистрибутив. Это означает, что он прошел тесты на соответствие, используемые CNCF для сертификации дистрибутивов Kubernetes.
  • Это проект песочницы CNCF. В августе 2020 года Rancher Labs пожертвовала k3s CNCF, где он стал проектом «песочница». Фактически, это первый дистрибутив Kubernetes, получивший такое отличие.
  • Более 1 миллиона загрузок. С февраля 2019 года k3s скачали более 1 миллиона раз, в среднем 20 000 установок в неделю.
  • Предназначен для производства. Основное различие между k3s и другими небольшими дистрибутивами Kubernetes, такими как Minikube и microk8s, заключается в том, что он с самого первого дня разрабатывался для работы в продакшене.
  • На момент 2022 года имеет на гитхабе 19 тысяч звезд, что говорит о заинтересованности сообщества в данном проекте.
  • Не существует ни полной формы названия k3s, ни официального произношения.
    Разработчики хотели, чтобы установка Kubernetes была вдвое меньше с точки зрения занимаемой памяти. А так как Kubernetes состоит из 10 букв, которое сообщество стилизовали под k8s, ребята из Rancher Labs просто уменьшили вдвое количество букв в Kubernetes и стилизовали под k3s.

Ознакомится с исходным кодом k3s и официальной документацией вы cможете по следующим ссылкам:



Кстати, присоединяйтесь к нашему телеграм-каналу, где мы публикуем новости о DevOps (и не только) — DevOps FM, а также читайте другие статьи в нашем блоге:


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


  1. tzlom
    05.04.2022 10:24
    +4

    Иронично что именно Rancher стал делать мини кубер, в то время как k8s спокойно влазит в 512 Мб 1 Core в отличии от Rancher. (да я понимаю что k3s разворачивается быстрее)


  1. slonopotamus
    05.04.2022 15:49
    +2

    По словам разработчиков из кода было вырезано порядка 1000 строк.

    Из скольких миллионов?)


  1. alexesDev
    06.04.2022 17:14

    Я понимаю, что k8s это круто и современно, но где-то в сторонке стоит nomad, который работает как палка и даже в деве из коробки разворачивает локальный кластер для тестов одной командой. С одним глобальным минусом - не пытается из коробки поддерживать stateful (но не все хотят засовывать базы в k8s или пользуются облачными решениями для этого).