Сегодня мы поговорим о Kubernetes: в частности о теме microk8s vs minikube, kompose и helm. Обзорная экскурсия, так сказать.
Написать статью о kubernetes (он же k8s или просто куб) руки у меня чесались уже довольно давно. Я активно работаю с ним уже больше года. Делится конкретным опытом внедрений в рамках данной статьи цели у меня не стоит, однако я опишу некоторые моменты на обучающих примерах. Так будет более последовательно и понятно. Можно назвать данный материал обзорным, который рассчитан на читателя, не знакомого с k8s. Однако я убежден, что каждый здесь сможет что-то для себя интересное, особенно в знакомстве с microk8s. Начнем с оглавления:
- МикроКуб или МиниКуб? (microk8s vs minikube)
- Пощупайте самостоятельно
- Kompose, что еще за зверь такой
- Конфиги для deployment, service, pvc и запуск
- Конфиги для ingress, service и внешний доступ
- Helm
- Итоги
Вообще, знакомство с кубом стоит начинать из далека. С 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
Создадутся эти конфиги, вот они наглядно:
- df-maria-deployment.yaml
- df-mariadata-persistentvolumeclaim.yaml
- df-phpmyadmin-deployment.yaml
- df-phpmyadmin-service.yaml
- df-wordpress-deployment.yaml
- df-wordpress-service.yaml
- wp-content-persistentvolumeclaim.yaml
Есть также одна волшебная команда в 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
А вот и каждый конфиг по отдельности:
- df-maria-deployment.yaml
- df-maria-service.yaml
- df-mariadata-persistentvolumeclaim.yaml
- df-phpmyadmin-deployment.yaml
- df-phpmyadmin-service.yaml
- df-wordpress-deployment.yaml
- df-wordpress-service.yaml
- wp-content-persistentvolumeclaim.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 максимально безшовным.