Thiết lập cụm Nomad bằng Consul và tích hợp với Gitlab

Giới thiệu

Gần đây, mức độ phổ biến của Kubernetes đang tăng lên nhanh chóng - ngày càng có nhiều dự án triển khai nó. Tôi muốn đề cập đến một nhà điều phối như Nomad: nó hoàn hảo cho các dự án đã sử dụng các giải pháp khác từ HashiCorp, chẳng hạn như Vault và Consul, và bản thân các dự án này không phức tạp về mặt cơ sở hạ tầng. Tài liệu này sẽ chứa hướng dẫn cài đặt Nomad, kết hợp hai nút thành một cụm cũng như tích hợp Nomad với Gitlab.

Thiết lập cụm Nomad bằng Consul và tích hợp với Gitlab

Kiểm tra đứng

Đôi nét về băng ghế thử nghiệm: ba máy chủ ảo được sử dụng với đặc điểm 2 CPU, 4 RAM, SSD 50 Gb, hợp nhất thành một mạng cục bộ chung. Tên và địa chỉ IP của họ:

  1. du mục-livelinux-01: 172.30.0.5
  2. du mục-livelinux-02: 172.30.0.10
  3. lãnh sự-livelinux-01: 172.30.0.15

Cài đặt Nomad, Lãnh sự. Tạo cụm Nomad

Hãy bắt đầu với việc cài đặt cơ bản. Mặc dù việc thiết lập rất đơn giản nhưng tôi sẽ mô tả nó vì tính toàn vẹn của bài viết: về cơ bản nó được tạo từ các bản nháp và ghi chú để truy cập nhanh khi cần.

Trước khi bắt đầu thực hành, chúng ta sẽ thảo luận về phần lý thuyết, vì ở giai đoạn này, điều quan trọng là phải hiểu cấu trúc tương lai.

Chúng tôi có hai nút du mục và chúng tôi muốn kết hợp chúng thành một cụm và trong tương lai, chúng tôi cũng sẽ cần mở rộng quy mô cụm tự động - để làm được điều này, chúng tôi sẽ cần Lãnh sự. Với công cụ này, việc phân cụm và thêm các nút mới trở thành một nhiệm vụ rất đơn giản: nút Nomad được tạo kết nối với đại lý Lãnh sự, sau đó kết nối với cụm Nomad hiện có. Do đó, ngay từ đầu, chúng tôi sẽ cài đặt máy chủ Lãnh sự, định cấu hình ủy quyền http cơ bản cho bảng điều khiển web (theo mặc định, nó không có ủy quyền và có thể được truy cập tại một địa chỉ bên ngoài), cũng như chính các đại lý Lãnh sự trên máy chủ Nomad, sau đó chúng ta sẽ chỉ tiến tới Nomad.

Việc cài đặt các công cụ của HashiCorp rất đơn giản: về cơ bản, chúng ta chỉ cần di chuyển tệp nhị phân vào thư mục bin, thiết lập tệp cấu hình của công cụ và tạo tệp dịch vụ của nó.

Tải xuống tệp nhị phân Consul và giải nén nó vào thư mục chính của người dùng:

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/

Bây giờ chúng ta có một tệp nhị phân lãnh sự được tạo sẵn để cấu hình thêm.

Để làm việc với Consul, chúng ta cần tạo một khóa duy nhất bằng lệnh keygen:

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

Hãy chuyển sang thiết lập cấu hình Lãnh sự, tạo thư mục /etc/consul.d/ với cấu trúc sau:

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

Thư mục bootstrap sẽ chứa tệp cấu hình config.json - trong đó chúng ta sẽ thiết lập cài đặt Lãnh sự. Nội dung của nó:

{
"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"]
}

Chúng ta hãy xem xét các chỉ thị chính và ý nghĩa của chúng một cách riêng biệt:

  • bootstrap: ĐÚNG VẬY. Chúng tôi cho phép tự động thêm các nút mới nếu chúng được kết nối. Tôi lưu ý rằng ở đây chúng tôi không chỉ ra số lượng nút dự kiến ​​chính xác.
  • máy chủ: ĐÚNG VẬY. Kích hoạt chế độ máy chủ. Lãnh sự trên máy ảo này sẽ đóng vai trò là máy chủ và máy chủ duy nhất vào lúc này, VM của Nomad sẽ là máy khách.
  • Trung tâm dữ liệu: dc1. Chỉ định tên của trung tâm dữ liệu để tạo cụm. Nó phải giống hệt nhau trên cả máy khách và máy chủ.
  • mã hóa: chìa khóa của bạn. Khóa cũng phải là duy nhất và khớp với tất cả máy khách và máy chủ. Được tạo bằng lệnh lãnh sự keygen.
  • bắt đầu_tham gia. Trong danh sách này, chúng tôi chỉ ra danh sách các địa chỉ IP mà kết nối sẽ được thực hiện. Hiện tại chúng tôi chỉ để lại địa chỉ của riêng mình.

Tại thời điểm này, chúng ta có thể chạy lãnh sự bằng dòng lệnh:

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

Đây là một cách tốt để gỡ lỗi ngay bây giờ, tuy nhiên, bạn sẽ không thể sử dụng phương pháp này thường xuyên vì những lý do rõ ràng. Hãy tạo một tệp dịch vụ để quản lý Lãnh sự thông qua systemd:

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

Nội dung của file 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

Khởi chạy Lãnh sự thông qua systemctl:

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

Hãy kiểm tra: dịch vụ của chúng tôi phải đang chạy và bằng cách thực thi lệnh của các thành viên lãnh sự, chúng tôi sẽ thấy máy chủ của mình:

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

Giai đoạn tiếp theo: cài đặt Nginx và thiết lập proxy và ủy quyền http. Chúng tôi cài đặt nginx thông qua trình quản lý gói và trong thư mục /etc/nginx/sites-enabled, chúng tôi tạo một tệp cấu hình consul.conf với nội dung sau:

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

Đừng quên tạo tệp .htpasswd và tạo tên người dùng và mật khẩu cho tệp đó. Mục này là bắt buộc để tất cả những người biết tên miền của chúng tôi không có sẵn bảng điều khiển web. Tuy nhiên, khi thiết lập Gitlab, chúng ta sẽ phải từ bỏ điều này - nếu không chúng ta sẽ không thể triển khai ứng dụng của mình lên Nomad. Trong dự án của tôi, cả Gitlab và Nomad đều chỉ có trên web xám nên không có vấn đề nào như vậy ở đây.

Trên hai máy chủ còn lại chúng ta cài đặt các đại lý Consul theo hướng dẫn sau. Chúng tôi lặp lại các bước với tệp nhị phân:

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/

Tương tự với máy chủ trước, chúng tôi tạo một thư mục chứa các tệp cấu hình /etc/consul.d với cấu trúc sau:

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

Nội dung của tệp 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
     }

Lưu các thay đổi và chuyển sang thiết lập tệp dịch vụ, nội dung của nó:

/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

Chúng tôi khởi chạy lãnh sự trên máy chủ. Bây giờ, sau khi khởi chạy, chúng ta sẽ thấy dịch vụ được định cấu hình ở các thành viên nsul. Điều này có nghĩa là nó đã kết nối thành công với cụm với tư cách là máy khách. Lặp lại tương tự trên máy chủ thứ hai và sau đó chúng ta có thể bắt đầu cài đặt và định cấu hình Nomad.

Việc cài đặt Nomad chi tiết hơn được mô tả trong tài liệu chính thức của nó. Có hai phương pháp cài đặt truyền thống: tải xuống tệp nhị phân và biên dịch từ nguồn. Tôi sẽ chọn phương pháp đầu tiên.

Ghi: Dự án đang phát triển rất nhanh, các bản cập nhật mới thường xuyên được tung ra. Có lẽ một phiên bản mới sẽ được ra mắt vào thời điểm bài viết này hoàn thành. Do đó, trước khi đọc, tôi khuyên bạn nên kiểm tra phiên bản hiện tại của Nomad và tải xuống.

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

Sau khi giải nén, chúng ta sẽ nhận được một file nhị phân Nomad nặng 65 MB - nó phải được chuyển đến /usr/local/bin.

Hãy tạo một thư mục dữ liệu cho Nomad và chỉnh sửa tệp dịch vụ của nó (rất có thể lúc đầu nó sẽ không tồn tại):

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

Dán các dòng sau vào đó:

[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

Tuy nhiên, chúng tôi không vội khởi chạy nomad - chúng tôi chưa tạo tệp cấu hình của nó:

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

Cấu trúc thư mục cuối cùng sẽ như sau:

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

Tệp nomad.hcl phải chứa cấu hình sau:

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

Nội dung của tệp 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
}

Đừng quên thay đổi tệp cấu hình trên máy chủ thứ hai - ở đó bạn sẽ cần thay đổi giá trị của lệnh http.

Điều cuối cùng ở giai đoạn này là định cấu hình Nginx để ủy quyền và thiết lập ủy quyền http. Nội dung của tệp 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";
        }
        
}

Bây giờ chúng ta có thể truy cập bảng điều khiển web thông qua mạng bên ngoài. Kết nối và đi đến trang máy chủ:

Thiết lập cụm Nomad bằng Consul và tích hợp với Gitlab
Hình ảnh 1. Danh sách các máy chủ trong cụm Nomad

Cả hai máy chủ đều được hiển thị thành công trong bảng điều khiển, chúng ta sẽ thấy điều tương tự ở đầu ra của lệnh trạng thái nút nomad:

Thiết lập cụm Nomad bằng Consul và tích hợp với Gitlab
Hình ảnh 2. Đầu ra của lệnh trạng thái nút du mục

Lãnh sự thì sao? Chúng ta hãy xem xét. Chuyển đến bảng điều khiển Lãnh sự, đến trang nút:
Thiết lập cụm Nomad bằng Consul và tích hợp với Gitlab
Hình ảnh 3. Danh sách các nút trong cụm Lãnh sự

Bây giờ chúng tôi đã chuẩn bị sẵn Nomad làm việc cùng với Lãnh sự. Ở giai đoạn cuối cùng, chúng ta sẽ đến phần thú vị: thiết lập việc phân phối các vùng chứa Docker từ Gitlab đến Nomad, đồng thời nói về một số tính năng đặc biệt khác của nó.

Tạo Á hậu Gitlab

Để triển khai hình ảnh docker cho Nomad, chúng tôi sẽ sử dụng một trình chạy riêng có tệp nhị phân Nomad bên trong (nhân tiện, ở đây, chúng tôi có thể lưu ý một tính năng khác của ứng dụng Hashicorp - riêng lẻ chúng là một tệp nhị phân duy nhất). Tải nó lên thư mục Á hậu. Hãy tạo một Dockerfile đơn giản cho nó với nội dung sau:


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

Trong cùng một dự án, chúng tôi tạo .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}

Kết quả là chúng ta sẽ có sẵn hình ảnh của Nomad Runner trong Gitlab Register, bây giờ chúng ta có thể vào thẳng kho dự án, tạo Pipeline và cấu hình công việc du mục của Nomad.

Thiết lập dự án

Hãy bắt đầu với hồ sơ công việc của Nomad. Dự án của tôi trong bài viết này sẽ khá nguyên thủy: nó sẽ bao gồm một nhiệm vụ. Nội dung của .gitlab-ci sẽ như sau:

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

Ở đây quá trình triển khai diễn ra theo cách thủ công nhưng bạn có thể định cấu hình nó để thay đổi nội dung của thư mục dự án. Quy trình bao gồm hai giai đoạn: lắp ráp hình ảnh và triển khai nó cho người du mục. Ở giai đoạn đầu tiên, chúng tôi tập hợp một hình ảnh docker và đẩy nó vào Sổ đăng ký của mình, sau đó ở giai đoạn thứ hai, chúng tôi bắt đầu công việc của mình trong 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" {}
                }
            }
        }
    }
}

Xin lưu ý rằng tôi có Sổ đăng ký riêng và để lấy hình ảnh docker thành công, tôi cần đăng nhập vào đó. Giải pháp tốt nhất trong trường hợp này là nhập thông tin đăng nhập và mật khẩu vào Vault rồi tích hợp với Nomad. Nomad vốn hỗ trợ Vault. Nhưng trước tiên, hãy cài đặt các chính sách cần thiết cho Nomad in Vault; chúng có thể được tải xuống:

# 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

Bây giờ, sau khi tạo các chính sách cần thiết, chúng tôi sẽ thêm tích hợp với Vault vào khối tác vụ trong tệp job.nomad:

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

Tôi sử dụng ủy quyền bằng mã thông báo và đăng ký trực tiếp tại đây, cũng có tùy chọn chỉ định mã thông báo làm biến khi khởi động tác nhân du mục:

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

Bây giờ chúng ta có thể sử dụng khóa với Vault. Nguyên lý hoạt động rất đơn giản: chúng ta tạo một file trong Nomad job sẽ lưu trữ giá trị của các biến, ví dụ:

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
}

Với cách tiếp cận đơn giản này, bạn có thể định cấu hình việc phân phối vùng chứa đến cụm Nomad và làm việc với nó trong tương lai. Tôi sẽ nói rằng ở một mức độ nào đó, tôi đồng cảm với Nomad - nó phù hợp hơn với các dự án nhỏ nơi Kubernetes có thể gây thêm sự phức tạp và sẽ không phát huy hết tiềm năng của nó. Ngoài ra, Nomad còn hoàn hảo cho người mới bắt đầu—dễ cài đặt và định cấu hình. Tuy nhiên, khi thử nghiệm trên một số dự án, tôi gặp phải một vấn đề với các phiên bản đầu tiên của nó - nhiều chức năng cơ bản không có ở đó hoặc chúng hoạt động không chính xác. Tuy nhiên, tôi tin rằng Nomad sẽ tiếp tục phát triển và trong tương lai nó sẽ có được những chức năng mà mọi người cần.

Tác giả: Ilya Andreev, được biên tập bởi Alexey Zhadan và nhóm Live Linux


Nguồn: www.habr.com

Thêm một lời nhận xét