Manage jobs from Nomad UI

このブログは Ghost というブログプラットフォームを使用し Nomad クラスター上で動作しています。

Nomad クラスター上で Ghost ブログを動作させる
このブログは数年間単一のサーバーで稼働していました。 学習も兼ねてわざわざ自前でサーバーを運用していたのですが、最近新しい構成に移したくなり、Kubernetes の流行もあってクラスターやマイクロサービスといった時代の流れに乗るべく、Nomad クラスターへの移行を行いました。 Nomad クラスターの作成までは下記記事にまとめています (インフラやクラスターの設定等はここからさらに変更しています)。 * Nomad クラスターを作成する 今回はこの Nomad クラスター上で Ghost を動かすところまでをまとめます。 構成 以下の通り、DigitalOcean のマネー…

色々悩んだ結果、Docker イメージ上にブログのコンテンツを全て収めており、これを Nomad ジョブとして動かす形で運用しています。
これはメリットもあるのですが、一番大きなデメリットとして更新が面倒というものがあります。例えば記事を更新する場合の手順をざっくり挙げると以下です。

  1. 最新の Docker イメージからコンテナを立ち上げる。
  2. 記事を更新し、 docker commit する。
  3. docker push し Docker Hub のイメージを更新する。
  4. Nomad の動作しているサーバーに ssh し、Nomad のジョブファイルを編集して最新の Docker イメージに書き換える。

うーん…面倒。

多少負担を減らすためスクリプトである程度手順の簡略化を図っていますが、それでもまだ面倒…。

ブログ管理用のスクリプトを書いた (構成変更までの繋ぎ)。
現在このブログを Nomad のタスクとして Docker で動かしています。 Nomad クラスター上で Ghost ブログを動作させるこのブログは数年間単一のサーバーで稼働していました。 学習も兼ねてわざわざ自前でサーバーを運用していたのですが、最近新しい構成に移したくなり、Kubernetesの流行もあってクラスターやマイクロサービスといった時代の流れに乗るべく、Nomad クラスターへの移行を行いました。 Nomad クラスターの作成までは下記記事にまとめています (インフラやクラスターの設定等はここからさらに変更しています)。 * Nomad クラスターを作成する [https:/…

そこで今回は Nomad UI を使用してジョブの書き換えをすることで手順 4 の簡略化を図ってみます。

以下の通り Nomad には標準で UI が付属します。

これにインターネットを介してアクセスできれば、ちまちま ssh して nomad コマンド叩いて…をするよりだいぶ楽になります。

が、この Nomad UI には特にサインインによる認証機構はないので Web サーバーの設定を更新してアクセスできるようにするだけでは誰でもアクセスできてしまい危険です。

そこで今回は Basic 認証をかけてみます。

Basic 認証の設定

このブログにアクセスするための構成は以下のようになっています。

  • ブラウザ → ロードバランサー (IaaS プロバイダーが提供するマネージドサービスを使ってます) → Nginx (Nomad ジョブで稼働) → Ghost (Nomad ジョブで稼働)

これと同じように、Ghost に加え Nomad UI へアクセスするようなルーティングを追加します。

Nginx の Nomad ジョブファイルから抜粋します。ジョブのタスクスタンザ内に Nginx の設定やらを定義しているので、タスクスタンザから抜粋します。

まず Docker の設定です。Nginx の設定ファイルと Basic 認証に必要な .htpasswd ファイルをコンテナ内で使用するためにボリュームの設定をしてします。

driver = "docker"
config {
  image = "nginx:1.15.12"
  ports = ["http"]
  volumes = [
    "custom/default.conf:/etc/nginx/conf.d/default.conf",
    "custom/.htpasswd:/etc/nginx/conf.d/.htpasswd"
  ]
}

次に、template スタンザを使用して上のボリュームで指定している custom/default.confcustom/.htpasswd を作成していきます。

まず custom/.htpasswd から。.htpasswd の中身 の部分は htpasswd コマンドで作成したファイルの中身をそのまま入れています。ここも後々 Vault から取得するようにしたい。destination がファイルの吐き出し先ですね。

template {
  data = "<.htpasswd の中身>"
  destination = "custom/.htpasswd"
}

custom/default.conf はちょっと長いので今回必要な部分のみ。

{{}} の部分は Consul 統合を使用して Consul のサービスカタログから自動的に Nomad クライアントの IP アドレス・ポートを取得している部分です。めっちゃ便利。Consul UI にアクセスさせたいサーバー名へのリクエストが来たら、upstream で指定した Nomad クライアントの IP アドレス・ポートに流すようにしています。それ以外は普通に Basic 認証を設定する Nginx の設定です。

template {
  data = <<EOH
  ...
    upstream nomadbackend {
      ip_hash;
      {{ range service "nomad-client" }} server {{ .Address }}:{{ .Port }};
      {{ end }}
    }
    ...
    server {
      listen 80;
      server_name <Nomad UI にアクセスするためのサーバー名>;
      location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://nomadbackend;
        proxy_redirect off;
        auth_basic "restricted";
        auth_basic_user_file conf.d/.htpasswd;
      }
    }
  EOH
  destination = "custom/default.conf"
}

Nomad UI の画面

こんな感じ。ジョブの情報やサーバー、クライアントの情報が見れます。なかなか細かく見れるので助かる!

このようにブラウザ上の UI からジョブ定義を書き換えて適用できるようになりました!

ジョブ定義の書き換え後ジョブの差分を確認できる
Run ボタンを押すとデプロイが始まる

今後

ジョブの更新が ssh でアクセスするよりもかなり楽になりました。
が、もう少し楽にしたい…。

  • Nomad UI を公開したことで Nomad API へのアクセスもできるようになったのでコマンド一発で更新できるようにしたい (ブログ運用スクリプトに組み込みたい)。

以下も改善したい。

  • ジョブ定義ファイル内の .htpasswd の情報は機密情報なので Vault に保管し使用したい。
  • Nomad の ACL を使用し UI の使用を制限したい。
  • サインイン機能ではなく、表示される項目を制限するもの。Basic 認証と併用すればより安全になる。