← Назад к статьям

Docker и Kubernetes для развертывания Atlassian: полное руководство

Контейнеризация стала стандартом де-факто для развертывания современных приложений. 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 — свяжитесь со мной.