
В сегодняшнем динамичном технологическом ландшафте востребованы быстрые, надежные, безопасные развертывания приложений. Исход гонки инноваций определяется слаженностью взаимодействия разработки и операций, где используются практики DevOps.
Среди фреймворков и инструментов этой экосистемы выделяется Kubernetes ― основа для развертывания масштабируемых приложений, а Jenkins остается главным инструментом автоматизации конвейеров сборки. Но по мере усложнения систем для обеспечения надежности и производительности незаменимой становится интеграция полноценного мониторинга с такими инструментами, как Prometheus и Grafana.
Эффективный конвейер DevOps создается гармоничным сочетанием проектирования, автоматизации и оркестрации компонентов. Воспользуемся передовыми технологиями: Jenkins, Ansible, Docker, Kubernetes, Prometheus, Grafana — и построим комплексный конвейер сборки, развертываемый на AWS. Продемонстрируем этим конвейером, как при объединении автоматизации инфраструктуры и мониторинга приложений создаются устойчивые системы, способные масштабироваться в соответствии с потребностями.
Начнем с высокоуровневой архитектуры, которой описывается рабочий процесс — от размещаемого на GitHub кода до контейнеризации, проверки безопасности и, наконец, развертывания в кластерах Kubernetes. Благодаря наблюдаемости — сбору метрик приложений в Prometheus и их визуализации в Grafana — расширяются возможности команд устранять потенциальные узкие места, повышать надежность системы.
Но мы не ограничимся теорией. Каждый описанный здесь конфигурационный файл, скрипт и этап тестируются в реальной среде — это настройка с тремя экземплярами AWS EC2, каждому из которых отводится конкретная роль в конвейере: Jenkins для оркестровки, Ansible для автоматизации, Kubernetes для оркестрации контейнеров. Настроив каждый экземпляр, сконфигурировав инструменты и подключив эти системы, создадим комплексный рабочий процесс.
Этот конвейер ориентирован на современные практики:
- Контейнеризация: приложение и его зависимости инкапсулируются при помощи Docker, чем обеспечивается его согласованная работа во всех средах.
- Безопасность: сканированием образов контейнеров, благодаря Trivy, уязвимости устраняются до развертывания, и это соответствует философии «сдвига влево» DevSecOps.
- Масштабируемость: благодаря развертыванию кластера Kubernetes осуществляется горизонтальное масштабирование, посредством реплик обеспечивается высокая доступность.
- Мониторинг и наблюдаемость: с Prometheus и Grafana в режиме реального времени получается представление о работоспособности и производительности системы.
- Автоматизация: применением Ansible упрощаются и автоматизируются развертывания Kubernetes, человеческое вмешательство и вызванные этим ошибки сокращаются.
Конвейер легко интегрируется с приложением Django и включенным в него django-prometheus, поэтому им собираются детализированные показатели на уровне приложения. В Prometheus регулярно предоставляются и извлекаются ключевые индикаторы производительности: скорость прохождения запросов, время выполнения запросов к базе данных, частота ошибок. Затем эти показатели визуализируются в динамических дашбордах Grafana, откуда получаются полезные сведения о производительности приложения и инфраструктуры. Само приложение проекта Django при помощи Docker контейнеризировано, в него включены передовые концепции автоматизации.
К концу статьи у вас сформируется четкое представление о том, как воспроизвести и адаптировать эту настройку к конкретному сценарию, с пониманием нюансов запуска надежного конвейера DevOps. Полученные здесь практические рекомендации и знания пригодятся и разработчику, который только знакомится с DevOps, и опытному инженеру, стремящемуся усовершенствовать рабочие процессы.
Сначала заложим основу, спроектировав архитектуру и настроив среду. Подробно описав каждую строку кода, конфигурационный файл и команду, сделаем из этой статьи полноценный ресурс для освоения конвейеров сборки.
Шаг 1. Создание основы: проект Django и контейнеризация
Первый этап создания надежного конвейера сборки начинается с самого приложения — это основа архитектуры проекта. Настроим проект, для мониторинга приложения воспользуемся django-prometheus, а при контейнеризации — для согласованности и масштабируемости — создадим Dockerfile.
1. Настройка проекта Django
Django — это высокоуровневый веб-фреймворк Python для быстрой разработки с чистым, прагматичным дизайном. Чтобы обеспечить детальный мониторинг на уровне приложения Django, в проект включены метрики Prometheus. Вот как он структурирован:
1.1 Структура проекта Django
studyPlat/
├── studyPlat/ # Основной каталог проекта
│ ├── settings.py # Настройки Django
│ ├── urls.py # Маршрутизация единых указателей ресурсов
│ ├── wsgi.py # Точка входа WSGI-стандарта для Gunicorn
│ └── ...
├── app/ # Каталог приложения Django
│ ├── models.py # Модели баз данных
│ ├── views.py # Логика приложения
│ ├── urls.py # Маршрутизация единых указателей ресурсов приложения
│ ├── admin.py # Конфигурация интерфейса администратора
├── requirements.txt # Зависимости Python
└── manage.py # Сценарий управления Django
1.2 requirements.txt
В файле requirements.txt содержатся зависимости проекта, в том числе django-prometheus для мониторинга.
asgiref==3.8.1
Django==5.1.4
django-debug-toolbar==4.4.6
django-prometheus==2.3.1
djangorestframework==3.14.0
gunicorn==20.1.0
Pillow==9.5.0
prometheus_client==0.21.1
python-decouple==3.8
pytz==2023.3
setuptools==75.6.0
sqlparse==0.4.3
tzdata==2022.7
whitenoise==6.4.0
1.3 Интегрирование метрик Prometheus
Для предоставления метрик приложения интегрирован django-prometheus с обновлением файла settings.py и промежуточной конфигурации:
В settings.py:
INSTALLED_APPS = [
...,
'django_prometheus',
]
MIDDLEWARE = [
...,
'django_prometheus.middleware.PrometheusBeforeMiddleware',
...,
'django_prometheus.middleware.PrometheusAfterMiddleware',
]# В основной файл «urls.py» добавляются URL-адреса Prometheus
urlpatterns = [
path('', include('app.urls')),
path('metrics/', include('django_prometheus.urls')),
]
После интеграции метрики предоставляются приложением в /metrics и позже извлекаются при помощи Prometheus. Среди этих метрик задержки при обработке запросов, продолжительность выполнения запросов, частота ошибок и другие.
2. Создание Dockerfile
Согласованное выполнение приложения в различных средах обеспечивается контейнеризацией. Приложение и его зависимости благодаря Docker упаковываются в легковесный, платформонезависимый контейнер.
Вот Dockerfile для этого проекта Django:
# В качестве базового используется официальный образ Python
FROM python:3.10-slim
# Задаются переменные окружения
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Внутри контейнера задается рабочий каталог
WORKDIR /app
# В контейнер копируются файлы проекта
COPY . .
# Устанавливаются системные зависимости
RUN apt-get update && apt-get install -y \
libpq-dev gcc && \
rm -rf /var/lib/apt/lists/*
# Устанавливаются зависимости Python
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
# Предоставляется порт, на котором выполняется приложение Django
EXPOSE 8000
# Копируется конфигурационный файл Prometheus
COPY prometheus.yml /etc/prometheus/prometheus.yml
# Команда для выполнения приложения
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "studyPlat.wsgi:application"]
3. Тестирование локально
Прежде чем продолжить, протестируем приложение локально и убедимся, что все выполняется без неожиданностей.
Этапы:
3.1 Сборка образа Docker:
docker build -t studyplat:latest .
3.2 Запуск контейнера:
docker run -p 8000:8000 studyplat:latest
3.3 Проверка метрик Prometheus:
Проверяем предоставление метрик, обращаясь к конечной точке /metrics в браузере или командой curl:
curl http://localhost:8000/metrics
4. Подготовка к конвейеру сборки
Создав Dockerfile и сделав приложение Django функциональным, подготовим проект к интеграции с Jenkins. Dockerfile подгружается на GitHub вместе с YAML-файлами развертывания и служб для Kubernetes и интерактивным сценарием Ansible для автоматизации.
Готовность проекта к непрерывной интеграции и непрерывному развертыванию означает, что конвейер активируется любыми новыми коммитами в репозитории GitHub. А дальше дело за Jenkins.
На этом первый этап конвейера DevOps завершается. Теперь настроим инфраструктуру в AWS.
Шаг 2. Настройка инфраструктуры: экземпляры EC2, SSH-доступ и подготовка
Прежде чем переходить к Jenkins и автоматизировать конвейер, подготовим инфраструктуру: создадим экземпляры EC2 для Ansible, Jenkins и Kubernetes, настроим SSH-доступ, обеспечим полную готовность к бесперебойной работе.
1. Настройка экземпляров EC2
Подготовим три экземпляра AWS EC2, у каждого из которых конкретное назначение.
Обзор экземпляров EC2:
╔═══════════════════╦═════════════════════════╦═════════════════╦════════════════════╗
║Название экземпляра║ Назначение ║ Тип экземпляра ║Операционная система║
╠═══════════════════╬═════════════════════════╬═════════════════╬════════════════════╣
║ ansible-server ║ Узел управления Ansible ║ t2.micro ║ Ubuntu 24.04 LTS ║
║ jenkins-server ║ Сервер CI/CD Jenkins ║ t2.micro ║ Ubuntu 24.04 LTS ║
║ k8s-node ║ Одноузловой кластер K8s ║ t2.large ║ Ubuntu 24.04 LTS ║
╚═══════════════════╩═════════════════════════╩═════════════════╩════════════════════╝
Этапы создания экземпляров EC2:
- Вход в консоль управления AWS и переход к дашборду EC2.
- Запуск экземпляров EC2:
- В качестве образа машины Amazon выбираем Ubuntu 24.04 LTS.
- В качестве типа экземпляра — условно-бесплатный уровень t2.micro для Ansible и Jenkins.
- А для Kubernetes — t2.large, чтобы выделенных ресурсов было достаточно.
3. Настройка деталей экземпляра:
- Каждому экземпляру —
ansible-server,jenkins-serverиk8s-node— присваиваем уникальный тег-название. - Для SSH-доступа включаем автоприсвоение общедоступного IP-адреса.
4. Добавление хранилища:
- Для Ansible и Jenkins достаточно 8 Гб эластичного блочного хранилища EBS по умолчанию.
- Чтобы создать minikube в узле Kubernetes, воспользуемся 32 Гб.
5. Настройка групп безопасности:
- Для удаленного доступа разрешаем SSH, порт 22.
- Для Jenkins и Kubernetes открываем дополнительные порты:
8080и6443соответственно, а также для служб NodePort Kubernetes30000-32767.
6. Создание или использование имеющейся пары ключей:
- Называем:
devops-key-pair. - Загружаем закрытый ключ
devops-key-pair.pemдля SSH-доступа.
7. Запуск экземпляров.
2. Пара ключей для SSH-доступа
Для безопасного подключения к экземплярам EC2 воспользуемся парой ключей, созданной при подготовке экземпляров, а для SSH-доступа — инструментами вроде Termius или терминала.
3. Подготовка сервера Ansible
Узлом управления Ansible ansible-server автоматизируются конфигурации и развертывания в инфраструктуре.
Базовая настройка для Ansible
3.1 Обновление системы:
sudo apt update && sudo apt upgrade -y
3.2 Установка Ansible:
sudo apt install ansible -y
3.3 Настройка файла инвентаризации:
Создаем файл инвентаризации /etc/ansible/hosts и добавляем другие экземпляры — узлы Jenkins и Kubernetes:
[jenkins]
<jenkins-server-private-ip>
[k8s]
<k8s-node-private-ip>
3.4 Копирование ключа в управляемые узлы:
Чтобы скопировать закрытый ключ на сервер Ansible и настроить беспарольный SSH-доступ к узлам Jenkins и Kubernetes, используется SSH:
ssh-copy-id -i ~/.ssh/devops-key-pair.pem ubuntu@<jenkins-server-private-ip>
ssh-copy-id -i ~/.ssh/devops-key-pair.pem ubuntu@<k8s-node-private-ip>
4. Подготовка сервера Jenkins
На сервере Jenkins jenkins-server разместится конвейер сборки, вот начальная настройка сервера Jenkins:
4.1 Обновление системы:
sudo apt update && sudo apt upgrade -y
4.2 Установка Java для Jenkins:
sudo apt install openjdk-11-jdk -y
4.3 Загрузка и установка:
- Добавляем репозиторий Jenkins:
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
- Устанавливаем Jenkins:
sudo apt update
sudo apt install jenkins -y
4.4 Запуск и включение Jenkins:
sudo systemctl start jenkins
sudo systemctl enable jenkins
4.5 Открытие порта 8080 Jenkins:
Чтобы разрешить входящий трафик через порт 8080, добавляем в группу безопасности Jenkins правило.
4.6 Доступ к Jenkins:
Открываем Jenkins в браузере, используя общедоступные IP-адрес и порт: http://<jenkins-server-public-ip>:8080.
5. Подготовка узла Kubernetes
В узле Kubernetes k8s-node размещается приложение и оркестрируются контейнеры, для установки воспользуемся minikube.
Базовая настройка для Kubernetes:
5.1 Установка Docker:
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker
sudo apt install -y apt-transport-https ca-certificates curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
5.2 Установка Kubectl:
sudo snap install kubectl --classic
kubectl version --client
5.3 Установка Minikube:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube version
5.4 Запуск Minikube с драйвером Docker:
minikube start --driver=docker
minikube status
5.5 Тестирование K8s:
kubectl cluster-info
kubectl get pods
kubectl get nodes
Подготовив и подключив серверы, переходим к конфигурации Jenkins и настройке конвейера.
Шаг 3. Конфигурация сервера Jenkins и этапы конвейера сборки
Запустив сервер Jenkins, сконфигурируем его для непрерывной интеграции и непрерывного развертывания. Определим соответствующие этапы в конвейере, где автоматизируются сборка, тестирование, контейнеризация и развертывание приложения Django.
1. Доступ к Jenkins
1.1 Открываем Jenkins в браузере:
http://<jenkins-server-public-ip>:8080
1.2 Получаем исходный пароль администратора:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
1.3 Войдя, устанавливаем предлагаемые плагины и создаем пользователя-администратора.
2. Установка необходимых конвейеру плагинов
- Pipeline: для создания конвейеров Jenkins.
- Git: для клонирования проекта Django из репозитория.
- SSH Agent: для использования SSH-ключей удаленного доступа.
- Blue Ocean — дополнительно — для визуализации конвейеров в современном пользовательском интерфейсе.
3. Настройка учетных данных в Jenkins
a) Добавление учетных данных GitHub
- Переходим в Manage Jenkins («Управлять Jenkins») > Credentials («Учетные данные») > Global («Глобальные») > Add Credentials («Добавить учетные данные»).
- Для HTTPS выбираем Username with Password («Имя пользователя с паролем»), для SSH — SSH Key («SSH-ключ»).
- Сохраняем учетные данные.
б) Добавление SSH-ключа для удаленного доступа
- Загружаем закрытый ключ
devops-key-pair.pemв Global Credentials. - Сохраняем как
remote-access-ssh-key.
4. Создание задачи конвейера
- В Jenkins создаем новый элемент, выбираем Pipeline («Конвейер») и даем название
django-pipelineили любое другое. - Настраиваем задачу на использование скрипта конвейера.
5. Этапы конвейера Jenkins
Вот структура этапов конвейера для приложения Django:
node {
stage('Git checkout'){
git 'https://github.com/KaramMajdi7/KubeDevOps'
}
stage('Sending docker file to Ansible server over ssh'){
sshagent(['remote-access-ssh-key']) {
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip>'
sh 'scp -r /var/lib/jenkins/workspace/pipeline-demo/* ubuntu@<ansible-server-private-ip>:/home/ubuntu/'
}
}
stage('Docker Image Build'){
sshagent(['remote-access-ssh-key']) {
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> cd /home/ubuntu/'
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> sudo docker image build -t $JOB_NAME:v1.$BUILD_ID .'
}
}
stage('Docker image tagging'){
sshagent(['remote-access-ssh-key']) {
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> cd /home/ubuntu/'
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> sudo docker image tag $JOB_NAME:v1.$BUILD_ID your_dockerhub_username/$JOB_NAME:v1.$BUILD_ID'
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> sudo docker image tag $JOB_NAME:v1.$BUILD_ID your_dockerhub_username/$JOB_NAME:latest'
}
}
stage('Push Docker image to Docker Hub'){
sshagent(['remote-access-ssh-key']) {
withCredentials([string(credentialsId: 'dockerhub_password', variable: 'dockerhub_password')]) {
sh "ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> docker login -u your_dockerhub_username-p ${dockerhub_password}"
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> docker image push your_dockerhub_username/$JOB_NAME:v1.$BUILD_ID'
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> docker image push your_dockerhub_username/$JOB_NAME:latest'
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> docker image rm your_dockerhub_username/$JOB_NAME:v1.$BUILD_ID your_dockerhub_username/$JOB_NAME:latest $JOB_NAME:v1.$BUILD_ID'
}
}
}
stage('Trigger Ansible Playbook'){
sshagent(['remote-access-ssh-key']) {
sh 'ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> ansible-playbook /path/to/your/ansible.yaml'
}
}
}
6. Активация конвейера
- Ручная активация: конвейер запускается из Jenkins.
- Автоматическая активация:
- Чтобы конвейер активировался при добавлениях кода, добавляем веб-хук GitHub.
- Переходим в GitHub Repository («Репозиторий GitHub») > Settings («Настройки») > Webhooks («Веб-хуки»).
- Добавляем URL-адрес Jenkins:
http://<jenkins-server-public-ip>:8080/github-webhook/.
Шаг 4. Aqua Trivy для сканирования образов контейнеров
Сканером безопасности с открытым исходным кодом Aqua Trivy выявляются проблемы конфигурации, уязвимости и открытые секреты в образах контейнеров. Благодаря интегрированию Trivy в конвейер Jenkins развертываются только безопасные образы Docker.
1. Установка Aqua Trivy на сервере Ansible
1.1 SSH-подключение к серверу Ansible:
ssh -i devops-key-pair.pem ubuntu@<ansible-server-private-ip>
1.2 Установка Trivy:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
1.3 Проверка установки:
trivy --version
2. Добавление в конвейер Jenkins этапа сканирования Trivy
Чтобы сканировать собранный образ Docker перед отправкой на DockerHub, Trivy интегрируется в Jenkinsfile и добавляется перед этапом отправки образа Docker на DockerHub.
stage('Trivy Scan') {
sshagent(['remote-access-ssh-key']) {
sh " ssh -o StrictHostKeyChecking=no ubuntu@<ansible-server-private-ip> trivy --config /dev/null image --no-progress --scanners vuln $JOB_NAME:v1.$BUILD_ID"
}
}
3. Обработка результатов сканирования
- В Trivy выводится подробный отчет с перечислением уязвимостей, их серьезности и возможных исправлений.
- Если обнаруживаются критические проблемы, конвейер настраивается на остановку процесса и уведомление заинтересованных по электронной почте или в Slack — здесь пригодятся плагины Jenkins.
4. Автоматизация обновлений базы данных Trivy
Чтобы поддерживать определения уязвимостей в актуальном состоянии, на обновление базы данных Trivy настраивается задание cron или Jenkins:
trivy --download-db-only
При такой интеграции уязвимые образы Docker не оказываются на продакшене и уровень безопасности процесса непрерывной интеграции и непрерывного развертывания повышается.
Шаг 5. Конфигурирование Ansible для автоматизации изменений Kubernetes
Благодаря Ansible автоматизируются задачи, связанные с обновлением конфигураций Kubernetes, обеспечивается согласованное развертывание, уменьшаются человеческие ошибки.
1. Настройка Ansible
Установка Ansible на сервере Ansible: Ansible устанавливается в экземпляре EC2 или на другом сервере для оркестрации задач, мы сделали это заранее.
2. Пример ansible-playbook.yml
---
- name: Automate Kubernetes Tasks
hosts: all
become: true
tasks:
- name: Ensure Deployment.yml file is absent
ansible.builtin.file:
path: /home/ubuntu/Deployment.yml
state: absent
ignore_errors: yes # Если файл не найден, ошибки игнорируются
- name: Ensure Service.yml file is absent
ansible.builtin.file:
path: /home/ubuntu/Service.yml
state: absent
ignore_errors: yes # Если файл не найден, ошибки игнорируются
- block:
- name: Copy Deployment.yml to the k8s server
ansible.builtin.copy:
src: /path/to/your/local/Deployment.yml
dest: /home/ubuntu/Deployment.yml
owner: ubuntu
group: ubuntu
mode: '0644'
when: ansible_facts['os_family'] == 'Debian'
- name: Copy Service.yml to the k8s server
ansible.builtin.copy:
src: /path/to/your/local/Service.yml
dest: /home/ubuntu/Service.yml
owner: ubuntu
group: ubuntu
mode: '0644'
when: ansible_facts['os_family'] == 'Debian'
name: Copy configuration files to the server
- name: Set KUBECONFIG environment variable
ansible.builtin.set_fact:
KUBECONFIG: "/home/ubuntu/.kube/config"
- name: Delete old deployment if exists
k8s:
kubeconfig: "{{ KUBECONFIG }}"
state: absent
definition: "{{ lookup('file', '/home/ubuntu/Deployment.yml') }}"
ignore_errors: yes # Так обрабатываются случаи, где «deployment» не существует
- name: Delete old service if exists
k8s:
kubeconfig: "{{ KUBECONFIG }}"
state: absent
definition: "{{ lookup('file', '/home/ubuntu/Service.yml') }}"
ignore_errors: yes # Так обрабатываются случаи, где «service» не существует
- name: Create new deployment
k8s:
kubeconfig: "{{ KUBECONFIG }}"
state: present
definition: "{{ lookup('file', '/home/ubuntu/Deployment.yml') }}"
- name: Create new service
k8s:
kubeconfig: "{{ KUBECONFIG }}"
state: present
definition: "{{ lookup('file', '/home/ubuntu/Service.yml') }}"
3. Разбор интерактивного сценария
- Copy Configuration Files: в этом блоке задач файлы конфигурации
Deployment.ymlиService.ymlкопируются с локальной машины на сервер Kubernetes, уже имеющиеся файлы предварительно удаляются. - Set KUBECONFIG Environment Variable: переменной окружения
KUBECONFIGуказывается на конфигурационный файл Kubernetes, благодаря чему Ansible «общается» с кластером Kubernetes. - Управление развертываниями и службами: в сценарии удаляются все старые развертывания и службы Kubernetes, затем с чистого листа создаются новые, как указано в файлах
Deployment.ymlиService.yml.
Развертывание при таком подходе упрощается, а конфигурация Kubernetes всегда актуальна и без ручного вмешательства.
Шаг 6. Конфигурирование и развертывание Kubernetes
Сердце этого проекта — Kubernetes, где ради масштабируемости, надежности и эффективного использования ресурсов оркестрируются контейнеры. Вот как структурирована настройка Kubernetes, а также YAML-файлы с пояснениями:
1. Deployment.yml
Файлом Deployment.yml определяется, как управлять подами приложения.
kind: Deployment
apiVersion: apps/v1
metadata:
name: your_app_name
spec:
replicas: 2
selector:
matchLabels:
app: your_app_name
template:
metadata:
labels:
app: your_app_name
spec:
containers:
- name: your_app_name
image: dockerhub_username/django-pipeline
imagePullPolicy: Always
ports:
- containerPort: 8000
Основные характеристики:
- Replicas: для приложения всегда запускается два пода.
- Image: образ Docker
dockerhub_username/django-pipelineизвлекается из DockerHub. - Ports: в каждом контейнере для приложения предоставляется порт
8000.
Применяемая команда:
Для развертывания применяется этот YAML-файл:
kubectl apply -f Deployment.yml
2. Service.yml
Файлом Service.yml к приложению предоставляется доступ извне:
kind: Service
apiVersion: v1
metadata:
name: your_app_name
labels:
app: your_app_name
spec:
ports:
- port: 8000
targetPort: 8000
nodePort: 31200
selector:
app: your_app_name
type: LoadBalancer
Основные характеристики:
- Type: благодаря
LoadBalancerслужба доступна извне по публичному IP-адресу. - NodePort: для внешнего доступа на рабочих узлах открывается порт
31200. - Target Port: запросы сопоставляются с портом
8000внутри контейнеров. - Selector: здесь эта служба подключается к подам с меткой
app: your_app_name.
Применяемая команда:
Чтобы предоставить доступ к службе, применяется этот YAML-файл:
kubectl apply -f Service.yml
3. Проверка развертывания
3.1 Проверка подов:
kubectl get pods
Проверяем работоспособность подов меткой app=karammajdi.
3.2 Проверка службы:
kubectl get svc
Выполняется поиск внешнего IP-адреса, присвоенного службе.
3.3 Доступ к приложению:
- Используется внешний IP-адрес или общедоступный DNS этого LoadBalancer с портом
8000. - Пример:
http://<external-ip>:8000.
Шаг 7. Настройка Prometheus
В Prometheus мониторятся приложения Kubernetes и другие ресурсы, собираются и визуализируются метрики из заданных целей.
1. Развертывание с Prometheus
Создадим файл Prometheus и сохраним его как prometheus-deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
labels:
app: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus:v2.43.0
args:
- '--config.file=/etc/prometheus/prometheus.yml'
ports:
- containerPort: 9090
volumeMounts:
- name: prometheus-config
mountPath: /etc/prometheus
readOnly: true
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
Пояснения:
- Deployment:
- Запускается единственная реплика контейнера Prometheus —
replicas: 1.
2. Image:
- Используется образ Prometheus Docker версии
v2.43.0.
3. Args:
- Указывается конфигурационный файл Prometheus
/etc/prometheus/prometheus.yml.
4. VolumeMount:
- ConfigMap
prometheus-configподключается к/etc/prometheus.
Применяемая команда:
kubectl apply -f prometheus-deployment.yml
2. Служба Prometheus
Переходим к prometheus-service.yml:
apiVersion: v1
kind: Service
metadata:
name: prometheus
spec:
ports:
- port: 9090
targetPort: 9090
nodePort: 30090
selector:
app: prometheus
type: LoadBalancer
Пояснения:
- Type:
- Этим
LoadBalancerк Prometheus предоставляется доступ извне по общедоступному IP-адресу.
2. Ports:
- В Prometheus прослушивается порт
9090— изнутри и извне. - В
NodePortзадается30090для отладки или прямого доступа по IP-адресу узла.
3. Selector:
- Эта служба связывается с развертыванием Prometheus меткой
app: prometheus.
Применяемая команда:
kubectl apply -f prometheus-service.yml
3. ConfigMap Prometheus
Наконец, получаем prometheus-configmap.yml:
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'django'
static_configs:
- targets: ['your_svc_name_for_django:8000']
Пояснения:
- ConfigMap:
- Конфигурация Prometheus сохраняется так, как это свойственно для Kubernetes.
2. Scrape Interval:
- Для частого сбора метрик глобально задается соответствующий интервал
15s.
3. Scrape Configs:
- Job Name: этим
djangoпомечается целевое задание для мониторинга. - Target: указывается служба
your_svc_name_for_django, запускаемая на порту8000и определяемая в файлеService.yml.
Применяемая команда:
kubectl apply -f prometheus-configmap.yml
Шаг 8. Настройка Grafana
Данные, особенно с источником данных Prometheus, визуализируются в Grafana. Настроим это в кластере Kubernetes.
1. Развертывание в Grafana
Вот grafana-deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
labels:
app: grafana
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:latest
ports:
- containerPort: 3000
volumeMounts:
- name: grafana-storage
mountPath: /var/lib/grafana
volumes:
- name: grafana-storage
emptyDir: {}
Пояснения:
- Deployment:
- Replicas: ради упрощения запускается единственная реплика контейнера Grafana.
2. Container:
- Image: в Grafana используется последний образ Docker.
- Ports: и предоставляется порт по умолчанию
3000. - Volume Mount: для хранения данных подключается том в
/var/lib/grafana.
3. Volume:
- Type: для временного хранилища используется
emptyDir. Данные сохраняются, только пока запускается под. Для постоянного хранения рекомендуетсяPersistentVolume.
Применяемая команда:
kubectl apply -f grafana-deployment.yml
2. Служба в Grafana
Теперь изучим grafana-service.yml:
apiVersion: v1
kind: Service
metadata:
name: grafana
spec:
type: LoadBalancer
ports:
- port: 3000
targetPort: 3000
nodePort: 30300
selector:
app: grafana
Пояснения:
- Type:
- LoadBalancer: предоставляется Grafana с общедоступным IP-адресом для внешнего доступа.
2. Ports:
- Port: в Grafana прослушивается порт
3000извне. - В NodePort: задается
30300для отладки или прямого доступа по IP-адресу узла.
3. Selector:
- Эта служба связывается с развертыванием меткой
app: grafana.
Применяемая команда:
kubectl apply -f grafana-service.yml
Что дальше
- Вход:
- Учетные данные по умолчанию: Имя пользователя:
admin| Пароль:admin - После первого входа пароль меняем.
2. Добавление Prometheus источником данных:
- Переходим в Configuration («Конфигурация») > Data Sources («Источники данных»).
- Добавляем Prometheus с вот этим:
URL: http://<prometheus-service-ip>:9090
- Заменяем
<prometheus-service-ip>на IP-адрес или DNS службы Prometheus.
3. Создание дашбордов:
- Для визуализации метрик приложения или кластера импортируем или создаем дашборды.
С такой настройкой Grafana делается доступной и интегрируется с реализованным выше инструментарием мониторинга Prometheus.

Заключение
Современными практиками и инструментами в этом комплексном конвейере DevOps упрощается процесс сборки, сохраняются полноценные возможности обеспечения безопасности и мониторинга. Вот как легко интегрируется рабочий процесс:
- Рабочий процесс начинается отправкой разработчиком кода и соответствующего Dockerfile в репозиторий GitHub. Так активируется вебхук, которым инициируется конвейер Jenkins в экземпляре EC2.
- Автоматизация и безопасность: в Jenkins автоматизируется процесс сборки, выполняется проверка безопасности с Aqua Trivy и образ Docker отправляется в Docker Hub. Так перед развертыванием обеспечивается соблюдение всеми контейнерами стандартов безопасности.
- Управление конфигурацией: в Ansible, запускаемом в специальном экземпляре EC2, осуществляется управление конфигурацией кластеров Kubernetes. Так упрощается процесс развертывания, обеспечивается согласованность во всех средах.
- Оркестрация Kubernetes: кластером управления Kubernetes, размещаемым в экземпляре EC2, приложение развертывается и управляется. Так обеспечиваются масштабируемость, отказоустойчивость, эффективное использование ресурсов.
- Мониторинг и визуализация: в Prometheus из кластера Kubernetes извлекаются метрики, обеспечивается всесторонний мониторинг производительности приложения. Затем эти метрики визуализируются в настраиваемых дашбордах Grafana, откуда из них получаются полезные данные.
Такой архитектурой обеспечиваются не только автоматизация и безопасность процесса развертывания, но и полноценная система мониторинга для более надежного приложения. Интеграцией Jenkins, Docker, Ansible, Kubernetes, Prometheus и Grafana в этом конвейере демонстрируются возможности комбинирования практик DevOps с современными облачными технологиями.
Читайте также:
- Почему стоит использовать Argo CD вместо (или вместе) с Helm в среде Kubernetes
- 5 продвинутых операторов Kubernetes, о которых должен знать каждый инженер DevOps
- Логи контейнеров Kubernetes: реализация и управление
Читайте нас в Telegram, VK и Дзен
Перевод статьи Karam Majdi: Building Seamless CI/CD Pipelines with Kubernetes at the Core





