/var/log/study

つまり雑記

Hashicorp Nomad で タスクにクライアント側の変数を利用する

Nomad とは

Nomad というのはおしゃれな緑色のHashicorpプロダクト

www.nomadproject.io

同じくHashicorpのConsulというツールと連動してジョブのスケジューラーとして動作してくれる製品です。

アーキテクチャ

NomadにはServerというユーザーからジョブを受け付けるヤツと、Clientというジョブを実際に実行するヤツとがいるっぽいです。

あまりきちんとドキュメントを読み込んでいないので、正しくないかもしれないですが。

実現したいしたいこと

あるジョブを実行した際、ホストごとに設定される環境変数を読み取り、挙動を変えたいと思いました。

以下のようなコードの中の DOMAIN をクライアントごとに切り替えたいという話です。

from flask import Flask
import os

app = Flask(__name__)

@app.route("/", methods=["GET"])
def root():
    return os.getenv("DOMAIN", "None")

if __name__ == "__main__":
    app.run(host="0.0.0.0")

ざっくりとした図は以下です。

f:id:yaaamaaaguuu:20180624120632p:plain

実現する方法

まず、クライアント側のサーバーを動かす設定ファイルの定義に meta というセクションを指定し、その中で適当に変数を宣言します

client {
    enabled = true
    servers = [ "ipaddress" ]
    meta {
        domain="This is domain value."
    }
}

次に、ジョブの定義の中で、クライアントのmetaを拾えるようにします。

以下の設定の中の、 envというところで、 DOMAIN="${meta.domain}" を指定しています。

こうすることで、上で示した実行したいコードは DOMAIN という環境変数がセットされた上で実行されるようになります。

job "web-app"{
    datacenters = ["dc1"]
    type = "system"
    update {
        stagger = "10s"
        max_parallel = 1
    }
    task "webservice" {
        driver = "docker"

        config {
            image = "flask-app:1.2.0"
            port_map {
                web = 5000
            }
        }
        resources {
            network {
                port "web" {}
            }
        }
        env {
            DOMAIN = "${meta.domain}"
        }
    }
}

以下の話は、ドキュメント に以下のように記載されていました。

${meta.key} | Metadata value given by key on the client | ${meta.foo} => bar

気づくのに時間がかかったので、覚書として。

全部ではないが、コードは以下

[Nomad] Use client side variables. · GitHub