Знакомство с MicroK8s (+ kompose, helm)

Сегодня мы поговорим о Kubernetes: в частности о теме microk8s vs minikube, kompose и helm. Обзорная экскурсия, так сказать.

Написать статью о kubernetes (он же k8s или просто куб) руки у меня чесались уже довольно давно. Я активно работаю с ним уже больше года. Делится конкретным опытом внедрений в рамках данной статьи цели у меня не стоит, однако я опишу некоторые моменты на обучающих примерах. Так будет более последовательно и понятно. Можно назвать данный материал обзорным, который рассчитан на читателя, не знакомого с k8s. Однако я убежден, что каждый здесь сможет что-то для себя интересное, особенно в знакомстве с microk8s. Начнем с оглавления:



Вообще, знакомство с кубом стоит начинать из далека. С docker и плавным переходом на docker-compose. Посему, рекомендую ознакомится с моими предыдущими статьями на данные темы:

Следущий этап, это теория. Следует начать с обзорной экскурсии (overview) на офф.сайте. Там доходчиво объясняют все базовые вещи по пунктам, с примерами. Поиграться с виртуальной консолью даже можно в katacoda. Однако, из всех многочисленных обзорных статей на Хабре, увы ни одного по настоящему доходчиво изложенного материала я порекомендовать не могу. Однако в блоге одного нашего коллеги есть весьма годная статья на Dots and Brackets, написанная понятным человеческим языком. С ней я рекомендую ознакомится сразу после обзорного курса по офф.докам.

Вот реально, не хватайтесь сразу за отвертку и молоток. Это реально тот случай, когда сначала надо «прочитать инструкцию».

Итак, а теперь прежде чем мы приступим к рассмотрению конкретных примеров, нам нужна для этого тестовая площадка. С этого и начнем.

 

МикроКуб или МиниКуб? (microk8s vs minikube)

Врятли у вас сразу в распоряжении окажется полноценный кластер K8s для экспериментов. И сразу возникнет вопрос что поставить у себя локально, или на отдельном одном сервере. Офф.доки рекомендуют для этого использовать minikube (Миникуб) и он часто многими используется в качестве примера. Я сам с ним тоже работал, однако minikube мне не понравился тем, что это все таки виртуальная машина. Для ее работы нужно «откусывать» часть ресурсов и использовать гипервизор (VirtualBox или KVM). Вы можете еще поспешить и возразить, что мол, есть же режим «—vm-driver=none»! Как видите, количество потенциальных косяков там внизу (перейдите по ссылке выше) просто зашкаливает, не говоря уже просто про root доступ контейнеров в хост системе. В общем, minikube в таком режиме мне не понравился. А гипервизоры я не особо жалую (хотя некоторые на KVM с драйверами virtio заслуживают уважения). Поэтому не minikube, а microk8s.

MicroK8s (он же МикроКуб) это продукт любимой нами Canonical, поэтому он уже по умолчанию является православным. Его мы и будем использовать!) Не, это шутка конечно, помимо религиозных предубеждений, здесь еще есть и целый ряд преимуществ (у microk8s):

  • использует только необходимые ему ресурсы и не каплей больше
  • полностью масштабируем в пределах одной wordstation или даже целого server (в описании новых версий значится даже «clustering» в статусе «beta».. недавно вот еще документации появились заметки о кластеризации нескольких microk8s, но я этот функционал еще не успел протестировать)
  • легкая и простая установка в Ubuntu через snap, хваленая изоляция snap пакетов, возможность легкого отката на предыдущую версию
  • наличие аддонов, в этом плане он очень похож на minikube
  • более нативный опыт работы с инструментарием K8s, ведь в minikube есть целый ряд specific-только-для-него команд

Далее, переходим в офф.доки microk8s, устанавливаем и настраиваем его. Дополнительно, есть еще и офф.tutorials, где подробно все расписано по пунктам.

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

sudo microk8s.enable dns storage ingress
sudo snap alias microk8s.kubectl kubectl
alias kubectl='microk8s.kubectl'
sudo microk8s.stop
sudo microk8s.start
sudo microk8s.status
sudo microk8s.inspect

Как видите, командой alias вы делаем линк с внутреннего приложения microk8s.kubectl в kubectl. Это конечно же актуально, если у вас отдельно не стоит kubectl. Если стоит,то можете подключить его следующим образом:

microk8s.kubectl config view --raw > $HOME/.kube/config

Актуальная версия microk8s на момент написания статьи: 1.16.3 (1079).

Еще тут в параметрах CoreDNS я прописываю локальные DNS адреса, для корректного resolve внутренних ресурсов в сети. Также обратите внимание на результат по командам «status» и «inspect». MicroK8s там обычно требует еще прописать ему правило в iptables для доступности его сервисов за пределами нашего workstation/server.

Если у вас нет возможности или желания настраивать кластер Kubernetes самостоятельно на своем железе, можете купить его в готовом виде как сервис в облаке Mail.ru Cloud Solutions: https://mcs.mail.ru/easy-k8s/

 

Пощупайте самостоятельно

Это как с сиськами, картинки и видео, наблюдение издалека.. это одно дело. А вот щупать своими руками, это уже совсем другие ощущения.. Так вот, в k8s работать с объектами можно по разному:

  • Императивные команды (Imperative commands) — последовательный ввод команд для создания объектов. По образу и подобию очень похоже на работу с docker.
  • Императивные объекты (Imperative object configuration) — скармливание кубу .yaml конфигов с параметрами объектов. Похоже на docker-compose.
  • Декларативные объекты (Declarative object configuration) — скармливание кубу целых директорий с .yaml конфигами различных объектов внутри. Это не похоже не на что другое, но это самый смак и true-way.

Подробнее об этом можно почитать в доках на офф.сайте. Поэксперементируйте самостоятельно с командами, попробуйте найти готовые .yaml конфиги на Github и скормите их k8s через kubectl. Это очень удобный и мощный инструмент, что позволяет применять конфиги различными способами, даже напрямую по ссылке (при наличии доступа в Инет).

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

 

Kompose, что еще за зверь такой

Как следует из названия, Kubernetes + Compose = Kompose. Эдакая ядреная утилита, которая позволяет запускать сервисы в k8s из конфигов docker-compose, или же конвертировать их в готовые конфиги k8s (а потом уже запускать их вручную, предварительно проверим и модифицировав). Конечно, стоит сразу сказать, что Kompose преследует скорее демонстративно-обучающие цели. Однако, он подойдет и для быстрого переноса существующих проектов на docker-compose. На офф.сайте смотрите варианты установки и базового использования. Актуальная версия kompose на момент написания статьи: 1.19.0 (f63a961c).

Итак, давайте рассмотрим все это на примерах. Возьмем docker-compose.yml из моей предыдущей статьи про docker-compose. У меня это лежит в $HOME/kompose/wordpress. Можно сразу создать такую же иерархию и напрямю скачать командой:

mkdir $HOME/kompose
mkdir $HOME/kompose/wordpress
cd $HOME/kompose/wordpress
curl -LO https://darkfess.ru/wp-content/uploads/2019/12/plus/docker-compose.yml

Далее, меняем версию манифеста у конфига docker-compose.yml:

sed -i 's/version: "3.7"/version: "3"/g' $HOME/kompose/wordpress/docker-compose.yml

Теперь сгенерируем на базе этого конфиги для k8s:

kompose convert

Увидим соответствующее сообщение вида:

INFO Kubernetes file "df-phpmyadmin-service.yaml" created
INFO Kubernetes file "df-wordpress-service.yaml" created
INFO Kubernetes file "df-maria-deployment.yaml" created
INFO Kubernetes file "df-mariadata-persistentvolumeclaim.yaml" created
INFO Kubernetes file "df-phpmyadmin-deployment.yaml" created
INFO Kubernetes file "df-wordpress-deployment.yaml" created
INFO Kubernetes file "wp-content-persistentvolumeclaim.yaml" created

Создадутся эти конфиги, вот они наглядно:

Есть также одна волшебная команда в kompose (up), которая позволяет запустить все сервисы сразу без генерации конфигов:

kompose up

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

kompose down

 

Конфиги для deployment, service, pvc и запуск

После convert, конфиги мы получили и теперь надо их отредактировать. В версии 1.16 k8s (а у нас в microk8s идет самая свежая стабильная), отключили старые «apiVersion: extensions/v1beta1» поэтому теперь нам надо все их заменить на актуальные «apiVersion: apps/v1». Тут обойдемся sed`ом:

sed -i 's/apiVersion: extensions\/v1beta1/apiVersion: apps\/v1/g' $HOME/kompose/wordpress/*

После этого можно попробовать стартануть, но теперь будет ругатся на поле «selector» которое также необходимо добавить в новой версии. Мне лень писать мульти-строчное регулярное выражение, поэтому давайте просто сделаем это ручками. Необходимо в конфигах *-deployment между строк «strategy: {}» и «template:» аккуратно вставить параметр (не забывайте про форматирование .yaml файлов, уровни и никаких TAB-ов.. label используем уже прописанный kompose):

   selector:
     matchLabels:
       io.kompose.service: <имя>

Также я внес некоторые правки в *-services: поменял порты для красоты (теперь 80:80). А еще, чтобы уж наверняка, прописал полные имена сервисов в переменных (это вида df-maria.default.svc.cluster.local). Создал дополнительный конфиг и сервис для доступа к базе (df-maria-service.yaml) по ее дефолтному порту 3306.

Все. После этого выполняем команду на запуск «всего»:

kubectl apply -f $HOME/kompose/wordpress

Если вам влом было проходить все эти шаги, можете сразу скачать и запустить готовый конфиг для всего* (df-wordpress-all.yaml):

kubectl apply -f https://darkfess.ru/wp-content/uploads/2019/12/plus/df-wordpress-all.yaml

*если интересно как собрать один большой конфиг из нескольких, то тут можно воспользоватся ‘kubectl kustomize’ и подложить ему соответствующий конфиг: kustomization.yaml

А вот и каждый конфиг по отдельности:

Проверить статус можно, допустим, так:

kubectl get deploy,svc,pods

После чего, если microk8s запущен локально, мы уже можем получить доступ к сервисам по их внутреннему IP (тип ClusterIP). Выглядит нам нужная строка так:

service/df-wordpress ClusterIP 10.152.183.138 <none> 80/TCP 10m

Таким образом, вбив в браузере адрес сервиса для wordpress, вы увидите что он доступен для первичной настройки (по 80 порту, соответственно).

А перейдя по адресу сервиса для phpmyadmin, авторизовавшись (по параметрам env из переменных в конфигах), мы сразу получаем доступ к нашей БД:

Конфиги для ingress, service и внешний доступ

Хм, теперь нам нужен внешний доступ к wordpress или phpmyadmin. Тут есть несколько вариантов, но мы рассмотрим три основных:

  • порт (правка service на NodePort)
  • поддиректория (через ingress)
  • поддомен (через ingress)

Важный момент, дальше я буду в качестве примера для внешнего доступа показывать phpmyadmin вместо wordpress. Т.к. wordpress держит параметр своего адреса в БД, и постоянно редиректит на него. По сути как бы держит его захардкоженым, что неудобно в нашем случае, т.к. мы будем переключать его туда-сюда. Мне лень с этим бодатся и каждый раз менять адрес (это пункт в настройках и параметр в БД), и лень искать способ обхода этого на стороне WP. Кто хоть когда-нить мигрировал wordpress знает о чем я говорю. Короче говоря, поэтому показываем на phpmyadmin, он не такой капризный.

 

NodePort

Самый простой способ. Но и достаточно кривой, подойдет когда надо быстро что-то пробросить, особенно для тестовых целей. В нашем распоряжении только диапазон портов 30000:32767. Можно отредактировать оригинальный конфиг в -service, но мы для наглядности и удобства сравнения, просто создадим еще один -service-nodeport. Это не добавит еще один сервис, просто отредактирует настройки текущего. Но у нас останется оба конфига на руках, старый и новый (можно все вернуть назад в любой момент, просто применив старый конфиг). Применяем:

kubectl apply -f $HOME/kompose/wordpress/df-phpmyadmin-service-nodeport.yaml

Либо (df-phpmyadmin-service-nodeport.yaml):

kubectl apply -f https://darkfess.ru/wp-content/uploads/2019/12/plus/df-phpmyadmin-service-nodeport.yaml

При просмотре статуса через kubectl get svc, увидим проброс:

service/df-phpmyadmin NodePort 10.152.183.211 <none> 80:30090/TCP 15m

Теперь phpmyadmin доступен из вне по порту (как по localhost, так и по IP нашего wordstation/server):

Итак, по порту пробрасывать мы научились.

 

Ingress (поддиректория)

Вообще, если крутить яйца ingress, то можно получить много чего интересного. Мы же рассмотрим в данном примере, чтобы можно было размещать разные сервисы в поддиректориях главного домена. Это будет выглядеть, например, как то так: darkfess.ru/service1,  darkfess.ru/service 2 и т.д. Не очень красивое решение, но зато можно быстро что-то прикрутить без дополнительных настроек DNS, ожидания его синхронизации и т.д (однако один раз вам, все же, придется DNS настроить на основном домене). Минусы тоже есть, некоторые сервисы могут держать в себе какой то захаркоженный путь и попросто не будут работать в поддиректории или будут работать криво.

Ну да ладно, поехали (для справки, я тестирую локально, поэтому сделал соответтвующую запись в /etc/hosts про FQDN darkfessus.ru)

kubectl apply -f $HOME/kompose/wordpress/df-ingress-path.yaml

Либо (df-ingress-path.yaml):

kubectl apply -f https://darkfess.ru/wp-content/uploads/2019/12/plus/df-ingress-path.yaml

Ага, здесь видим что то не так. Ошибка 404:

Запрос к phpmyadmin уходит и мы можем проверить это через логи (но phpmyadmin не понимает что это за адрес такой /phpmyadmin, потому что сам он работает в корне /):

kubectl logs deployment.apps/df-phpmyadmin -f

Нужно «помочь Даше найти дорогу, давайте все вметсе позовем Карту!» (с) Как мы и делали раньше, применяем другой конфиг ingress с тем же name и модифицируем его настройки (здесь появляется режим rewrite, и это функционал nginx, как вы уже наверное догадались):

kubectl apply -f $HOME/kompose/wordpress/df-ingress-path-rewrite.yaml

Либо (df-ingress-path-rewrite.yaml):

kubectl apply -f https://darkfess.ru/wp-content/uploads/2019/12/plus/df-ingress-path-rewrite.yaml

Теперь все. Вуаля! Заработало на поддиректории:

Подробнее об режиме rewrite можно почитать в офф.доках.

 

Ingress (поддомен)

Это, пожалуй, мой самый любимый способ. Он самый красивый, через поддомены сервисы выглядят очень окультуренными, по типа такого: service1.darkfess.ru, service2.darkfess.ru. Прописываем DNS записи на нужные сервисы, прописываем конфиг ingress — и пли! Все красиво, никаких портов, никаких лишних хвостов в виде поддиректорий и прочего.

Ну да ладно, поехали (для справки, я тестирую локально, поэтому сделал соответтвующую запись в /etc/hosts про FQDN svc1.darkfessus.ru):

kubectl apply -f $HOME/kompose/wordpress/df-ingress-fqdn.yaml

Либо (df-ingress-fqdn.yaml):

kubectl apply -f https://darkfess.ru/wp-content/uploads/2019/12/plus/df-ingress-fqdn.yaml

Вот теперь все. Заработало на поддомене:

На этой ноте пожалуй наш экскурс по ingress закончим. Я показал лишь часть его возможностей, есть еще и множество его различных контроллеров. Кроме NodePort, Ingress есть еще и тип сервиса LoadBalancer (Network Load Balancer). Мы его здесь не рассматривали, и его обзор не входит в рамки данной статьи.

Подводя итоги по Ingress хочется сказать, что это очень мощный и очень гибкий инструмент, в который по настоящему влюбляешься. Он просто значительно упрощает жизнь. Чтобы вывести WordPress через ingress, придумайте ему и пропишите DNS запись в виде поддомена. Потом зайдите через phpmyadmin и поменяйте эти параметры в базе на свой FQDN соответственно:

Helm

Пройдя весь этот путь до конца, вы наверное нехило так подзаебались… и возникает вполне логичный вопрос, а нельзя ли попроще? Можно! Дело в том, что здесь я взял wordpress+phpmyadmin+mariadb как хороший пример из уже написанной мной ранее статьи. По сути все это те компоненты, на которых работает мой блог. Мы его взяли, прежде всего, в обучающих целях, чтобы во всем хорошенько разобратся. Но, конечно же, можно сделать проще. Особенно когда дело касается каких то известных продуктов или сервисов.

У k8s есть свой package manager. Да-да, вы не ослышались. У «куба» есть свой менеджер пакетов, который позволяет с легкостью пера ставить огромные тяжеловестные продукты. И там, конечно же, есть и WordPress и многое другое.

На офф.сайте вы можете почитать описательную часть документации. А также, изучить местный Hub. Текущая версия Helm состоит из 2-х частей, клиентская часть (собственно, сам helm) и tiller (компонент, который устанавливается в k8s). Устанавливается все как обычно, через snap:

sudo snap install helm --channel=2.16/stable --classic

Вот и все. Дальше собственно устанавливаем компонент tiller в k8s:

helm init

Обновить его можно такой же командой с флагом —upgrade. Маленькая шпаргалка по использованию:

helm version
helm list
helm del <имя> --purge

Обратите внимание также и на совместимость версии k8s с каждой актуальной версией Helm. Я столкнулся с этим совсем недавно, когда вышла версия k8s 1.16, helm тогда без шаманств не работал. Ну а что дальше? Дальше идите на HelmHub, ищите нужный софт и ставьте его по инструкции внутри. Помимо официальных, очень много готовых собранных образов идет от bitnami, например. Идите в Hub, там есть что посмотреть.

Собственно, на этом пожалуй, этот краткий обзор по Helm я закончу. А все потому, что скоро выйдет новая мажорная версия Helm 3.0, и она принесет в себе множество новых изменений. Одной из основных будет отказ по Tiller. но это уже совсем другая история, может быть я лучше на нее отдельный обзор напишу.

 

Итоги

Не люблю я писать эпилоги. Будут ли еще статьи про k8s? Очевидно, что да.  А так, данный материал получился довольно большого объема, да и писал я его достаточно долго. Бесят бессконечные редактирования! Но в целом.. хочется верить, что данный материал окажется вам полезен в понимании k8s и работе с ним. В частности с microk8s, если вы с ним еще не знакомы. Ведь это чрезвычайно удобная и крутая штука, на которой спокойно можно построить все, пожалуй, кроме серьезных больших production сред. Но зато можно сделать переезд на этот самый «бАльшой» prod максимально безшовным.

Добавить комментарий