Skip to content

nshvyryaev microservices repository

License

Notifications You must be signed in to change notification settings

Otus-DevOps-2020-02/nshvyryaev_microservices

Repository files navigation

nshvyryaev_microservices Build Status

nshvyryaev microservices repository

ДЗ12 - Docker 2

  • Настроены репозиторий и Travis
  • Использованы базовые команды для работы с контейнерами: run, start, create, commit, inspect, ps
  • (*) Выполнено сравнение вывода команды inspect для контейнера и образа
  • Образ запушен в Docker Hub
docker tag reddit:latest nikitagsh/otus-reddit:1.0
docker push nikitagsh/otus-reddit:1.0

Как запустить проект

  • Предварительно нужно авторизовать приложения с помощью команды gcloud auth application-default login
  • Для запуска docker host в GCP выполнить команду
docker-machine create --driver google  --google-machine-image https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/family/ubuntu-1604-lts  --google-machine-type n1-standard-1  --google-zone europe-west1-b  docker-host
  • Начать использовать docker host можно командой eval $(docker-machine env docker-host)
  • Для сборки образа выполнить команду docker build -t reddit:latest . в папке dockermonolith
  • Для запуска контейнера из собранного образа - docker run --name reddit -d --network=host reddit:latest
  • Запустить локально из запушенного образа - docker run --name reddit -d -p 9292:9292 --rm nikitagsh/otus-reddit:1.0

(*) Создание окружения с помощью Packer, Terraform, Ansible

  • Добавлена папка docker-monolith/infra
  • С помощью Packer собран образ docker-host, содержащий установленный Docker
  • С помощью Terraform можно запустить конфигурируемое переменной количество инстансов и разрешить трафик на порт 9292
  • Ansible устанавливает необходимые для своей работы с докером плагины и запускает контейнер с приложение на каждом инстансе, полученном с помощью динамического inventory.
  • Инструкции по запуску инфраструктуры можно найти в infra README

Примечания

  • Для доступа к приложению нужно открыть порт 9292 (использовать скрипт gcloud_add_firewall_rule_puma.sh):
gcloud compute firewall-rules create reddit-app \
 --allow tcp:9292 \
 --target-tags=docker-machine \
 --description="Allow PUMA connections" \
 --direction=INGRESS

ДЗ №13 - Docker 3

  • Скопирован код микросервисов
  • Созданы Dockerfile для каждого сервиса:
  • Все файлы пропущены через линтер командой docker run --rm -i hadolint/hadolint < Dockerfile
  • Найденые проблемы исправлены
  • Выполнена сборка образов командами
    • docker build -t nikitagsh/post:1.0 ./post-py
    • docker build -t nikitagsh/comment:1.0 ./comment
    • docker build -t nikitagsh/ui:1.0 ./ui
    • Сборка ui началась с шага копирования Gemfile
  • Запущено приложение командами, запущено приложение, проверена работоспособность
  • (★) Запуск с другими алиасами:
    • Остановить все контейнеры docker kill $(docker ps -q)
    • docker run -d --network=reddit --network-alias=post_db_alt --network-alias=comment_db_alt mongo:latest
    • docker run -d --network=reddit --network-alias=post_alt -e POST_DATABASE_HOST=post_db_alt nikitagsh/post:1.0
    • docker run -d --network=reddit --network-alias=comment_alt -e COMMENT_DATABASE_HOST=comment_db_alt nikitagsh/comment:1.0
    • docker run -d --network=reddit -e POST_SERVICE_HOST=post_alt -e COMMENT_SERVICE_HOST=comment_alt -p 9292:9292 nikitagsh/ui:1.0
  • Изменен образ UI, сборка началась с 1 шага, так как изменился базовый образ
  • (★) Образ UI собран из ruby:alpine, понадобилось добавить build-base для сборки приложения.
    • Образ на основе FROM ruby:2.2-alpine с удалением build-base вышел 162 Mb, но теперь установка пакетов не кэшируется (Dockerfile.1)
    • Образ собранный из FROM alpine:3.11.6 без удаления build-base весит 253 Mb (Dockerfile)
  • Создан Volume docker volume create reddit_db
  • Созданный volume подключен к базе с помощью флага -v reddit_db:/data/db. Теперь посты переживают перезапуск контейнеров.

Как запустить

  • Команды для запуска:
    • docker network create reddit
    • docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db -v reddit_db:/data/db mongo:latest
    • docker run -d --network=reddit --network-alias=post nikitagsh/post:1.0
    • docker run -d --network=reddit --network-alias=comment nikitagsh/comment:1.0
    • docker run -d --network=reddit -p 9292:9292 nikitagsh/ui:3.0

Как проверить

  • Выполнить docker-machine ls для получени IP адреса docker-host
  • Зайти на http://<docker-host-ip>:9292/
  • Написать пост

ДЗ №14 - Docker 4: сети, docker-compose

  • Выполнены эксперименты с запуском docker-контейнеров в сети с драйверами none, host, bridge

  • Запуск больше одного контейнера nginx с --network host невозможен так как порт уже занят, возникает ошибка, в случае запуска nginx с --network none все хорошо - каждый раз создаётся отдельный network namespace.

  • Сервисы запущены через docker run с использование двух сетей front_net и back_net, так чтобы ui не имел доступа к mongodb. При запуске докер может добавить только одну сеть, подсоединять новую надо отдельной командой docker network connect front_net post.

  • Проведены исследования bridge-интерфейсов и сетей на docker-machine.

  • Создан файл docker-compose.yml

    • Добавлен alias comment_db для базы, иначе сервис комментариев ее не видит. Можно так же подправить переменную окружения в docker-compose.yml для сервиса comment.
  • Создан файл с переменными .env, docker-compose.yml параметризован

  • Созданные сущности имеют префикс src - название директории, в которой находится docker-compose.yml. Можно переопределить с помощью:

    • COMPOSE_PROJECT_NAME
    • Из командной строки с ключом -p, --project-name NAME
    • Примечание: ключ командной строки перебивает значение переменной.
  • (★) Создан docker-compose.override.yml для запуска puma в режиме debug с двумя воркерами, а также с возможностью динамического редактирования кода

    • docker-compose.override.yml ломает запуск приложения на docker-host, так как на нем нет копии нужных файлов. Локально все работает.

Как запустить

  • docker-compose up -d
  • docker-compose down

Как проверить

  • Выполнить docker-machine ls для получени IP адреса docker-host
  • Зайти на http://<docker-host-ip>:9292/
  • Написать пост

ДЗ №15 - Gitlab 1: построение процесса непрерывной поставки

  • Запущен docker-host в GCE
  • Установлен gitlab
  • Запущен docker runner для проекта
  • Создан Gitlab-проект и настроен для использования CI/CD. Этот репозиторий запушен в него как в дополнительный remote.
  • CI/CD сконфигурирован запускать тесты, ссылаться на динамические окружения с учетом требований к веткам и других ограничений (тэги, ручной запуск).

Как запустить

Установка gitlab

Запуск runner

  • Используя docker-machine (eval $(docker-machine env gitlab-ci))
  • Выполнить
docker run -d --name gitlab-runner --restart always \
           -v /srv/gitlab-runner/config:/etc/gitlab-runner \
           -v /var/run/docker.sock:/var/run/docker.sock \
           gitlab/gitlab-runner:latest
  • Для регистрации runner выполнить docker exec -it gitlab-runner gitlab-runner register --run-untagged --locked=false

Как проверить

  • После установки Gitlab на VM можно перейти по http://VM_PUBLIC_IP. (Начальная инициализация Gitlab может занять несколько минут)
  • Добавленные для проекта раннеры видны тут: http://VM_PUBLIC_IP/group/project/-/settings/ci_cd

ДЗ №16 - Monitoring 1: Введение. Системы мониторинга

  • Запущен docker-host в GCE: команды тут
  • Добалвен Docker образ для Prometheus
  • Собраны образы сервисов командами bash docker_build.sh в каждой из папок src/ui, src/post-py, src/comment
  • Prometheus добавлен в docker-compose.yml
  • Использован UI Prometheus для проверки состояния приложения
  • Добавлен node_exporter
  • Собранные образы запушены в Docker Hub
  • Добавлены экспортеры:
  • (★) Добавлен Makefile для сборки образов и доставки их в Docker Registry

Как запустить

  • Создать инстанс в GCE: команды тут
  • Создать правила файервола: script
  • Собрать все необходимые образы командой make b_all
  • Запустить докер-инфраструктуру
cd ./docker
docker-compose -f docker-compose.yml up -d
  • Запушить в Docker Registry можно командо make p_all

Как проверить

  • Получить IP адрес VM с запущенными сервисами docker-machine ip docker-host
  • Приложение должно быть доступно по http://docker-host-ip:9292
  • Prometheus должен быть доступен по http://docker-host-ip:9090

ДЗ-17 "Мониторинг приложения и инфраструктуры"

В процессе сделано:

  • Рефакторинг docker-compose файла, разбит на docker-compose.yml и docker-compose-monitoring.yml

  • Добавлены источники метрик для Prometheus:

    • cAdvisor для докер-метрик

    • сервиса post

  • В составе мониторинг-кластера поднята Grafanа.

  • Настроены дашборды в Grafana:

    • Импортирован дашборд для Докера

    • Дашборд для мониторинга состояния приложения

    • Дашборд для мониторинга бизнес-метрик

  • С помощью Alertmanager настроен алёрт в Slack-канал #nikita_shvyryaev о недоступности любого из компонентов приложения

Как запустить проект:

  • Созадть GCP-инстанс

    export GOOGLE_PROJECT=_your_project_
    docker-machine create --driver google \
        --google-machine-image https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/family/ubuntu-1604-lts \
        --google-machine-type n1-standard-1 \
        --google-zone europe-west1-b \
        docker-host
    
  • Создать правила файервола для открытия наружу портов tcp 8080, 8000, 3000

  • Переключиться на докер-окружение (см. подробнее в здесь)

    eval $(docker-machine env docker-host)
    export USER_NAME=nikitagsh
    
  • Запустить докер-инфраструктуру приложения и мониторинга

    cd ./docker
    docker-compose -f docker-compose.yml up -d
    docker-compose -f docker-compose-monitoring.yml up -d
    
  • В Grafan'e создать источник данных Prometheus и импортировать дашборды

Как проверить работоспособность:

  • Получить IP адрес VM с запущенными сервисами

    docker-machine ip docker-host
    
  • Приложение должно быть доступно по http://docker-host-ip:9292

  • Prometheus должен быть доступен по http://docker-host-ip:9000

  • cAdviser должен быть доступен по http://docker-host-ip:8080

  • Grafana должы быть доступна по http://docker-host-ip:3000

  • Метрики отдельных экспортеров доступны на их портах, если были добавлены соответствующие правила файервола.

ДЗ-18 "Логирование и распреде распределенная трассировка"

В процессе сделано:

  • Собраны образы сервисов приложения под тэгом logging

  • Создан отдельный docker-compose-logging.yml, который запускает сервисы Fluentd, ElasticSearch, Kibana, Zipkin

    ElasticSearch запускается в development & testing режиме с помощью env discovery.type=single-node

  • Севрис post настроен отправлять логи во Fluentd, которые парсятся json-фильтром. Сервис ui настроен отправлять неструктурированные логи во Fluentd, которые парсятся regex-ами или grok-фильтрами в нужный формат.

  • В Kibana создан индекс-паттерн для наблюдения за логами.

  • В Zipkin произведен трэйсинг запросов на ui сервис

Как запустить проект:

  • Создать GCP-инстанс (ссылка на gist)

  • Создать правила файервола: разрешить порты tcp:5601,9292,9411

  • Переключиться на докер-окружение

    eval $(docker-machine env logging)
    export USER_NAME=nikitagsh
    
  • Запустить докер-инфраструктуру логгинга и приложения

    cd ./docker
    docker-compose -f docker-compose-logging.yml up -d
    docker-compose -f docker-compose.yml up -d
    

Как проверить работоспособность:

  • Получить IP адрес VM с запущенными сервисами

    docker-machine ip docker-host
    
  • Приложение должно быть доступно по http://docker-host-ip:9292

  • Kibana должна быть доступен по http://docker-host-ip:5601

  • Zipkin должен быть доступен по http://docker-host-ip:9411

  • Метрики отдельных экспортеров доступны на их портах, если были добавлены соответствующие правила файервола.

ДЗ-19 "Введение в Kubernetes"

  • Kubernetes кластер развернут в GCP вручную, следуя туториалу The Hard Way

    Выполненные шаги и заметки собраны здесь

  • Проверено, что в созданном K8s-кластере заготовки деплойментов (*-deployment.yml) применяются и поды создаются

Как запустить проект:

  • Выполнить инстукции туториала The Hard Way

    Чтобы учесть огрничение GCP в 4 IP-адресса, вместо 3 контроллеров и 3 воркеров, создаются 2 контролллера и 2 воркера. Команды из инструкции были скорректированы с учетом этого

Как проверить работоспособность:

  • Проверка работоспособности K8s-кластера выполняется шагом Smoke Test

  • Проверить запуск подов reddit-приложения можно командой

    kubectl get pods
    

ДЗ-20 "Kubernetes. Запуск кластера и приложения. Модель безопасности"

В процессе сделано:

  • Reddit-приложение развернуто в локальном K8s кластере minikube в отдельном нэймспэйсе dev.

    • По 3 реплики(пода) на каждый сервис: ui, comment, post.
    • 1 реплика MongoDB с персистентным хранилищем.
    • Созданы k8s-сервисы для взаимодействия между компонентами и БД
    • Создан сервис типа NodePort для доступа к веб-интерфейсу всего приложения извне.
  • Создан GKE-кластер вручную.

  • Reddit-приложение развернуто в GKE k8s кластере. Шаги для запуска см. в KUBERNETES.md

  • (⭐) Создан GKE-кластер с помощью Terraform

  • (⭐) Настроено использование dashboard addon'а для кластера. Шаги по настройке см. в DASHBOARD.md

    Примечание: при использовании дашборда на минимальных инстансах не хватает CPU для размещения pod'ов приложения.

Как запустить проект:

  • Создать k8s кластер

    • локальный

      minikube start
      
    • или в GKE с помощью Terrafrom. См KUBERNETES.md

      cd ./kubernetes/terraform
      terraform init
      terraform plan
      terraforn apply
      
  • Создать нэймспэйс

    kubectl apply -f ./kubernetes/reddit/dev-namespace.yml
    
  • Применить деплойменты и сервисы для приложения

    kubectl apply -f ./kubernetes/reddit/. -n dev
    
  • Включить dashboard addon для кластера в GKE и настроить его использование. См. DASHBOARD.md Запустить проксирование дашборда на локалхост

    kubectl proxy
    

Как проверить работоспособность:

  • Проверить текущий K8s контекст

    kubectl config current-context
    
  • Проверить наличие и состояние ресурсов приложения

    kubectl get all -n dev
    
  • Приложение должно быть доступно по http://<node_ip>:<node_port> , где node_ip можно получить из вывода команды

    kubectl get nodes -o wide
    

    а nodeport - из вывода команды

    kubectl describe service ui -n dev | grep NodePort
    
  • K8s дашборд должен быть доступен по http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

ДЗ-21 "Kubernetes. Networks, Storages"

В процессе сделано:

  • Проведен эксперимент: Деплойменты kube-dns-autoscaler и kube-dns (namespace kube-system) проскейлены в 0 В этой конфигурации поды перестают иметь сетевой доступ друг к другу.

  • Опробованы следующие способы публикации ui сервиса:

    • LoadBalancer
    • Ingress
    • Не удалось запустить Ingress одновременно с LoadBalancer - заработало только вместе с NodePort
    • Ingress с TLS терминацией
    • (⭐) Созданный tls-сертификат загружается в кластер с помощью ui-tls-secret.yml
  • Сетевой доступ к MongoDB ограничен post и comment сервисами с помощью NetworkPolicy. Для этого для кластера включается GKE-плагин network policy CALICO с помощью Terraform

  • Для хранения данных MongoDB задействован volume:

    • emptyDir (удаляется при удалениик деплоймента)
    • gcePersistentDisk (используется целый диск)
    • PersistentVolume (используется часть диска) по запросу PersistentVolumeClaim cо Standard storage-class'ом
    • динамически PersistentVolumeClaim'ом с fast (ssd) storage-class'ом

Как запустить проект:

  • Создать k8s кластер в GKE с помощью Terrafrom. (Подробнее см. KUBERNETES.md)

    cd ./kubernetes/terraform
    terraform init
    terraform plan
    terraforn apply
    
  • Создать namespace

    kubectl apply -f ./kubernetes/reddit/dev-namespace.yml
    
  • Создать деплойменты, сервисы и прочие ресурсы для приложения

    kubectl apply -f ./kubernetes/reddit/. -n dev
    
  • Выпустить TLS сертификат для Ingress

    export INGRESS_IP=$(kubectl get ingress ui -n dev -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=$INGRESS_IP"
    

    и загрузить его в кластер с помощью kubectl apply -f ./ui-tls-secret.yml -n dev где

    data:
      tls.crt: cat ./tls.crt | base64
      tls.key: cat ./tls.key | base64
    

Как проверить работоспособность:

  • Проверить текущий K8s контекст

    kubectl config current-context
    
  • Проверить наличие и состояние ресурсов приложения

    kubectl get all -n dev
    
  • Приложение должно быть доступно по https://<ingress_ip> , где ingress_ip можно получить из вывода команды

    kubectl get ingress ui -n dev -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
    

ДЗ-22 "CI/CD в Kubernetes"

В процессе сделано:

Helm
  • Развертывание kubernetes-компонентов для ui, comment, post щаблонизировано с помощью Helm. См kubernetes/Charts. Для деплоя создан общий чарт reddit, зависящий от ui, comment, post

  • Установка Helm-релиза reddit-приложения осуществлена с помощью

    • Helm2 + Tiller (server side)
    • Helm2 + Tiller plugin
    • Helm3

    Подробнее см. HELM.md

Gitlab
  • В Kubernetes-кластере поднят Gitlab с с помощью opensource Helm-чарта

  • Под каждую из компонент Reddit-приложения, включая деплой, создан отдельный репозиторий со своим CI/CD пайплайном

  • Для feature-веток поднимаются динамические окружения

  • Деплой всего приложения осуществяется на статические окружения: staging, production

Как запустить проект:

  • Создать k8s кластер в GKE с помощью Terrafrom. (Подробнее см. KUBERNETES.md)

    cd ./kubernetes/terraform
    terraform init
    terraform plan
    terraforn apply
    
  • С помощью Helm задеплоить релиз

    cd kubernetes/Charts
    helm install --name <release-name> ./reddit
    
  • Установить Gitlab

    helm install --name gitlab ./gitlab-omnibus -f values.yaml
    
  • Для доступа на Gitlab UI добавить в /etc/hosts IP адрес gitlab ingress'а

    GITLAB_IP=$(kubectl get service -n nginx-ingress nginx -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
    echo "$GITLAB_IP gitlab-gitlab staging production" >> /etc/hosts
    

    Поступить аналогично в случае динамических окружений feature-веток

Как проверить работоспособность:

  • Проверить текущий K8s контекст

    kubectl config current-context
    
  • Проверить наличие и состояние ресурсов приложения

    kubectl get all
    
  • Приложение должно быть доступно по https://<ingress_ip> , где ingress_ip можно получить из вывода команды

    kubectl get ingress ui -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
    
  • Gitlab UI должен быть доступен по http://<gitlab_ingress_ip

    kubectl get service -n nginx-ingress nginx -o jsonpath="{.status.loadBalancer.ingress[0].ip}"
    
  • Запушить изменения в репозиторий, соответсвующий компоненте: ui, comment, post, reddit. Динамические и статические окружения должны быть доступны по http://<staging|production|branch>

ДЗ-23 "Kubernetes. Мониторинг и логирование"

В процессе сделано:

  • Скорректирован Terraform-проект для развертывания Kubernetes кластера.
Мониторинг
  • Из актуального Helm-чарта развернут Prometheus вместе с Alertmanager. Настройки для чарта: custom_values.yaml

  • Добавлены таргеты для Prometheus для компонент reddit-приложения: ui, comment, post. Настроен relabling

  • Из stable/grafana чарта развернута Grafana.

    В ней добавлены дашборды:

Как запустить проект:

  • Создать k8s кластер в GKE с помощью Terrafrom. (Подробнее см. KUBERNETES.md)

    cd ./kubernetes/terraform
    terraform init
    terraform plan
    terraforn apply
    

Дальнейшие действия описаны в MONITORING.md. А именно:

  • Задеплоить reddit приложение

    cd kubernetes/Charts/ helm upgrade staging --namespace ./reddit --install

  • С помощью Helm задеплоить nginx

    helm install stable/nginx-ingress --name nginx
    

    Прописать адрес nginx в /etc/hosts:

    <IP> reddit reddit-prometheus reddit-grafana reddit-non-prod production redditkibana staging prod
    
  • Задеплоить Prometheus

    cd kubernetes/Charts/prometheus
    helm upgrade prom . -f custom_values.yaml --install
    
  • Установить Grafana

    helm upgrade --install grafana stable/grafana \
        --set "adminPassword=admin" \
        --set "service.type=NodePort" \
        --set "ingress.enabled=true" \
        --set "ingress.hosts={reddit-grafana}"
    

Как проверить работоспособность:

  • Проверить текущий K8s контекст

    kubectl config current-context
    
  • Проверить наличие и состояние ресурсов приложения

    kubectl get all
    
  • Приложение, Prometheus должны быть доступны по прописанным в /etc/hosts адресам по http.

About

nshvyryaev microservices repository

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published