ブログ | NGINX

NGINX、Chef、Consul を使用した動的インフラストラクチャの負荷分散

NGINX-F5 水平黒タイプ RGB の一部
ケビン・リーディ サムネイル
ケビン・リーディ
2017 年 5 月 22 日公開


この投稿は、2014 年 10 月に nginx.conf で Belly Card の Kevin Reedy 氏が行ったプレゼンテーションを基に作成されています。 それは数年前のことですが、その内容は今でも非常に関連性があります。 プレゼンテーションの録画はYouTubeでご覧いただけます。

目次

0:00 導入
  概要
  免責事項
1:16 Bellyとは何ですか?
  ベリーズスタック
1:44 バージョン0: 暗黒時代
2:04 バージョン 1: 新たな希望
2:35 バージョン2: ホームページとAPIを分離
  今日の流行語: サービス指向アーキテクチャ!
  SOAを有効にする
  NGINX が ELB に代わる
  アップストリームおよび仮想サーバーの構成
  結果
4:43 Chef による設定
  レシピ
  ファイル
  テンプレート
  料理本
6:49 例: NGINX 用 Chef
  インストール、構成、チューニング
  APIトラフィックのルーティング
9:46 実際の Chef の例
10:08 バージョン2: アプリの導入
10:40 バージョン3: SOAのすべて
  そしてハートブリードが起こった
  SSL すべて
12:25 バージョン4: ドッカー
  利点
  コンテナのデプロイ
15:45 展開戦略
17:43 サービス検出オプション
18:33 領事建築
19:30 領事の機能
22:07 領事テンプレート
  Consul テンプレートを起動するコマンド
  Consul テンプレートを使用した NGINX 構成
  Consul テンプレートを使用した構成管理
24:35 Chef を使って Consul をデプロイする
25:44 プロのヒント
  Chef 部分検索
  DNS
  古い構成を避ける
30:35 質問
36:31 連絡先情報

0:00 はじめに

みなさん、おはようございます。 私の名前はケビン・リーディです。シカゴに拠点を置くベリーカードという会社で働いています。 当社には約100人の従業員と20人のエンジニアがいます。 今日は、常に変化する動的なインフラストラクチャで、どのように負荷分散を行っているかについてお話しします。

0:21 概要

まず最初に、私が暗黒時代と呼んでいるバージョン 0 から始まる、当社のインフラストラクチャ スタックの変遷についてお話しします。 次に、Chef を使用して NGINX を構成する方法について説明します。その後、NGINX を構成するために、Consul サービス検出プラットフォームと呼ばれるものからのデータを使用するように変更した方法について説明します。時間が許せば、NGINX を構成するための、特に構成管理に関するプロのヒントをいくつか紹介します。

0:49 免責事項

これから Chef と Consul についてお話ししますが、この講演の内容はこれらに特有のものではないことをあらかじめご了承ください。 Chef、Puppet、Ansible、Salt、CFEngine などはすべて優れた製品であり、そのうちの 1 つを使用する必要があります。 私たちは Chef を楽しんでいますが、他の多くの人もそうだと思います。

サービス検出についても同様です。 Consul、etcd、ZooKeeper はどれも優れているので、自分に合ったものを使用してください。

1:16 Belly とは何ですか?

Bellyとは何ですか? 本質的には、コーヒーショップでドリンクを 10 杯買うと 1 杯無料になるパンチカードのデジタル版です。 店内に iPad を設置し、お客様が携帯電話または QR コード付きの物理カードを使用してスキャンし、ポイントを追跡して特典を提供し、さらにその上にマーケティング ツールを構築します。

1:36 ベリーズスタック

しかし、私は企業としてのベリーについて話すためにここに来たわけではありません。 ご興味がございましたら、弊社のWeb サイトをご覧ください。 私たちのインフラストラクチャ スタックについてお話しします。

1:44 バージョン0: 暗黒時代

つまりバージョン0です。 私が入社する前、開発者が 3 人いた頃、Belly はモノリシックな Ruby on Rails アプリケーションでした。つまり、すべての API 呼び出しと Web サイトの一部が 1 つの Rails アプリケーションに送られていました。これは MySQL、MongoDB、Memcached によってサポートされ、Heroku にデプロイされました。Heroku は、開始するには最適な場所です。

2:04 バージョン1: 新たな希望

つまりバージョン 1 – 新たなる希望です。 Heroku ではもはやニーズを満たせないと判断したため、Ruby で書かれた「シェル スクリプトよりも優れた」 Capistrano と呼ばれるものの導入を開始しました。 物事を展開するのに役立ちます。

Amazon Web Services EC2 には約 6 台のサーバーがありました。 それは静的な数字でしたが、何か大きなことが起きているとわかった場合は数字を上げ、必要な場合は下げました。 その前に AWS Elastic Load Balancer がありました。

2:35 バージョン2: ホームページとAPIを分離

そこで、ホームページを他の API から分離したいというプロジェクトが立ち上がりました。そうすることで、ホームページの開発を迅速化し、さまざまな開発者が作業できるようにしたいと考えました。

2:47 今日の流行語: サービス指向アーキテクチャ!

当時も今も大きな流行語となっているのが、サービス指向アーキテクチャです。

2:50 SOAの実装

したがって、スタックのバージョン 2 では、サービス指向アーキテクチャを有効にすることになりました。 最初の計画は、ホームページを API から分離することでした。これは非常に単純なことのようです。www.bellycard.comapi.bellycard.comがあるだけです。

しかし、一部のモバイル アプリケーションはwww.bellycard.com/api/api‑assets を使用するように静的に記述されていたため、実際には非常に複雑で、まったく単純ではありませんでした。 当社のメール プロバイダーと、すでにメールで送信されているすべてのクリック リンクには、「メールの開封」を表す/eoと、「メールのクリック」を表す/ec が付いていました。 私たちの Facebook アプリは/facebook/callbackに設定されました。

3:28 NGINX が ELB に取って代わる

つまり、AWS Elastic Load Balancer では、このトラフィックをさまざまなアプリケーションにルーティングするために必要な柔軟性が得られなくなったのです。 そこで、NGINX が救世主として登場しました。 具体的には、複数のアップストリームを用意し、ルールを書き換えて、さまざまなアプリケーションにトラフィックをルーティングすることができます。

3:44 アップストリームと仮想サーバーの構成

この非常に基本的な例では、API 用の 6 つのサーバーを持つアップストリームブロックと、ホームページ用の 2 つのサーバーを持つブロックを定義します。

また、[仮想サーバーを定義する] 2 つのサーバーブロックもあります。 1 つはapi.bellycard.comをリッスンし、そのトラフィックをすべて API サーバーにルーティングします。 一方、私たちはwww.bellycard.comでリッスンし、それに応じてルーティングします。

4:02 結果

これはうまくいきました。 それにより、開発者は迅速に行動できるようになりました。 弊社のフロントエンド担当者は 1 つのプロジェクトに取り組んでおり、API によってブロックされていませんでした。そこで、3 番目のサービスを導入しました。 これは Apple の Passbook との統合のためだったと思います。 そして4つ目は、Facebook の機能をすべて移行したことです。 5 つ目は、Web サイトでのユーザー イベントを処理することです。

その後、誰かがそれを Node.js で記述するのは素晴らしいアイデアだと判断したので、今では 2 つの言語で 5 つの異なるサービスが存在します。 これらはすべて、構成管理をほとんど行わずに独立してデプロイされており、多くの人が最初に行うであろう NGINX を手動で編集していました。

4:43 Chef による設定

このプロセスをスケーリングするためのより良い方法が必要だったので、Chef を使用しました。

Chef は構成管理スイートです。 これは Ruby で書かれており、実際の構成管理も Ruby で記述できるため、開発者に最適です。learnchef.comは Chef について学習するための素晴らしいリソースです。45 分で私が学ぶよりもはるかに多くの Chef について学ぶことができます。

ただし、全員が同じ認識を持つように、いくつかの基本事項について説明します。

5:17 レシピ

Chef の最初の種類の構成要素はレシピです。 シェフは、ナイフなどの気の利いた名前を道具やレシピとしてたくさん使い、すべてが料理本に載っています。 こうすると、楽しくて簡単に理解でき、優れた比喩が提供されますが、何かを Google で検索するのは非常に難しくなります。

それで、私が思いついた最も基本的なレシピを紹介します。 nginxパッケージをインストールし、 nginxサービスを起動して有効にします。

5:56 ファイル

ファイル リソースを使用することもできます。 たとえば、 Hello World!というコンテンツを/usr/share/NGINX/html/index.htmlファイルに書き込みたいとします。

6:08 テンプレート

それをテンプレート システムに組み込むこともできます。 ここでは、 HelloKevinを表す変数gw がいくつかあり、これらの変数を ERB 形式 (Ruby テンプレート スクリプト) のテンプレート ファイルに渡すことができます。

したがって、コンテンツを手動で書き出すのではなく、読み手と挨拶する相手のためのテンプレートを作成できます。

6:19 料理本

最後の主要な構成要素は、レシピ、ファイル、テンプレートのコレクションであるクックブックです。 また、リソース、プロバイダー、ライブラリなど、より複雑なリソースもあります。 https://supermarket.getchef.comには、NGINX、MySQL、Java、 aptyum向けのものや、 ssh_known_hostsファイルの管理に関するものなど、オープンソースやその他のクックブックが多数あります。 構成管理で実行しようとしていることの主要な構成要素のほとんどは、すでにクックブックに記載されています。

6:49 例: NGINX 用 Chef

Chef を使用した簡単な NGINX の例を紹介します。ここでは、NGINX をインストールし、いくつかの変数を変更して設定します。 Chef を使用してアプリケーションが実行されている場所を検出し、トラフィックをアプリケーションにルーティングするように NGINX を構成します。

7:14 インストール、構成、チューニング

この例では、Chef構成で最初に行われることは、NGINXノード属性を調整し、次にnginxをインストールし、アプリケーションノードを見つけて、サイト構成を生成することです。

したがって、この例では、最初にいくつかのノード属性を設定します。 すべてのノードに対して、JSON ドキュメントを追加することで属性値を設定できます。 これらの属性の設定を探すサードパーティの NGINX クックブックを使用します。 worker_connections を特定の値に設定し、 worker_rlimit_nofileディレクティブ、NGINX で使用するイベントタイプ、さらにはclient_max_body_sizeも設定します。

その後、NGINX クックブックから 2 つのレシピを追加します。 1 つ目はnginx::repo で、オペレーティング システムに応じてaptまたはyumリポジトリを設定します。 次に、[ nginxレシピ] によって NGINX がインストールされます。ソースから NGINX をインストールすることもできますが、パッケージを使用する方が高速です。

次に、Chef の検索機能を活用します。 Chef を実行する場合、マシン上のエージェントとして実行することも、基本的にスクリプトのように実行されるソロ モードで実行することもできます。 マシン上にエージェントがある場合は、Chef サーバーにノードやその他の属性を照会できます。

ここでは、レシピbelly-apiがアタッチされているすべてのノードのリストを Chef に要求しています。 その後、 /sites‑enabled/apiというサイト ファイルをテンプレート化します。 そのソースは、次に紹介するテンプレート [ api.erbというファイル] です。 渡す変数は、直前に検索したノードです。

ここで最後に新しいのは、 nginxサービスを再ロードするためのnotifiesステートメントです。 これは、このテンプレートが変更されるたびに、このサービスを再ロードする必要があることを示しています。

8:54 APIトラフィックのルーティング

したがって、ここでのテンプレート ファイルは非常にシンプルです。 apiと呼ばれるアップストリームがあり、ERB では、IP アドレスとポート 8080 でサーバーを指定して、変数として通過するすべてのサーバーを反復処理します。 サーバー名をコメントに記入することもできます。 オペレーターがこのサービスで何が起こっているか調べるときに、これは彼らにとって良いコメントになるでしょう。

また、 api.bellycard.comをリッスンするためのサーバーブロックも定義します。 すべてのトラフィックをAPIアップストリームに渡すだけです。

9:46 実際の Chef の例

実際の例も紹介したいと思います。 皆さんが読むには小さすぎるかもしれませんが、Chef のレシピがどれだけ複雑になるかは、なんとなくわかると思います。 これは、現在弊社の運用サーバーから実際に使用されているテンプレートとレシピです。



10:08 バージョン2: アプリの導入

さて、スタックに戻りましょう。 すでに 5 つのアプリケーションを導入しており、順調に進んでいると申し上げました。 これでトラフィックをルーティングする方法ができたので、開発者はこれを採用し、現在では Chef を使用して約 40 個の Ruby アプリケーションがサーバーにデプロイされています。 トラフィックは、NGINX を使用して完全に動的にルーティングされます。

開発者は、1 つのレシピを編集して新しいサービスの名前を追加する以外、実際に何もする必要はありません。 すべてのトラフィックは NGINX によってルーティングされ、Chef によって動的に構成されます。

10:40 バージョン3: SOAのすべて

また、CDN (Amazon) CloudFront) を介して S3 にデプロイする静的ファイルだけのフロントエンド JavaScript アプリケーションも 10 個ほどありました。 index.html はS3 バケットから提供され、残りのアセットは CloudFront 経由で提供されました。 また、開発者が Heroku にプッシュしたアプリが 5 つほどありました。これは、最終的に本番環境になった 1 回限りのアプリだったため、誰にも知らされていなかったからです。

11:10 そしてハートブリードが起こった

[Heroku 上の 5 つのアプリ] は、Heartbleed バグが発表された 4 月の素晴らしい日まで、独立した、つまり完全に当社のインフラストラクチャの外部にありました。 多くの人が慌てました。 Heartbleed はOpenSSL のバグであり、これにより他人がユーザーの秘密鍵を抽出できる可能性がありました。

当社では Chef を使用しているため、パッチが利用可能になるとすぐに、すべてのボックスで OpenSSL インフラストラクチャをアップグレードすることができました。 約 20 分でインフラストラクチャ全体のあらゆる場所に展開されたと思います。 しかし、AWS (および Heroku) が Elastic Load Balancer にパッチを適用するのに約 24 時間かかりました。

これにより、S3 と Heroku の両方にデプロイされているかどうかに関係なく、すべてのロード バランシングSSL ターミネーションをNGINX に移行することになりました。 そうすることで多少のペナルティは受けますが、少なくとも 4 月のその日は私たちにとってはそれだけの価値がありました。

11:57 SSL すべて

そのため、私たちのスタックのバージョン 3 は、「SOA すべて」から「SSL すべて」に変わりました。 bellycard.comとそのサブドメインへのトラフィックはすべて、ロード バランサーを通過します。 パフォーマンス上の理由から、当社のアセットは実際には別のドメインの CloudFront から提供されています。 SSL のオーバーヘッドは不要であり、また、東海岸にはデータセンターが 1 つしかありません。

12:25 バージョン4: ドッカー

バージョン 4 – 今年、誰もが話題にしている流行語は Docker です。 Docker のバージョンが 0.5 だったと思うので、私たちの開発者はそれを使い始めることに興奮していました。

12:38 メリット

[Docker を使用する] 理由は単純です。

アプリケーションの導入が大幅に簡素化されます。 書くべきレシピはありません。 アセットのコンパイルをどのように行うかについて心配する必要はありません。 他の誰かが Python でアプリを書いているときに、あなたが Ruby でアプリを書いているかどうかは問題ではありません。

本質的には、開発と運用の責任を分離します。 開発者は、コード、使用するライブラリ、さらにはインストールする Linux パッケージについて心配する必要がありません。 運用部門は、「どこにこれを展開するのか」といったことについても心配できます。 そこからログをキャプチャするにはどうすればよいですか? どうやって監視するのですか? これらの問題と操作を解決すれば、どのような言語で記述されていても、すべてのアプリケーションが動作するようになります。

これの利点は、開発者が自分のラップトップ上で依存サービスを簡単に起動できることです。 先ほど述べたように、現在約 55 種類のアプリケーションがあり、その多くは現在 Docker コンテナ内にあります。

たとえば、電子メール キャンペーンを送信するための新しいサービスを開発しているとします。 電子メールサービスに依存します。 したがって、開発マシンでは通常、コードをダウンロードし、 bundle installを実行し、バックグラウンドで起動しますが、「ああ、でも実際には、それは別のサービス、つまりユーザー サービスに依存しています」ということになります。

そのサービスは何か他のものに依存しています。 つまり、実際には、新しい電子メール キャンペーン サービスは、MySQL、Elasticsearch、Redis など、約 5 つの他のサービスに依存しています。

Docker を使用すると、実際に本番環境で使用しているのと同じ Chef レシピからコンテナを構築し、開発者に非常に迅速にダウンロードできるコンテナを提供できます。

これにより、展開と開発がスピードアップします。

14:23 コンテナのデプロイ

そのため、バージョン 4 では、Chef を使用してアプリケーションをデプロイするのではなく、コンテナーにデプロイするようになりました。 これを行うための解決策は数多くあり、今後もさらに増えていくと確信しています。

1つ目はCoreOSとFleetです。 CoreOS は、 etcdと呼ばれるサービス検出エンジンを実行する、簡素化された Linux オペレーティング システムです。 Fleet は、「コンテナーを 5 回実行したいが、他のサービスと同じマシンでは実行したくない」といったことを定義するための方法です。

Git Push インターフェースを備えている点で Heroku に似ている Deis という別のツールもあります。 Apache の Mesos や Google の Kubernetes があり、Flynn も最近登場したばかりのものです。 実は、この航海を始めたとき、これらのツールのほとんどがまだ使える状態になかったため、私たちは独自のものを作成しました。

私たちのものは Jockey と呼ばれ、私たちの展開プロセスは非常に独断的なので、非常にうまく機能しています。 Docker の優れた点は、基本的にコンテナ化のための共通 API のセットを提供していることです。 Linux の LXC コンテナだけを使用する場合に心配する必要のある多くのことがありません。

私たちはこれをオープンソース化する予定ですが、前述したように、デプロイは非常に主観的なもので、私たちにとってうまくいくものがあなたにとってもうまくいくとは限りません。

15:45 展開戦略

また、Docker に移行したときに、デプロイメント戦略も多少変わりました。 以前は、アプリケーションの新しいバージョンをその場でデプロイすることで、ゼロダウンタイムのデプロイを実行していました。 つまり、4 台のマシンでユーザー FAX サービスを実行している場合、Chef を使用して新しいバージョンをダウンロードし、[古いバージョン] の上にインストールしてから、Web サーバーにリロードの信号を送信します。 Unicorn はそれを実現するのに最適な Ruby エンジンです。

ただし、コンテナは不変です。 コンテナが実行中になったら、新しいビルドを作成する場合は新しいコンテナを作成する必要があります。 Git の場合と同じように、これにアタッチして追加のコマンドを実行し、保存することができます。 しかし、実際に Docker を最大限に活用したいのであれば、コンテナは完全に不変である必要があります。

つまり、その場での展開ができなくなったため、新しい展開戦略を考え出す必要がありました。 いくつかあります。 青緑は興味深い色です。 これは、4 台のマシンでアプリケーションを実行している場合に、そのアプリケーションを 4 台の新しいマシンで起動し、ロード バランサーが新しいマシンを指すようにするものです。 実際に期待どおりに動作していることが確認できたら、青色を破壊して、緑色を青色にすることができます。 Amazon には、AWS でこれを行うための非常に優れたツールがあります。

また、「カナリア」デプロイもあります。これは、新しいマシンの 1 つのバージョンをデプロイして監視し、メトリック チェックとヘルス チェックに合格した場合にデプロイを続行できるものです。

ここでのコンテナとの違いは、実際にコンテナを解体して新しいコンテナを起動することになるため、インフラストラクチャ内で実行されている各アプリケーションの場所を追跡するための何らかのシステムが必要になることです。

Chef は実際にこれを実行するための非常に優れた方法になり始めています。 Chef Metal と呼ばれる統合されたクックブックがあり、これを使用すると、コンテナを Chef インフラストラクチャ内の他のリソースと同じように扱うことができます。

17:43 サービス検出オプション

サービス検出もあります。 ZooKeeper は、Hadoop 全体で使用されている非常に人気のあるツールです。[Airbnb] には、ZooKeeper でデプロイメントを実行し、それを追跡できるSmartStackという優れた製品があります。

先ほどetcdについて説明しましたが、これは基本的に REST インターフェースを備えた分散型キーバリューストアです。 これは、Java クライアント ライブラリに近い ZooKeeper と比べて優れています。どのアプリケーションからでも etcd と通信できるようになったからです。 先ほど触れたオープンソースの Platform‑as‑a‑Service の多くは、Deis や Flynn、さらには Google の Kubernetes など、etcd を使用しています。 CoreOS を使用している場合は、etcd がすでに組み込まれています。

もう一つの REST ベースのツールが登場しました。Consulです。 これは、Vagrant や Packer など数多くの素晴らしいツールを開発している HashiCorp の人たちによってリリースされました。 実際に私たちが使用することに決めたのは Consul です。

18:33 領事建築

以下は Consul の基本的な図です。 複数のデータセンターがあり、それぞれに 3 台のサーバーがあることがわかります。 データセンター 1 にはクライアントも存在します。 興味深いのは、サーバー エージェントの中からプライマリ エージェントを選択すると、すべてのクライアントがすべてのサーバーだけでなく、他のすべてのクライアントも認識するようになることです。 次に、ゴシップ プロトコルを使用して他のすべてのエージェントと通信します。

これは、2 人の友人に伝え、その友人がさらに 2 人の友人に伝え、その友人がさらに 2 人の友人に伝え、そのメッセージがノードのネットワーク全体に広がるという、AT&T の古いコマーシャルを思い出させます。[編集者 – まあ、近いですね。Faberge Organics シャンプーのコマーシャルでした。 ] これは、基本的にサーバー エージェントがあり、クライアントがそれに接続するだけの etcd や ZooKeeper と比較されます。

Consul のやり方では、Docker を展開しているすべてのサーバー、ロード バランサーを実行しているすべての場所で、実際に Consul クライアントを実行することになります。 したがって、ローカルホストのポート 8500 でいつでもその API と通信できます。

19:30 領事特集

etcdと同様に、[Consul]は分散型キーバリューストアです。 キーを設定および取得すると、線形化可能性が維持されるため、常に一貫性を保つことができます。 いくつか問題点はありますが、それらの問題点がどこにあるのかについてのドキュメントは素晴らしいです。 ただし、etcd とは異なり、サービス検出を第一級の対象として扱います。

キーと値のペアだけでなく、API などのサービスも登録できます。サービスを登録するときは、そのサービスがどのノードで実行されているかを Consul に伝えます。 つまり、コンテナをデプロイするときに、このホストにもこのサービス API を登録するように Consul に指示することになります。

さらに、Consul には分散ヘルスチェック機能があるため、サービス検出プラットフォーム内で Nagios スタイルのヘルスチェックを定義できるようになりました。 Consul にクエリを実行する場合は、API サービスが実行されているすべての場所のリストを要求できます。 「すべて」または「合格のみ」または「不健康のみ」のフラグを送信できます。

複数のデータセンターもサポートしています。 Consul クライアントをどこでも実行する必要があると述べました。 起動時に、データセンターを指定するパラメータを渡します。 データセンター イーストとデータセンター ウェストがある場合は、データセンターを意識する必要もなく、アドレスなどを尋ねることなく、ローカル Consul クライアントにクエリを実行できます。

私たちは実際にデータセンターをステージング環境と本番環境の境界として使用しています。 ステージング中のアプリケーションの構成では、「 MySQL.services.consulがどこにあるか確認してください」と表示されます。 実際にステージング ノードで実行されているか、実稼働ノードで実行されているかに関係なく、データ センターや複数の環境を認識する必要なく、正しい値を取得できます。

これ (および etcd) のもう 1 つの優れた点は、HTTP インターフェースで長時間ポーリングが実行されることです。 つまり、このサービスを実行しているすべてのサーバーのリストを照会して要求できるだけでなく、接続を 60 秒間開いたままにして、何か変更があった場合にすぐに通知を受け取ることもできます。 ポーリング時間は実際には最長 10 分かかる場合があります。 つまり、インフラストラクチャの変更があれば即座に通知を受け取ることができます。

すでに述べたもう 1 つの点は、クライアントをあらゆる場所に配置すると、エージェントをスケールアウトする機能を構築できることです。 いつでもローカルホストと通信できるので、これは素晴らしいです。

しかし、大きな疑問は、分散サービス検出プラットフォームにこのデータが存在するので、そのデータから NGINX をどのように構成するかということです。

22:07 領事テンプレート

ありがたいことに、 Consul Templateというツールがあります。 文字通り昨日リリースされたので、この時点で今日のスライドを変更しました。 以前は「Consul HAProxy」と呼ばれていましたが、これは実際には HAProxy に固有のものではないため、ひどい名前でした。

Consul テンプレートは、サービスの変更、サービスのヘルスチェック、さらにはキー値ストアをサブスクライブするためのテンプレートを構築するための非常にシンプルなインターフェースを提供します。 これにより、NGINX ワーカーの数などの設定をキー値ストア内に保存し、設定が変更されたときに構成を再生成できるようになります。

ここでの大きな機能は、テンプレートからファイルを生成することです。これは、以前 Chef で行っていたことと非常に似ています。 ここでの大きな違いは、Ruby である ERB ではなく、Golang テンプレート言語を使用していることです。 ファイルを変更したら、オプションで変更に対してコマンドを呼び出すことができます (例: service nginx reload )

22:59 Consul テンプレートを起動するコマンド

以下は、コマンド ラインで Consul テンプレートを実行する例です。 実際の Consul ホスト (この場合はconsul‑prod.example.com)を指定します。 実際の運用環境では、どこでも Consul を実行し、localhost に接続することをお勧めします。

次に、Golang テンプレートであるテンプレート ファイルを渡します。 私たちの場合、 /etc/consul‑templates/apiを渡します。 次に、実際に書き出すファイル (この場合は/etc/NGINX/sites‑enabled/api )を渡します。 次に、 service nginx reloadというコマンドを呼び出します。

23:32 Consul テンプレートを使用した NGINX 構成

Consul テンプレートは、ERB ではなく Golang であることを除いて、以前のスライドと非常によく似ています。 したがって、ここでは 2 つのアップストリームを定義します。 1 つはapiと呼ばれ、もう 1 つはホームページと呼ばれます。 サービス API には範囲ステートメントがあり、そのサービスが実際に実行されている IP とポートを取得するための組み込み変数があります。

23:54 Consul テンプレートを使用した構成管理

Consul テンプレートの優れた点と、これをこのように使用する利点は、サービスの変更に対する収束が速いことです。 Docker を使用してデプロイする前は、マシンに応じて約 5 分または 10 分ごとに Chef を実行していました。 弊社ではその場で展開していたため、十分な速さでした。

現在、より高度なデプロイメント システムを構築しているため、これらの変更を数分ではなく数秒で通知する必要があります。 実際には数ミリ秒で取得でき、平均するとおそらく約 200 ミリ秒です。

ただし、テンプレートを生成するには、依然として構成管理が必要です。 Chef を Consul に置き換えるだけでは不十分です。 Consul と Consul テンプレートなどをどのようにデプロイするかをまだ決める必要があります。

24:35 Chef を使って Consul をデプロイする

そのため、実際には Chef テンプレートを使用して Consul テンプレートをデプロイしていますが、これは少し複雑に思えます。 Chef レシピで最初に行うことは、Consul ホストにすべてのサービスのリストを照会することです。 次にConsulテンプレートを生成します[ テンプレート そして ソース ステートメント]でSSL証明書とキーの場所を渡し、リロードします 領事テンプレート. [編集者 – リーディ氏は当初、 領事代理、最初に現れる 通知する スライド上の声明。 その後、彼は訂正し、このスライドは Consul テンプレートのリリース以前のものであることを明確にしました。 ]

また、Consul テンプレート用の設定ファイルも作成し、Consul ホスト、ソース、宛先、およびリロード コマンドを指定する [変数] を渡します。 これは、Chef と Consul を併用して NGINX 構成を瞬時に更新する方法の本質です。

25:44 プロのヒント

次に、Chef、Consul、NGINX の設定全般に関するプロのヒントをいくつか紹介します。

25:52 Chef 部分検索

最初のヒントは、Chef 検索を使用してサービスが実行されている場所を検索する場合は、Chef 部分検索を調べる必要があるということです。 Chef 検索の問題は、すべての属性を含むノード全体のコピーが作成されることです。 ノードの属性に多くのものを保存する場合は、Chef サーバーと通信しながらそれらをネットワーク経由で取得し、メモリに保存する必要があります。

Chef 検索で数百または数千のサーバーが返される場合、実際のレシピでメモリが不足する可能性があることが簡単にわかります。 部分検索を使用すると、必要なキーのみを返すことができます。

例えば、私たちは最初に

ノード = 検索(:node, 'recipe:belly-api')

この検索では、すべてのオブジェクトに関するすべての情報が返されます。 これには、ディスク容量、RAM、CPU、および独自のノード属性を書き込んだすべてのアプリケーションに関する情報が含まれます。

代わりに、 search_keysという新しいハッシュを作成し、必要なキーのリスト (この場合は名前と IP アドレスのみ) を指定する部分検索を使用できます。 次に、 partial_searchと呼ばれる非常によく似た API を実行し、追加の [ keys ] パラメータを渡します。

26:53 ドナー

S3 と Heroku の前で負荷分散に移行したときに 2 番目に問題になったのは、NGINX が設定の再読み込み時にのみアップストリームブロック内のホスト名を解決するために DNS を使用することです。 つまり、アップストリーム サーバーをs3.amazonaws.comまたはanything.herokuapp.comに設定していて、それが変更された場合、ロード バランサーは次回の再ロードまで新しい IP アドレスを認識しません。

私たちがこれを回避した方法は、実際に Chef で DNS 解決を実行し、それが変更されたときに NGINX のリロードをトリガーすることでした。 これにより、2 番目の問題が発生しました。[DNS 応答内のアドレスの順序] は常に同じではないため、テンプレートに書き込む前に応答を並べ替えるようにしてください。

27:36 古い設定を避ける

大量のサービスを展開し始めるときに発生するもう 1 つの問題は、古い構成を避けたいということです。[編集者 – Reedy 氏はプレゼンテーションを一時停止して、聴衆からの質問に答えます。 ] Apache、NGINX、およびその他の UNIX では、 conf.dフォルダーを用意して、そこからすべてをロードするのが一般的な構成パターンです。 したがって、サービス A、B、C をデプロイする場合は、 service-a.confservice-b.confservice-c.confを作成します。

次に、サービス B を D に置き換えることにしました。これで、NGINX 構成フォルダーに 4 つの構成が作成されましたが、サービス B は存在しなくなりました。 ホスト名が似ているため、B と D で競合が発生する可能性があります。

これまで、これ(古い構成の削除)を実現するために私たちが目指してきた方法は 2 つあります。 テンプレートを使用すると:delete関数を追加できますが、これはすぐに扱いにくくなります。 本質的には、存在する場合は常に削除しようとする古いサービスのリストがありました。 それは実際にはスケールアウトしませんでした。

もう 1 つできることは、すべてのサイト構成を 1 つのファイルにレンダリングすることです。 多くの人がこれを「べき等性の上方への移動」と呼んでいます。 基本的には、複数のソースからロードされる NGINX 構成を持つ代わりに、すべてをnginx.confに投入します。

実際にボックスにログインするときに少し扱いにくくなりますが、運用環境で構成ファイルのトラブルシューティングを行わない段階に到達できることを願っています。 Chef レシピでまだ扱いにくい場合は、一連の異なるサイトを読み込む 1 つのnginx.conf を作成します。 たとえば、サイトの設定ファイルの 1 つには約 30 個のサービスがリストされており、Heroku 用に 1 つ、S3 のすべてのサービス用に 1 つなどあります。

したがって、サイトのすべての構成を 1 つまたは少数のファイルにレンダリングする場合は、後からクリーンアップする必要がありません。 Chef の観点からサービスがなくなると、Chef は実際のファイルへのレンダリングを停止するだけです。

30:35 質問

質問: これまでのところ、Consul はいかがでしたか?

答え: 私たちは Consul を気に入っていますが、etcd などと比べて Consul が本当に気に入っているのは、その上に構築され続けるサービスがあるということです。 サービスの検出について心配する必要はありません。 実際、レガシー アプリケーションがあり、Consul を使用して MySQL サーバーをデプロイする場合、Consul は DNS インターフェースも提供します。

アプリケーションは Consul を意識する必要はなく、「 mysqldb.services.consulからどのアドレスを取得するか」をクエリするだけで済みます。 この場合、Consul は DNS サーバーです。 TLD [トップレベルドメイン] が.consulで終わる場合、クエリが Consul にルーティングされるように DNS インフラストラクチャを設定します。

私たちにとってはスケールアウトが素晴らしいです。 実稼働環境では、サーバー エージェント用に約 3 つのノード、クライアント用に約 60 個のノードが不足しています。 何も問題は起きていません。 機能が追加され続け、下位互換性が損なわれることがないため、アップグレードは常に快適です。

質問: NGINX Plus を使用していますか?

答え: 違います。 私たちは、Consul を使い始めたとき、まさにこのことを検討しました。 テンプレート システムが必要なければ、HTTP ロング ポーリングをリッスンし、ユーザーに代わって NGINX API と通信するスクリプトを用意するだけで済むので便利です。 唯一の問題は、NGINX が再起動する場合に備えてテンプレート システムも必要になる可能性があることです。 アップストリーム構成がその場でリロードされます。

NGINX Lua で Consul を直接クエリする作業も他の人によって行われています。 適切な実装はまだ見たことがありません。なぜなら、それらは 2 つのカテゴリのいずれかに分類される傾向があるからです。 1 つ目は、すべての HTTP リクエストで Consul にクエリを実行するため、速度が遅くなることです。 2 つ目は、構成実行時にロードされ、DNS の場合と同じ問題が発生してしまうことです。 したがって、現時点ではテンプレート化が最適ですが、将来的には NGINX Lua を使用してテンプレート化する方法が登場しても驚かないでしょう。

質問: Chef から離れることはありますか?

答え: Consul にはこれらのテンプレートを維持するための優れた方法が組み込まれておらず、私たちはすでに Chef とともに NGINX を導入しています。 現時点では、ログ記録、トレース、OAuth など、NGINX で実行している他のすべての処理のために、レシピは数百、場合によっては数千行に及んでいます。 私たちのインフラストラクチャで Chef から移行して置き換えることは考えていませんが、これは優れた拡張機能であり、迅速な通知を取得するための優れた方法です。

質問: Chef が提供するオーバーヘッドはどれくらいですか?

答え: ほとんどのマシンは単一のタスクを実行しているため、実際の Chef のオーバーヘッドは非常に低くなります。 アイドル状態のときの RAM の使用量は低くなります。 実際にはタイマー内に配置され、分岐することができます。 収束の速さを気にしないのであれば、 cronで実行する人もいます。 一部の重いレシピでは CPU の使用率がわずかに上昇しますが、別のサーバーを展開すれば修正できる問題ではありません。

質問: CloudFormation をどれくらい活用しましたか?

答え: CloudFormationはまだ使用していません。 これは私たちの計画に含まれていますが、私たちが行った変更の 1 つは、より多くの Auto Scaling グループを活用することです。 動作の仕組みとしては、インスタンスが起動すると、Chef 実行リストを含むユーザー データが作成されます。

新しいマシンは、そのイメージに基づいたキーをすでに備えた状態でクラスターに追加されるため、Chef サーバーと通信し、自身を登録し、必要なクックブックを取得できます。 これにより、CloudFormation に関連するほとんどの問題が解決されます。これは、CloudFormation と連携する他の AWS ツールをあまり使用していないためです。

質問: サーバーが破壊された場合、どのように対処しますか?

答え: Auto Scaling グループ内のサーバーが停止した場合は、Amazon SNS [Simple Notification Service] を使用してその通知を受け取ることができます。 これらの通知をリッスンし、Chef サーバーをクリーンアップする非常にシンプルなサービスがあります。

質問: AWS の OpsWorks を使用したことがありますか?

答え: まだです。 当社は最初からホスト型 Chef を使用してきましたが、非常にうまく機能しています。 これについてはよく分かりませんが、OpsWorks はプロビジョニングのためだけに使用する Chef Solo に似ていると思います。 私たちは現在でもほぼすべてのマシンで Chef Agent を実行しており、同じ Chef レシピを使用して開発用の Docker コンテナを生成しています。

36:31 連絡先情報


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"