2019年5月22日水曜日

nomad 超入門

概要

nomad は Hashicorp 社が開発するコンテナスケジューリングツールです
位置づけとして k8s と同じ部類かなと思います
今回は Vagrant 上で nomad を簡単に触ってみました

環境

  • macOS 10.14.4
  • Vagrant 2.1.1
  • Ubuntu 16.04 (コンテナホスト)
    • nomad 0.8.6
    • consul 1.4.0
    • docker 18.09.6

nomad インストール (任意)

  • brew install nomad

ここ からバイナリをダウンロードして PATH に配置しても OK です
今回は基本的に Vagrant 上で作業を進めるので Mac 上へのインストールは任意です

nomad でコンテナを動かすサーバの準備

Vagrant を使います
公式の GettingStarted に Ubuntu16 用の Vagrantfile があるのでそれを使います
使わない場合は docker, nomard, consul がインストールされているホストを準備すれば OK です

  • mkdir nomad_host1
  • cd nomad_host1
  • wget 'https://raw.githubusercontent.com/hashicorp/nomad/master/demo/vagrant/Vagrantfile'
  • vagrant up

VM が起動したら vagrant ssh して中身を確認しましょう

vagrant@nomad:~$ docker -v
Docker version 18.09.6, build 481bc77
vagrant@nomad:~$ consul -v
Consul v1.4.0
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
vagrant@nomad:~$ nomad -v
Nomad v0.8.6 (ab54ebcfcde062e9482558b7c052702d4cb8aa1b+CHANGES)

少し nomad のバージョンが低いですが大丈夫でしょう
また推奨は 3 から 5 台のホストで構成されるクラスタですが今回は入門なので 1 台で行きます

nomad agent の起動

  • sudo nomad agent -dev

フォアグラウンドで起動するのでターミナルは戻ってきません
別のターミナルを開いて動作している確認しましょう

vagrant@nomad:~$ nomad node status
ID        DC   Name   Class   Drain  Eligibility  Status
84c8013c  dc1  nomad  <none>  false  eligible     ready
vagrant@nomad:~$ nomad server members
Name          Address    Port  Status  Leader  Protocol  Build  Datacenter  Region
nomad.global  127.0.0.1  4648  alive   true    2         0.8.6  dc1         global

ちなみに Mac からアクセスしたい場合は

  • nomad server members -address=http://10.0.2.15:4646

のような感じで -address を指定すれば OK です
ただ今回の Vagrantfile を使った場合は hostonly アダプタで VM が起動しているため Mac からアクセスできないのと agent が 127.0.0.1 で起動するのでバインドアドレスを

  • sudo nomad agent -dev -bind=0.0.0.0

という感じで指定しましょう

ジョブの作成

nomad はジョブ単位でコンテナを起動します
ジョブは .nomad という拡張子が付くファイルを作成することで定義します

  • nomad job init

これで example.nomad というファイルが作成されます

job "example" {
  datacenters = ["dc1"]
  type = "service"
  update {
    max_parallel = 1
    min_healthy_time = "10s"
    healthy_deadline = "3m"
    progress_deadline = "10m"
    auto_revert = false
    canary = 0
  }
  migrate {
    max_parallel = 1
    health_check = "checks"
    min_healthy_time = "10s"
    healthy_deadline = "5m"
  }
  group "cache" {
    count = 1
    restart {
      attempts = 2
      interval = "30m"
      delay = "15s"
      mode = "fail"
    }
    ephemeral_disk {
      size = 300
    }
    task "redis" {
      driver = "docker"
      config {
        image = "redis:3.2"
        port_map {
          db = 6379
        }
      }
      resources {
        cpu    = 500 # 500 MHz
        memory = 256 # 256MB
        network {
          mbits = 10
          port "db" {}
        }
      }
      service {
        name = "redis-cache"
        tags = ["global", "cache"]
        port = "db"
        check {
          name     = "alive"
          type     = "tcp"
          interval = "10s"
          timeout  = "2s"
        }
      }
    }
  }
}

コメントを削除すると上記のようになっています
サンプルのジョブでは Redis コンテナが起動するようなジョブになっています

ジョブ起動

.nomad ファイルを元にコンテナを起動してみましょう

  • nomad job run example.nomad
==> Monitoring evaluation "bd2147b2"
    Evaluation triggered by job "example"
    Allocation "946c0f27" created: node "8a89cc14", group "cache"
    Evaluation within deployment: "f48565d1"
    Evaluation status changed: "pending" -> "complete"
==> Evaluation "bd2147b2" finished with status "complete"

という感じでコンテナが起動すれば OK です

ジョブの確認

ジョブの一覧を確認してみます

  • nomad job status
ID       Type     Priority  Status   Submit Date
example  service  50        running  2019-05-21T06:20:28Z

詳細も確認できます

  • nomad status example
Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created    Modified
946c0f27  8a89cc14  cache       0        run      running  5m28s ago  4m33s ago

Allocations を確認するとホスト側で LISTEN しているポートなどが確認できます

  • nomad alloc status 946c0f27
g"
Task Resources
CPU        Memory            Disk     IOPS  Addresses
2/500 MHz  1012 KiB/256 MiB  300 MiB  0     db: 127.0.0.1:30684

Task Events:
Started 

また Allocations でログも確認できます

  • nomad alloc logs 946c0f27 redis

試しに表示されたポートにアクセスするとちゃんと Redis が起動していることが確認できると思います

  • sudo apt -y install redis-tools
  • redis-cli -p 30684 info server

ジョブを更新する

次にジョブを更新してみます
group ディレクティブの count を 1 から 3 に上げてみます

group "cache" {
  count =3 
  ...
}

これを適用してみます

  • nomad job plan example.nomad
+/- Job: "example"
+/- Task Group: "cache" (2 create, 1 in-place update)
  +/- Count: "1" => "3" (forces create)
      Task: "redis"

Scheduler dry-run:
- All tasks successfully allocated.

Job Modify Index: 18
To submit the job with version verification run:

nomad job run -check-index 18 example.nomad

When running the job with the check-index flag, the job will only be run if the
server side version matches the job modify index returned. If the index has
changed, another user has modified the job and the plan's results are
potentially invalid.

実行中のタスクは check-index を指定して確認することができます

  • nomad job run -check-index 18 example.nomad
e.nomad
==> Monitoring evaluation "eb1d87df"
    Evaluation triggered by job "example"
    Allocation "423dca4c" created: node "8a89cc14", group "cache"
    Allocation "f9e5ff00" created: node "8a89cc14", group "cache"
    Allocation "946c0f27" modified: node "8a89cc14", group "cache"
    Evaluation within deployment: "979cd34b"
    Allocation "423dca4c" status changed: "pending" -> "running"
    Allocation "f9e5ff00" status changed: "pending" -> "running"
    Evaluation status changed: "pending" -> "complete"
==> Evaluation "eb1d87df" finished with status "complete"

complete になっていれば変更完了です
確認してみましょう
ジョブの Allocations を確認すると 3 つコンテナが起動していることが確認できると思います

  • nomad status example
Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created     Modified
423dca4c  8a89cc14  cache       1        run      running  2m38s ago   2m21s ago
f9e5ff00  8a89cc14  cache       1        run      running  2m38s ago   2m22s ago
946c0f27  8a89cc14  cache       1        run      running  16m14s ago  2m28s ago

docker ps -a で確認してもコンテナが 3 台起動していることが確認できると思います
ポートを確認する場合は alloc でそれぞれ確認しましょう

ジョブの停止

  • nomad job stop example

これでコンテナが停止します
エージェントをいきなり停止してもコンテナの停止/削除が行われます

クラスタにホストを追加する

今回はここまでです
公式は次にホスト追加の手順に進むので興味があれば試してみてください
サーバモードとクライアントモードで agent を個別に動作させることでクラスタを構築する感じです
サーバモードは管理画面もあるので更に便利に使えると思います

最後に

nomad に入門してみました
.nomad というファイルにコンテナのスケジューリングの定義をすることでコンテナの配置やライフサイクルを管理してくれる感じです

k8s は yamlhaml を使って定義するのがそこが一番の違いかなと思います
ただ k8s には Ingress や StorageClass など他のシステムとシームレスにつながる機能や istio などのサードパーティのツールも充実しているので機能的には k8s のほうが豊富かなと思います

k8s ほどたくさんの機能はいらないけど簡単なコンテナスケジューリング、クラスタ管理はしたいという場合に便利かなと思います

参考サイト

0 件のコメント:

コメントを投稿