Контейнеризация стала стандартом де-факто для развертывания современных приложений. Docker и Kubernetes позволяют упростить управление инфраструктурой, обеспечить масштабируемость и повысить надежность систем. В этой статье разберем, что представляют собой эти технологии, их преимущества и недостатки, основные команды, а также рассмотрим практические примеры развертывания продуктов Atlassian в контейнерах.
Что такое Docker
Docker — это платформа для контейнеризации приложений, которая позволяет упаковать приложение вместе со всеми его зависимостями (библиотеки, системные инструменты, код) в единый контейнер. Контейнер — это изолированная среда выполнения, которая работает на основе операционной системы хоста, но имеет собственную файловую систему, процессы и сетевые настройки.
Основные концепции Docker:
- Образ (Image) — шаблон, содержащий файловую систему и метаданные для создания контейнера
- Контейнер (Container) — запущенный экземпляр образа
- Dockerfile — текстовый файл с инструкциями для сборки образа
- Docker Compose — инструмент для оркестрации нескольких контейнеров
- Docker Hub — публичный реестр образов
Что такое Kubernetes
Kubernetes (K8s) — это платформа для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Kubernetes работает на уровне выше Docker, управляя множеством контейнеров на нескольких хостах, обеспечивая их отказоустойчивость, балансировку нагрузки и автоматическое масштабирование.
Ключевые концепции Kubernetes:
- Pod — минимальная единица развертывания, может содержать один или несколько контейнеров
- Node — виртуальная или физическая машина, на которой запускаются Pod'ы
- Service — абстракция, предоставляющая стабильный IP и DNS для группы Pod'ов
- Deployment — декларативное описание желаемого состояния приложения
- Namespace — виртуальная группировка ресурсов в кластере
Плюсы Docker
Изоляция и переносимость
Приложение работает одинаково на любой системе, где установлен Docker. "Работает на моей машине" больше не проблема — контейнер гарантирует идентичную среду выполнения.
Быстрое развертывание
Контейнеры запускаются за секунды, в отличие от виртуальных машин, которым требуются минуты. Это значительно ускоряет процесс разработки и деплоя.
Эффективное использование ресурсов
Контейнеры используют общее ядро операционной системы, что означает меньший расход памяти и CPU по сравнению с виртуальными машинами. На одном сервере можно запустить в несколько раз больше контейнеров.
Простота управления зависимостями
Все зависимости приложения включены в образ, что исключает конфликты версий и проблемы с установкой на разных системах.
Версионирование образов
Легко откатиться к предыдущей версии приложения, просто запустив другой образ. Это упрощает управление релизами и откат изменений.
Минусы Docker
Сложность управления на уровне продакшена
Для управления множеством контейнеров в production нужны дополнительные инструменты оркестрации (Kubernetes, Docker Swarm, Nomad). Docker сам по себе не решает задачи масштабирования и высокой доступности.
Проблемы с хранением данных
Контейнеры эфемерны — данные внутри контейнера теряются при его удалении. Требуется настройка volumes для постоянного хранения данных, что добавляет сложности.
Безопасность
Контейнеры используют общее ядро ОС, что создает потенциальные векторы атак. Неправильная конфигурация может привести к утечкам между контейнерами. Требуется особое внимание к безопасности образов и конфигурации.
Кривая обучения
Новая парадигма требует обучения команды. Необходимо понимать концепции контейнеризации, Dockerfile, docker-compose, управление сетями и volumes.
Плюсы Kubernetes
Автоматическое масштабирование
Kubernetes может автоматически увеличивать или уменьшать количество реплик приложения в зависимости от нагрузки (Horizontal Pod Autoscaler). Это позволяет эффективно использовать ресурсы и обеспечивать производительность под нагрузкой.
Самовосстановление
Kubernetes автоматически перезапускает упавшие контейнеры, заменяет неисправные Pod'ы и распределяет нагрузку между работоспособными экземплярами. Это обеспечивает высокую доступность приложения.
Балансировка нагрузки
Встроенная балансировка нагрузки между Pod'ами через Service и Ingress. Kubernetes автоматически направляет трафик на здоровые экземпляры приложения.
Декларативная конфигурация
Состояние приложения описывается в YAML-файлах, которые можно версионировать в Git. Это обеспечивает Infrastructure as Code подход и упрощает управление конфигурацией.
Мощная экосистема
Большое сообщество, множество готовых решений (Helm charts, Operators), интеграции с CI/CD системами, инструменты мониторинга и логирования.
Минусы Kubernetes
Высокая сложность
Kubernetes — это сложная система с множеством концепций и компонентов. Требуется значительное время на изучение и понимание архитектуры. Неправильная настройка может привести к проблемам в production.
Ресурсоемкость
Kubernetes сам по себе требует значительных ресурсов. Для небольшого проекта настройка полноценного кластера может быть избыточной. Минимальный кластер требует как минимум 2-4 CPU и 4-8 GB RAM.
Overhead на управление
Требуется отдельная команда для поддержки и мониторинга кластера (если не используете managed решение). Обновления, безопасность, резервное копирование — все это требует постоянного внимания.
Stateful приложения
Работа с stateful приложениями (например, базы данных) в Kubernetes сложнее, чем с stateless. Требуется настройка StatefulSets, PersistentVolumes, правильная конфигурация storage class.
Основные команды Docker
Управление образами
# Скачать образ
docker pull atlassian/jira-software
# Просмотреть список образов
docker images
# Удалить образ
docker rmi atlassian/jira-software
# Построить образ из Dockerfile
docker build -t my-jira:latest .
# Просмотреть историю образа
docker history atlassian/jira-software
Управление контейнерами
# Запустить контейнер
docker run -d --name jira -p 8080:8080 atlassian/jira-software
# Запустить контейнер с volumes
docker run -d --name jira \
-p 8080:8080 \
-v jira-data:/var/atlassian/application-data/jira \
atlassian/jira-software
# Просмотреть запущенные контейнеры
docker ps
# Просмотреть все контейнеры (включая остановленные)
docker ps -a
# Остановить контейнер
docker stop jira
# Запустить остановленный контейнер
docker start jira
# Перезапустить контейнер
docker restart jira
# Удалить контейнер
docker rm jira
# Удалить контейнер с принудительной остановкой
docker rm -f jira
# Просмотреть логи контейнера
docker logs jira
# Следить за логами в реальном времени
docker logs -f jira
# Выполнить команду внутри контейнера
docker exec -it jira bash
# Просмотреть использование ресурсов
docker stats jira
Управление volumes
# Создать volume
docker volume create jira-data
# Просмотреть список volumes
docker volume ls
# Просмотреть информацию о volume
docker volume inspect jira-data
# Удалить volume
docker volume rm jira-data
Docker Compose
# Запустить сервисы из docker-compose.yml
docker-compose up -d
# Остановить сервисы
docker-compose down
# Просмотреть логи
docker-compose logs -f
# Пересобрать образы
docker-compose build
# Просмотреть статус сервисов
docker-compose ps
Основные команды Kubernetes
Управление Pod'ами
# Просмотреть Pod'ы
kubectl get pods
# Просмотреть Pod'ы с подробной информацией
kubectl get pods -o wide
# Просмотреть Pod'ы в namespace
kubectl get pods -n jira
# Просмотреть описание Pod'а
kubectl describe pod jira-7d8f9c6b4-abc123
# Просмотреть логи Pod'а
kubectl logs jira-7d8f9c6b4-abc123
# Выполнить команду в Pod'е
kubectl exec -it jira-7d8f9c6b4-abc123 -- bash
# Удалить Pod
kubectl delete pod jira-7d8f9c6b4-abc123
Управление Deployments
# Создать Deployment из YAML
kubectl apply -f jira-deployment.yaml
# Просмотреть Deployments
kubectl get deployments
# Просмотреть описание Deployment
kubectl describe deployment jira
# Масштабировать Deployment
kubectl scale deployment jira --replicas=3
# Обновить образ в Deployment
kubectl set image deployment/jira jira=atlassian/jira-software:9.0.0
# Просмотреть историю изменений
kubectl rollout history deployment/jira
# Откатить к предыдущей версии
kubectl rollout undo deployment/jira
# Удалить Deployment
kubectl delete deployment jira
Управление Services
# Просмотреть Services
kubectl get services
# Просмотреть описание Service
kubectl describe service jira-service
# Создать Service из YAML
kubectl apply -f jira-service.yaml
# Удалить Service
kubectl delete service jira-service
Общие команды
# Просмотреть все ресурсы
kubectl get all
# Просмотреть все ресурсы в namespace
kubectl get all -n jira
# Применить конфигурацию из файла
kubectl apply -f config.yaml
# Удалить ресурсы из файла
kubectl delete -f config.yaml
# Просмотреть версию Kubernetes
kubectl version
# Просмотреть информацию о кластере
kubectl cluster-info
# Просмотреть конфигурацию
kubectl config view
Развертывание Jira в Docker
Atlassian предоставляет официальные Docker-образы для своих продуктов. Рассмотрим пример развертывания Jira Software в Docker.
Простой пример с docker run
# Создать volume для данных
docker volume create jira-data
# Запустить Jira
docker run -d \
--name jira \
-p 8080:8080 \
-v jira-data:/var/atlassian/application-data/jira \
-e ATL_TOMCAT_MGMTPORT=8005 \
atlassian/jira-software:latest
Docker Compose для Jira с PostgreSQL
Создайте файл docker-compose.yml:
version: '3.8'
services:
postgres:
image: postgres:13
environment:
POSTGRES_DB: jiradb
POSTGRES_USER: jira
POSTGRES_PASSWORD: jira_password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U jira"]
interval: 10s
timeout: 5s
retries: 5
jira:
image: atlassian/jira-software:latest
ports:
- "8080:8080"
environment:
ATL_JDBC_URL: jdbc:postgresql://postgres:5432/jiradb
ATL_JDBC_USER: jira
ATL_JDBC_PASSWORD: jira_password
ATL_DB_TYPE: postgres72
volumes:
- jira-data:/var/atlassian/application-data/jira
depends_on:
postgres:
condition: service_healthy
volumes:
postgres-data:
jira-data:
Запуск:
docker-compose up -d
Dockerfile для кастомизированного образа Jira
FROM atlassian/jira-software:latest
# Копировать кастомные плагины
COPY plugins/* /opt/atlassian/jira/atlassian-jira/WEB-INF/lib/
# Копировать кастомную конфигурацию
COPY server.xml /opt/atlassian/jira/conf/server.xml
# Установить переменные окружения
ENV JAVA_OPTS="-Xms1024m -Xmx2048m -XX:+UseG1GC"
USER root
RUN chown -R jira:jira /opt/atlassian/jira
USER jira
EXPOSE 8080
Развертывание Jira в Kubernetes
Deployment для Jira
Создайте файл jira-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: jira
namespace: jira
spec:
replicas: 2
selector:
matchLabels:
app: jira
template:
metadata:
labels:
app: jira
spec:
containers:
- name: jira
image: atlassian/jira-software:latest
ports:
- containerPort: 8080
env:
- name: ATL_JDBC_URL
valueFrom:
secretKeyRef:
name: jira-secrets
key: jdbc-url
- name: ATL_JDBC_USER
valueFrom:
secretKeyRef:
name: jira-secrets
key: jdbc-user
- name: ATL_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: jira-secrets
key: jdbc-password
- name: JAVA_OPTS
value: "-Xms1024m -Xmx2048m -XX:+UseG1GC"
volumeMounts:
- name: jira-data
mountPath: /var/atlassian/application-data/jira
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /status
port: 8080
initialDelaySeconds: 300
periodSeconds: 30
readinessProbe:
httpGet:
path: /status
port: 8080
initialDelaySeconds: 180
periodSeconds: 10
volumes:
- name: jira-data
persistentVolumeClaim:
claimName: jira-pvc
Service для Jira
Создайте файл jira-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: jira-service
namespace: jira
spec:
selector:
app: jira
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
PersistentVolumeClaim для данных
Создайте файл jira-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jira-pvc
namespace: jira
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: fast-ssd
Применение конфигурации
# Создать namespace
kubectl create namespace jira
# Создать Secret с учетными данными БД
kubectl create secret generic jira-secrets \
--from-literal=jdbc-url='jdbc:postgresql://postgres:5432/jiradb' \
--from-literal=jdbc-user='jira' \
--from-literal=jdbc-password='jira_password' \
-n jira
# Применить конфигурацию
kubectl apply -f jira-pvc.yaml
kubectl apply -f jira-deployment.yaml
kubectl apply -f jira-service.yaml
# Проверить статус
kubectl get all -n jira
Развертывание Confluence в Docker
Аналогично можно развернуть Confluence. Пример docker-compose.yml для Confluence с PostgreSQL:
version: '3.8'
services:
postgres:
image: postgres:13
environment:
POSTGRES_DB: confluencedb
POSTGRES_USER: confluence
POSTGRES_PASSWORD: confluence_password
volumes:
- postgres-data:/var/lib/postgresql/data
confluence:
image: atlassian/confluence-server:latest
ports:
- "8090:8090"
environment:
ATL_JDBC_URL: jdbc:postgresql://postgres:5432/confluencedb
ATL_JDBC_USER: confluence
ATL_JDBC_PASSWORD: confluence_password
ATL_DB_TYPE: postgres72
volumes:
- confluence-data:/var/atlassian/application-data/confluence
depends_on:
- postgres
volumes:
postgres-data:
confluence-data:
Важные замечания для Atlassian в контейнерах
Хранение данных
Всегда используйте volumes для хранения данных приложений Atlassian. Данные в /var/atlassian/application-data
должны сохраняться между перезапусками контейнеров. Используйте named volumes или host mounts.
Настройка памяти
Убедитесь, что контейнеру выделено достаточно памяти через переменную окружения JAVA_OPTS или
через limits в Kubernetes. Для Jira рекомендуется минимум 2GB heap памяти, для Confluence — 1-2GB.
База данных
Для production окружения используйте внешнюю базу данных (PostgreSQL, MySQL, MS SQL). Встроенная H2 база данных предназначена только для тестирования и не поддерживается в production.
Кластеризация
Для Data Center версий в Kubernetes требуется дополнительная настройка shared file storage (например, NFS) и правильная конфигурация кластерных параметров через переменные окружения.
Резервное копирование
Настройте регулярное резервное копирование volumes и базы данных. В Kubernetes используйте решения типа Velero для backup всей конфигурации и данных.
Мониторинг
Настройте мониторинг состояния контейнеров через health checks, логирование в централизованную систему (ELK, Loki) и метрики (Prometheus, Grafana).
Выводы
Docker и Kubernetes предоставляют мощные инструменты для современного развертывания приложений Atlassian. Docker упрощает упаковку и изоляцию приложений, а Kubernetes решает задачи масштабирования, высокой доступности и автоматизации управления.
Выбор между простым Docker и Kubernetes зависит от масштаба вашей инфраструктуры:
- Docker/Docker Compose — подходит для небольших и средних инсталляций, development и staging окружений
- Kubernetes — необходим для крупных кластеров, высоких требований к доступности, автоматического масштабирования
Важно помнить, что контейнеризация не решает все проблемы автоматически. Правильная настройка, мониторинг, резервное копирование и безопасность требуют внимания независимо от выбранной технологии.
Если вам нужна помощь с развертыванием Atlassian в Docker или Kubernetes — свяжитесь со мной.