Създаване на клъстер Nomad с Consul и интегриране с Gitlab

въведение

Напоследък популярността на Kubernetes нараства бързо - все повече и повече проекти го прилагат у дома. Исках да се спра на оркестратор като Nomad: той е идеален за проекти, в които вече се използват други решения от HashiCorp, като Vault и Consul, а самите проекти не са сложни по отношение на инфраструктурата. Тази статия ще предостави инструкции за инсталиране на Nomad, сливане на два възела в клъстер и интегриране на Nomad с Gitlab.

Създаване на клъстер Nomad с Consul и интегриране с Gitlab

изпитателен стенд

Малко за тестовия стенд: използвани са три виртуални сървъра с характеристики 2 CPU, 4 RAM, 50 Gb SSD, обединени в обща локална мрежа. Техните имена и IP адреси:

  1. nomad-livelinux-01: 172.30.0.5
  2. nomad-livelinux-02: 172.30.0.10
  3. консул-livelinux-01: 172.30.0.15

Инсталиране на Nomad, Consul. Създаване на номадски клъстер

Да започнем с основната инсталация. Въпреки лекотата на инсталиране, ще го опиша в името на целостта на статията: всъщност тя е създадена от чернови и бележки за бърз достъп в случай на нужда.

Преди да продължим към практиката, ще обсъдим теоретичната част, тъй като на този етап е важно да разберем бъдещата структура.

Имаме два номадни възела и искаме да ги комбинираме в клъстер, също така за в бъдеще ще ни трябва автоматично мащабиране на клъстера - за това се нуждаем от Consul. С този инструмент клъстерирането и добавянето на нови възли става много проста задача: създаденият Nomad възел се свързва с агента Consul, след което се свързва със съществуващия Nomad клъстер. Затова в началото ще инсталираме Consul сървъра, ще конфигурираме основната http авторизация за уеб панела (по подразбиране е без авторизация и може да бъде достъпен на външен адрес), както и самите Consul агенти на Nomad сървъри, след като което просто ще продължим към Nomad.

Инсталирането на инструментите на HashiCorp е много просто: по същество ние просто преместваме двоичния файл в директорията bin, настройваме конфигурационния файл на инструмента и създаваме неговия сервизен файл.

Изтеглете двоичния файл Consul и го извлечете в домашната директория на потребителя:

root@consul-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@consul-livelinux-01:~# mv consul /usr/local/bin/

Вече имаме двоичния файл на консула, готов за по-нататъшно персонализиране.

За да работим с Consul, трябва да създадем уникален ключ с помощта на командата keygen:

root@consul-livelinux-01:~# consul keygen

Нека да преминем към конфигурирането на Consul, създайте директория /etc/consul.d/ със следната структура:

/etc/consul.d/
├── bootstrap
│   └── config.json

Bootstrap директорията ще съдържа конфигурационния файл config.json - в него ще зададем настройките на Consul. Съдържанието му:

{
"bootstrap": true,
"server": true,
"datacenter": "dc1",
"data_dir": "/var/consul",
"encrypt": "your-key",
"log_level": "INFO",
"enable_syslog": true,
"start_join": ["172.30.0.15"]
}

Нека анализираме отделно основните директиви и техните значения:

  • Bootstrap: вярно. Разрешете автоматично добавяне на нови възли, ако са свързани. Отбелязвам, че тук не посочваме точния брой очаквани възли.
  • сървър: вярно. Включете сървърния режим. Consul на тази виртуална машина ще действа като единствен сървър и master в момента, VM на Nomad ще бъдат клиенти.
  • център за данни: dc1. Посочете името на центъра за данни, за да създадете клъстера. Трябва да е идентичен както на клиенти, така и на сървъри.
  • криптиране:вашият-ключ. Ключът, който също трябва да бъде уникален и да съответства на всички клиенти и сървъри. Генерирано с помощта на командата consul keygen.
  • start_join. В този списък посочваме списък с IP адреси, към които ще се осъществи връзката. В момента оставяме само собствения си адрес.

В този момент можем да стартираме consul с помощта на командния ред:

root@consul-livelinux-01:~# /usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui

Това е добър начин за отстраняване на грешки сега, но няма да работи постоянно по очевидни причини. Нека създадем сервизен файл за управление на Consul чрез systemd:

root@consul-livelinux-01:~# nano /etc/systemd/system/consul.service

Съдържание на файла Consul.service:

[Unit]
Description=Consul Startup process
After=network.target
 
[Service]
Type=simple
ExecStart=/bin/bash -c '/usr/local/bin/consul agent -config-dir /etc/consul.d/bootstrap -ui' 
TimeoutStartSec=0
 
[Install]
WantedBy=default.target

Стартирайте Consul чрез systemctl:

root@consul-livelinux-01:~# systemctl start consul

Проверяваме: нашата услуга трябва да работи и чрез изпълнение на командата consul members трябва да видим нашия сървър:

root@consul-livelinux:/etc/consul.d# consul members
consul-livelinux    172.30.0.15:8301  alive   server  1.5.0  2         dc1  <all>

Следващата стъпка: инсталиране на Nginx и настройка на прокси, http авторизация. Инсталирайте nginx през мениджъра на пакети и в директорията /etc/nginx/sites-enabled създайте конфигурационен файл consul.conf със следното съдържание:

upstream consul-auth {
    server localhost:8500;
}

server {

    server_name consul.doman.name;
    
    location / {
      proxy_pass http://consul-auth;
      proxy_set_header Host $host;
      auth_basic_user_file /etc/nginx/.htpasswd;
      auth_basic "Password-protected Area";
    }
}

Не забравяйте да създадете .htpasswd файл и да генерирате потребителско име и парола за него. Този елемент е необходим, така че уеб панелът да не е достъпен за всеки, който познава нашия домейн. Въпреки това, когато настройваме Gitlab, ще трябва да откажем това - в противен случай няма да можем да разположим нашето приложение в Nomad. В моя проект и Gitlab, и Nomad са само в сивата мрежа, така че тук няма такъв проблем.

На останалите два сървъра инсталирайте Consul агенти съгласно следните инструкции. Повтаряме стъпките с двоичния файл:

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# unzip consul_1.5.0_linux_amd64.zip
root@nomad-livelinux-01:~# mv consul /usr/local/bin/

По аналогия с предишния сървър създаваме директория за конфигурационни файлове /etc/consul.d със следната структура:

/etc/consul.d/
├── client
│   └── config.json

Съдържание на файла config.json:

{
    "datacenter": "dc1",
    "data_dir": "/opt/consul",
    "log_level": "DEBUG",
    "node_name": "nomad-livelinux-01",
    "server": false,
    "encrypt": "your-private-key",
    "domain": "livelinux",
    "addresses": {
      "dns": "127.0.0.1",
      "https": "0.0.0.0",
      "grpc": "127.0.0.1",
      "http": "127.0.0.1"
    },
    "bind_addr": "172.30.0.5", # локальный адрес вм
    "start_join": ["172.30.0.15"], # удаленный адрес консул сервера
    "ports": {
      "dns": 53
     }

Запазваме промените и продължаваме към настройката на сервизния файл, съдържанието му е:

/etc/systemd/system/consul.service:

[Unit]
Description="HashiCorp Consul - A service mesh solution"
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target

[Service]
User=root
Group=root
ExecStart=/usr/local/bin/consul agent -config-dir=/etc/consul.d/client
ExecReload=/usr/local/bin/consul reload
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

Стартираме консул на сървъра. Сега, след стартиране, трябва да видим конфигурираната услуга в nsul members. Това ще означава, че той успешно се е свързал с клъстера като клиент. Повторете същото на втория сървър и след това можем да започнем инсталирането и конфигурирането на Nomad.

По-подробна инсталация на Nomad е описана в официалната му документация. Има два традиционни метода за инсталиране: изтегляне на двоичен файл и компилиране от източника. Аз ще избера първия начин.

Внимание: проектът се развива много бързо, често се пускат нови актуализации. Може би, докато статията бъде завършена, ще бъде пусната нова версия. Ето защо, преди да прочетете, препоръчвам да проверите текущата версия на Nomad в момента и да я изтеглите.

root@nomad-livelinux-01:~# wget https://releases.hashicorp.com/nomad/0.9.1/nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# unzip nomad_0.9.1_linux_amd64.zip
root@nomad-livelinux-01:~# mv nomad /usr/local/bin/
root@nomad-livelinux-01:~# nomad -autocomplete-install
root@nomad-livelinux-01:~# complete -C /usr/local/bin/nomad nomad
root@nomad-livelinux-01:~# mkdir /etc/nomad.d

След разопаковането ще получим 65 MB Nomad двоичен файл - той трябва да бъде преместен в /usr/local/bin.

Нека създадем директория с данни за Nomad и редактираме нейния сервизен файл (вероятно няма да съществува в началото):

root@nomad-livelinux-01:~# mkdir --parents /opt/nomad
root@nomad-livelinux-01:~# nano /etc/systemd/system/nomad.service

Вмъкнете следните редове там:

[Unit]
Description=Nomad
Documentation=https://nomadproject.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/nomad agent -config /etc/nomad.d
KillMode=process
KillSignal=SIGINT
LimitNOFILE=infinity
LimitNPROC=infinity
Restart=on-failure
RestartSec=2
StartLimitBurst=3
StartLimitIntervalSec=10
TasksMax=infinity

[Install]
WantedBy=multi-user.target

Ние обаче не бързаме да стартираме nomad - все още не сме създали неговия конфигурационен файл:

root@nomad-livelinux-01:~# mkdir --parents /etc/nomad.d
root@nomad-livelinux-01:~# chmod 700 /etc/nomad.d
root@nomad-livelinux-01:~# nano /etc/nomad.d/nomad.hcl
root@nomad-livelinux-01:~# nano /etc/nomad.d/server.hcl

Получената структура на директорията ще бъде както следва:

/etc/nomad.d/
├── nomad.hcl
└── server.hcl

Файлът nomad.hcl трябва да съдържа следната конфигурация:

datacenter = "dc1"
data_dir = "/opt/nomad"

Съдържание на файла Server.hcl:

server {
  enabled = true
  bootstrap_expect = 1
}

consul {
  address             = "127.0.0.1:8500"
  server_service_name = "nomad"
  client_service_name = "nomad-client"
  auto_advertise      = true
  server_auto_join    = true
  client_auto_join    = true
}

bind_addr = "127.0.0.1" 

advertise {
  http = "172.30.0.5"
}

client {
  enabled = true
}

Не забравяйте да промените конфигурационния файл на втория сървър - там ще трябва да промените стойността на http директивата.

Последното нещо на този етап е настройката на Nginx за прокси и инсталиране на http авторизация. Съдържание на файла nomad.conf:

upstream nomad-auth {
        server 172.30.0.5:4646;
}

server {

        server_name nomad.domain.name;
        
        location / {
	        proxy_pass http://nomad-auth;
	        proxy_set_header Host $host;
	        auth_basic_user_file /etc/nginx/.htpasswd;
		   auth_basic "Password-protected Area";
        }
        
}

Сега имаме достъп до уеб панела през външна мрежа. Свържете се и отидете на страницата на сървърите:

Създаване на клъстер Nomad с Consul и интегриране с Gitlab
Изображение 1. Списък със сървъри в клъстер Nomad

И двата сървъра са показани успешно в панела, ще видим същото в изхода на командата за състояние на nomad node:

Създаване на клъстер Nomad с Consul и интегриране с Gitlab
Изображение 2. Изход на командата за състояние на Nomad node

Ами консул? Нека да погледнем. Отидете в контролния панел на Consul, на страницата с възли:
Създаване на клъстер Nomad с Consul и интегриране с Gitlab
Изображение 3. Списък на възлите в клъстера Consul

Сега имаме готов Nomad, който работи съвместно с Consul. В последния етап ще преминем към най-интересната част: ще настроим доставката на Docker контейнери от Gitlab до Nomad и ще говорим за някои от другите му отличителни характеристики.

Създаване на Gitlab Runner

За да разположим докер изображения в Nomad, ще използваме отделен бегач с двоичния файл на Nomad вътре (тук, между другото, може да се отбележи още една характеристика на приложенията на Hashicorp - поотделно те са единственият двоичен файл). Качете го в директорията на runner. Нека създадем прост Dockerfile за него със следното съдържание:


FROM alpine:3.9
RUN apk add --update --no-cache libc6-compat gettext
COPY nomad /usr/local/bin/nomad

В същия проект създайте .gitlab-ci.yml:

variables:
  DOCKER_IMAGE: nomad/nomad-deploy
  DOCKER_REGISTRY: registry.domain.name
 

stages:
  - build

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:latest
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}

В резултат на това ще имаме наличен образ на Nomad runner в регистъра на Gitlab, сега можем да отидем директно в хранилището на проекта, да създадем Pipeline и да настроим nomad заданието на Nomad.

Настройка на проекта

Нека започнем с файла на работата за Nomad. Моят проект в тази статия ще бъде доста примитивен: ще се състои от една задача. Съдържанието на .gitlab-ci ще бъде както следва:

variables:
  NOMAD_ADDR: http://nomad.address.service:4646
  DOCKER_REGISTRY: registry.domain.name
  DOCKER_IMAGE: example/project

stages:
  - build
  - deploy

build:
  stage: build
  image: ${DOCKER_REGISTRY}/nomad-runner/alpine:3
  script:
    - tag=${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${CI_COMMIT_SHORT_SHA}
    - docker build --pull -t ${tag} -f Dockerfile .
    - docker push ${tag}


deploy:
  stage: deploy
  image: registry.example.com/nomad/nomad-runner:latest
  script:
    - envsubst '${CI_COMMIT_SHORT_SHA}' < project.nomad > job.nomad
    - cat job.nomad
    - nomad validate job.nomad
    - nomad plan job.nomad || if [ $? -eq 255 ]; then exit 255; else echo "success"; fi
    - nomad run job.nomad
  environment:
    name: production
  allow_failure: false
  when: manual

Тук внедряването се извършва ръчно, но можете да го конфигурирате да променя съдържанието на директорията на проекта. Pipeline, от друга страна, се състои от два етапа: от сглобяването на изображението и неговото разгръщане към номада. На първия етап изграждаме докер изображението и го изпращаме в нашия регистър, а на втория етап стартираме нашата работа в Nomad.

job "monitoring-status" {
    datacenters = ["dc1"]
    migrate {
        max_parallel = 3
        health_check = "checks"
        min_healthy_time = "15s"
        healthy_deadline = "5m"
    }

    group "zhadan.ltd" {
        count = 1
        update {
            max_parallel      = 1
            min_healthy_time  = "30s"
            healthy_deadline  = "5m"
            progress_deadline = "10m"
            auto_revert       = true
        }
        task "service-monitoring" {
            driver = "docker"

            config {
                image = "registry.domain.name/example/project:${CI_COMMIT_SHORT_SHA}"
                force_pull = true
                auth {
                    username = "gitlab_user"
                    password = "gitlab_password"
                }
                port_map {
                    http = 8000
                }
            }
            resources {
                network {
                    port "http" {}
                }
            }
        }
    }
}

Моля, обърнете внимание, че имам частен регистър и за успешно изтегляне на докер изображението трябва да вляза в него. Най-доброто решение в този случай е да заключите данните за вход и парола в Vault и след това да ги интегрирате с Nomad. Nomad поддържа Vault първоначално. Но първо, в самия Vault, ще зададем необходимите политики за Nomad, те могат да бъдат изтеглени:

# Download the policy and token role
$ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
$ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L

# Write the policy to Vault
$ vault policy write nomad-server nomad-server-policy.hcl

# Create the token role with Vault
$ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json

Сега, след като създадем необходимите политики, ще добавим интеграция с Vault в блока задачи във файла job.nomad:

vault {
  enabled = true
  address = "https://vault.domain.name:8200"
  token = "token"
}

Използвам оторизация на токен и го пиша директно тук, има и опция за указване на токена като променлива при стартиране на номадния агент:

$ VAULT_TOKEN=<token> nomad agent -config /path/to/config

Вече можем да използваме ключове с Vault. Принципът на работа е прост: създаваме файл в заданието Nomad, който ще съхранява стойностите на променливите, например:

template {
                data = <<EOH
{{with secret "secrets/pipeline-keys"}}
REGISTRY_LOGIN="{{ .Data.REGISTRY_LOGIN }}"
REGISTRY_PASSWORD="{{ .Data.REGISTRY_LOGIN }}{{ end }}"

EOH
    destination = "secrets/service-name.env"
    env = true
}

С този прост подход можете да настроите доставката на контейнери към клъстера Nomad и да работите с него в бъдеще. Ще кажа, че до известна степен симпатизирам на Nomad - той е по-подходящ за малки проекти, където Kubernetes може да създаде допълнителни затруднения и няма да реализира пълния си потенциал. В допълнение, Nomad е страхотен за начинаещи - лесно се инсталира и конфигурира. Въпреки това, когато тествам върху някои проекти, се сблъсквам с проблема на ранните му версии - много основни функции просто не съществуват или не работят правилно. Вярвам обаче, че Nomad ще продължи да се развива и в бъдеще ще придобие функциите, от които всеки има нужда.

Автор: Иля Андреев, редактиран от Алексей Жадан и екипа на Live Linux


Източник: www.habr.com

Добавяне на нов коментар