Docker kubernetes: Docker vs Kubernetes: ?
В чём разница между Docker и Kubernetes?
Может показаться, что
разработка приложения – это написание надёжного кода и всё. Настоящая
проблема заключается в работе с несколькими языками программирования на разных платформах и
управлении интерфейсами между инструментами. Здесь на помощь приходит Docker.
Инструмент контролирует приложения и во время разработки, и в рантайме, помогает управлять хранилищем, памятью и правами приложений, обеспечивает согласованную среду на любом
совместимом хосте (*nix или Windows).
Особенности Docker
- Простая и быстрая настройка.
- Высокая производительность.
- Изоляция – Docker использует для запуска приложений контейнеры.
- Качественное управление безопасностью.
Примеры популярных программных решений, которые можно запустить в Docker
Kubernetes – инструмент
управления контейнерами, автоматизирующий развёртывание. Это платформа с открытым исходным кодом, разработанная компанией Google, а теперь управляемая Cloud Native. Kubernetes помогает в обновлении приложений простым и быстрым способом, управляет рабочей нагрузкой и планированием контейнеров в кластере, автоматизирует многие ручные процессы, например, управлением приложенияй в контейнере и их масштабированием.
Особенности Kubernetes
- Автоматизация ручных процессов.
- Балансировка нагрузки. Kubernetes распределяет сетевой трафик и поддерживает стабильность развёртывания.
- Самовосстановление. Инструмент перезапускает отказавшие контейнеры, перемещает, а также «убивает» контейнер, не отвечающий шаблону пользователя.
- Инструментирование хранилища: пользователи могут автоматически монтировать систему хранения на свой вкус.
Docker и Kubernetes – это разные технологии. Не совсем справедливо сравнивать два этих варианта или ставить вопрос о том, кому из них следует отдать приоритет.
Docker – это контейнерная
площадка, а Kubernetes
является инструментом оркестровки контейнеров для таких платформ, как Docker.
Разница в Docker и Kubernetes
Docker и Kubernetes часто работают вместе. Docker используется для изоляции приложений в контейнерах, а Kubernetes как планировщик для развёртывания и масштабирования.
Сходства Docker и Kubernetes:
- Архитектура, основанная на микросервисах.
- В основном написаны на Go, так что поставляться в виде лёгких бинарников.
- Оба используют файлы в человекочитаемом формате YAML.
Если в вашей работе используется
микросервисная архитектура – берите Docker и назначайте контейнер для каждого
микросервиса.
Kubernetes – это быстро развивающаяся технология, но она нужна только если у вас крупный штат разработчиков,
которым нужна серьезная продакшн-среда. Для маленького проекта и трёх-четырёх разработчиков накладные расходы могут «съесть» всю пользу.
Когда и что
использовать?
Docker:
- если приложение подходит для работы в контейнере;
- приложение не требует графического интерфейса;
- приложение должно быть развернуто последовательно.
Kubernetes:
Если организация не
привязана к одному облачному провайдеру, то использование Kube является самым
разумным. Причина в том, что он работает одинаково на всех системах. Вот почему
его называют вендор-независимым.
Совершенно ясно, что
обе технологии идут рука об руку и запускаются друг за другом. Но что
заставляет думать, что существует конкуренция между ними? Docker
Swarm.
Это один из инструментов оркестровки контейнеров, предоставляемый ребятами из Docker
Inc.
Это внутренний
инструмент оркестровки контейнеров, разработанный для «общения» с контейнерами,
работающими в среде Docker. Он используется для кластеризации и планирования,
позволяет управлять несколькими контейнерами, развёрнутыми на нескольких
хост-машинах. В работе используется стандартный Docker API.
Принципы работы
- обратная совместимость;
- безопасность по умолчанию;
- устойчивая и отказоустойчивая архитектура;
- простой, но динамичный пользовательский интерфейс.
Развёртывание
Kubernetes:
приложения могут быть развёрнуты с использованием сочетания модулей и сервисов/микросервисов.
Docker Swarm: приложения
могут быть развёрнуты как сервисы/микросервисы в Swarm-кластере или при помощи Docker
Compose. Для обозначения универсальных контейнеров используется файл YAML.
Установка
Kubernetes: здесь установка полностью ручная. Это требует тщательного планирования, чтобы поднять Kube
и заставить работать. Процесс установки может отличаться для разных ОС и зависит
от поставщика услуг.
Docker Swarm: установка в сравнении с Kubernetes отличается скоростью и простотой. Понадобится лишь один набор инструментов, чтобы научиться строить на его основе
среды и конфигурации.
Функционирование
Kubernetes: для
перемещения внутри структуры и запуска Kubernetes понадобятся знания и
представление о Docker CLI. Для запуска и настройки нужно
общее понимание инфраструктуры.
Docker Swarm:
как уже говорилось ранее, Docker Swarm – разработка Docker, поэтому для навигации внутри структуры
используется один язык. Это повышает скорость работы и обеспечивает вариативность. Таким образом, Docker получает
значительное преимущество в удобстве использования.
Журналирование
Kubernetes: для
развернутой в кластере службы, например Elasticsearch/Kibana, Kubernetes
поддерживает несколько версий мониторинга и ведения журнала.
Docker Swarm: здесь
поддерживается только мониторинг с помощью сторонних приложений. Для данных
целей обычно рекомендуется Riemann.
Масштабирование
Kubernetes: для
распределённых систем Kube
– самое то. Этот сложный all-in-one
фреймворк предоставляет надежные гарантии относительно состояния кластера и
унифицированного набора API.
Docker Swarm: в
отличие от Kubernetes, скорость развёртывания контейнеров намного выше. Масштабирование по требованию позволяет добиться быстрого времени
реакции.
Сеть
Kubernetes: сеть
в Kube – плоская. Все контейнеры могут общаться друг с другом. В
Kubernetes необходимы два CIDR – один для получения IP-адреса, а другой – для внутренних
сервисов.
Docker Swarm поддерживает возможность самостоятельно шифровать пользовательский трафик в контейнере
во время оверлея.
В эру облачных сервисов,
опенсорсного ПО, сервисов/микросервисов и контейнеризации компаниям удастся
привлечь талантливых DevOps-специалистов
для развития инфраструктуры. Контейнеры помогут сосредоточиться на
бизнес-логике, не отвлекаясь на то, что находится под капотом.
Если вы только начинаете знакомство с контейрными технологиями и вас интересует Docker, обратите внимание на другие наши материалы:
Учимся разворачивать микросервисы. Часть 2. Kubernetes / Хабр
Привет, Хабр!
Это вторая часть из серии статей «Учимся разворачивать микросервисы». В предыдущей части мы написали 2 простеньких микросервиса — бекенд и шлюз, и разобрались с тем, как их упаковать в docker-образы. В этой же статье мы будем организовывать оркестрацию наших docker-контейнеров с помощью Kubernetes. Мы последовательно составим конфигурацию для запуска системы в Minikube, а затем адаптируем ее для деплоя в Google Kubernetes Engine.
План серии:
Создание сервисов на Spring Boot, работа с Docker
Ключевые слова: Java 11, Spring Boot, Docker, image optimization
Разработка Kubernetes конфигурации и деплой системы в Google Kubernetes Engine
Ключевые слова: Kubernetes, GKE, resource management, autoscaling, secrets
Создание чарта с помощью Helm 3 для более эффективного управления кластером
Ключевые слова: Helm 3, chart deployment
Настройка Jenkins и пайплайна для автоматической доставки кода в кластер
Ключевые слова: Jenkins configuration, plugins, separate configs repository
Что конкретно мы попытаемся добиться с помощью Kubernetes:
- Репликация. У нас в эксплуатации будет находится несколько контейнеров каждого типа, между которыми будет распределяться трафик. В случае смерти одного из контейнеров, он должен быть заменен новым.
- Автомасштабирование. Если трафик мал, то логично держать меньше реплик, а при всплесках нагрузки автоматически их добавлять.
- Управление ресурсами. Произвольный контейнер не должен иметь возможность использовать все ресурсы и тем самым подорвать работу других контейнеров. Также неплохо было бы ограничить ресурсы для всей системы в целом.
- Плавные обновления. Если мы захотим что-то поменять в контейнерах, например используемый Docker-образ, то Kubernetes должен плавно заменять старые контейнеры на обновленные, тем самым не допуская простоя в работе.
- Распределенность. Система должна работать на произвольном количестве узлов (нод).
Kubernetes — сложный механизм, призванный сделать нашу систему масштабируемой, отказоустойчивой и простой в развертывании. Он включает в себя множество настроек и возможностей. В статье основной акцент будет сделан на создании Kubernetes-конфигурации для конкретного учебного проекта.
Код проекта доступен на GitHub по ссылке.
Среда Kubernetes
Minikube — это удобный инструмент для экспериментов с Kubernetes на локальной машине. Изначально мы создадим конфигурацию для работы именно в этой среде. Далее мы поговорим, какие корректировки нужно внести, чтобы задеплоить систему в GKE. Google Cloud Platform был выбран из-за бесплатных 300$ на эксперименты в первый год. Для приведенной в статье конфигурации стоит использовать кластер из 2+ стандартных машин (n1-standard-1).
Ссылки по настройке среды:
Объекты Kubernetes
При работе с Kubernetes инженер описывает желаемое состояние системы через определение объектов и связей между ними. А конкретные действия для достижения нужного состояния оркестратор волен выбирать сам. То есть можно сказать, что настройка носит декларативный характер.
Рассмотрим некоторые объекты Kubernetes:
Namespace — пространство имен. Объекты могут взаимодействовать, только если находятся в одном неймспейсе. С помощью неймспейсов возможно развернуть несколько виртуальных кластеров на одном физическом.
Pod — минимальный юнит развертывания. В большинстве случаев включает в себя один контейнер. Множество настроек пода делегируются непосредственно контейнеру докера, например, управление ресурсами, политики рестартов, управление портами.
ReplicaSet — контроллер, позволяющий создать набор одинаковых подов и работать с ними, как с единой сущностью. Поддерживает нужное количество реплик, при необходимости создавая новые поды или убивая старые. На самом деле в большинстве случаев вы не будете работать с ReplicaSet напрямую — для этого есть Deployment.
Deployment — контроллер развертывания, являющийся абстракцией более высокого уровня над ReplicaSet’ом. Добавляет возможность обновления управляемых подов.
Service — отвечает за сетевое взаимодействие группы подов. В системе обычно существует несколько экземляров одного микросервиса, соответственно каждый из них имеет свой IP-адрес. Количество подов может изменяться, следовательно набор адресов также не постоянен. Другим частям системы для доступа к рассматриваемым подам нужен какой-то статичный адрес, который Service и предоставляет.
Во избежание путаницы здесь и в дальнейшем под словом «сервис» я буду подразумевать именно объект Kubernetes, а не экземпляр приложения.
Существует несколько видов сервисов. Перечисленные ниже типы для простоты понимания можно рассматривать, как матрешку. Каждый последующий оборачивает предыдущий и добавляет некоторые правила маршрутизации. Создавая сервис более высокого уровня, автоматически создаются сервисы нижележащего типа. Типы сервисов:
- ClusterIP — дефолтный тип сервиса. Единая точка доступа к подам по постоянному IP-адресу, доступному только изнутри кластера.
- NodePort — общий IP-адрес подов (полученный из ClusterIP) соединяется с определенным портом всех нод, на которых развернуты обслуживаемые поды. Поды становятся доступны по адресу
<NodeIP>:<NodePort>
. - LoadBalancer — выходной порт NodePort присоединяется к внешнему балансировщику нагрузки, предоставляемому облачным провайдером. Таким образом мы получаем статический внешний IP-адрес для нашего приложения.
Также Kubernetes из коробки предоставляет поддержку DNS внутри кластера, позволяя обращаться к сервису по его имени. Более подробно про сервисы можно почитать тут.
ConfigMap — объект с произвольными конфигурациями, которые могут, например, быть переданы в контейнеры через переменные среды.
Secret — объект с некой конфиденциальной информацией. Секреты могут быть файлами (№ SSL-сертификатами), которые монтируются к контейнеру, либо же base64-закодированными строками, передающимися через те же переменные среды. В статье будут рассмотрены только строковые секреты.
HorizontalPodAutoscaler — объект, предназначенный для автоматического изменения количества подов в зависимости от их загруженности.
Minikube configuration
Namespace:
Создадим неймспейс:
kubectl create namespace msvc-ns
Установим его как текущий:
kubectl config set-context --current --namespace=msvc-ns
Далее все объекты будут создаваться в неймспейсе ‘msvc-ns’. Если этот шаг пропустить, то будет использоваться неймспейс ‘default’.
Обычно конфигурация для Kubernetes представляет собой обычный yaml-файл с описанием объектов, но также есть возможность создавать эти объекты и через CLI. В дальнейшем все объекты будут описываться в yaml-формате.
ConfigMap
Объект, предоставляющий свойства для подов. В нашем случае шлюзу для связи с подами бекенда необходимо знать URL-адрес их сервиса. Наш ConfigMap будет содержать адреса внутренних сервисов нашего кластера, и его можно будет заинжектить во все заинтересованные микросервисы (в нашей системе это только шлюз).
apiVersion: v1
kind: ConfigMap
metadata:
name: urls-config
data:
BACKEND_URL: "http://backend:8080/"
Как я говорил ранее, в кластере Kubernetes сервисы доступны по их именам. Как мы увидим далее, сервис бекенда будет иметь имя ‘backend’ и использовать 8080 порт.
Secret
apiVersion: v1
kind: Secret
metadata:
name: msvc-secret
type: Opaque
stringData:
secret: secret
Тип Opaque подразумевает, то что секрет задается парами ключ-значение. Для особых секретов, например, паролей реестров Docker-образов, существуют отдельные типы. В данном конфиге мы указываем пароль в открытом виде в блоке stringData. Так как секреты хранятся в кодировке base64, то наши данные будут закодированы автоматически. Секрет можно указать в уже закодированном виде:
data:
secret: c2VjcmV0
Deployments
У нас будет два деплоймента — для бекенда и шлюза.
Деплоймент шлюза:
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
labels:
tier: gateway
app: microservices
spec:
replicas: 3
selector:
matchLabels:
tier: gateway
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
tier: gateway
spec:
containers:
- name: gateway
image: anshelen/microservices-gateway:latest
envFrom:
- configMapRef:
name: urls-config
env:
- name: SECRET
valueFrom:
secretKeyRef:
name: msvc-secret
key: secret
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
memory: "256Mi"
cpu: "200m"
requests:
memory: "128Mi"
cpu: "50m"
metadata.labels
Эти поля служат для настройки связей между объектами, а также для их уникальной идентификации. В нашем случае мы отмечаем, что наш деплоймент принадлежит приложению с названием ‘microservices’ и слою ‘gateway’.
Дополнительно хочется отметить похожий по смыслу блок metadata.annotations — он используются исключительно для предоставления метаинформации, которая может быть интроспектирована внешними инструментами.spec.replicas
В этом поле задается количество реплик нашего микросервиса.spec.selector.matchLabels
Этот элемент устанавливает связь между деплойментом и управляемыми подами. Так в нашем случае деплоймент будет управлять только теми подами, у которых есть метка tier, равная ‘backend’. Далее в spec.template мы зададим шаблон для создания подов, причем для корректной работы у каждого из них в поле metadata.labels должна быть та же метка, что и здесь.spec.strategy
Блок spec.strategy описывает стратегию обновления подов. Тип ‘rollingUpdate’ подразумевает, что будет создан новый ReplicaSet, старые поды постепенно будут удаляться из старого ReplicaSet’а, а обновленные добавляться в новый. Скорость замены подов (максимальное количество добавляемых/удаляемых реплик от нужного количества) можно регулировать параметрами maxSurge и maxUnavailable. Эта стратегия позволяет плавно обновить деплоймент, избежав даунтайма. В данном контексте блок spec.strategy приведен только в демонстрационных целях, так как полностью совпадает с дефолтным значением.spec.templates
Блок spec.templates содержит информацию о создаваемых деплойментом подах.spec.templates.metadata.labels
Как уже было сказано выше, это поле должно коррелировать с spec.selector.matchLabels, чтобы создаваемые поды могли быть «подхвачены» деплойментом.spec.templates.spec.containers.image
Используемый образ. Тег latest будет присвоен Docker-образу, если мы его запушим в реестр, явно не указав другой тег. Хоть по смыслу этот тег и обозначает самый свежий образ, однако его использование — не лучшая практика в Kubernetes. В случае чего мы не сможем откатиться к предыдущей версии пода, если его образ был перезаписан в реестре. Как минимум поэтому лучше использовать образы с уникальными тегами. Сейчас же мы умышленно используем ‘latest’ образ и поправим это в 4 части этого цикла статей, когда будем настраивать пайплайн в Jenkins.spec.templates.spec.containers.envFrom.configMapRef
Ссылаемся на уже созданный ConfigMap и помещаем все значения из него в переменные среды.spec.templates.spec.containers.env
В этом блоке создаем переменную среды ‘SECRET’, равную значению из нашего объекта-секрета под ключом ‘secret’.spec.templates.spec.containers.readinessProbe
Проверка готовности пода принимать трафик. Здесь мы указываем эндпойнт, предоставляющий информацию о состоянии микросервиса. Kubernetes будет периодически делать запросы на этот адрес, и если 3 раза подряд статус ответа будет не 200, то проблемный под будет исключен из балансировки нагрузки.initialDelaySeconds — задежка перед первой проверкой.
periodSeconds — интервал между проверками.Также существует проверка жизнеспособности пода livenessProbe, но я сомневаюсь в рациональности ее применения здесь (хорошая статья на эту тему).
spec.templates.spec.containers.ports
В блоке ports мы сообщаем какие порты у контейнера открыть. Эта настройка делегируется докеру (аналогично указанию при запуске контейнера параметра-p 8080:8080
).spec.templates.spec.containers.resources
Ограничения контейнера по ресурсам. limits — максимально доступное количество, а requests — количество ресурсов, предоставляемое контейнеру единовременно при старте. 200m — 200 миллиядер (одна пятая ядра), Mi — мегабайты.
Деплоймент микросервиса бекенда имеет аналогичную конфигурацию, за исключением того, что мы не должны сообщать ему секрет через переменную среды.
Services
Сервис бекенда:
apiVersion: v1
kind: Service
metadata:
labels:
tier: backend
name: backend
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
tier: backend
spec.ports.targetPort — порт облуживаемых подов, spec.ports.port — выходной порт сервиса. В spec.selector мы указываем, что этот сервис будет направлять запросы подам, имеющим метку tier, равную ‘backend’. Так как тип сервиса не указан явно, то он считается равным ClusterIP, и сервис доступен напрямую только изнутри кластера по адресу http://backend:8080
.
Сервис шлюза:
apiVersion: v1
kind: Service
metadata:
labels:
tier: gateway
name: gateway
spec:
ports:
- nodePort: 30500
port: 80
protocol: TCP
targetPort: 8080
selector:
tier: gateway
type: NodePort
Так как мы работаем с Minikube, и у нас нет внешнего балансировщика нагрузки, то выберем тип сервиса NodePort. spec.ports.nodePort — порт на хосте. Если его не указать, то будет выбран рандомный порт из интервала 30000-32767.
Итоговый файл конфигурации для Minikube
deploy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: urls-config
data:
BACKEND_URL: "http://backend:8080/"
---
apiVersion: v1
kind: Secret
metadata:
name: msvc-secret
type: Opaque
stringData:
secret: secret
---
apiVersion: v1
kind: Service
metadata:
labels:
tier: backend
name: backend
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
tier: backend
---
apiVersion: v1
kind: Service
metadata:
labels:
tier: gateway
name: gateway
spec:
ports:
- nodePort: 30500
port: 80
protocol: TCP
targetPort: 8080
selector:
tier: gateway
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
labels:
tier: backend
app: microservices
spec:
replicas: 3
selector:
matchLabels:
tier: backend
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
tier: backend
spec:
containers:
- name: backend
image: anshelen/microservices-backend:latest
envFrom:
- configMapRef:
name: urls-config
ports:
- containerPort: 8080
protocol: TCP
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
resources:
limits:
memory: "256Mi"
cpu: "200m"
requests:
memory: "128Mi"
cpu: "50m"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
labels:
tier: gateway
app: microservices
spec:
replicas: 3
selector:
matchLabels:
tier: gateway
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
tier: gateway
spec:
containers:
- name: gateway
image: anshelen/microservices-gateway:latest
envFrom:
- configMapRef:
name: urls-config
env:
- name: SECRET
valueFrom:
secretKeyRef:
name: msvc-secret
key: secret
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
memory: "256Mi"
cpu: "200m"
requests:
memory: "128Mi"
cpu: "50m"
Запуск
Применяем конфигурацию:
kubectl apply -f deploy.yaml
Подождем пока все объекты Kubernetes запустятся и получим URL нашего приложения:
minikube service gateway --url -n msvc-ns
Далее сгенерируем трафик:
for i in `seq 50`; do curl $(minikube service gateway --url -n msvc-ns) && echo; done
Вывод команды (будет отличаться в вашем случае):
Number of requests 1 (gateway 544429797, secret secret)
Number of requests 1 (gateway 1543772618, secret secret)
Number of requests 2 (gateway 544429797, secret secret)
Number of requests 3 (gateway 544429797, secret secret)
Number of requests 4 (gateway 544429797, secret secret)
Number of requests 1 (gateway -1940767433, secret secret)
Number of requests 2 (gateway -1940767433, secret secret)
Number of requests 2 (gateway 1543772618, secret secret)
Number of requests 5 (gateway 544429797, secret secret)
...
Показать полностью
Number of requests 1 (gateway 544429797, secret secret)
Number of requests 1 (gateway 1543772618, secret secret)
Number of requests 2 (gateway 544429797, secret secret)
Number of requests 3 (gateway 544429797, secret secret)
Number of requests 4 (gateway 544429797, secret secret)
Number of requests 1 (gateway -1940767433, secret secret)
Number of requests 2 (gateway -1940767433, secret secret)
Number of requests 2 (gateway 1543772618, secret secret)
Number of requests 5 (gateway 544429797, secret secret)
Number of requests 3 (gateway 1543772618, secret secret)
Number of requests 6 (gateway 544429797, secret secret)
Number of requests 3 (gateway -1940767433, secret secret)
Number of requests 4 (gateway 1543772618, secret secret)
Number of requests 7 (gateway 544429797, secret secret)
Number of requests 4 (gateway -1940767433, secret secret)
Number of requests 8 (gateway 544429797, secret secret)
Number of requests 9 (gateway 544429797, secret secret)
Number of requests 10 (gateway 544429797, secret secret)
Number of requests 5 (gateway 1543772618, secret secret)
Number of requests 5 (gateway -1940767433, secret secret)
Number of requests 6 (gateway -1940767433, secret secret)
Number of requests 7 (gateway -1940767433, secret secret)
Number of requests 6 (gateway 1543772618, secret secret)
Number of requests 8 (gateway -1940767433, secret secret)
Number of requests 7 (gateway 1543772618, secret secret)
Number of requests 11 (gateway 544429797, secret secret)
Number of requests 12 (gateway 544429797, secret secret)
Number of requests 8 (gateway 1543772618, secret secret)
Number of requests 9 (gateway -1940767433, secret secret)
Number of requests 10 (gateway -1940767433, secret secret)
Number of requests 11 (gateway -1940767433, secret secret)
Number of requests 9 (gateway 1543772618, secret secret)
Number of requests 10 (gateway 1543772618, secret secret)
Number of requests 11 (gateway 1543772618, secret secret)
Number of requests 12 (gateway -1940767433, secret secret)
Number of requests 12 (gateway 1543772618, secret secret)
Number of requests 13 (gateway 544429797, secret secret)
Number of requests 13 (gateway 1543772618, secret secret)
Number of requests 13 (gateway -1940767433, secret secret)
Number of requests 14 (gateway 1543772618, secret secret)
Number of requests 14 (gateway -1940767433, secret secret)
Number of requests 15 (gateway -1940767433, secret secret)
Number of requests 14 (gateway 544429797, secret secret)
Number of requests 15 (gateway 544429797, secret secret)
Number of requests 16 (gateway 544429797, secret secret)
Number of requests 17 (gateway 544429797, secret secret)
Number of requests 15 (gateway 1543772618, secret secret)
Number of requests 16 (gateway 1543772618, secret secret)
Number of requests 16 (gateway -1940767433, secret secret)
Number of requests 17 (gateway 1543772618, secret secret)
Запросы поступают бекендам равномерно, и каждый бекенд принимает запросы именно от своего шлюза. Признаюсь, я несколько раз проводил запуск, чтобы получить такую картину. Если запустить команду повторно через какое-то время, то шлюзы и бекенды могут быть связаны уже по-другому, причем есть вероятность, что все шлюзы будут слать запросы одному бекенду. Это связано с тем, что имеет место балансировка между клиентами, а не запросами. Например, если один клиент будет слать 1 запрос в секунду, а другой 1000, и они будут изначально «привязаны» к разным репликам, то это приведет к разнице в нагрузке в 1000 раз. Это, безусловно, не лучший вариант балансировки трафика, однако дальнейшее исследование этой темы оставим за рамками данной статьи. Подробнее можно прочитать здесь.
Управление кластером
Здесь я перечислю несколько полезных команд для управления кластером.
Извлечение информации
kubectl get <object-type>
— вывести список объектов определенного типа. В качестве типов может выступать ‘pod’, ‘service’, ‘deployment’ и другие. Чтобы посмотреть все объекты в неймспейсе подставьте ‘all’.kubectl get <object-type> <object-name> -o yaml
— выведет полную конфигурацию объекта в yaml-формате.kubectl describe <object-type> <object-name>
— подробная информация об объекте.kubectl cluster-info
— информация о кластере.kubectl top pod/node
— потребляемые ресурсы подами/нодами.
Изменение конфигурации кластера
kubectl apply -f <file/directory>
— применить конфигурационный файл или же все файлы из директории.kubectl delete <object-type> <object-name>
— удалить объект.kubectl scale deployment <deployment-name> --replicas=n
— отмасштабировать деплоймент. Если выполнить подряд две команды: с n = 0, а затем с другим n, то пересоздаст все поды в деплойменте.kubectl edit <object-type> <object-name>
— редактировать конфигурацию объекта в редакторе.kubectl rollout undo deployment <deployment-name>
— откатить изменения деплоймента до прошлой версии.
Дебаг
kubectl logs <pod-name>
— отобразить логи контейнера. Параметр -f
позволит следить за логами в реальном времени.kubectl port-forward <pod-name> <host-port>:<container-port>
— пробросить порт хоста на порт контейнера. Используется для отправки запросов подам вручную.kubectl exec -it <pod-name> -- /bin/sh
— открыть терминал в контейнере пода.kubectl run curl --image=radial/busyboxplus:curl -i --tty
— создать отдельный под. В данном примере создается легкий контейнер с curl, с помощью которого можно будет, например, проверить доступность сервисов.kubectl get events --sort-by='.metadata.creationTimestamp'
— получить список внутренних событий Kubernetes. Эта информация поможет ответить, например, на вопрос, почему под не смог запуститься.
GKE configuration
Как я уже говорил, далее мы обсудим, как можно изменить конфигурацию, чтобы задеплоить систему в Google Kubernetes Engine.
Services
Инфраструктура GKE предоставляет нам внешний балансировщик нагрузки, который нам нужен для получения статичного внешнего IP-адреса. Чтобы подключить балансировщик, изменим тип сервиса шлюза на LoadBalancer:
apiVersion: v1
kind: Service
metadata:
labels:
tier: gateway
name: gateway
spec:
selector:
tier: gateway
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer
Как справедливо заметили в комментариях, при пересоздании балансировщика его статический адрес поменяется, что чаще всего нежелательно. Чтобы этого избежать, надо арендовать статический адрес у GCP (Сеть VPC -> Внешние IP-адреса) в той же зоне, что и кластер, а затем прописать его в элементе spec.loadBalancerIp.
HorizontalPodAutoscalers
HorizontalPodAutoscaler будет автоматически масштабировать деплоймент в зависимости от нагрузки на его поды. Мне не удалось заставить работать этот компонент на Minikube (какие-то странные неполадки с сервером метрик), но в GKE он работает из коробки.
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: backend
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 50
В spec.scaleTargetRef мы указываем, что мы собираемся автомасштабировать деплоймент под именем backend. Далее сообщаем, что собираемся содержать от 1 до 3 реплик и планируем держать поды загруженными на 50%. Отмечу, чтобы задавать планируемую загрузку в процентах (можно указывать и в абсолютных величинах), то надо обязательно указать requests.cpu у управляемых контейнеров.
Конфигурация HorizontalPodAutoscaler’а шлюза аналогична.
Quotas
Квоты позволяют настроить максимальное потребление ресурсов всем кластером. Это обычно нужно, если несколько команд используют один кластер (multitenant environment). Давайте ограничим ресурсы, доступные объектам нашего неймспейса:
apiVersion: v1
kind: ResourceQuota
metadata:
name: msvc-quota
spec:
hard:
limits.cpu: "2"
limits.memory: 4Gi
Если мы проставляем жесткие ограничения квот по какому-либо параметру, то для каждого из создаваемых подов этот параметр становится обязательным. Это может вызывать неудобства, например, при создании контейнеров из CLI (см. kubectl run
), поэтому установим дефолтные параметры с помощью объекта LimitRange:
apiVersion: v1
kind: LimitRange
metadata:
name: msvc-default-resources
spec:
limits:
- default:
memory: "512Mi"
cpu: "250m"
defaultRequest:
memory: "256Mi"
cpu: "50m"
type: Container
Так как конфигурация квот напрямую не относится к нашему приложению, то лучше оформить ее в отдельный файл.
Итоговые файлы конфигурации для GKE
Поместим все файлы в папку scripts_gke/
.
create_quotas.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: msvc-quota
spec:
hard:
limits.cpu: "2"
limits.memory: 4Gi
---
apiVersion: v1
kind: LimitRange
metadata:
name: msvc-default-resources
spec:
limits:
- default:
memory: "512Mi"
cpu: "250m"
defaultRequest:
memory: "256Mi"
cpu: "50m"
type: Container
deploy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: urls-config
data:
BACKEND_URL: "http://backend:8080/"
---
apiVersion: v1
kind: Secret
metadata:
name: msvc-secret
type: Opaque
stringData:
secret: secret
---
apiVersion: v1
kind: Service
metadata:
labels:
tier: backend
name: backend
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
tier: backend
---
apiVersion: v1
kind: Service
metadata:
labels:
tier: gateway
name: gateway
spec:
selector:
tier: gateway
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
labels:
tier: backend
app: microservices
spec:
replicas: 2
selector:
matchLabels:
tier: backend
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
tier: backend
spec:
containers:
- name: backend
image: anshelen/microservices-backend:latest
envFrom:
- configMapRef:
name: urls-config
ports:
- containerPort: 8080
protocol: TCP
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
resources:
limits:
memory: "512Mi"
cpu: "250m"
requests:
memory: "256Mi"
cpu: "50m"
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: backend
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 50
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
labels:
tier: gateway
app: microservices
spec:
replicas: 2
selector:
matchLabels:
tier: gateway
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
tier: gateway
spec:
containers:
- name: gateway
image: anshelen/microservices-gateway:latest
envFrom:
- configMapRef:
name: urls-config
env:
- name: SECRET
valueFrom:
secretKeyRef:
name: msvc-secret
key: secret
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
memory: "512Mi"
cpu: "250m"
requests:
memory: "256Mi"
cpu: "50m"
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: gateway
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: gateway
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 50
Запуск
Применим все конфигурационные файлы из папки scripts_gke:
kubectl apply -f scripts_gke/
Время разворачивания в этот раз может составить несколько минут, так как потребуется время на установку внешнего балансировщика. URL нашего приложения:
kubectl get svc gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
Через некоторое время HorizontalPodAutoscaler’ы в отсутствие нагрузки сократят количество подов в каждом деплойменте до одного.
Заключение
В этой статье мы написали Kubernetes-конфигурацию и успешно задеплоили нашу систему в Google Kubernetes Engine.
Возможно, когда вы читали эту статью, то заметили, что даже для деплоя простенькой системы из двух микросервисов очень многое надо держать в голове. Для установки корректной связи между объектами одну и ту же метку надо не забыть прописать в нескольких местах, при описании сервисов и подов надо не запутаться в их портах… Было бы неплохо подключить какой-нибудь шаблонизатор и получить возможность гибко управлять настройками нашей системы в целом, обособившись от абстракций Kubernetes. Все это (и много больше) позволяет сделать пакетный менеджер Helm.
В третьей части этого цикла статей мы потрогаем Helm 3, создадим helm-чарт для нашей системы и выложим его в репозиторий, созданный на основе GitHub Pages.
разбираемся с системой управления контейнерами — «Хакер»
Содержание статьи
С появлением Docker интерес к контейнерам вырос взрывообразно: разворачивать приложения оказалось настолько удобно, что технологию начали использовать буквально везде. Облачные сервисы уже дают быстрый доступ к большому количеству виртуальных машин, которыми нужно управлять. Поэтому без инструмента, позволяющего запускать контейнеры на множестве хостов, масштабировать и выполнять балансировку, уже не обойтись. Разберемся с решением, предложенным Google.
Проект Kubernetes
Проект Kubernetes, или K8S, стартовал в Google в 2014 году, первая публичная версия 0.1 была представлена сообществу практически через год — в июле 2015-го. Нужно, наверное, особо отметить, что разработка не начиналась с нуля. В основе K8S лежит суперсекретный (в буквальном смысле этого слова) проект Гугла Borg — фактически основа основ управления кластерами в этой корпорации, проект, наработками которого до этого гигант не особо хотел делиться. Многие из разработчиков Borg перешли в Kubernetes, а вместе с ними туда перекочевали все идеи и решения проблем — перенос контейнеров без потерь данных, балансировка нагрузки, обнаружение сервисов. То есть можно сказать, что K8S — точная копия того, что в Google создавали долгое время, но адаптированная и ориентированная к применению Docker. Сразу после анонса проекта совместно с Linux Foundation была сформирована Cloud Computing Native Foundation (CNCF), в которую вошли сама Google, Cisco, IBM, Docker и VMware. Задача CNCF — выработать единый стандарт и обеспечить взаимодействие между разработчиками.
В Kubernetes реализованы все функции, необходимые для запуска приложений на основе Docker в конфигурации с высокой доступностью (кластеры более 1000 узлов, с multi-availability и multi-region зонами): управление кластером, планирование, обнаружение сервисов, мониторинг, управление учетными данными и многое другое. Выглядит это пугающе, но вся внутренняя кухня скрыта от админа. Он просто размещает контейнеры, все остальное — забота K8S. Для реализации этого используется больше десятка сторонних взаимодействующих услуг, которые вместе обеспечивают требуемую функциональность. Например, за координацию и хранение настроек отвечает etcd, создание сетей между контейнерами — flannel. Это несколько усложняет первоначальную настройку (хотя в последних релизах это уже не так заметно), но позволяет при необходимости просто заменить любой компонент. Для состыковки служб используются разные CLI, API, которые уже совместно реализуют API более высокого уровня для сервисных функций, таких как планирование ресурсов. Нужная функциональность должна быть специально адаптирована для K8S. Например, обратиться напрямую к API Docker нельзя (точнее, можно, но очень и очень нежелательно), следует использовать Docker Compose.
Kubernetes представляет собой систему с несколькими концепциями. Многие из этих понятий проявляются как «объекты» или «ресурсы» RESTful API. Кроме общепринятых, таких как Node, Cluster и Replication controller, есть и весьма специфические.
- Pods — единица планирования в Kubernetes. Группа или ресурс, в котором могут работать несколько контейнеров. Контейнеры из одного Pod будут запускаться на одном сервере и могут совместно использовать общие разделы. Объекты Pod описаны в так называемых PodSpec — YAML/JSON-файлах.
- Services — набор контейнеров, которые работают вместе, обеспечивая, например, функционирование многоуровневого приложения. K8S поддерживает динамическое наименование и балансировку нагрузки Pods с помощью абстракций, гарантируя прозрачное подключение к Services по имени и отслеживая их текущее состояние.
- Labels — пары ключ/значение, которые прикрепляются к Pod и фактически к любому объекту (сервису), позволяя их легко группировать, отбирать и назначать задания.
- IP-per-Pod — в Borg сервисы использовали один IP и для распределения сетевых ресурсов применялись порты. Это накладывало ряд ограничений. В K8S возможно назначить каждому Pod отдельный адрес.
- Namespaces — способ, позволяющий логически разделить единый кластер K8S на несколько виртуальных, каждый из них будет существовать в изолированном пространстве, ограниченном квотами, не влияя на других.
На всех узлах кластера minion устанавливаются агенты kubelet и kube-proxy (прокси-балансировщик). Агенты принимают из специального API сервера данные PodSpec (файл или HTTP) и гарантируют работоспособность указанных в нем объектов. Прокси обеспечивает перенаправление потоков между Pod. Мастер кластера содержит специальные компоненты — kube-controller-manager (менеджер сервисов) и kube-scheduler (планировщик), kube-apiserver, etcd и flannel. Доступ к API управления, кроме программного способа, можно получить через консольную утилиту kubectl и веб-интерфейс. С их помощью можно просматривать текущую конфигурацию, управлять ресурсами, создавать и разворачивать контейнеры.
Установка Kubernetes
Установка Kubernetes выполняется скриптом, и в процессе следует ориентироваться на официальную инструкцию, адаптировав ее к своему дистрибутиву. Она несложная, просто нужно быть очень внимательным. Мануалы из Сети работают не всегда, так как в разных версиях дистрибутива часто требуются различные действия и встречаются специфические проблемы, также разработчики по мере развития K8S меняют процесс развертывания и параметры в конфигурационных файлах. Установим в простейшем варианте K8S на одну систему master/minion в Ubuntu 14.04/16.04, так что нам не потребуются некоторые компоненты вроде сервера ключей. Перед установкой нужно составить список всех узлов и их сетевые параметры и роль. Проект предлагает исходные тексты и bash-скрипт.
Скрипт установки Kubernetes
Первый вариант дает чуть больше контроля, если что-то пойдет не так. Ставим приложения:
$ sudo apt install docker.io curl git bridge-utils
Для беспарольного входа генерируем ключ. Так как впоследствии понадобятся права root, то ключи генерируем для него. Все параметры оставляем по умолчанию, на запрос пароля жмем Enter.
$ sudo ssh-keygen -t rsa
$ sudo ssh-copy-id -i /home/user/.ssh/id_rsa.pub 127.0.0.1
Подтверждаем операцию и вводим свой пароль.
$ sudo cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys
После этого пробуем войти. Должно пустить без запроса пароля:
$ sudo ssh [email protected]
Если серверов несколько, поступаем аналогично и копируем на них ключи. Несмотря на простоту, это очень важный момент. Малейшая ошибка — и дальнейшие действия ни к чему не приведут. Забираем актуальный релиз (файл большой, почти 1,5 Гбайт):
$ wget -c https://github.com/kubernetes/kubernetes/releases/download/v1.3.5/kubernetes.tar.gz
Или ветку master:
$ wget -c https://github.com/kubernetes/kubernetes/archive/master.zip
Распаковываем:
$ tar -xvf kubernetes.tar.gz
Архив содержит примеры и готовые настройки в kubernetes/cluster
для самых разных конфигураций. Следует выбрать свою и запустить установочный скрипт. Так как ставим на Ubuntu, то выбираем этот вариант. Для начала нам нужно указать конфигурацию сети. Смотрим вывод ifconfig
— настройку физического интерфейса и docker0 — и приступаем к настройке.
# nano kubernetes/cluster/ubuntu/config-default.sh
# Прописываем ноды, она у нас пока одна, остальные при необходимости добавляем через пробел
export nodes=${nodes:-"[email protected]"}
# Роль a(master), i(minion), ai(master+minion)
export roles="ai"
# Количество minion
export NUM_MINIONS=${NUM_MINIONS:-1}
# Диапазон IP кластера, приватная сеть rfc1918
export SERVICE_CLUSTER_IP_RANGE=${SERVICE_CLUSTER_IP_RANGE:-192.168.1.0/24}
# Диапазон IP flannel сети Docker
export FLANNEL_NET=${FLANNEL_NET:-172.17.42.0/16}
DNS_SERVER_IP=${DNS_SERVER_IP:-"192.168.1.1"}
DNS_DOMAIN=${DNS_DOMAIN:-"cluster.local"}
ENABLE_CLUSTER_UI="${KUBE_ENABLE_CLUSTER_UI:-true}"
Конфигурационный файл config-default.sh
Это основные настройки, позволяющие запустить K8S. В файле также настраиваются параметры Docker и остальных компонентов, журналирование, мониторинг. Если к интернету подключение происходит через прокси, то его параметры следует прописать в PROXY_SETTING
.
PROXY_SETTING="http_proxy=http://server:port https_proxy=https://server:port"
Теперь можно развернуть кластер.
$ cd kubernetes/cluster
$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh
Starting cluster using provider: ubuntu
Скрипт закачает и установит все необходимые компоненты (etcd), на все прописанные в конфиге ноды. В процессе потребуется указать пароль для управления узлом. По окончании получим сообщение Cluster validation succeeded. Причем скрипт повторно будет скачивать последний релиз K8S — чтобы не повторять это дважды, просто скопируй файл kubernetes.tar.gz
в каталог kubernetes/cluster/ubuntu
и подправь скрипт закачки download-release.sh
.
Еще одна проблема, которую не могут устранить уже пару месяцев, — это ошибка при создании кластера:
saltbase/salt/generate-cert/make-ca-cert.sh: No such file or directory
Нужный файл расположен в каталоге kubernetes/server
, его просто забыли положить на место. Это можно сделать вручную или добавить в cluster/ubuntu/download-release.sh
две строки распаковки kubernetes-salt
.
tar xzf kubernetes-server-linux-amd64.tar.gz
tar xzf kubernetes-salt.tar.gz
....
cp kubernetes/server/kubernetes/server/bin/kubectl binaries/
cp -a kubernetes/server/kubernetes/saltbase ../
После чего master будет слушать на порту http://127.0.0.1:8080. Остановить кластер можно также одной командой:
$ KUBERNETES_PROVIDER=ubuntu ./kube-down.sh
Устанавливаем Kubernetes
Управляем кластером
Для управления K8S используется утилита kubectl. Настройки можно указывать прямо в командной строке или использовать заранее подготовленный YAML/JSON-файл. Чтобы было проще вводить команды, укажем в переменной PATH, где ее искать.
$ export PATH=$PATH:~/kubernetes/cluster/ubuntu/binaries
Для удобства лучше строку прописать сразу в ~/.bash_profile
. Два подкаталога — master и minion в ubuntu/binaries
— содержат утилиты для настройки мастера и подчиненных узлов. Все операции реализуются указанием одного из 20 ключей, список которых можем получить, введя
$ kubectl --help
Параметры kubectl
Смотрим список нод, настройки и данные кластера.
$ kubectl get nodes
$ kubectl cluster-info
$ kubectl config
В ответ должны получить список указанных ранее в config-default.sh
узлов. Запустим контейнер с nginx:
$ kubectl run nginxtest --image=nginx --port=80 --hostport=81
K8S сам загрузит и установит образ. Через время к nginx можно обратиться, подключившись на 81-й порт. Если нод несколько и нам нужна балансировка, может указываться параметр --create-external-load-balancer
и указывается количество реплик --replicas=№
. Текущее состояние репликации выводится командой kubectl get rc
.
Возможно заранее прописать настройки контейнера в файле, который затем использовать при развертывании командой create
:
$ kubectl create -f nginx.yaml
Если файлов много, то просто указывается каталог, в котором они находятся. Далее создаем сервис:
$ kubectl expose rc nginx --port=80 --target-port=80 --service-name=nginx -s "http://192.168.1.2:8080"
Теперь можем проверить доступные сервисы и POD.
$ kubectl get pods
В ответ получим имя (по которому можем обращаться к POD), состояние и возраст.
$ kubectl get services
Получение информации при помощи kubectl
Если нужно выполнить команду внутри контейнера, то используем kubectl exec
. Kubectl позволяет обращаться к некоторым ресурсам сразу по имени. В настоящее время доступно 19 типов ресурсов, все они описаны в документации к kubectl. Когда информации много, можно форматировать вывод при помощи -o
, отбирая произвольные колонки, или вывести в JSON/YAML-формате для дальнейшей обработки. Например, выведем в расширенном формате список нод и сервисов:
$ kubectl get rc,services -o=wide
Веб-интерфейс доступен по адресу https://<K8S-host>/ui
, пароль для входа можно посмотреть в выводе kubectl config view
. Если он не работает, следует установить его последнюю стабильную версию.
$ kubectl create -f https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml
Веб-интерфейс Kubernetes
Не Kubernetes единым
Параллельно с Kubernetes несколько компаний предложило свои решения, которые внешне похожи, но существенно различаются по реализации. Это Docker Swarm от разработчиков Docker, Nomad, Mesos/Marathon и Fleet.
Docker Swarm позволяет очень просто объединить Docker-хосты в один виртуальный хост, который внешне выглядит как обычный. Очень прост в развертывании, фактически нужно запустить еще один контейнер и присоединить к остальным. Для управления используется REST API интерфейс, совместимый с Docker API. В итоге абсолютно все инструменты, совместимые с API Docker, — Dokku, Compose, DockerUI и многие другие — могут работать с кластером Docker Swarm, как с обычным хостом. Это огромный плюс Docker Swarm, но, если API не поддерживает какую-то возможность, простого решения проблемы не будет.
Разработкой Nomad занимается HashiCorp — компания, специализирующаяся на инструментах управления кластерами, виртуальными машинами и облачными сервисами. В итоге получился универсальный многофункциональный инструмент, который может быть использован для более широкого круга задач. Он сочетает в себе легкий менеджер ресурсов и сложный планировщик, определяющий, на каком узле развернуть указанные ресурсы. Архитектурно проще Kubernetes, его легко разворачивать и настраивать. Поддерживает несколько ЦОД и multi-region конфигурации. Тестировался на кластерах до 5000 узлов, хотя вполне способен работать на гораздо более крупных кластерах. Серверная и клиентская часть реализованы в одном бинарнике, для координации или хранения не требуется других внешних служб. Может использоваться Consul для обнаружения сервисов и Vault для организации единого доступа. Все разработки HashiCorp.
Marathon представляет собой надстройку над менеджером кластера Apache Mesos, расширяя его возможности управлять контейнерами в нескольких ЦОД. Изначально разработан и применяется в Twitter. Использует другие решения Apache Software Foundation для организации, обнаружения приложений, планирования и прочего — ZooKeeper, Chronos, Kafka, Hadoop и другие. Поддерживается формат контейнера Docker и свой Mesos, но в принципе можно просто добавить другую технологию. Самостоятельная установка не самое простое дело, поэтому удобный способ развертывания — Mesosphere Enterprise DC/OS (CentOS + репозиторий). Кстати, уже есть наработки по интеграции API планировщика Kubernetes с Mesos — Kubernetes-Mesos.
Fleet — распределенная система инициализации на основе Systemd и etcd, которые разработчики представляют как Systemd уровня кластера. Нет некоторых важных функций — балансировки нагрузки, интеграции DNS, ACL и других. Их реализация пока под вопросом.
Вывод
Вывод короткий: несомненно, Kubernetes — интересный проект, который поможет справиться с увеличивающимся количеством контейнеров Docker и снимет с сисадмина часть проблем.
Что такое Kubernetes и зачем Big Data нужен этот DevOps-инструмент
Kubernetes (K8s) – это программное обеспечение для автоматизации развёртывания, масштабирования и управления контейнеризированными приложениями. Поддерживает основные технологии контейнеризации (Docker, Rocket) и аппаратную виртуализацию [1].
Зачем нужен Kubernetes
Kubernetes необходим для непрерывной интеграции и поставки программного обеспечения (CI/CD, Continuos Integration/ Continuos Delivery), что соответствует DevOps-подходу. Благодаря «упаковке» программного окружения в контейнер, микросервис можно очень быстро развернуть на рабочем сервере (production), безопасно взаимодействуя с другими приложениями. Наиболее популярной технологией такой виртуализации на уровне операционной системы считается Docker, пакетный менеджер которого (Docker Compose) позволяет описывать и запускать многоконтейнерные приложения [2].
Однако, если необходим сложный порядок запуска большого количества таких контейнеров (от нескольких тысяч), как это бывает в Big Data системах, потребуется средство управления ими – инструмент оркестрации. Именно это считается основным назначением Kubernetes.
При этом кубернетис – это не просто фреймворк для оркестрации контейнеров, а целая платформа управления контейнерами, которая позволяет параллельно запускать множество задач, распределённых по тысячам приложений (микросервисов), расположенных на различных кластерах (публичном облаке, собственном датацентре, клиентских серверах и т.д.).
Тем не менее, Kubernetes нельзя назвать классическим PaaS-решением: K8s состоит из нескольких модулей, которые можно различным образом комбинировать между собой, сохраняя ключевые функциональные возможности (развёртывание приложений, масштабирование, балансировка нагрузок, журналирование и пр.) [3].
История развития K8s
Изначально проект кубернетис был разработан корпорацией Google, одной из крупнейших Big Data компаний, для своих внутренних нужд на языке программирования Go. В середине 2014 года были опубликованы исходные коды проекта. Первый готовый релиз системы был выпущен 21 июля 2015 года (версия 1.0). Во второй половине 2015 года корпорация Google совместно с Linux Foundation организовали специальный фонд Cloud Native Computing Foundation (CNCF), которому и был передан Kubernetes в качестве начального технологического вклада [1].
Кубернетис, как и Docker, относится к технологиям виртуальной контейнеризации
Архитектура кубернетис
Kubernetes устроен по принципу master/slave, когда ведущим элементом является подсистема управления кластером, а некоторые компоненты управляют ведомыми узлами. Под узлом (node) понимается физическая или виртуальная машина, на которой работают контейнеры приложений. Каждый узел в кластере содержит инструменты для запуска контейнеризированных сервисов, например, Docker [2], а также компоненты для централизованного управления узлом.
Также на узлах развернуты поды (pods) — базовые модули управления и запуска приложений, состоящие из одного или нескольких контейнеров. При этом на одном узле для каждого пода обеспечивается разделение ресурсов, межпроцессное взаимодействие и уникальный IP-адрес в пределах кластера. Это позволяет приложениям, развёрнутым на поде, без риска конфликта использовать фиксированные и предопределённые номера портов. Для совместного использования нескольких контейнеров, развернутые на одном поде, их объединяют в том (volume) – общий ресурс хранения [1].
Помимо подов, на ведомых узлах также работают следующие компоненты Kubernetes [1]:
- Kube-proxy – комбинация сетевого прокси-сервера и балансировщика нагрузки, который, как сервис, отвечает за маршрутизацию входящего трафика на конкретные контейнеры в пределах пода на одном узле. Маршрутизация обеспечивается на основе IP-адреса и порта входящего запроса.
- Kubelet, который отвечает за статус выполнения подов на узле, отслеживая корректность выполнения каждого работающего контейнера.
Управление подами реализуется через API Kubernetes, интерфейс командной строки (Kubectl) или специализированные контроллеры (controllers) – процессы, которые переводят кластер из фактического состояния в желаемое, оперируя набором подов, определяемого с помощью селекторов меток. Селекторы меток (label selector) – это запросы, которые позволяют получить ссылку на нужный объект управления (узел, под, контейнер) [1].
На ведущем компоненте (master) работают следующие элементы [1]:
- Etcd – легковесная распределённая NoSQL-СУБД класса «ключ — значение», которая отвечает за согласованное хранение конфигурационных данных кластера.
- сервер API— ключевой компонент подсистемы управления, предоставляющий интерфейс программирования приложений в стиле REST (в формате JSON поверх HTTP-протокола) и используемый для внешнего и внутреннего доступа к функциям Kubernetes. Сервер API обновляет состояние объектов, хранящихся в etcd, позволяя своим клиентам управлять распределением контейнеров и нагрузкой между узлами системы.
- планировщик (scheduler), который регулирует распределение нагрузки по узлам, выбирая узел выполнения для конкретного пода в зависимости от доступности ресурсов узла и требований пода.
- менеджер контроллеров (controller manager) – процесс, выполняющий основные контроллеры Kubernetes (DaemonSet Controller и Replication Controller), которые взаимодействуют с сервером API, создавая, обновляя и удаляя управляемые ими ресурсы (поды, точки входа в сервисы и т.д.).
Архитектура Kubernetes
Как работает Kubernetes
Согласно концепции контейнеризации, контейнеры содержат выполняемые сервисы, библиотеки и прочие ресурсы, необходимые для работы этих приложений. Доступ к контейнеру извне реализуется через индивидуально назначаемый ему IP-адрес. Таким образом, в Kubernetes контейнер – это программный компонент самого низкого уровня абстракции. Для межпроцессного взаимодействия нескольких контейнеров они инкапсулируются в поды.
Задачей Kubernetes является динамическое распределение ресурсов узла между подами, которые на нем выполняются. Для этого на каждом узле с помощью встроенного агента внутреннего мониторинга Kubernetes cAdvisor ведется непрерывный сбор данных о производительности и использовании ресурсов (время работы центрального процессора, оперативной памяти, нагрузок на файловую и сетевую системы).
Что особенно важно для Big Data проектов, Kubelet – компонент Kubernetes, работающий на узлах, автоматически обеспечивает запуск, остановку и управление контейнерами приложений, организованными в поды. При обнаружении проблем с каким-то подом Kubelet пытается повторно развернуть и перезапустить его на узле.
Аналогично HDFS, наиболее популярной распределенной файловой системе для Big Data-решений, реализованной в Apache Hadoop, в кластере Kubernetes каждый узел постоянно отправляет на master диагностические сообщения (heartbeat message). Если по содержанию этих сообщений или в случае их отсутствия мастер обнаруживает сбой какого-либо узла, процесс подсистемы управления Replication Controller пытается перезапустить необходимые поды на другом узле, работающем корректно [1].
Принципы работы Kubernetes
Примеры использования кубернетис
Поскольку K8s предназначен для управления множеством контейнеризированных микросервисов, неудивительно, что эта технология приносит максимальную выгоду именно в Big Data проектах. Например, кубернетис используют популярный сервис знакомств Tinder [4], телекоммуникационная компания Huawei [5], крупнейший в мире онлайн-сервисом поиска автомобильных попутчиков BlaBlaCar [6], Европейский Центр ядерных исследований (CERN) [7] и множество других компаний, работающих с большими данными и нуждающимися в инструментах быстрого и отказоустойчивого развертывания приложений [3].
В связи с цифровизацией предприятий и распространением DevOps-подхода, спрос на владение Kubernetes растет и в отечественных компаниях. Как показал обзор вакансий с рекрутинговой площадки HeadHunter, в 2019 году для современного DevOps-инженера и Big Data разработчика данная технология является практически обязательной.
Kubernetes — настоящий must have для современного DevOps-инженера
Источники
- https://ru.wikipedia.org/wiki/Kubernetes
- https://ru.wikipedia.org/wiki/Docker
- https://habr.com/ru/company/flant/blog/327338/
- https://habr.com/ru/company/flant/blog/440278/
- https://habr.com/ru/company/flant/blog/349940/
- https://habr.com/ru/company/flant/blog/345780/
- https://habr.com/ru/company/flant/blog/412571/
Kubernetes против Docker: учебник
Различия и сходства между двумя наиболее влиятельными проектами с открытым кодом в 2018 году.
Kubernetes против Docker — тема, которая неоднократно поднималась в индустрии облачных вычислений. Если у вас нетехнический опыт и вам нужно быстрое представление или вам нужно принять деловое решение, я надеюсь, что следующие несколько слов прояснят этот вопрос раз и навсегда.
Нам нужно выйти за рамки ажиотажа, окружающего Kubernetes и Docker. Что означают эти слова, важно понять, прежде чем начинать на них свой бизнес.
Симбиоз Kubernetes и Docker
Вопрос: «Kubernetes или Docker?» само по себе довольно абсурдно, как сравнивать яблоки с апельсинами. Одно не является альтернативой другому. Наоборот; Kubernetes может работать без Docker, а Docker может работать без Kubernetes. Но Kubernetes может (и получает) большую выгоду от Docker, и наоборот.
Docker — это автономное программное обеспечение, которое можно установить на любой компьютер для запуска контейнерных приложений. Контейнеризация — это подход к запуску приложений в ОС, при котором приложение изолировано от остальной системы. Вы создаете иллюзию для своего приложения, что оно получает собственный экземпляр ОС, хотя могут быть и другие контейнеры, работающие в той же системе. Docker — это то, что позволяет нам запускать, создавать и управлять контейнерами в одной операционной системе.
Kubernetes увеличивает его, так сказать, до 11.Если у вас установлен Docker на нескольких хостах (разных операционных системах), вы можете использовать Kubernetes. Эти узлов или хостов Docker могут быть «голыми» серверами или виртуальными машинами. Kubernetes затем может позволить вам автоматизировать подготовку контейнеров, организацию сети, балансировку нагрузки, безопасность и масштабирование на всех этих узлах из единой командной строки или панели инструментов. Набор узлов, которым управляет один экземпляр Kubernetes, называется кластером Kubernetes.
Итак, зачем вам вообще нужно иметь несколько узлов? За этим стоят две основные мотивации:
- Чтобы сделать инфраструктуру более устойчивой: ваше приложение будет в сети, даже если некоторые из узлов отключатся, например, Высокая доступность .
- Чтобы сделать ваше приложение более масштабируемым : Если рабочая нагрузка увеличивается, просто создайте больше контейнеров и / или добавьте больше узлов в свой кластер Kubernetes.
Kubernetes автоматизирует процесс масштабирования, управления, обновления и удаления контейнеров.Другими словами, это платформа оркестровки контейнеров. Хотя Docker лежит в основе контейнеризации, он в первую очередь позволяет нам иметь контейнеры.
Различия между Kubernetes и Docker
В принципе Kubernetes может работать с любой технологией контейнеризации. Два самых популярных варианта, с которыми Kubernetes может интегрироваться, — это rkt и Docker. Однако больше всего внимания уделяется Docker, что привело к гораздо большим усилиям по совершенствованию интеграции между ним и Kubernetes, чем любая другая технология контейнеризации.
Точно так же Docker Inc., компания, стоящая за Docker, предлагает собственный механизм оркестровки контейнеров, Docker Swarm. Но даже компания осознала тот факт, что Kubernetes вырос до такой степени, что даже Docker для настольных ПК (MacOS и Windows) поставляется с собственным дистрибутивом Kubernetes .
Если кто-то нервничал по поводу принятия Kubernetes для своего продукта на основе Docker, этот последний пункт должен развеять любые сомнения. Оба проекта искренне приняли друг друга и получили огромную пользу от этого симбиоза.
Сходства между Kubernetes и Docker
Эти проекты — больше, чем просто технологии; это сообщество людей, которые, несмотря на их различия, составляют одни из самых ярких умов в отрасли. Когда единомышленники сотрудничают, они обмениваются яркими идеями и перенимают друг у друга передовой опыт.
Вот некоторые из идей, которые разделяют и Kubernetes, и Docker:
- Их любовь к архитектуре на основе микросервисов (подробнее об этом позже).
- Их любовь к сообществу открытого исходного кода. Оба являются крупными проектами с открытым исходным кодом.
- Они в основном написаны на языке программирования Go, что позволяет поставлять их в виде небольших легких двоичных файлов.
- Они используют удобочитаемые файлы YAML для определения стеков приложений и их развертывания.
Теоретически вы можете узнать об одном, даже не имея представления о другом. Но имейте в виду, что на практике вы получите гораздо больше пользы, если начнете с простого случая, когда Docker работает на одной машине, а затем постепенно поймете, как Kubernetes вступает в игру.
Давайте углубимся в эту тему.
Что такое докер?
Есть два взгляда на Docker. Первый подход предполагает рассмотрение контейнеров Docker как действительно легких виртуальных машин, тогда как второй подход заключается в том, чтобы рассматривать Docker как платформу для упаковки и доставки программного обеспечения. Последний подход оказался гораздо более полезным для разработчиков-людей и привел к широкому распространению технологии.
Давайте посмотрим на две разные точки зрения более внимательно.
Обзор контейнеров Docker
Традиционно поставщики облачных услуг использовали виртуальные машины для изоляции запущенных приложений друг от друга. Гипервизор или операционная система хоста предоставляет виртуальный ЦП, память и другие ресурсы многим гостевым операционным системам. Каждая гостевая ОС работает так, как если бы она была запущена на реальном физическом оборудовании, и в идеале она не знает о других гостевых системах, работающих на том же физическом сервере.
Однако есть несколько проблем с виртуализацией.Во-первых, выделение ресурсов требует времени. Каждый образ виртуального диска большой и громоздкий, и подготовка виртуальной машины к использованию может занять до минуты. Вторая — и более важная проблема — системные ресурсы используются неэффективно. Ядра ОС — фанаты контроля, которые хотят управлять всем, что им якобы доступно. Поэтому, когда гостевая ОС считает, что ей доступно 2 ГБ памяти, она берет на себя управление этой памятью, даже если приложения, работающие в этой ОС, используют только половину ее.
С другой стороны, когда мы запускаем контейнерные приложения, мы виртуализируем операционную систему (ваши стандартные библиотеки, пакеты и т.) само по себе, а не оборудование. Теперь вместо предоставления виртуального оборудования виртуальной машине вы предоставляете виртуальную ОС своему приложению. Вы можете запускать несколько приложений и налагать ограничения на использование их ресурсов, если хотите, и каждое приложение будет работать, не обращая внимания на сотни других контейнеров, с которыми оно работает.
Docker как инструмент разработчика
Одна из проблем, с которой часто сталкиваются разработчики, — это разница между производственным сервером, на котором выполняются приложения, и их собственными машинами разработчика (обычно ноутбуками и рабочими станциями), на которых разрабатываются приложения.Представим, что на вашем рабочем столе работает Windows 10, но вы хотите писать приложения для Ubuntu 18.04. Возможно, вы используете Python v3.6 для написания своего приложения, в то время как сервер Ubuntu все еще работает на версии 3.4.
Слишком много переменных, которые нужно учитывать, поэтому мы используем Docker, чтобы абстрагироваться от этой сложности. Docker можно установить на любую ОС; даже Windows и Mac OS X хорошо поддерживаются. Таким образом, вы можете упаковать свой код в образ Docker , запустить и протестировать его локально с помощью Docker, чтобы гарантировать, что контейнеры, созданные из этого образа Docker, будут вести себя одинаково в производственной среде.
Примечание. Все зависимости, такие как версия языка программирования, стандартная библиотека и т. Д., Содержатся в этом образе.
Такой взгляд на образы Docker как на программный пакет привел к следующей популярной цитате: «Docker сделает то, что apt сделал с tar».
Apt, менеджер пакетов, по-прежнему использует tar под капотом, но пользователям не о чем беспокоиться. Точно так же при использовании Docker нам не нужно беспокоиться о диспетчере пакетов, хотя он присутствует.Например, даже при разработке на основе технологии Node.js разработчики предпочитают создавать свои образы Docker поверх официального образа Docker.
Итак, это краткий обзор того, что такое Docker и почему о нем может быть интересно узнать, даже если они не участвуют в DevOps.
Теперь продолжим с Kubernetes.
Что такое Kubernetes?
Kubernetes использует технологию контейнеризации, как описано выше, и доводит ее до 11. Это позволяет нам запускать контейнеры на нескольких вычислительных узлах (это могут быть виртуальные машины или серверы без операционной системы).Как только Kubernetes берет на себя управление кластером узлов, контейнеры могут разворачиваться или отключаться в зависимости от наших потребностей в любой момент времени.
Официальный сайт ясно заявляет о цели Kubernetes: «… система с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнерными приложениями».
Пока что мы представили только наивный обзор Kubernetes как автоматизации создания нескольких контейнеров. У приложения должно быть хранилище, и есть записи DNS, которыми нужно управлять.Вам необходимо убедиться, что участвующие вычислительные узлы надежно связаны друг с другом и так далее. Наличие набора разных узлов вместо одного создает совершенно другой набор проблем.
Краткий обзор архитектуры Kubernetes поможет нам пролить свет на то, как ей удается достичь всего этого и многого другого.
Архитектура Kubernetes: краткий обзор
Есть две основные концепции, которые стоит знать о кластере Kubernetes. Первый — это узел .Это общий термин для виртуальных машин и / или серверов без операционной системы, которыми управляет Kubernetes. Второй термин — pod , который является базовой единицей развертывания в Kubernetes. Модуль pod — это набор связанных контейнеров Docker, которые должны сосуществовать с . Например, ваш веб-сервер может потребоваться развернуть с кэширующим сервером Redis, чтобы вы могли инкапсулировать их два в один модуль. Kubernetes разворачивает их одновременно. Если это упростит вам задачу, вы можете полностью представить контейнер, состоящий из одного контейнера, и это будет нормально.
Возвращаясь к узлам, есть два типа узлов. Один из них — это главный узел , на котором установлено сердце Kubernetes. Он контролирует планирование подов на различных рабочих узлах (также известных как узлов ), на которых ваше приложение фактически запускается. Задача главного узла — убедиться, что желаемое состояние кластера поддерживается.
Вот краткое изложение диаграммы Kubernetes, показанной выше.
На Kubernetes Master у нас:
- kube-controller-manager: Он отвечает за учет текущего состояния кластера (например,g, X количество работающих модулей) и принятие решений для достижения желаемого состояния (например, наличие Y количества активных модулей вместо этого). Он слушает на kube-apiserver информацию о состоянии кластера
- kube-apiserver: Этот сервер api раскрывает механизмы и рычаги Kubernetes. Он используется панелями управления WebUI и утилитой командной строки, например kubeclt. Эти утилиты, в свою очередь, используются людьми-операторами для взаимодействия с кластером Kubernetes.
- kube-scheduler: Это то, что определяет, как события и задания будут планироваться в кластере в зависимости от доступности ресурсов, политики, установленной операторами, и т. Д.Он также прослушивает kube-apiserver для получения информации о состоянии кластера.
- etcd: Это «стек хранения» для главных узлов Kubernetes. Он использует пары ключ-значение и используется для сохранения политик, определений, секретов, состояния системы и т. Д.
У нас может быть несколько мастер-узлов, чтобы Kubernetes мог выжить даже при выходе из строя главного узла.
На рабочем узле имеем:
- kubelet: Это передает информацию о состоянии узла обратно мастеру, а также выполняет инструкции, данные ему основным узлом.
- kube-proxy: Этот сетевой прокси-сервер позволяет различным микросервисам вашего приложения взаимодействовать друг с другом внутри кластера, а также предоставлять ваше приложение остальному миру, если вы того пожелаете. В принципе, каждый модуль может общаться с любым другим модулем через этот прокси.
- Докер: Это последний кусок головоломки. Каждый узел имеет механизм докеров для управления контейнерами.
Конечно, Kubernetes гораздо больше, и я призываю вас изучить все это.
Внедрение Docker и Kubernetes в отрасли
Многие концепции, которые мы обсуждали до сих пор, кажутся хорошими на бумаге, но являются ли они экономичными? Смогут ли они на самом деле помочь вашему бизнесу расти, сократить время простоя и сэкономить ресурсы как с точки зрения человеческих часов, так и с точки зрения вычислительной мощности?
Докер в производстве
Ответ прост, когда дело доходит до внедрения Docker. В частности, если вы применяете архитектуру на основе микросервисов для своего программного обеспечения, вам обязательно следует использовать контейнеры Docker для каждого микросервиса.
Технология достаточно зрелая и мало что можно сказать против нее. Имейте в виду, что простой контейнер для вашего кода не сделает его лучше для вас. Старайтесь избегать монолитных проектов и переходите на микросервисы, если вы действительно хотите использовать платформу контейнеризации.
Kubernetes в производстве
Нельзя обвинять в разглагольствовании о Kubernetes в производственной среде, и, по моему личному мнению, причина этого двоякая.
Во-первых, большинство организаций слепо прыгают, не понимая основных концепций распределенной системы.Они пытаются создать собственный кластер Kubernetes и использовать его для размещения простых веб-сайтов или небольшого масштабируемого приложения. Это довольно рискованно, если у вас нет глубоких знаний о системе. Вещи могут легко сломаться.
Во-вторых, Kubernetes стремительно развивается, и другие организации добавляют к нему свои собственные особенности, такие как сервисная сетка, сетевые плагины и т. Д. Большинство из них имеют открытый исходный код и поэтому привлекательны для операторов. Однако запускать их в производство — это не то, что я бы рекомендовал.Чтобы не отставать от них, требуется постоянное обслуживание кластера и больше человеческих часов.
Однако существуют облачные платформы Kubernetes, которые организации могут использовать для запуска своих приложений. Доступность размещенных центров обработки данных по всему миру действительно может помочь вам получить максимальную отдачу от распределенной природы Kubernetes. И, конечно же, вам не нужно беспокоиться об обслуживании кластера.
Это то, что малые и средние организации часто упускают из виду.Если вы хотите пережить сбои узлов и получить высокую масштабируемость, вам не следует запускать Kubernetes на одной стойке высотой 1U или даже в одном центре обработки данных.
Итак, Kubernetes в производстве? Да, но большинству я бы порекомендовал облачные решения.
Контейнеры и новая эра облачных вычислений
Docker не позиционировался как программное обеспечение для виртуализации на уровне ОС; он позиционируется как механизм упаковки и доставки программного обеспечения. Единственная причина, по которой контейнеры Docker привлекли больше внимания, чем их конкуренты, заключается в таком подходе к доставке программного обеспечения.
Автоматическая сборка намного проще благодаря Dockerfiles. Сложные многоконтейнерные развертывания теперь стандартизированы благодаря docker-compose. Программные инженеры довели контейнеры до своего логического предела, предоставив полные решения CI / CD, включающие создание и тестирование образов Docker и управление общедоступными или частными реестрами Docker.
Kubernetes избавил контейнеры от застревания на одном компьютере, сделав облако еще более привлекательным местом для этой технологии.Медленно, но верно контейнеризация станет нормой для каждой облачной службы; поэтому важно использовать эту технологию раньше, чем позже. Это позволит минимизировать затраты на миграцию и связанные с этим риски.
Пример для распределенной операционной системы
Теперь, когда я рассказывал о компаниях, внедряющих Kubernetes, не понимая этого полностью, позвольте мне объяснить, почему вы должны принять Kubernetes. Облачные вычисления превратились в этот высококонкурентный рынок, на котором Google, Microsoft, Amazon и многие другие игроки конкурируют друг с другом.
Это резко снизило стоимость развертывания вашего программного обеспечения в облаке. Лучшее в Kubernetes — это то, что это в основном открытый исходный код, поэтому вы можете понять, что происходит, не слишком увязнув в деталях.
Простое знание того, как оно работает на поверхностном уровне, позволяет вам рассуждать о вашем программном обеспечении, поскольку оно работает в распределенной системе. Но вам не нужно беспокоиться об управлении базовым кластером.
Даже малые предприятия и индивидуальные разработчики теперь могут масштабировать свои приложения по всей планете.Небольшое понимание того, как это достигается, не повредит, поэтому вы должны хотя бы мельком познакомиться с Kubernetes и Dockers.
Более тонкие различия — Сеть
Многие споры между Kubernetes и Docker уходят корнями в основы, такие как реализация стека хранения и сети. И Docker, и Kubernetes любят действовать по-разному.
Контейнер требует гораздо большего, чем просто ЦП и немного памяти, чтобы быть полезным. Есть много тонких различий между запуском приложения на платформе, такой как Kubernetes или хосты Docker.Этих различий слишком много, чтобы упоминать их здесь кратко, но одно, что всегда привлекает мое внимание, — это сетевая сторона вещей.
Kubernetes указывает, что каждый модуль должен иметь возможность свободно взаимодействовать с каждым другим модулем в кластере в заданном пространстве имен, тогда как Docker имеет концепцию создания топологий виртуальной сети, и вы должны указать, к каким сетям вы хотите, чтобы ваши контейнеры подключались. Подобные различия могут действительно отпугнуть людей, пытающихся проверить воду, но они имеют решающее значение, если учесть фундаментальные различия Kubernetes и Docker: первый предназначен для работы в кластере, а второй — на одном узле.
У этой дилеммы действительно нет альтернативы, и вам просто нужно набраться терпения, продвигаясь по кривой обучения. Постепенно более широкая картина станет яснее вашим глазам.
Что усыновить?
Преимущества Docker очевидны. Если вы отправляете свое приложение в контейнере Docker, его также можно запустить в любом дистрибутиве Linux. Даже операционные системы на основе Illumos, которые вообще не являются Linux, поддерживают Docker и могут запускать контейнеры Docker.
Ваше приложение может быть разбито на несколько микросервисов; Таким образом, каждый микросервис можно упаковать как контейнер Docker.Благодаря четко определенному API новые функции могут быть легко добавлены к существующим. Например, если вам нужна аналитика, просто разверните контейнер Hadoop, который может взаимодействовать с базой данных.
Аналогичным образом, когда дело доходит до Kubernetes, как пользователи, так и поставщики облачных услуг могут получить большую выгоду, приняв его. Поскольку Kubernetes основан на контейнеризации, поставщики облачных услуг могут получить высокую плотность контейнеров, эффективно используя свои ресурсы, в отличие от традиционных виртуальных машин. Это позволяет им существенно снизить цену.
Пользователи, с другой стороны, могут развернуть свое приложение по всему миру, уменьшая задержку и улучшая взаимодействие с пользователем.
Единственным исключением из этого изменения будут разработчики настольных приложений. Большинство настольных приложений используют облако для обновлений и / или резервного копирования, но в основном они предназначены для работы на одном компьютере.
Заключение
Контейнеры потрясающие. Они позволяют нам думать об услугах и системах совершенно по-новому и в цифровом формате. И Docker, и Kubernetes здесь, чтобы остаться — они постоянно меняются, чтобы в будущем стать чем-то лучше.Реализуйте контейнеры, которые больше всего нужны вашей инфраструктуре.
Разработка нового программного обеспечения для платформы, ориентированной на контейнер, не только делает ваши приложения более масштабируемыми, но и более перспективными. Придерживаться старых виртуальных машин на данный момент может сработать, но через несколько лет вам в конечном итоге придется либо нести большие затраты на перенос всего в контейнеры, либо вообще отказаться от проектов.
Надеюсь, что теперь, если кто-то поднимет тему Kubernetes против Docker , , вы не попадете под жаргон.
Связанные
.
Извлечь образ из частного реестра
На этой странице показано, как создать модуль, который использует секрет для извлечения образа из
частный реестр или репозиторий Docker.
Перед тем как начать
У вас должен быть кластер Kubernetes, а инструмент командной строки kubectl должен
быть настроенным для связи с вашим кластером. Если у вас еще нет
кластер, вы можете создать его, используя
Миникубе,
или вы можете использовать одну из этих игровых площадок Kubernetes:Чтобы проверить версию, введите
kubectl version
.Для выполнения этого упражнения вам понадобится
Docker ID и пароль.
Войдите в Docker
На портативном компьютере вы должны пройти аутентификацию в реестре, чтобы получить частный образ:
При появлении запроса введите имя пользователя и пароль Docker.
Процесс входа в систему создает или обновляет файл config.json
, содержащий токен авторизации.
Просмотрите файл config.json
:
cat ~ / .docker / config.json
Вывод содержит подобный раздел:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "c3R ... zE2"
}
}
}
Примечание: Если вы используете хранилище учетных данных Docker, вы увидите не запись
auth
, а записьcredsStore
с именем хранилища в качестве значения.
Создайте секрет на основе существующих учетных данных Docker
Кластер Kubernetes использует секрет docker-registry типа
для аутентификации с помощью
реестр контейнеров для получения личного образа.
Если вы уже запустили docker login
, вы можете скопировать эти учетные данные в Kubernetes:
kubectl create secret generic regcred \
--from-file = .dockerconfigjson = <путь / к / .docker / config.json> \
--type = kubernetes.io / dockerconfigjson
Если вам нужно больше контроля (например, чтобы установить пространство имен или метку на новом
secret), то вы можете настроить секрет перед его сохранением.
Обязательно:
- задайте имя элемента данных
.dockerconfigjson
- base64 кодирует файл докера и вставляет эту строку без разрывов
в качестве значения поляdata [". dockerconfigjson"]
- установить
type
наkubernetes.io/dockerconfigjson
Пример:
apiVersion: v1
вид: Секрет
метаданные:
имя: myregistrykey
пространство имен: awesomeapps
данные:
.dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg ==
тип: кубернетес.io / dockerconfigjson
Если вы получаете сообщение об ошибке error: никакие объекты не переданы для создания
, это может означать, что строка в кодировке base64 недействительна.
Если вы получаете сообщение об ошибке типа Секретный ключ "myregistrykey" недействителен: данные [.dockerconfigjson]: недопустимое значение ...
, это означает
строка данных в кодировке base64 была успешно декодирована, но не может быть проанализирована как файл .docker / config.json
.
Создайте секрет, указав учетные данные в командной строке
Создайте этот секрет, назвав его regcred
:
kubectl create secret docker-registry regcred --docker-server = --docker -username = <ваше-имя> --docker-password = <ваш-пароль> --docker-email = <ваш-адрес>
где:
-
-
-
<ваш-пароль>
— ваш пароль Docker. -
Вы успешно установили свои учетные данные Docker в кластере в качестве секрета с именем regcred
.
Примечание: Секреты ввода в командной строке могут хранить их в истории вашей оболочки незащищенными, и
эти секреты также могут быть видны другим пользователям на вашем ПК в то время, когда
kubectl
работает.
Проверка секрета regcred
Чтобы понять содержимое только что созданного секрета regcred
, начните с просмотра секрета в формате YAML:
kubectl get secret regcred --output = yaml
Результат выглядит примерно так:
apiVersion: v1
вид: Секрет
метаданные:
...
имя: regcred
...
данные:
.dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0 =
введите: kubernetes.io/dockerconfigjson
Стоимость .Поле dockerconfigjson
представляет собой представление ваших учетных данных Docker в формате base64.
Чтобы понять, что находится в поле .dockerconfigjson
, преобразуйте секретные данные в
читаемый формат:
kubectl get secret regcred --output = "jsonpath = {. data. \. dockerconfigjson}" | base64 --decode
Вывод будет примерно таким:
{"auths": {"your.private.registry.example.com": {"username": "janedoe", "password": "xxxxxxxxxxx", "email ":" jdoe @ example.com "," auth ":" c3R ... zE2 "}}}
Чтобы понять, что находится в поле auth
, преобразуйте данные в кодировке base64 в читаемый формат:
echo "c3R ... zE2" | base64 --decode
Выходные данные, имя пользователя и пароль, объединенные с :
, выглядят следующим образом:
janedoe: xxxxxxxxxxx
Обратите внимание, что секретные данные содержат токен авторизации, аналогичный локальному файлу ~ / .docker / config.json
.
Вы успешно установили свои учетные данные Docker в качестве секрета с именем regcred
в кластере.
Создайте Pod, который использует ваш Secret
Вот файл конфигурации для Pod, которому требуется доступ к вашим учетным данным Docker в regcred
:
apiVersion: v1
вид: Стручок
метаданные:
имя: private-reg
спецификации:
контейнеры:
- имя: private-reg-container
изображение: <ваше частное изображение>
imagePullSecrets:
- имя: regcred
Загрузите указанный выше файл:
wget -O my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml
В файле my-private-reg-pod.yaml
замените
на путь к образу в частном реестре, например:
your.private.registry.example .com / janedoe / jdoe-private: v1.
Чтобы извлечь образ из частного реестра, Kubernetes необходимы учетные данные.
Поле imagePullSecrets
в файле конфигурации указывает, что Kubernetes должен получать учетные данные от секрета с именем regcred
.
Создайте модуль, использующий ваш секрет, и убедитесь, что модуль работает:
kubectl apply -f my-private-reg-pod.yaml
kubectl get pod private-reg
Что дальше
Последнее изменение 30 мая 2020 г., 15:10 по тихоокеанскому стандартному времени: добавить страницы en (ecc27bbbe).