راه اندازی یک خوشه 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. consul-livelinux-01: 172.30.0.15

نصب نوماد کنسول. ایجاد یک خوشه عشایر

بیایید با نصب اولیه شروع کنیم. اگرچه تنظیم ساده بود، به خاطر یکپارچگی مقاله آن را شرح می دهم: اساساً از پیش نویس ها و یادداشت ها برای دسترسی سریع در صورت نیاز ایجاد شده است.

قبل از شروع تمرین، بخش تئوری را مورد بحث قرار خواهیم داد، زیرا در این مرحله درک ساختار آینده مهم است.

ما دو گره نومد داریم و می‌خواهیم آنها را در یک خوشه ترکیب کنیم، و در آینده نیز به مقیاس‌بندی خودکار خوشه‌ای نیاز خواهیم داشت - برای این کار به Consul نیاز داریم. با استفاده از این ابزار، خوشه بندی و افزودن گره های جدید به یک کار بسیار ساده تبدیل می شود: گره Nomad ایجاد شده به نماینده Consul متصل می شود و سپس به خوشه Nomad موجود متصل می شود. بنابراین، در ابتدا سرور Consul را نصب می کنیم، مجوز اصلی http را برای پنل وب پیکربندی می کنیم (به طور پیش فرض بدون مجوز است و در یک آدرس خارجی قابل دسترسی است) و همچنین خود نمایندگان کنسول روی سرورهای 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

دایرکتوری بوت استرپ حاوی یک فایل پیکربندی 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"]
}

بیایید به دستورالعمل های اصلی و معانی آنها به طور جداگانه نگاه کنیم:

  • بوت استرپ: درست است، واقعی. اگر گره‌های جدید متصل باشند، اضافه کردن خودکار آنها را فعال می‌کنیم. توجه داشته باشم که ما در اینجا تعداد دقیق گره های مورد انتظار را نشان نمی دهیم.
  • سرور: درست است، واقعی. حالت سرور را فعال کنید. کنسول در این ماشین مجازی به عنوان تنها سرور و مستر در حال حاضر عمل می کند و VM Nomad مشتری خواهد بود.
  • مرکز داده: dc1. نام مرکز داده را برای ایجاد خوشه مشخص کنید. باید هم در کلاینت ها و هم در سرورها یکسان باشد.
  • رمزگذاری: کلید شما کلید، که همچنین باید منحصر به فرد باشد و در همه کلاینت ها و سرورها مطابقت داشته باشد. با استفاده از دستور consul keygen تولید شده است.
  • start_join. در این لیست لیستی از آدرس های IP که اتصال به آنها برقرار می شود را نشان می دهیم. در حال حاضر فقط آدرس خودمان را می گذاریم.

در این مرحله می‌توانیم کنسول را با استفاده از خط فرمان اجرا کنیم:

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

راه اندازی کنسول از طریق systemctl:

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

بیایید بررسی کنیم: سرویس ما باید در حال اجرا باشد و با اجرای دستور اعضای کنسول باید سرور خود را ببینیم:

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 مستقر کنیم. در پروژه من، هم گیتلب و هم نومد فقط روی وب خاکستری هستند، بنابراین در اینجا چنین مشکلی وجود ندارد.

بر روی دو سرور باقیمانده، ما نمایندگان کنسول را طبق دستورالعمل های زیر نصب می کنیم. مراحل را با فایل باینری تکرار می کنیم:

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 ببینیم. این بدان معنی است که با موفقیت به عنوان مشتری به خوشه متصل شده است. همین کار را در سرور دوم تکرار کنید و بعد از آن می توانیم نصب و پیکربندی 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

پس از باز کردن، یک فایل باینری Nomad به وزن 65 مگابایت دریافت می کنیم - باید به /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 با استفاده از Consul و ادغام با Gitlab
تصویر 2. خروجی فرمان وضعیت گره nomad

کنسول چطور؟ بیایید نگاهی بیندازیم. به کنترل پنل کنسول، به صفحه گره ها بروید:
راه اندازی یک خوشه Nomad با استفاده از Consul و ادغام با Gitlab
تصویر 3. لیست گره ها در خوشه Consul

اکنون ما یک Nomad آماده داریم که با کنسول کار می کند. در مرحله آخر، به قسمت سرگرم کننده می رسیم: راه اندازی تحویل کانتینرهای Docker از Gitlab به Nomad و همچنین صحبت در مورد برخی از ویژگی های متمایز دیگر آن.

ایجاد Gitlab Runner

برای استقرار تصاویر داکر در Nomad، از یک runner جداگانه با فایل باینری Nomad در داخل استفاده می‌کنیم (در اینجا، اتفاقاً می‌توانیم به یکی دیگر از ویژگی‌های برنامه‌های Hashicorp اشاره کنیم - به صورت جداگانه آنها یک فایل باینری واحد هستند). آن را در فهرست راهنما آپلود کنید. بیایید یک 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’s 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 پشتیبانی می کند. اما ابتدا، بیایید سیاست های لازم را برای Nomad در خود Vault نصب کنیم؛ آنها را می توان دانلود کرد:

# 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"
}

من از مجوز توسط توکن استفاده می‌کنم و مستقیماً آن را در اینجا ثبت می‌کنم، همچنین گزینه تعیین رمز به‌عنوان یک متغیر هنگام شروع نماینده nomad وجود دارد:

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

اکنون می توانیم از کلیدها با Vault استفاده کنیم. اصل کار ساده است: ما یک فایل در Nomad job ایجاد می کنیم که مقادیر متغیرها را ذخیره می کند، به عنوان مثال:

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 به توسعه خود ادامه خواهد داد و در آینده عملکردهایی را که همه به آن نیاز دارند را به دست خواهد آورد.

نویسنده: Ilya Andreev، ویرایش شده توسط Alexey Zhadan و تیم Live Linux


منبع: www.habr.com

اضافه کردن نظر