въведение
Напоследък популярността на Kubernetes нараства бързо - все повече и повече проекти го прилагат у дома. Исках да се спра на оркестратор като Nomad: той е идеален за проекти, в които вече се използват други решения от HashiCorp, като Vault и Consul, а самите проекти не са сложни по отношение на инфраструктурата. Тази статия ще предостави инструкции за инсталиране на Nomad, сливане на два възела в клъстер и интегриране на Nomad с Gitlab.
изпитателен стенд
Малко за тестовия стенд: използвани са три виртуални сървъра с характеристики 2 CPU, 4 RAM, 50 Gb SSD, обединени в обща локална мрежа. Техните имена и IP адреси:
- nomad-livelinux-01: 172.30.0.5
- nomad-livelinux-02: 172.30.0.10
- консул-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";
}
}
Сега имаме достъп до уеб панела през външна мрежа. Свържете се и отидете на страницата на сървърите:
Изображение 1. Списък със сървъри в клъстер Nomad
И двата сървъра са показани успешно в панела, ще видим същото в изхода на командата за състояние на nomad node:
Изображение 2. Изход на командата за състояние на Nomad node
Ами консул? Нека да погледнем. Отидете в контролния панел на Consul, на страницата с възли:
Изображение 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