Когда говорим о высокой доступности (HA), мы имеем в виду системы, которые могут работать непрерывно без сбоев в течение длительного времени. Jenkins — один из ключевых компонентов DevOps, а потому критически важно, чтобы он оставался высокодоступным.
В статье разберём два способа настройки Jenkins в режиме высокой доступности с использованием IaC в IBM Cloud:
настройка Jenkins в режиме высокой доступности в IBM Cloud с помощью сценариев Terraform и Ansible;
использование шаблонов схем (schematics templates) на IBM Cloud в рамках template-based подхода.
Примечание: вы также можете адаптировать эти способы к другим облачным платформам.
Вам понадобится
аккаунт IBM Cloud;
репозиторий GitHub;
базовые знания NGINX или HAProxy;
базовые знания Terraform и Ansible;
базовые знания CI/CD.
Расчётное время
Выполнение инструкций займёт около 30 минут.
Подготовьте NFS-хранилище в IBM Cloud
Общая схема архитектуры Jenkins с использованием IBM Cloud:
Пользователь отправляет трафик балансировщику нагрузки (NGINX или HAProxy). Балансировщик нагрузки отправляет трафик контроллеру Jenkins. Если контроллер не работает, трафик перенаправляется на резервный сервер Jenkins.
Для обеспечения высокой доступности любого приложения важно внутреннее хранилище, поэтому перейдём к подготовке внутреннего хранилища Jenkins:
В меню навигации IBM Cloud выберите «Classic Infrastructure» > «File Storage».
Нажмите «Order File Storage».
Введите необходимые данные и подготовьте файловое хранилище. Вам нужно выбрать облачную часть хранилища файлов, размер хранилища файлов и способ оплаты — ежемесячно или ежечасно (мы выбрали общий тип хранения на длительный срок). После вы сможете посмотреть файловые хранилища, доступные в системе:
Подготовьте сервер балансировки нагрузки и два сервера Jenkins в IBM Cloud
Вы можете это, используя любой из следующих способов:
IBM Cloud CLI;
IBM SoftLayer Portal;
Terraform.
В рамках этой статьи мы используем скрипты Terraform для подготовки трёх серверов: одного — для балансировки нагрузки, и двух — для Jenkins.
The main.tf script:
data "ibm_compute_image_template" "centos" {
name = var.os
}
resource "ibm_compute_vm_instance" "virtualguest" {
count = var.vm_count
hostname = "haproxypoc${count.index + 1}"
domain = "abc.com"
image_id = data.ibm_compute_image_template.centos.id
datacenter = var.datacenter
private_vlan_id = var.vlan_id
network_speed = 100
ssh_key_ids = ["11111"]
hourly_billing = true
private_network_only = true
flavor_key_name = var.vm_flavor
local_disk = false
}
The variables.tf script:
variable "vip" {
default = "10.114.128.14"
}
variable "vm_count" {
default = "2"
}
variable "vm_flavor" {
default = "B1_2X4X100"
}
variable "vlan_id" {
default = "9999999"
}
variable "datacenter" {
default = "tor01"
}
variable "os" {
default = "centos"
}
variable "http_port" {
default = {
"0" = "80" #haproxy
}
}
The provider.tf script:
variable "iaas_classic_username" {
description = "Enter the user name to access IBM Cloud classic infrastructure. "
}
variable "iaas_classic_api_key" {
description = "Enter the API key to access IBM Cloud classic infrastructure. "
}
variable "ibmcloud_api_key" {
description = "Enter your IBM Cloud API Key "
}
provider "ibm" {
iaas_classic_username = var.iaas_classic_username
iaas_classic_api_key = var.iaas_classic_api_key
ibmcloud_api_key = var.ibmcloud_api_key
}
The versions.tf script:
terraform {
required_version = ">= 0.12"
}
Настройте HAProxy (сервер балансировки нагрузки)
Для запуска и настройки HAPproxy на каждом из серверов используйте роль Ansible. Основной модуль — playbook_haproxy.yml.
Плейбук Ansible для настройки сервера балансировки нагрузки:
---
- hosts: all
remote_user: root
become: yes
roles:
- haproxy
tasks:
- name: shutdown haproxy cluster
shell: /usr/local/bin/docker-compose -f /app/haproxy/docker-compose.yml down
- name: start haproxy
shell: /usr/local/bin/docker-compose -f /app/haproxy/docker-compose.yml up -d haproxy
Более подробную информацию о HAProxy вы найдёте в репозитории configJenkins GitHub repo.
Ниже показан файл конфигурации для HAProxy. HAProxy принимает трафик через порт 80 и перенаправляет его на порт 8080 на сервере Jenkins.
defaults
log global
maxconn 2000
mode http
option redispatch
option forwardfor
option http-server-close
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout check 10s
frontend ft_jenkins
bind *:80
acl host_cicdprod hdr(host) -i cicdprod.abc.com
use_backend bk_jenkins if host_cicdprod
default_backend bk_jenkins
reqadd X-Forwarded-Proto:\ http
backend bk_jenkins
server jenkins1 {{ cicdhostprod1.stdout }}:8080 check
server jenkins2 {{ cicdhostprod2.stdout }}:8080 check backup
Настройте Jenkins
Основной модуль — playbook_jenkins.yml. Он использует Docker Compose для запуска Jenkins.
version: '2'
services:
jenkins:
image: jenkins:lts
container_name: jenkins
ports:
- "8080:8080"
- "50000:50000"
restart: always
environment:
- TZ=America/Toronto
volumes:
- /var/run/docker.sock:/var/run/docker.sock
network_mode: "host"
Назначьте cron job для синхронизации файлов между серверами Jenkins
Jenkins работает на двух серверах. Вам необходимо синхронизировать логи на обеих нодах. Для этого используйте shell script на обеих нодах, а также используйте cron для назначения джобы каждую минуту.
Cron добавится как часть playbook_jenkins.yml:
#!/bin/bash
crumb_id=$(curl -s 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)',-u admin:admin)
curl -s -XPOST 'http://localhost:8080/reload' -u admin:admin -H "$crumb_id"
Скрипт будет вызывать Jenkins reload API для перезагрузки конфигурации Jenkins каждую минуту.
Автоматизируйте с помощью IBM Cloud Schematics и DevOps-инструментов
Terraform
1. Загрузите main.tf, provider.tf, variable.tf и version.tf в свой репозиторий GitHub.
2. В консоли IBM Cloud нажмите > «Schematics» > «Create a Schematics Workspace». 3. Введите уникальное имя рабочего пространства и нажмите «Create».
3. Введите URL-адрес репозитория GitHub и нажмите «Save template information».
4. Настройте переменные для проверки подлинности ключей API и учётных данных пользователя и сохраните изменения. Это те же самые переменные, которые были объявлены в файлах variable.tf и provider.tf.
5. Нажмите «Enable continuous delivery», чтобы создать цепочку инструментов DevOps.
6. Введите данные для цепочки инструментов:
Toolchain name: имя создаваемой цепочки инструментов.
Region: область, где должна быть создана цепочка инструментов.
Resource group: выберите группу ресурсов.
Repository type: Новый.
IBM Cloud API key: IAM key for IBM Cloud.
7. В меню навигации IBM Cloud нажмите «Schematics» > «Workspaces». Выберите местоположение из раскрывающегося списка:
8. Нажмите «Generate plan»:
9. Нажмите «View log»:
10. Если в журнале нет ошибок, нажмите «Apply plan».
11. В меню навигации выберите «DevOps», чтобы просмотреть цепочку инструментов:
Ansible
Ansible — один из самых простых инструментов управления конфигурацией, который не требует установки агента.
1. Загрузите плейбук Ansible на GitHub:
---
- hosts: all
remote_user: root
become: yes
roles:
- haproxy
tasks:
- name: shutdown haproxy cluster
shell: /usr/local/bin/docker-compose -f /app/haproxy/docker-compose.yml down
- name: start haproxy
shell: /usr/local/bin/docker-compose -f /app/haproxy/docker-compose.yml up -d haproxy
Вы создаёте два действия: одно для Jenkins (hajenkins), а другое для nginx (loadbalancer).
2. В меню навигации консоли IBM Cloud нажмите «Schematics».
3. В поле Управление конфигурацией выберите «Create action».
4. Заполните форму, чтобы создать действие.
5. Введите URL-адрес GitHub и нажмите «Retrieve playbooks»:
6. Нажмите на раскрывающийся список «Playbook», чтобы выбрать плэйбук.
7. Нажмите «Verbosity», чтобы выбрать уровень логирования.
8. В поле «Key» введите дополнительные переменные и нажмите «Save»:
9. Нажмите «Create Inventory», чтобы создать файл инвентаризации, в котором будут хосты в IBM Cloud Classic Infrastructure. Вы также можете ввести IP-адрес хоста-бастиона и закрытый ключ, который плэйбук использует для входа на хосты.
10. Нажмите «Run Action» для выполнения плейбука:
11. Просмотрите журнал Ansible:
Повторите шаги, чтобы создать действие для Jenkins.
Коротко о главном
Из этой статьи вы узнали, как настроить Jenkins в режиме высокой доступности в IBM Cloud. Описанный метод считается cloud-agonistic — его можно использовать с другими облачными провайдерами с учётом различий платформ. При этом применяется IaC, поэтому конфигурацию можно поддерживать на GitHub или в репозитории на основе Git.
justdani
мне кажется, что мы потеряли консистентность данных при рероле конфигурации каждую минуты. И что происходит в момент когда возвращается дженкинс из даунтайма? Ну ещё бы упомянуть что jenkins должен быть как CasC сделан.
alexovchinnicov
Поддерживаю ваши замечания и добавлю своё, лучше использовать модули в плейбуке: