Skip to content

Otus-DevOps-2022-05/kaineer_microservices

Repository files navigation

kaineer_microservices

Проверки от OTUS

Курс «DevOps, практики и инструменты», часть 2, микросервисы.

kubernetes-3 [31]

  • Снова поднял кластер на yandex cloud
  • Втянул содержимое, полученное в конце прошлой домашки
  • Поигрался со скейлом для kube-dns и обнаружил, что он исчезает, вернул его на место
  • Поменял тип ui-service на LoadBalancer
  • Проимпортировал компонент для создания IngressController-а
  • Добавил ui-ingress для доступа к ui-service
  • Открыл список ingress-ов, посмотрел IP единственного доступного, открыл его в браузере, увидел работающую приложеньку
  • Посмотрел в методичку, увидел упоминания gcloud, понял, что, скорее всего, дальше ничего сделать не получится
  • Допилил ветку, чтобы автопроверки были довольны

kubernetes-2 [29]

  • Установил локально minikube
  • Поднял и отладил в нем приложение
  • Создал кластер на yandex.cloud
  • Поднял приложение в кластере на yandex.cloud
  • Приложил (на всякий случай) картинку с web-интерфейсом:

Веб-интерфейс кластера с подами

  • Грохнул кластер на yandex.cloud

kubernetes-1 [27]

  • Поднял ноды через tf

  • Создал *-deployment файлы, скопировал на первую ноду

  • Установил kube{adm,let,ctl}

  • Дальше пошел ставить сетевой плагин

  • Скопировал по scp *-deployment.yml файлы

  • Запустил все на исполнение через kubectl apply -f <filename>

  • Посмотрел, поумилялся, все грохнул

  • Запушил все что было в PR

  • Посмотрел, чего просят проверки

  • Поискал pdf-ку про "kubernetes the hard way"

  • (оставил себе заметку на будущее поискать такой ресурс)

  • Нагло сделал вид, будто у меня есть такие файлы (mkdir, touch, все дела)

logging-1 [25]

  • Залез в репозиторий express42/reddit и посмотрел, сколько в нем веток
  • Отыскал уже склонированный reddit.git и перешел в нем в ветку logging
  • Почистил каталог src (оставив свои makefile и скрипты) и скопировал репозиторий себе
  • Построил образы, подкрутил docker_build.sh, чтобы не мешал при запуске make build
  • Дошел до построения kaineer/fluentd
  • Перестроил alpine-образы ui и comment
    • Использовал ruby:2.2-alpine
    • Указал точные версии для base-build и ruby-bundler
  • Обнаружил, что kibana ничего не получает через fluentd
  • Профилонил поиск по логам fluentd и подергал знающего человека
  • После этого fluentd-таки отдал свои данные в elasticsearch
  • Посмотрел на данные из post-py (готовые json)
  • Посмотрел на данные из ui (фильтр, парсер на регулярках)
    • В процессе выяснилось, что grok все-таки не грузится :(
  • Подтянул zipkin и попытался запустить. Заработало

monitoring-1 [22]

  • Скопировал tf-код для создания VM, скопировал .envrc и запустил

  • Получил VM, на которой уже установлены docker и docker-compose

  • Скачал prom/prometheus:latest

  • Запустил prometheus и открыл по :9090

  • В очередной раз убедился, что использовать *:latest в методичках — неправильно. Так же, как и в ansible-рецептах, например. Ну, т.е. то, что я увидел в браузере с картинками в презентации не билось процентов на 60. В частности, на картинке были вкладки Graph и Console, а в браузере Table и Graph :)

  • Кликнул по кнопке "Metrics Explorer", рядом с кнопкой "Execute", повыбирал наугад метрики, посмотрел на таблички. Попырил на график "go_memstats_alloc_bytes". Красивое. Обнаружил возможность визуально растягивать график, указывая левую и правую границы.

  • Остановил prometheus

  • Перенес docker-monolith внутрь каталога docker

  • В инструкциях по сборке докер-образа обнаружил номер версии prometheus, на которую нужно ориентироваться (2.1.0)

  • Еще раз построил образы сервисов (напрягаться почти не пришлось)

  • Скопировал первый найденный docker-compose в docker/

  • Добавил в .envrc версии собранных образов

  • Долго искал, почему не поднимается post-py

  • Узнав, долго матерился. Но не так долго, как искал :(

  • Увидишь :latest в docker-compose - дай по башке автору файла.

  • Наконец-то смог запустить на одной машине prometheus и приложеньку

  • Подергал node-exporter

  • Посмотрел, как он отслеживает загруженность локального процессора

  • Запушил образы kaineer/{ui,post,comment,prometheus} на hub.docker.com

  • Забил на задания со звездой :(

gitlab-ci-1 [20]

  • Поднят из старых и уже пыльных архивов механизм раскатки приложений в облаке
  • Сделан по максимуму подготовленный к запуску docker-compose образ в yandex.cloud
  • Подготовлено три (можно было, наверное, два) плэйбука. Первые два для подтягивания зависимостей в packer, третья - для подготовки, закачки docker-compose.yml и запуска docker-compose
  • В итоге, впрочем, выяснилось, что если запускать службы через ансибловский модуль docker_compose, то docker-compose ps ничего не покажет. Через это имел некоторое количество ругательств, но, в конце концов, просто принял, как есть.
  • В конце-концов дождался запуска gitlab в контейнере.
  • Поискал на youtube (сам поражаюсь) рецепт - где найти пароль в gitlab. Нашёл.
  • Зарегистрировал runner (поднятие роутера есть в docker-compose.yml.j2)
  • Быстренько потыкал в кнопки, подобавлял стэйджей в .gitlab-ci.yml.
  • Пришел к выводу, что если VM слабенький, ставить в before_script подтягивание бандлов - такое себе решение. Наверняка, в хороших, правильных пайплайнах задействовано кэширование.
  • Удалил из корня reddit/ (хотя в истории намусорил, конечно).
  • Удалил VM
  • Скопировал docker-compose.yml.j2 в папку gitlab-ci, переименовал, как надо и заменил external_ip на 55.66.77.88
  • Перенес раскатку инфраструктуры в подпапку gitlab-ci/infra

docker-4 [18]

docker networks

  • Скачан образ joffotron/docker-net-tools

  • Запущен ifconfig в режиме network none

    • команда make network_none в каталоге src
    • Вывод показал наличие лупбэка и больше ничего
  • Запущен ifconfig в режиме network host

    • команда make network_host в каталоге src
    • Вывод показал все сетки, доступные на host-машине
  • Запущен nginx в режиме network host несколько раз

    • В течение какого-то времени вновь запущенный контейнер оставался активным, потом умирал, т.к. не мог получить в пользование порт
  • Задумался, как выполнить задание на docker-host, ведь его у меня нет

  • Запустил VM в VirtualBox, в ней - debian

  • Поставил на нём докеровские пакеты

  • Сделал ln -s /var/run/docker/netns /var/run/netns (почему-то мне кажется, что на локальной OS этого лучше не делать)

  • Запустил в отдельном окне внутри debian (на дополнительном мониторе, хвастаюсь) watch "sudo ip netns".

    • Пока запускал nginx в сетке host, отличий не обнаружил, namespace оставался один - default.
    • Когда запустил несколько раз в none, увидел, что на каждый запуск приводит к появлению нового namespace. Например, так выглядел вывод sudo ip netns после двух запусков с network none
41b82aec2fd6
b3503bb5cd01
default
  • Ни с того ни с сего вспомнил, что неплохо бы перенести старые ворклоги в readme. И перенёс.

  • Начало следующей части задания было знакомо из docker-2, поэтому неудачный запуск bridge network пропустил

  • Успешный запуск можно посмотреть в src/scripts/run.sh или src/scripts/run_env.sh

  • Собрал запуск с раздельными сетями в src/scripts/run_net.sh

  • Список сетей полученных в проекте получил через docker network ls | grep _net:

ef5e35431b04   back_net    bridge    local
fdb8a7e79817   front_net   bridge    local
  • brctl show без указания id показывает полный список (вместе с интерфейсом смамого docker-а)
bridge name     bridge id               STP enabled     interfaces
br-ef5e35431b04         8000.02420b717a11       no
br-fdb8a7e79817         8000.02420d42b4d9       no
…
  • Посмотрел на вывод iptables. Понял мало, но поразился красоте. Поставил себе отметку «почитать про iptables на досуге». Выглядело это счастье так:
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.1.0/24          0.0.0.0/0
MASQUERADE  all  --  10.0.2.0/24          0.0.0.0/0
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
LIBVIRT_PRT  all  --  0.0.0.0/0            0.0.0.0/0
  • Ага, это было уже после того, как я убил все контейнеры. С поднятым приложением это выглядело чуть длиннее:
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.1.0/24          0.0.0.0/0
MASQUERADE  all  --  10.0.2.0/24          0.0.0.0/0
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
LIBVIRT_PRT  all  --  0.0.0.0/0            0.0.0.0/0
MASQUERADE  tcp  --  10.0.1.2             10.0.1.2             tcp dpt:9292
  • Обнаружил правило перенаправления по порту 9292 в цепочке DOCKER
  • ps aux | grep docker-proxy | grep -v grep выдало целых два процесса

docker-compose

  • Собрал docker-compose.yml из примера в gist, в процессе закомментировал ключи <sevicename>.build (уже построено, зачем второй раз бегать)

  • Убил старый набор контейнеров, поднятый скриптом

  • Ещё раз почитал методичку, обнаружил конструкцию export USERNAME=…

  • Поднял docker-compose up

    • Обнаружил, что volume, созданный докером не втягивается
    • Зато созданный docker-compose остается живым между запусками
  • Посмотрел на docker-compose ps, обнаружил список запущенных контейнеров

    • Правда контейнер комментариев почему-то не был запущен
    • Поменял контейнер на собираемый из ubuntu и всё заработало
    • Похоже, что сборке kaineer/comment:2.0 чего-то не хватает
  • Настроил src/.envrc для запуска docker-compose с параметрами: имя пользователя, версии образов, порт, на котором нужно открывать страничку

  • Проверил, что вариант с .env тоже работает и принял это к сведенью

  • Добавил .env.example, вдруг его потребуют проверки?

  • Чтобы поменять базовое имя проекта достаточно указать переменную окружения COMPOSE_PROJECT_NAME как указано в .env.example :)

  • Поискал в PR предыдущего потока, как указать в docker-compose.override.yml команду для контейнера

  • Погуглил на предмет задания volume-ов из файловой системы для проектов

  • Решил, что пока хватит

  • Зафйэлил сделать коммит правильно

  • Перекинул worklog в readme

  • Исправил Dockerfile.alpine для ui, перестроил образы, теперь поднимается docker-compose.override.yml

docker-3 [17]

  • Скачал hadolint, настроил чтобы работал (ну так, семь на восемь)

  • Скачал архив reddit-microservices, распаковал в microservices/src, удалил архив

  • Создал src/post-py/Dockerfile, допилил до состояния, в котором он строится

  • Довел до состояния, когда не ругается, строится и запускается

  • Повторил для src/comment/Dockerfile

  • Повторил для src/ui/Dockerfile

    • Недокопировался каталог view
    • Добавил создание каталога /app/view и копирование в него
  • Теперь скрипт поднимает приложение целиком и его видно в http://localhost:9292

  • Пробую прокинуть переменные

    • Хосты поднимаются
    • Переменные в них передаются
    • На выходе ничего нет
    • Нашел опечатку, заработало
  • Сделал в скрипте передачу переменных, все поднимается

  • Перенес src/comment на базу ruby:2-alpine

  • Перенес src/ui на базу ruby:2-alpine

  • Поправил скрипт для запуска с новыми образами

  • Добавил volume и поправил скрипт, чтобы mongo стартовал с этим volume-ом

docker-2 [16]

  • Вдоволь накекался с опечатки dockermonolith/docker-monolith
  • Решил остановиться на варианте с дефисом, пусть будет пока
  • Посмотрел на ссылку про установку docker и решил, что я самый умный и у меня есть apt, а с остальным постепенно разберусь (так и вышло).
  • Поставил docker и docker-compose.
  • Погуглил в поисках docker-machine.
  • Поразбирался, как при помощи docker swarm делать то же самое, что делалось при помощи docker-machine.
  • После визита в чатик удостоверился, что docker swarm не будет за меня ставить docker на удаленную машину.
  • Смирился с этим и установил на удалённую машину docker сам.
  • Потыкался в основные команды docker, нашёл пару интересных (например system df). Остальные, разумеется, уже знал.

Примерно тут заканчивается первая домашка и начинается вторая

  • Откопал свои настройки для yc cli
  • Запустил swarm manager на удалённом компе (у него ip-шник публичный)
  • Подцепил к нему swarm worker на своём
  • В процессе построения docker image много думал, сравнивал с предыдущими заданиями и нашёл два отличия:
    • устанавливается mongodb-server (возможно, это и правильно) вместо mongodb-org
    • зачем-то устанавливается bundler не через apt
  • После исправления этих двух отличий к исходному состоянию, всё снова запустилось.
  • Потом построил docker image и запустил на своём компе
  • .. и быдыщ открыл его с адреса удалённого компа. Вот тут я, конечно, некий дзен ощутил :)
  • Зарегистрировался на hub.docker.com и загрузил на него kaineer/otus-reddit:1.0
  • Слегка схалявил в задании со звездой:
    • Создал шаблон для packer, чтобы строить образ
    • Создал конфигурацию terraform, которая поднимает с этим образом инстанс, настраивает на этом инстансе питон, докер и обвязку питон-докер, чтобы запускать модуль ansible docker_container и через провижнер local-exec сначала слепил инвентори для ansible, а потом, пользуясь этим inventory, установил и запустил образ приложеньки на инстансе.
    • К этому моменту я был несколько в офигевшем состоянии и за раскатку на несколько инстансов решил не замахиваться.