Slide 1

Slide 1 text

Legacy в коробочке Dev-среда на базе Kubernetes Илья Сауленко Avito

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Как выглядит микросервисная архитектура?

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Суровая реальность Монолит надо разрабатывать: ● Поддерживать старый код ● Разрабатывать новые фичи Монолит надо тестировать: ● Тестировать новые фичи ● Интегрировать с микросервисами

Slide 9

Slide 9 text

Среды в Avito: раньше LXC dev: test:

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Нужны новые среды!

Slide 12

Slide 12 text

Что не нравится? Vagrant-окружения слишком хрупкие Vagrant/Chef-конфигурации сильно отличаются от продакшена Разные решения для dev- и test-сред Тесты используют общие хранилища данных Общие базы/сфинксы etc

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Микросервисы в Avito

Slide 15

Slide 15 text

Среды в Avito: сейчас

Slide 16

Slide 16 text

Kubernetes — это сложно! Настраивать сеть Ставить etcd Готовить сертификаты

Slide 17

Slide 17 text

Kubernetes — это сложно! Minikube

Slide 18

Slide 18 text

Kubernetes — это сложно! Minikube ...или kubeadm

Slide 19

Slide 19 text

Kubernetes — это перебор! У нас же всего одно приложение на одном локальном сервере! Зачем оркестрация? Мы просто хотим писать код!

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Kubernetes — это перебор! Раздаёт IP-адреса контейнерам автоматически kube-dns для service discovery Ingress controller для HTTP-роутинга Readiness probe Heapster для мониторинга отдельных компонентов

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Микросервис vs монолит: найдите 10 отличий

Slide 24

Slide 24 text

Среднестатистический микросервис Приложение Хранилища данных Зависимости от других сервисов Описание сборки (Dockerfile) Описание деплоя (Chart.yaml) Приложение Dockerfile Chart.yaml Данные Сторонний сервис

Slide 25

Slide 25 text

Монолит Приложение Puppet + python + bash Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Приложение Puppet + python + bash Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные

Slide 28

Slide 28 text

Базы в Docker-контейнерах

Slide 29

Slide 29 text

Базы в Docker-контейнерах Immutable

Slide 30

Slide 30 text

Базы в Docker-контейнерах Immutable Ограничены по размеру

Slide 31

Slide 31 text

Как быть с большими базами?

Slide 32

Slide 32 text

Как быть с большими базами? 1. Никак — ходить в продакшен

Slide 33

Slide 33 text

Как быть с большими базами? 1. Никак — ходить в продакшен 2. Никак — поднимать пустой сервер без данных

Slide 34

Slide 34 text

Как быть с большими базами? 1. Никак — ходить в продакшен 2. Никак — поднимать пустой сервер без данных 3. Поднимать сервер без данных и накатывать тестовые данные

Slide 35

Slide 35 text

Как быть с большими базами? 1. Никак — ходить в продакшен 2. Никак — поднимать пустой сервер без данных 3. Поднимать сервер без данных и накатывать тестовые данные 4. Семплировать часть боевых данных

Slide 36

Slide 36 text

Как быть с большими базами? 1. Никак — ходить в продакшен 2. Никак — поднимать пустой сервер без данных 3. Поднимать сервер без данных и накатывать тестовые данные 4. Семплировать часть боевых данных 5. Сделать пул серверов на снапшотах файловых систем (ZFS, etc)

Slide 37

Slide 37 text

Docker commit Не всегда образ можно собрать с помощью docker build Например, если нужно сделать образ SphinxSearch из базы данных, запущенной в соседнем контейнере

Slide 38

Slide 38 text

Docker commit $ docker run -d --name db-container db-image $ docker run -d --name sphinx-container --link db-container sphinxsearch $ docker exec sphinx-container indexer -c sphinx.conf --all $ docker stop sphinx-container $ docker commit -m “sphinx indexes” sphinx-container sphinx-image

Slide 39

Slide 39 text

Docker commit: альтернативы Ansible Container Packer

Slide 40

Slide 40 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Puppet + python + bash

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Puppet + python + bash

Slide 43

Slide 43 text

Сборка кода: версии софта

Slide 44

Slide 44 text

Сборка кода: версии софта В Vagrant одна версия node.js, на тестовых серверах — другая

Slide 45

Slide 45 text

Сборка кода: версии софта В Vagrant одна версия node.js, на тестовых серверах — другая docker build обычно решает большую часть проблем

Slide 46

Slide 46 text

Сборка кода: когда docker build не хватает

Slide 47

Slide 47 text

Сборка кода: когда docker build не хватает Для сборки и запуска приложений — разный набор софта

Slide 48

Slide 48 text

Сборка кода: когда docker build не хватает Для сборки и запуска приложений — разный набор софта Внешние зависимости (например, собрать словарь из базы данных)

Slide 49

Slide 49 text

Build container base OS build dependencies build image:

Slide 50

Slide 50 text

Build container base OS build dependencies sources build image: +

Slide 51

Slide 51 text

Build container base OS build dependencies sources build image: app + =

Slide 52

Slide 52 text

Build container app

Slide 53

Slide 53 text

Build container base OS runtime dependencies app image: app

Slide 54

Slide 54 text

Build container base OS runtime dependencies app app image: app

Slide 55

Slide 55 text

Build container base OS build dependencies base OS runtime dependencies sources app build image: app image: app + =

Slide 56

Slide 56 text

Build container Dockerfile.build: FROM debian RUN apt-get install php composer nodejs npm ENTRYPOINT [“make”, “build”] … $ docker build -f Dockerfile.build -t build-image . $ docker run -v $PWD:/app/ build-image Dockerfile: FROM debian RUN apt-get install php COPY ./build/ /app/ … $ docker build -t run-image .

Slide 57

Slide 57 text

Build container: альтернативы IMPORT/EXPORT в Rocker mount в dapp Multi-stage builds в Docker 17.05

Slide 58

Slide 58 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Dockerfile Puppet + python + bash

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Dockerfile Puppet + python + bash

Slide 61

Slide 61 text

Helm для деплоя

Slide 62

Slide 62 text

Почему Helm? Менеджер релизов: приложение + конфигурация Шаблонизация Kubernetes-ресурсов Использует существующие Kubernetes-примитивы

Slide 63

Slide 63 text

Helm: альтернативы AppController Flux Spinnaker

Slide 64

Slide 64 text

Helm Chart Chart.yaml templates/ charts/ метаданные k8s-ресурсы рекурсия values.yaml значения по умолчанию, публичный интерфейс чарта deployment.yaml configmap.yaml ingress.yaml service.yaml

Slide 65

Slide 65 text

$ helm upgrade --install --wait release-name ./ Helm Kubernetes Pod Container Container Container ... Pod Container Декларативный деплой Chart

Slide 66

Slide 66 text

Readiness probe

Slide 67

Slide 67 text

Readiness probe > GET /healthz < 200 OK

Slide 68

Slide 68 text

Readiness probe > GET /healthz < 200 OK > GET /healthz < 500 Internal Server Error

Slide 69

Slide 69 text

$ helm upgrade --install --wait release-name ./ $ echo $? 1 Readiness probe = Smoke test Helm Kubernetes Pod Container Container Container ... Pod Container

Slide 70

Slide 70 text

Helm: проблемы Молодой, быстро развивающийся Нет фидбэка в процессе установки* go/template внутри yaml** * https://github.com/kubernetes/helm/pull/2386 ** https://github.com/ksonnet/ksonnet-lib

Slide 71

Slide 71 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Dockerfile Chart.yaml

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

Приложение Данные Сторонний сервис Сторонний сервис Сторонний сервис Данные Данные Данные Dockerfile Chart.yaml

Slide 74

Slide 74 text

Условные зависимости

Slide 75

Slide 75 text

“Хочу тестовую среду, у которой будет своя база, локально поднятые сервисы A и B, а за сервисом C пусть ходит в staging” Условные зависимости

Slide 76

Slide 76 text

“Хочу тестовую среду, у которой будет своя база, локально поднятые сервисы A и B, а за сервисом C пусть ходит в staging” “Мне нужно разрабатывать новый сервис D локально и интегрировать его с монолитом. Остальные зависимости можно вообще не поднимать” Условные зависимости

Slide 77

Slide 77 text

values.yaml, values.dev.yaml, values.test.yaml Условные зависимости

Slide 78

Slide 78 text

values.yaml, values.dev.yaml, values.test.yaml serviceA.location: ‘on-cluster’ Условные зависимости

Slide 79

Slide 79 text

values.yaml, values.dev.yaml, values.test.yaml serviceA.location: ‘on-cluster’ {{- if eq .Values.location “on-cluster” -}} … {{- end -}} Условные зависимости

Slide 80

Slide 80 text

values.yaml, values.dev.yaml, values.test.yaml requirements.yaml Условные зависимости

Slide 81

Slide 81 text

Приложение Сторонний сервис Данные Dockerfile Chart.yaml

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

Developer Experience

Slide 84

Slide 84 text

vboxfs: ● Медленное чтение ● Нет поддержки смены прав внутри дерева ● inotify не работает kubectl: ● Слишком fine-grained ● “kubectl exec” — это вам не терминал Developer Experience: проблемы

Slide 85

Slide 85 text

Скрипт для автоматизации рутины: логи, ssh, etc CLI-дашборд, показывающий самое важное lsyncd вместо vboxfs Облако вместо VirtualBox Draft? Developer Experience: решение

Slide 86

Slide 86 text

Что получилось?

Slide 87

Slide 87 text

Что получилось? Docker + Kubernetes + Helm (+ VirtualBox + Minikube) Переиспользование образов при разработке и тестировании “Legacy в коробочке”, поднимаемое одной командой локально или в кластере

Slide 88

Slide 88 text

Спасибо! Вопросы? Илья Сауленко, Avito @mynameiswhm