SaltStackインフラストラクチャ:NginxWebサーバーのSalt状態の作成

提供:Dev Guides
移動先:案内検索

序章

SaltStack(Salt)は、構造化された反復可能な方法でインフラストラクチャを簡単に管理するために使用できる強力なリモート実行および構成管理システムです。 このシリーズでは、Saltデプロイメントから開発、ステージング、および実稼働環境を管理する1つの方法を示します。 ソルト状態システムを使用して、繰り返し可能なアクションを記述して適用します。 これにより、環境を破壊することができます。後で同じ状態で簡単にオンラインに戻すことができるため、安全です。

以前のガイドでは、salt-cloudのDigitalOceanプロバイダーをセットアップすることにより、Saltマスターサーバーの機能を拡張しました。 環境ごとに新しいサーバーを起動できるようにするために必要なファイルを作成しました。 この記事では、NginxのSalt状態ファイルを作成することで構成管理について詳しく説明します。 Nginxは、Webリクエストを処理するために、3つの環境すべてのWebサーバーノードで使用されます。

メインのNginx状態ファイルを作成します

Saltは、状態システムを通じて構成管理を処理します。 最も単純なケースでは、これらは、Saltのファイルサーバールート(/srv/saltとして構成)内にあるファイルによって制御されます。 Nginx構成を開始するには、構成しているソフトウェアに固有のディレクトリをこの場所に作成します。

sudo mkdir /srv/salt/nginx

状態ファイルには.slsサフィックスが付いています。 ディレクトリ内のinit.slsファイルは、その特定のソルト状態または式のメイン構成ファイルとして機能します。 関連するinit.slsファイルに含まれる機能を実行するために、親ディレクトリ名を参照します。

そのことを念頭に置いて、このディレクトリ内にinit.slsファイルを作成して開き、開始します。

sudo nano /srv/salt/nginx/init.sls

Nginxパッケージとサービスの状態

まず、nginx識別子を使用して状態を作成します。 これは、Salt状態システム内のこの特定の状態の一意の名前として機能します。 状態モジュールの「name」属性は含めないため、インストールするターゲット(pkg.installed関数の場合)および実行するサービス(service.running機能)。

パッケージが更新されたとき、メイン構成ファイルが変更されたとき、またはデフォルトのサーバーブロックファイルが変更されたときなど、特定の条件下でNginxを自動的にリロードする必要があります。 watchを使用すると、これらの状態が発生したときにNginxサービスを再起動するようにSaltに指示できます。

/srv/salt/nginx/init.sls

nginx:
  pkg:
    - installed
  service.running:
    - watch:
      - pkg: nginx
      - file: /etc/nginx/nginx.conf
      - file: /etc/nginx/sites-available/default

watch:キーの下にあるpkg:およびfile:キーは、監視するリソースに関連付けられた状態モジュールを表します。 pkgリソースは、この同じ定義の最初の部分で処理されます。 次に、fileリソースに一致する状態を作成する必要があります。

Nginx構成ファイルの状態

/etc/nginx/nginx.confファイルから始めることができます。 これを管理ファイルにします。 ソルトの用語では、これは、マスターサーバーでファイルの内容を定義し、それを必要とする各ミニオンにアップロードすることを意味します。 ファイルにかなり一般的な権限と所有権を設定します。 ソースはSaltファイルサーバー内の場所を参照します(現在のファイルもこの構造内にあります)。 このパスとファイルをすぐに作成します。

/srv/salt/nginx/init.sls

nginx:
  pkg:
    - installed
  service.running:
    - watch:
      - pkg: nginx
      - file: /etc/nginx/nginx.conf
      - file: /etc/nginx/sites-available/default

/etc/nginx/nginx.conf:
  file.managed:
    - source: salt://nginx/files/etc/nginx/nginx.conf
    - user: root
    - group: root
    - mode: 640

/etc/nginx/sites-available/defaultファイルの内容も制御したいと思います。 これは、コンテンツの提供方法を制御するサーバーブロックを定義します。 状態ブロックは、最後のブロックとかなり似ています。 主な違いは、このファイルがJinjaテンプレートになることです。

Jinjaテンプレートを使用すると、Saltは、ファイルが配置される各ミニオンに固有の詳細を使用して、ファイルのコンテンツの一部をカスタマイズできます。 これは、各ホストから情報を取得し、Webサーバーごとに適切なカスタマイズされたバージョンのファイルを作成できることを意味します。 このファイルはtemplateオプションでJinjaを使用することを示しています。 また、ソースファイルに.jinjaサフィックスを使用して、ファイルがテンプレートであることを一目で確認できるようにします。

/srv/salt/nginx/init.sls

. . .

/etc/nginx/nginx.conf:
  file.managed:
    - source: salt://nginx/files/etc/nginx/nginx.conf
    - user: root
    - group: root
    - mode: 640

/etc/nginx/sites-available/default:
  file.managed:
    - source: salt://nginx/files/etc/nginx/sites-available/default.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 640

ミニオンホストのsites-availableディレクトリに配置される予定のデフォルトのサーバーブロックファイルがあります。 ただし、ファイルをアクティブ化するには、ファイルをsites-enabledディレクトリにリンクする必要があります。 file.symlink関数でそれを行うことができます。 元のファイルの場所をtargetとして指定する必要があります。 また、前の状態が正常に完了した後にのみこの状態が実行されるように、そのファイルを「要求」する必要があります。

/srv/salt/nginx/init.sls

. . .

/etc/nginx/sites-available/default:
  file.managed:
    - source: salt://nginx/files/etc/nginx/sites-available/default.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 640

/etc/nginx/sites-enabled/default:
  file.symlink:
    - target: /etc/nginx/sites-available/default
    - require:
      - file: /etc/nginx/sites-available/default

デフォルトのサイトコンテンツの状態

Nginxのインストールと構成の状態が書き込まれています。 ここで、index.htmlファイルの状態を作成する必要があります。これは、サイトの実際のコンテンツになります。

この状態は、以前のテンプレート状態とまったく同じ形式を使用します。 唯一の違いは、このファイルの識別子、ソース、およびアクセス許可モードです。

/srv/salt/nginx/init.sls

. . .

/etc/nginx/sites-enabled/default:
  file.symlink:
    - target: /etc/nginx/sites-available/default
    - require:
      - file: /etc/nginx/sites-available/default

/usr/share/nginx/html/index.html:
  file.managed:
    - source: salt://nginx/files/usr/share/nginx/html/index.html.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 644

終了したら、このファイルを保存して閉じます。 今のところ、実際のNginx状態情報は完了です。

Nginxをインストールし、元のファイルをソルトマスターに転送します

メインのNginxSalt状態ファイルが作成されました。 ただし、作成した状態の一部は、Saltマスターのファイルサーバー上にまだ存在しない参照ファイルです。

私たちのファイルはUbuntuのNginxパッケージによってインストールされたデフォルトのファイルとほぼ同じであるため、開始する最も簡単な方法はそのパッケージのファイルを使用することです。 いずれかの環境のWebサーバーは、必要なファイルを取得できるようにNginxをインストールするのに最適な場所を提供します。

いずれかの環境をまだスピンアップしていない場合は、展開する環境マップファイルの1つを選択します。 このシリーズでは「ステージ」環境を使用します。これは、必要なすべてのサーバータイプを備えた最小の環境だからです。

sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map

サーバーが稼働したら、NginxをインストールするWebサーバーの1つを選択します。 状態がまだ完全に機能していないため、現時点ではpkg実行モジュールを使用します。

sudo salt stage-www1 pkg.install nginx

ソルトマスター構成をセットアップするときに、file_recvオプションを有効にしました。 これにより、ミニオンに特定のファイルをマスターにプッシュバックするように要求できます。 これを使用して、管理するファイルのデフォルトバージョンを取得できます。

sudo salt stage-www1 cp.push /etc/nginx/nginx.conf
sudo salt stage-www1 cp.push /etc/nginx/sites-available/default
sudo salt stage-www1 cp.push /usr/share/nginx/html/index.html

これで、これらのファイルがマスターで使用できるようになります。 これらのファイルへのパスは、/var/cache/salt/master/minions/minion_id/filesディレクトリ内に再作成されます。 この場合、ミニオンIDはstage-www1になります。 次のように入力することで、ミニオンのファイルパスを表すこの場所の下のディレクトリをSalt状態ディレクトリにコピーできます。

sudo cp -r /var/cache/salt/master/minions/stage-www1/files /srv/salt/nginx

状態ディレクトリの内容を見ると、「ファイル」と呼ばれる新しいディレクトリが表示されます。 このディレクトリの下には、ミニオンのファイルシステム内の関連するディレクトリと、コピーした3つのファイルがあります。

find /srv/salt/nginx -printf "%P\n"
Outputfiles
files/usr
files/usr/share
files/usr/share/nginx
files/usr/share/nginx/html
files/usr/share/nginx/html/index.html
files/etc
files/etc/nginx
files/etc/nginx/sites-available
files/etc/nginx/sites-available/default
files/etc/nginx/nginx.conf
init.sls

これは、すべての管理対象ファイルが維持される場所です。 これは、Nginx状態ファイルで設定した「ソース」の場所と一致します。

Nginxがインストールされているミニオンから必要なすべてのファイルを取得したので、ミニオンを破棄して再構築できます。 これにより、後で状態ファイルをクリーンなサーバーでテストできるようになります。 Nginxミニオンを破壊します:

sudo salt-cloud -d stage-www1

イベントが処理されるのを待った後、ミニオンを再構築できます。

通常、これにはマップファイルを使用しますが、再構築するサーバーは1つだけなので、実際にはstage-webプロファイルを直接使用することをお勧めします。 次に、salt-cloudの代わりにcloud.profileソルト実行関数を使用できます。これにより、--asyncフラグを追加できます。 基本的に、これにより、作業を継続しながらstage-www1サーバーをバックグラウンドで再構築できます。 これは必要なクラウドプロファイルを備えたサーバーであるため、このコマンドでソルトマスターをターゲットにする必要があります。

sudo salt --async sm cloud.profile stage-web stage-www1

stage-www1ノードがバックグラウンドで再構築されている間、続行できます。

/etc/nginx/nginx.confファイルを構成します

まず、ミニオンの/etc/nginx/nginx.confに配置されるメインのNginx構成ファイルを見てみましょう。 このパスは、filesディレクトリの下にあり、Nginx状態ディレクトリはありません。

cd /srv/salt/nginx/files/etc/nginx

現時点では実際にはこのファイルを変更する予定はありませんが、今すぐ元のファイルをバックアップすることができます。

sudo cp nginx.conf nginx.conf.orig

これにより、将来行う可能性のあるカスタマイズの参考になります。 次のように入力することで、行った変更をすばやく確認できます。

diff nginx.conf nginx.conf.orig

将来、さまざまな環境でNginxの構成をカスタマイズする必要がある場合(たとえば、worker_processesを後で本番サーバーのCPUの数と一致させたい場合)、次のようにすることができます。テンプレートファイルの使用に移行します。 現時点ではこれは必要ないため、非テンプレートファイルとして、変更はハードコーディングされます。

ただし、前述したように、現時点では変更は必要ありません。 次へ移りましょう。

/ etc / nginx / sites-available/defaultテンプレートを構成します

次に、デフォルトのサーバーブロックテンプレートを見てみましょう。 このディレクトリでオリジナルを見つけることができます:

cd /srv/salt/nginx/files/etc/nginx/sites-available

繰り返しになりますが、後で必要になった場合に備えて、元の場所をバックアップ場所にコピーする必要があります。

sudo cp default default.orig

次に、ファイルの名前を.jinja拡張子になるように変更できます。 これにより、このファイルはテンプレートであり、それ自体では使用可能なファイルではないことが視覚的にわかります。

sudo mv default default.jinja

これで、テンプレートファイルを開いていくつかの変更を加えることができます。

sudo nano default.jinja

ファイルの一番上で、Jinjaのテンプレート機能の利用を開始する必要があります。 デフォルトのサーバーブロックは、Webサーバーがロードバランサーの背後にあるかどうかに応じて、異なるファイルをレンダリングする必要があります。

ロードバランサーを介して接続を受信する場合、Webサーバーのトラフィックをプライベートインターフェイスに制限する必要があります。 ただし、開発環境にいるときは、ロードバランサーがないため、パブリックインターフェイスを介してサービスを提供する必要があります。 Jinjaでこの区別を作成できます。

interfaceという変数を作成します。この変数には、アドレスを指定するインターフェイスが含まれている必要があります。 ミニオンの環境が「dev」に設定されているかどうかをテストします。設定されている場合は、eth0インターフェイスを使用します。 それ以外の場合は、サーバーのプライベートインターフェイスであるeth1に設定します。 次に、grains.get実行モジュール関数を使用して、選択したインターフェイスに関連付けられているアドレスを取得し、それをaddr変数の値として使用します。 これをファイルの一番上に追加します。

/srv/salt/nginx/files/etc/nginx/sites-available/default.jinja

{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
{%- set addr = salt['network.interface_ip'](interface) -%}
# You may add here your
# server {
#       ...
# }

. . .

次に、ファイルのさらに下のserverブロックを編集できます。 listenおよびserver_nameディレクティブの上部に設定したaddr変数を使用できます。 このブロックが提供するものを制限するために、IPv6とデフォルトのサーバー部分を削除しました。

/srv/salt/nginx/files/etc/nginx/sites-available/default.jinja

{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
{%- set addr = salt['network.interface_ip'](interface) -%}

. . .

server {
    listen {{ addr }}:80;

    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name {{ addr }};

    location / {
        try_files $uri $uri/ =404;
    }
}

終了したら、ファイルを保存して閉じます。

/usr/share/nginx/html/index.htmlテンプレートを構成します

これで、index.htmlファイルに移動できます。 ファイルを含むSaltマスターのディレクトリに移動します。

cd /srv/salt/nginx/files/usr/share/nginx/html

内部では、前回使用したのと同じ手順から始める必要があります。 監査とバックアップの目的で、元のファイルのコピーを保存する必要があります。 次に、ファイルの名前を変更して、これがテンプレートになることを示す必要があります。

sudo cp index.html index.html.orig
sudo mv index.html index.html.jinja

テンプレートファイルを開いて、必要な変更を加えます。

sudo nano index.html.jinja

上部では、Jinjaを使用して別の変数を設定します。 grains.get実行モジュール関数を使用して、ミニオンのホスト名を取得します。 これをhost変数に格納します。

{% set host = salt['grains.get']('host') -%}
<!DOCTYPE html>
<html>

. . .

次に、ファイル全体でこの値を使用して、どのWebサーバーがリクエストを処理しているかを簡単に判断できるようにします。 最初に<title>の値を変更します。

{% set host = salt['grains.get']('host') -%}
<!DOCTYPE html>
<html>
<head>
<title>Welcome from {{ host }}</title>
. . .

本文を次のように変更してみましょう。

. . .

<body>
<h1>Welcome to nginx!</h1>
<p>Hello!  This is being served from:</p>

<h2>{{ host }}</h2>

</body>
</html>

終了したら、ファイルを保存して閉じます。

Nginx状態ファイルのテスト

これで、Nginxの構成が完了しました。 状態が正しく機能することを確認するために、状態の特定の側面をテストできます。

まず、state.show_sls実行モジュール関数を使用して、SaltがNginx状態ファイルをどのように解釈するかを確認できます。 stage-www1サーバーをターゲットとして使用できます。 ただし、この時点ではサーバー上で何も実行されません。

sudo salt stage-www1 state.show_sls nginx

次のような出力が返されるはずです。

Outputstage-www1:
    ----------
    /etc/nginx/nginx.conf:
        ----------
        __env__:
            base
        __sls__:
            nginx
        file:
            |_
              ----------
              source:
                  salt://nginx/files/etc/nginx/nginx.conf
            |_
              ----------
              user:
                  root
            |_
              ----------
              group:
                  root
            |_
              ----------
              mode:
                  640
            - managed
            |_
              ----------
              order:
                  10002

. . .

これは主に、/srv/salt/nginx/init.slsファイルからの情報にいくつかの興味深い追加を加えてレンダリングします。 Saltがコマンドの読み方を知らなかった場合に解釈エラーがないことを確認してください。 各ピースの「順序」は、チェックするもう1つの良い項目です。 これにより、ファイル内の個々の状態がいつ実行されるかが決まります。 最初の状態の注文番号は「10000」です。 追加の状態はすべてそこからカウントアップされます。 __env__は、グレインを使用して設定したenvとは異なることに注意してください。 このガイドでは、Saltの環境の概念を使用していません。

次に、状態ファイルを適用するドライランを実行できます。 これは、state.apply関数とtest=Trueオプションを使用して行うことができます。 コマンドは次のようになります。

sudo salt stage-www1 state.apply nginx test=True

これにより、test=Trueオプションが削除された場合に行われる変更が表示されます。 変更が意味をなし、Saltがすべてのファイルを正しく解釈できることを確認してください。 「コメント」フィールドは、Saltが状態を失敗としてマークしなかった場合でも問題を明らかにできるため、特に重要です。

ドライランで問題が見つからなかった場合は、次のように入力して、使用可能なすべてのWebサーバーに状態を適用してみてください。

sudo salt -G 'role:webserver' state.apply nginx

Nginx状態をステージングまたは本番Webサーバーに適用した場合は、それらの内部IPアドレスを取得する必要があります。 これらのページは、パブリックインターフェイスでは利用できません。

sudo salt-call mine.get 'role:webserver' internal_ip expr_form=grain
Outputlocal:
    ----------
    stage-www1:
        ip_address
    stage-www2:
        ip_address

一方、開発Webサーバーを起動してNginx状態を適用した場合は、次の理由から外部アドレスを取得する必要があります。

sudo salt-call mine.get 'role:webserver' external_ip expr_form=grain

curlを使用してサーバーをテストできます。

curl ip_address

変更したindex.htmlページが表示されます。

Output<!DOCTYPE html>
<html>
<head>
<title>Welcome from stage-www1</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>Hello!  This is being served from:</p>

<h2>stage-www1</h2>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

ご覧のとおり、Jinjaがレンダリングされたときに、ミニオンのホスト名がファイルに配置されました。 これでNginxの状態が完了しました。

結論

これで、完全に機能するNginx状態が得られます。 これにより、Saltで制御されたマシンを、仕様に合わせてすばやく簡単にWebサーバーに変えることができます。 これをより大規模なインフラストラクチャ管理戦略の一部として使用して、環境内にWebサーバーを簡単に構築します。

次のガイドでは、先に進み、トラフィックをWebサーバーの前に転送するロードバランサーの状態を構築します。 このガイドで使用したのと同じ手法のいくつかを使用して、ロードバランサーを柔軟にします。