使用 Consul 設定 Nomad 叢集並與 Gitlab 集成

介紹

最近,Kubernetes 的受歡迎程度正在迅速增長——越來越多的項目正在實施它。 我想接觸像Nomad這樣的編排器:它非常適合已經使用HashiCorp其他解決方案的項目,例如Vault和Consul,而且項目本身在基礎設施方面並不復雜。 本資料將包含安裝 Nomad、將兩個節點組合成叢集以及將 Nomad 與 Gitlab 整合的說明。

使用 Consul 設定 Nomad 叢集並與 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。 創建Nomad集群

讓我們從基本安裝開始。 儘管設定很簡單,但為了文章的完整性,我將對其進行描述:它本質上是根據草稿和註釋創建的,以便在需要時快速存取。

在開始實踐之前,我們將討論理論部分,因為在這個階段了解未來的結構很重要。

我們有兩個遊牧節點,我們想將它們組合成一個集群,將來我們還需要自動集群擴展 - 為此我們需要 Consul。 有了這個工具,叢集和新增節點就變成了一個非常簡單的任務:創建的Nomad節點連接到Consul代理,然後連接到現有的Nomad叢集。 因此,一開始我們要安裝Consul伺服器,為Web面板配置基本的http授權(預設是無授權的,可以透過外部位址存取),以及Nomad伺服器上的Consul代理本身,之後我們只會前往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 二進位檔案用於進一步配置。

要使用 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"]
}

讓我們分別看看主要指令及其意義:

  • 引導: 真的。 如果新節點已連接,我們會自動新增它們。 我注意到,我們在這裡沒有指出預期節點的確切數量。
  • 服務器: 真的。 啟用伺服器模式。 該虛擬機器上的 Consul 目前將充當唯一的伺服器和主伺服器,Nomad 的 VM 將是客戶端。
  • 數據中心:DC1。 指定建立叢集的資料中心名稱。 它在客戶端和伺服器上必須相同。
  • 加密:你的鑰匙。 密鑰也必須是唯一的並且在所有客戶端和伺服器上都匹配。 使用 consul keygen 指令產生。
  • 開始加入。 在此清單中,我們指示將建立連線的 IP 位址清單。 目前我們只留下自己的地址。

此時我們可以使用命令列運行consul:

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

這是現在偵錯的好方法,但是,由於顯而易見的原因,您將無法持續使用此方法。 讓我們建立一個服務文件來透過 systemd 管理 Consul:

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 啟動 Consul:

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

我們在伺服器上啟動 consul。 現在,啟動後,我們應該在 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

解壓縮後,我們將收到一個大小為 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";
        }
        
}

現在我們可以透過外部網路存取網頁面板了。 連接並轉到伺服器頁面:

使用 Consul 設定 Nomad 叢集並與 Gitlab 集成
圖 1。 Nomad叢集中的伺服器列表

兩台伺服器都成功顯示在面板中,我們將在 nomad node status 命令的輸出中看到相同的內容:

使用 Consul 設定 Nomad 叢集並與 Gitlab 集成
圖 2。 nomad 節點狀態指令的輸出

領事呢? 我們來看看吧。 進入Consul控制面板,進入節點頁面:
使用 Consul 設定 Nomad 叢集並與 Gitlab 集成
圖 3。 Consul叢集中的節點列表

現在我們有一個準備好的Nomad 與Consul 一起工作。 在最後階段,我們將進入有趣的部分:設定 Docker 容器從 Gitlab 到 Nomad 的交付,並討論它的一些其他獨特功能。

建立 Gitlab 運行器

要將 docker 映像部署到 Nomad,我們將使用一個單獨的運行程序,其中包含 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}

這樣,我們就可以在 Gitlab 註冊表中獲得 Nomad 運行器的可用鏡像,現在我們可以直接進入專案儲存庫,建立 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

這裡的部署是手動進行的,但您可以對其進行配置以更改專案目錄的內容。 管道由兩個階段組成:影像組裝及其部署到遊牧者。 在第一階段,我們組裝一個 docker 映像並將其推送到我們的註冊表中,第二階段我們在 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" {}
                }
            }
        }
    }
}

請注意,我有一個私人註冊表,要成功提取 Docker 映像,我需要登入它。 在這種情況下,最好的解決方案是在 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

現在,創建了必要的策略後,我們將在 job.nomad 檔案的任務區塊中新增與 Vault 的整合:

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

我使用令牌授權並直接在這裡註冊它,還有啟動 nomad 代理程式時將令牌指定為變數的選項:

$ 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會繼續發展,未來它會獲得大家需要的功能。

作者:Ilya Andreev,由 Alexey Zhadan 和 Live Linux 團隊編輯


來源: www.habr.com

添加評論