Comments 43
Есть какая-то задача, которую вы не можете решить? Тогда опишите конкретнее о задаче.
Для начала почитайте документацию k8s про Cluester Networking, Services и Ingress. Многое встанет на свои места.
Можно копнуть глубже и почитать про устройство overlay сети в общем
Посмотри для начала вот это видео, меня оно вдохновило:
www.youtube.com/watch?v=CgCLPYJRxbU&t=1406s
Если чисто докер, без куба, то https://docs.docker.com/engine/swarm/ingress/ гляньтк
У flannel есть режим работы host-gw, когда все ваши машины в пределах одного сегмента L2, там минимальный оверхед — по сути он просто все забивает в таблицу маршрутизации.
С другой стороны, calico так тоже может, но у calico еще и NetworkPolicy есть.
А почему не https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd? Зачем патчить контроллер?
Мне видится мой вариант проще и надежнее. Не нужно клонировать стороннюю репу, не нужно разбираться с Go и ловить баги сторонних разработчиков.
У меня есть пара замечаний.
Ваш k8s получился с одним мастером, что при трёх серверах как-то не понятно. Я устанавливал через kubespray, плюс тут в том, что у меня получаеся кластер с мультимастером и есть лёгкая возможность добавлять новые ноды (путём записи в inventory файл). Так-же можно позже делать обновления всего кластера, я так делал, когда обновлял с 1.7 на 1.8.
И второй момент это StorageClass, с этим пунктом я не очень уверен и может быть путаю. Как я помню, для использования rbd, перед этим его (rbd) надо сперва создать. В принципе в этом нет ничего сложного, но для этого его надо в ручную создать (или через скрипты), что вроде не очень удобно. Может быть использовать лучше cephfs и её потом монтировать в поды, для каждого можно создавать отдельные папки. Как-то так:
volumeMounts:
- name: icingaweb2
mountPath: /icingaweb2
...
volumes:
- name: icingaweb2
hostPath:
path: /a/data/monitoring.adito.de/icingaweb2
То есть "/a/data" это папка на cephfs, а остальное создаётся при запуске pod/deployment
и для rbd и для cephfs есть контроллеры StorageClass, которые создают хранилище сами.
Разделы создаются, форматируются и монтируются автоматически.
CephFS и Ceph (RBD) это немного разные вещи, даже сильно разные)
CephFS требует создания раздела для данных и мета-данных (да, их нужно создавать самостоятельно). Далее, такие разделы монтируются с помощью обычного mount, например так:
mount -t cehp kub01:.....:/ /mnt/, либо через fuse.
Ceph (RBD) — создает раздел и устройство автоматически c помощью утилиты rbd, выглядит это так:
rbd create rbd/aaa --size 100M # создаем раздел
rdb map rbd/aaa # создаем устройство, вида: /dev/rbd0
mkfs.ext3 /dev/rbd0 # форматируем
mount /dev/rbd0 /mnt/disk # монтируем
Я использую именно RBD, и k8s эти команды выполняет самостоятельно)
Для контейнеров типа MySQL где предполагается их постоянные данные хранить?
Резюмирую: k8s не готов к работе с сервисами, требующих больших дисковых ресурсов (производительности).
Рассматривали ли вы альтернативы Ceph? Какой-либо glusterfs или иное?
Да, можете еще рассказать о сетевой инфраструктуре в вашем случае? Как будет себя чувствовать дисковый кластер (и k8s) при высокой нагрузке и слабым uplink между серверами?
При всём желании не получится описать в одной статье всё и про всё.
Не очень понятен вопрос о базе без пароля выставленную во внешнюю сеть. О чем это?
Если вы запустите какую либо БД (или вообще любое ПО) через k8s, то она не выставляется во внешнюю сеть, а наличие в ней пароля зависит от деплоя.
Для того, чтобы понять как работает k8s со внешней средой, советую почитать про Ingress.
Например при настройках по умолчанию может остаться доступ к API без пароля или с каким-то известным паролем, заданным при установке по умолчанию.
Тогда без дополнительной настройки (смены пароля, закрытие всех путей доступа к API и методов авторизации, кроме тех что заданы явно) — кластер получается открытым для для внешних систем и кто угодно сможет запускать там свои образы.
k8s требует распределенного файлового хранилища.я может что то пропустил, но с каких пор k8s стал именно требовать распределенное хранилище? Сама суть кубернетиса в том, что у вас запускаются контейнеры и потеря контейнера никак не должна влиять на работу кластера. При потере контейнера/ноды scheduler k8s просто запустит их на другой ноде(подах)
Не увидел настройку докера для работы с flannel. Каким образом в вашем случае поды запущенные на разных нодах, а по дефолту докер использует подсеть 172.17.0.0/16, будут общаться между собой?
Если БД не сильно нагружена, то можно разместить ее в Cephда вы батенька знаете толк в извращениях
я может что то пропустил, но с каких пор k8s стал именно требовать распределенное хранилище?
Это написано в разделе про «Диски». Если приложению нужен диск (storage), то да, я повторюсь: «требует», и в статье я объяснил почему. Если приложению диск не нужен, то и требования не возникает.
Не увидел настройку докера для работы с flannel. Каким образом в вашем случае поды запущенные на разных нодах, а по дефолту докер использует подсеть 172.17.0.0/16, будут общаться между собой?
Когда k8s запускает pod (докер), он выделяет свободный IP адрес из диапазона flannel, и назначает его контейнеру. Ничего дополнительно конфигурировать не нужно.
Когда k8s запускает pod (докер), он выделяет свободный IP адрес из диапазона flannelочень странно, а откуда докер вообще узнает о существовании flannel? Насколько я помню, то по дефолту pod'ы поднимались в дефолтной подсети docker и только после явной правки конфига docker оно начинало работать как надо.
У них собственно и в документации об этом говорится. И именно поэтому flannel генерирует файл /var/run/flannel_docker_opts.env. Например у меня в тестовой среде он имеет вид
# cat /var/run/flannel_docker_opts.env
DOCKER_OPT_BIP="--bip=172.16.2.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1450"
Соответственно на каждой ноде flannel получает свою подсеть /24, запрашивая ее у etcd
Если приложению нужен диск (storage), то да, я повторюсь: «требует», и в статье я объяснил почемулично мне не понятна формулировка «Если приложению нужен диск (storage)» — в каких случаях приложение будет требовать диск? Например при запуске nginx диск будет востребован? При этом нигде не упоминается stateful/stateless приложения и их отличия.
И пробросим порт 8001 с вашей рабочей машины до сервера kub01:для этих вещей специально придумали kubectl proxy --port=8001
ssh -L 8001:127.0.0.1:8001 -N kub01 &
очень странно, а откуда докер вообще узнает о существовании flannel?
Этого я не знаю. К счастью, k8s работает очень прозрачно, и многое от нас скрыто под капотом (да, туда можно залезть, но если всё и так работает, то зачем?). Хотите верьте, хотите нет, но k8s запускает pod-ы c уже настроенной сетью, и нам ничего дополнительного делать не нужно.
Если у вас есть желание разобраться в этом глубже, добро пожаловать на Хабр со своей статьей)
лично мне не понятна формулировка «Если приложению нужен диск (storage)» — в каких случаях приложение будет требовать диск?
Тут два пути:
1) Вы сами создаете нужный вам контейнер, и пишите к нему YAML файл, где и просите у k8s (claim) о диске (если он вам нужен).
2) Используете helm, где для каждого проекта описана необходимость в диске
Вообще, постановка вопроса странная: мне кажется, вы просто обязаны понимать, что делаете и как это должно работать, и нужен ли вам диск.
для этих вещей специально придумали kubectl proxy --port=8001
Спасибо, не знал)
мне кажется, вы просто обязаны понимать, что делаете и как это должно работать, и нужен ли вам диск.
Не все разработчики понимают нужен ли им диск, по крайней мере диск с rw правами. На прямой вопрос нужен ли rw доступ куда-то на диск, говорят "нет, мы не используем в приложении работу с файлами, у нас всё в базе". А потом выясняется, по логам ошибок, что они -то не использует, а вот рантайм под капотом использует: сессии, временные файлы какие-то, иногда даже исполняемые. Ну и собственно логи :)
С чем столкнулся я:
1) Прежде всего нужно удалить из /etc/hosts связку хостнейма и 127.0.0.1, в противном случае команда ceph-deploy не пройдет и упадет с ошибкой:
[ceph_deploy][ERROR ] UnableToResolveError: Unable to resolve host: kub01
2) На всех тачках нужно поставить python. Без него все тот же ceph-deploy будет валиться с ошибкой, только уже с другой:
[kub02][INFO ] Running command: ssh -CT -o BatchMode=yes kube02
bash: python: command not found
3) В пункте про обмен ssh ключами было бы не лишним указать от имени какого юзера мы обмен ключами делаем. Потому что если мы распыляем ключ рута и коннектимся от имени рута, то нужно разрешить ssh коннект от рута, потому что в Ubuntu 16.04 по дефолту он запрещен.
4) После правки конфига контроллера нужно производить какие либо операции? У меня спустя даже полчаса ничего не произошло. В итоге помог ребут тачки.
5) На шаге присоединения нод не хватает однозначности. Что мы в итоге делаем, новый токен или используем старый. Если используем старый то как собрать команду приведенную вами? А самое главное IP 8.8.8.8 очень путает.
6) Еще было бы интересно организовать доступ к подам снаружи без проброса через ssh.
6)Что бы можно было ходить к подам снаружи можно взять другой сетевой плагин, например calico.
Отдельно стоит отметить, что kube-adm решение не для production.
p.s. Самую активную помощь по продуктам описанным в статье можно получить в каналах телеграм.
t.me/kubernetes_ru
t.me/ceph_ru
1) Прежде всего нужно удалить из /etc/hosts связку хостнейма и 127.0.0.1, в противном случае команда ceph-deploy не пройдет и упадет с ошибкой:
Вы что-то делали не так) Разумеется, если вы используете домен вида: kub01, то он должен резолвится. Если он прописан в /etc/hosts как 127.0.0.1, то он будет резолвится, и такой ошибки быть не должно. И да, наверное его лучше не прописывать как 127.0.0.1.
Я на эту проблему не попадал, так как hostname серверу задавал уже после инсталляции сервера.
2) На всех тачках нужно поставить python. Без него все тот же ceph-deploy будет валиться с ошибкой, только уже с другой:
У вас Ubunta? Странно, что python не поставился по зависимостям, при установке самого ceph-deploy…
Я python ставил отдельно, так как была необходимость запускать ansible (для своих целей).
коннектимся от имени рута, то нужно разрешить ssh коннект от рута, потому что в Ubuntu 16.04 по дефолту он запрещен.
Спасибо за замечание. Подумаю как это решить по изящнее)
В итоге помог ребут тачки.
Это какой-то windows-way. Всегда бейте себя по рукам за такое)
У меня нет четкого ответа на это. Обычно, k8s сам замечает изменения и перезапускает controller. Но если этого не произошло, то можно перезапустить: kubelet и docker. Если кто знает, как это сделать красиво, отпишитесь.
5) На шаге присоединения нод не хватает однозначности. Что мы в итоге делаем, новый токен или используем старый. Если используем старый то как собрать команду приведенную вами? А самое главное IP 8.8.8.8 очень путает.
Если у вас есть «старый» токен, то можно использовать его. Самое простое, это сохранить команду «присоединения», которая пишется после инсталляции k8s (kubeadm init ...).
Если по каким-то причинам, у вас нет этой команды, то смело создавайте новую. Токен присоединения имеет срок истечения, и он пропадет спустя два дня. Главное, успеть присоедениться )
Если же, вы присоединяете ноды спустя два дня, вам всегда потребуется создавать токен присоединения.
Чем пугает 8.8.8.8? его нужно заменить на IP вашего мастера.
6) Еще было бы интересно организовать доступ к подам снаружи без проброса через ssh.
Зачем так? Делайте сервис + Ingress.
Но если очень хочется, то iptables вам в помощь (PREROUTING, POSTROUTING).
Вы что-то делали не так) Разумеется, если вы используете домен вида: kub01, то он >должен резолвится. Если он прописан в /etc/hosts как 127.0.0.1, то он будет резолвится, >и такой ошибки быть не должно. И да, наверное его лучше не прописывать как 127.0.0.1.
Да я просто наткнулся на ошибку и первое что посоветовал гугл это как раз: "In /etc/hosts, remove the hostname of loopback address. Add a line of real IP address and hostname correspondence, then problem solved."
У вас Ubunta? Странно, что python не поставился по зависимостям, при установке самого >ceph-deploy…
Я python ставил отдельно, так как была необходимость запускать ansible (для своих >целей).
Да Ubuntu 16.04. Питон автоматом поставился только на мастер. А на остальных тачках команды python нет, только python3 из коробки.
Это какой-то windows-way. Всегда бейте себя по рукам за такое)
Я хочу чтоб вы правильно понимали мой подход к данной статье)
Я рассчитывал просто на copy-paste без напряга мозгов, что покрутить/посмотреть.
Поскольку для серьезного деплоя есть тот де kubespray.
Если у вас есть «старый» токен, то можно использовать его. Самое простое, это >сохранить команду «присоединения», которая пишется после инсталляции k8s (kubeadm >init ...).
Если по каким-то причинам, у вас нет этой команды, то смело создавайте новую. Токен >присоединения имеет срок истечения, и он пропадет спустя два дня. Главное, успеть >присоедениться )
Если же, вы присоединяете ноды спустя два дня, вам всегда потребуется создавать токен >присоединения.
ИМХО если нам нужен токен, тогда нужно описать на этапе init о том что нужно сохранить команду присоединения либо уж однозначно создавать новый токен на этапе коннекта нод.
Чем пугает 8.8.8.8? его нужно заменить на IP вашего мастера.
Пугает тем что это гугловый DNS. Вводит в заблуждение тем что не понятно, толи автор реально просто юзает гугловый DNS для каких то целей присоединения (ну мало ли что там может понадобиться), толи его надо заменить на мастер. Вот реально, лучше измените на какой нибудь 1.2.3.4 или вообще %master_ip%.
Зачем так? Делайте сервис + Ingress.
Но если очень хочется, то iptables вам в помощь (PREROUTING, POSTROUTING).
Да в том что и дело что я и еще не малый процент аудитории не знает как правильно. И понятия не имеет о том что такое Ingress :)
Отсюда и вопросы такие.
Еще кстати момент. На этапе создания конфига kube-controller-manager copy-paste сработает не правильно, потому что при вставке баш попытается отрезолвить переменные ${KUBERNETES_DOWNLOAD_ROOT},${KUBERNETES_COMPONENT} и тп, а их нет в том окружении в котором делаем вставку, они появятся только при сборке, но на этапе сборки на их месте будет уже пустота.
Весь план сводится к запуску собственно кубернетеса любым способом и дальше через kubectl деплоится ceph за счет «родного» PVC ну и использует относительно новую абстракцию операторов.
Если интересно, могу в песочницу написать howto на базе любого облака.
Лично мне пока боязно «запихивать» ceph в контейнеры. Опять же, тут нужно пояснить, какую часть ceph мы собираемся запускать в контейнерах.
Раньше были приблуды типа только клиентов для маунта экспортированной вне кубернетеса файловой системы, но это не тру контейнер вей.
Тут же интеграция на основе и в рамках API самого кубернетеса. Для примера можете посмотреть как coreos написали операторы для кубернетеса.
Напишу статью – сюда линк положу, если не забуду.
У меня ceph в контейнерах (официальный контейнер) в виде статических манифестов kubelet. С одной стороны удобно и изоляция, и обновлять приятно, и мониторить можно из k8s, с другой — хранилище полностью отделено от control plane куба (и управляется ансиблой).
Запускаем полноценный кластер на Kubernetes с нуля на Ubuntu 16.04