ウェブサイト検索

Chefでサーバー構成を制御するためのロールと環境の使用方法


紹介

インフラを構築するにつれて、多くのサーバー、サービス、ユーザー、アプリケーションを管理することは、非常に迅速に手に負えなくなることがあります。構成管理システムを使用することで、この混乱を管理する手助けができます。

Chefは、全体システムのさまざまなコンポーネントを非常に簡単に設定できる優れた構成管理システムです。以前のガイドでは、Chefの用語、Chefサーバー、ワークステーション、ノードのインストール方法(Chef 12またはChef 11を使用)、構成を管理するためのシンプルなクックブックの作成方法について説明しました。

このガイドでは、Chefを使用して環境を管理する方法を引き続き探っていきます。今回は、サーバーやサービスがどのような機能を持つべきかに基づいて、それらを区別するために役割と環境をどのように使用するかについて話します。

サーバー、ワークステーション、およびクライアントをインストール済みであり、前回のガイドで作成したクックブックが利用可能であると仮定します。

役割と環境

役割とは何ですか?

あなたの組織では、インフラストラクチャがより高いトラフィックの要求に応じて成長すると、基本的な作業をすべて行う多くの冗長サーバーが存在する可能性があります。例えば、これらは負荷分散装置がリクエストを渡すウェブサーバーであるかもしれません。それらはすべて同じ基本的な設定を持ち、各々が同じ「役割」を満たすと言えるでしょう。

シェフの役割に関する見解は、通常の定義とほぼ同じです。シェフにおける役割とは、特定のマシンが何をするべきかを説明するカテゴリです。それにはどのような責任があり、どのソフトウェアや設定が与えられるべきかが含まれます。

異なる状況では、特定の機械が1つ以上の役割を果たすことがあります。例えば、ソフトウェアをテストしている場合、1つのサーバーにデータベースとウェブサーバーのコンポーネントが含まれることがありますが、本番環境ではこれらを別々のサーバーに配置する予定です。

Chefを使用すれば、最初のサーバーを両方の役割に割り当て、その後各役割を生産用マシン用の別々のコンピュータに割り当てるだけで、これが非常に簡単になります。 各役割には、その役割を果たすために必要な完全な運用状態にマシンを持っていくための設定詳細が含まれます。 これは、パッケージのインストール、サービスの設定、その役割に特有の属性などを処理するクックブックを収集できることを意味します。

環境とは何ですか?

役割に関連するアイデアは、Chef環境の概念です。環境とは、サーバーが生産プロセスのどの段階にあるのかを管理者が知るための指定に過ぎません。各サーバーは、正確に一つの環境の一部であることができます。

デフォルトでは、「_default」という環境が作成されます。別の環境が指定されない限り、各ノードはこの環境に配置されます。環境は、サーバーをプロセスグループの一部としてタグ付けするために作成できます。

例えば、ある環境は「テスト」と呼ばれ、別の環境は「本番」と呼ばれることがあります。テスト中のコードが本番環境のマシンに存在することを望まないため、各マシンは一つの環境のみに属することができます。そうすれば、テスト環境のマシン用の一つの設定と、本番環境のコンピュータ用のまったく異なる設定を持つことができます。

上記の役割の例では、テスト環境ではウェブサーバーとデータベースサーバーの役割が1台のマシンで実行されることを指定できます。本番環境では、これらの役割は個別のサーバーで対処されるべきです。

環境はテストプロセス自体にも役立ちます。本番環境では、クックブックが安定したバージョンであるべきことを指定できます。しかし、もし機械がテスト環境の一部であれば、より新しいバージョンのクックブックを受け取ることができると指定することもできます。

役割の使い方

Ruby DSLを使用してロールを作成する

私たちは、ワークステーションのchef-repoディレクトリ内のrolesディレクトリを使用して役割を作成できます。

ワークステーションにログインして、このディレクトリに移動してください:

cd ~/chef-repo/roles

このディレクトリ内で、私たちは組織内で望む役割を定義するさまざまなファイルを作成できます。各役割ファイルは、ChefのRuby DSLでもJSONでも記述できます。

ウェブサーバーの役割を作成しましょう:

nano web_server.rb

このファイルの内部では、役割に関する基本データを指定することから始めることができます:

name "web_server"
description "A role to configure our front-line web servers"

これらは非常に簡単であるべきです。私たちが付ける名前にはスペースを含めることができず、一般的にはこの役割のために選択したファイル名と一致すべきです(拡張子を除く)。説明は、この役割が管理すべき内容についての人間が読めるメッセージです。

次に、この特定の役割に使用したい run_list を指定できます。役割の run_list には、デフォルトレシピを実行するクックブック(cookbooks)、クックブックからのレシピ(cookbook::recipe 構文を使用して指定)、および他の役割を含めることができます。覚えておいてください、run_list は常に順次実行されるため、依存関係のアイテムを他のアイテムの前に置いてください。

もし私たちがrun_listが最後のガイドで設定したものと正確に一致する必要があると言いたいなら、次のように見えるものになるでしょう:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"

環境特有のランリストを使用して、サーバーがどの環境に属しているかに応じて変数の設定変更を指定することもできます。

たとえば、ノードが「プロダクション」環境にある場合、そのサーバーをプロダクションポリシーの要件に合わせるために、あなたの「nginx」クックブック内で特別なレシピを実行したいかもしれません。また、テストサーバー用の特別な変更を設定するためのレシピもnginxクックブックに含まれている可能性があります。

これら2つのレシピがそれぞれ「config_prod」と「config_test」と呼ばれていると仮定すると、次のように環境特有の実行リストを作成できます:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"
env_run_lists "production" => ["recipe[nginx::config_prod]"], "testing" => ["recipe[nginx::config_test]"]

上記の例では、ノードが本番環境の一部である場合は、「nginx」クックブック内の「config_prod」レシピを実行するように指定しています。しかし、ノードがテスト環境にある場合は、「config_test」レシピが実行されます。ノードが異なる環境にある場合は、デフォルトの実行リストが適用されます。

同様に、デフォルト属性とオーバーライド属性を指定できます。この時点でデフォルト属性に慣れているはずです。私たちの役割では、他の場所で設定されているデフォルト属性をオーバーライドできるデフォルト属性を設定できます。

私たちは、他の多くの属性宣言よりも優先度が高いオーバーライド属性を設定することもできます。これを使用して、この役割に割り当てられたノードが特定の方法で動作するように強制しようとすることができます。

私たちのファイルでは、これらは次のように追加できます:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"
env_run_lists "production" => ["recipe[nginx::config_prod]"], "testing" => ["recipe[nginx::config_test]"]
default_attributes "nginx" => { "log_location" => "/var/log/nginx.log" }
override_attributes "nginx" => { "gzip" => "on" }

ここでは、ノード内のサーバーのデフォルトのログ場所を設定しました。また、他の場所で他の属性の宣言が述べていることに関係なく、この役割のノードはgzip属性を「on」に設定する必要があることを指定しました。これは他のいくつかの場所でオーバーライドできますが、一般的には高い優先度の宣言です。

JSONを使用してロールを作成する

ロールを設定するために使用できる他の形式はJSONです。実際、この形式を探るために、ナイフを使用してこの形式のロールを自動的に作成することができます。テストロールを作成しましょう:

knife role create test

あなたのテキストエディタが事前にロードされたテンプレートロールファイルで開かれます。それはこのように見えるべきです:

{
  "name": "test",
  "description": "",
  "json_class": "Chef::Role",
  "default_attributes": {
  },
  "override_attributes": {
  },
  "chef_type": "role",
  "run_list": [

  ],
  "env_run_lists": {
  }
}

これは基本的に、私たちがRuby DSL形式のファイルに入力したのと同じ情報です。唯一の違いは、フォーマットとjson_classおよびchef_typeと呼ばれる2つの新しいキーの追加です。これらは内部で使用され、変更すべきではありません。

それ以外では、次のようなもので別のファイルをJSON形式で簡単に再作成できます:

{
  "name": "web_server",
  "description": "A role to configure our front-line web servers",
  "json_class": "Chef::Role",
  "default_attributes": {
    "nginx": {
      "log_location": "/var/log/nginx.log"
    }
  },
  "override_attributes": {
    "nginx": {
      "gzip": "on"
    }
  },
  "chef_type": "role",
  "run_list": [
    "recipe[apt]",
    "recipe[nginx]"
  ],
  "env_run_lists": {
    "production": [
      "recipe[nginx::config_prod]"
    ],
    "testing": [
      "recipe[nginx::config_test]"
    ]
  }
}

これは、上記のRubyバージョンとほぼ同じ機能を持っているはずです。

ワークステーションとサーバー間での役割の転送

ナイフコマンドを使用して作成したJSONファイルを保存すると、役割がChefサーバーに作成されます。それに対して、ローカルで作成したRubyファイルはサーバーにアップロードされません。

このようなコマンドを実行することで、サーバーにルビーファイルをアップロードできます:

ファイルからのナイフの役割 path/to/role/file 

これは、私たちのファイルに指定された役割情報をサーバーにアップロードします。これは、Ruby DSL形式のファイルまたはJSONファイルのいずれかで機能します。

同様に、サーバーからJSONファイルを取得したい場合は、ナイフコマンドにそのロールファイルをJSON形式で表示するよう指示し、それを次のようにファイルにパイプできます:

 ナイフ役割表示 web_server -Fjson > 保存先のパス 

ノードに役割を割り当てる

では、使用したフォーマットに関係なく、Chefサーバー上で私たちの役割があります。ノードに特定の役割を割り当てるにはどうすればよいですか?

ノードのランリストに、レシピのようにノードに役割を割り当てます。

ノードに役割を追加するためには、次のようにノードを見つけます:

knife node list

そして、私たちは次のような命令を出します:

 ナイフ ノード 編集 ノード名 

これによりノードの定義ファイルが表示され、実行リストにロールを追加できるようになります。

{
  "name": "client1",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "recipe[nginx]"
  ]
}

例えば、このファイルでは私たちのレシピを私たちの役割に置き換えることができます:

 { "name": "クライアント1", "chef_environment": "_default", "normal": { "tags": [

]

}, 「run_list」: [ 「role[web_server] 」 ] } < /pre>

これは私たちの以前のレシピと同じ手順を実行しますが、サーバーが持つべき役割について単に話すだけです。

これにより、特定の役割のすべてのサーバーに検索でアクセスできるようになります。たとえば、役割と環境を検索することで、プロダクション環境内のすべてのデータベースサーバーを検索することができます:

knife search "role:database_server AND chef_environment:prod" -a name

これにより、データベースサーバーとして構成されているノードのリストが得られます。この情報を料理本内で使用して、ウェブサーバーを構成し、すべての本番データベースサーバーをプールに自動的に追加して、読み取りリクエストを行うことができます。

環境の使用方法

環境を作ること

ある意味で、環境は役割に非常に似ています。また、異なるサーバーを区別するためにも使用されますが、サーバーの機能によって区別するのではなく、マシンが属する開発の段階によって環境は区別されます。

役割について話しているときに、これについていくつか話しました。実際の製品ライフサイクルと一致する環境が最も理にかなっています。コードをテスト、ステージング、プロダクションを通じて実行する場合、対応する環境を持っているべきです。

役割と同様に、定義ファイルはRuby DSLまたはJSONで設定できます。

私たちのワークステーションの「chef-repo」ディレクトリには、environmentsディレクトリが必要です。ここに環境ファイルを置くべきです。

cd ~/chef-repo/environments

このディレクトリ内で、開発のための環境を定義するつもりなら、このようなファイルを作成することができます。

nano development.rb
name "development"
description "The master development branch"
cookbook_versions({
    "nginx" => "<= 1.1.0",
    "apt" => "= 0.0.1"
})
override_attributes ({
    "nginx" => {
        "listen" => [ "80", "443" ]
    },
    "mysql" => {
        "root_pass" => "root"
    }
})

ご覧のように、環境をシステムに組み込む主要な利点の一つは、デプロイされるクックブックやレシピのバージョン制約を指定できることです。

私たちはJSON形式も使用できます。ナイフツールは、次のように入力することで環境ファイルのテンプレートを生成できます:

knife environment create development

これにより、名前が入力された事前ロードされた環境ファイルを持つエディタが再び開きます(再度、export EDITOR=nanoを使用してエディタを設定できます)。

同じファイルを入力することで作成できます:

{
  "name": "development",
  "description": "The master development branch",
  "cookbook_versions": {
    "nginx": "<= 1.1.0",
    "apt": "= 0.0.1"
  },
  "json_class": "Cheff:Environment",
  "chef_type": "environment",
  "default_attributes": {
  },
  "override_attributes": {
    "nginx": {
      "listen": [
        "80",
        "443"
      ]
    },
    "mysql": {
      "root_pass": "root"
    }
  }
}

このファイルは、上で示したRubyファイルと機能的には同じであるべきです。JSONロールファイルと同様に、環境のJSONファイルには二つの追加情報(json_class と chef_type)があり、これらはそのままにしておく必要があります。

サーバーへの環境ファイルの移動とサーバーからの移動

この時点で、もしRuby DSLを使用した場合、あなたのファイルはワークステーションにあり、もしJSONを使用した場合、あなたのファイルはサーバー上にのみ存在します。私たちは、knifeを通じてファイルを簡単に移動することができます。

私たちは次のように入力することで、RubyファイルをChefサーバーにアップロードできます。

knife environment from file ~/chef-repo/environments/development.rb

私たちのJSONファイルのために、サーバーから環境ファイルを取得するには、次のように入力できます:

knife environment show development -Fjson > ~/chef-repo/environments/development.json

これにより、サーバーからJSONファイルが表示され、その結果が環境のサブディレクトリ内のローカルファイルにパイプされます。

ノードにおける環境設定

各ノードは正確に1つの環境に属することができます。ノードの情報を編集することで、ノードが属する環境を指定することができます。

例えば、client1というノードを編集するには、次のように入力します:

knife node edit client1

これは、現在のノードパラメータを含むJSON形式のファイルを開きます。

{
  "name": "client1",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "role[web_server]"
  ]
}

ご覧のように、chef_environmentは元々_defaultに設定されています。この値を変更することで、ノードを新しい環境に置くことができます。

完了したら、ファイルを保存して閉じてください。ノードで次回のchef-clientの実行時に、新しい属性とバージョン制約を取り込み、ポリシーに合わせて自らを修正します。

結論

今や、機械がどのような状態にあるべきかを確固たるものにするために、ロールと環境を扱うさまざまな方法について十分な理解を得ているはずです。これらの分類戦略を使用することで、Chefが異なる文脈でサーバーを扱う方法を管理し始めることができます。

ジャスティン・エリングウッドによる

関連記事: