ダメSE uramonの奮闘記

インフラ関連技術など

【Chef Tips 4】 ディレクトリの設定

 ディレクトリを作成するには、directoryというResourceを使う。しかし、複数のディレクトリを作成したい場合、同じような構文を繰り返し定義するのは冗長である。

 そこで便利なのが、rubyの配列式。配列式を使った場合と使わなかった場合の例を以下に示す。

※配列式を使わなかった場合

directory "/opt/hoge"
  mode 00755
  owner "sample"
  group "sample"
  action :create
  recursive true
end

directory "/opt/fuga"
  mode 00755
  owner "sample"
  group "sample"
  action :create
  recursive true
end

 

※配列式を使かった場合

%w(hoge fuga).each do |dir|
  directory "/opt/#{dir}"
    mode 00755
    owner "sample"
    group "sample"
    action :create
    recursive true
  end
end

 

ポイント

  • 同一階層に作成するディレクトリを%w()にスペース区切りで定義する。

 

Cookbookの作成から実行までの流れ

 Chef Server、Chef Clientのインストール後の流れを簡単にまとめておく。

 

 

 

① Cookbookの作成

 まずは、knifeコマンドで任意の名称のCookbookを作成する。

# knife cookbook create Cookbook名 -o ~/chef-repo/cookbooks

 

 次に、Recipe、Template、File等をそれぞれ所定のディレクトリに作成する。

  • Recipe・・・~/chef-repo/cookbooks/クックブック名/recipes
  • Template・・・~/chef-repo/cookbooks/クックブック名/templates/default
  • File・・・~/chef-repo/cookbooks/クックブック名/files/default

 

 Cookbookが作成できたら、knifeコマンドでSyntaxチェックを行い、Chef Serverにアップロードする。

# knife cookbook test Cookbook  ←Systaxエラーがあるとここで引っかかる
# knife cookbook upload Cookbook

 

 ② Roleの作成

 knifeコマンドでRoleを作成する。

# knife role create Role名 -e vim


  "name": "Role",
  "discription": "",
  "json_class": "Chef::Role",
  "default_attributes": {
    "Attribute名": "Attibuteの値" ←ここにAttributeを追加
  },
  "override_attributes": {
  },
  "chef_type": "role",
  "run_list": [
    "recipe[Cookbook名::Recipe名]" ←ここにRecipeを追加
  ],
  "env_run_lists": {
  }

 

ポイント

  • Roleの作成は必須ではない。
  • "run_list"には複数のRecipeを追加可能。
  • 必要に応じて、Attributeも追加する。

 

 ③ Environmentの作成

 knifeコマンドでEnvironmentを作成する。

# knife environment create Environment名 -e vim


  "name": "Environment名",
  "discription": "",
  "cookbook_versions" : {
  },
  "json_class": "Chef::Environment",
  "chef_type": "environment",
  "default_attributes": {
    "Attribute名": "Attibuteの値" ←ここにAttributeを追加
  },
  "overide_attributes": {
 
  }

 

ポイント

  • Environmentの作成は必須ではない。
  • 例として、development(開発環境)、staging(ステージング環境)、production(本番環境)といった名前で作成する。
  • 必要な環境分作成する。
  • 必要に応じて、Attributeも追加する。(環境毎に変わるホスト名等をAttributeに持たせると便利)

 

④ Nodeのrun list編集

 knifeコマンドでNodeのrun listを編集する。

# knife node edit Node -e vim


  "name": "Node名",
  "chef_environment": "Environment名", ←ここにEnvironment名を指定
  "normal" : {
    "tags": [
  
    ],
    "Attribute名": "Attibuteの値" ←ここにAttributeを追加
  "run_list": [
    "recipe[Cookbook名::Recipe名]" ←ここにRecipeやRoleを追加
  ]

 

ポイント

  • 必要に応じて、Environmentを指定する。デフォルトの場合は、"_default"を指定する。
  • 必要に応じて、Attributeを追加する。
  • "run_list"には複数のRecipeやRoleを追加可能。Roleを追加する場合は、"role[Role名]"と記述する。

 

⑤ chef-clientの実行

 knifeコマンドでchef-clientを実行する。ここでは、sshオプションを使用し、Chef Client側ではなく、Chef Server側から実行する。

# knife ssh "name:Node名" -a node.ipaddress "sudo chef-client" -i /root/.ssh/id_rsa

 

ポイント

  • デバッグモードで実行したい場合は、"sudo chef-client -l debug"とする。

【Chef Tips 3】 hostsファイルの設定

 hostsファイルを編集する場合、ruby_block+FileEditユーティリティを使用しても良いが、ここでは、環境(Environment)単位でhostsファイルをTemplateで作成する方法を紹介する。

 まず、開発環境を"development"、本番環境を"production"とする。そして、開発環境の場合は、"hosts_development.erb"のテンプレートを、本番環境の場合は"hosts_production.erb"のテンプレートを用意する。

template "/etc/hosts" do
  source "hosts_" + node.chef_environment + ".erb"
  owner "root"
  mode "0644"
end

 

 次に、ノードのEnvironmentを設定する。以下は、開発環境として"development"を設定する例。

{
  "chef_environment": "development",
  "run_list": [
    "recipe[hoge::fuga]"
  ],
  "normal": {
    "tags": [

    ],
  },
  "name": "node01"
}

 

ポイント

  • 開発環境、本番環境といった環境毎に同一のhostsファイルを使用する場合にここで紹介した方法が便利。
  • 事前にEnvironmentを作成しておく。(Environmentの作成の仕方はまた次回)

【Chef Tips 2】SSHサーバの設定(ssh_config)

 sshd_configを編集する場合にも、カーネルパラメータのときと同様、ruby_block+FileEditユーティリティが役立つ。

 sshd_configでは、デフォルト値がコメントアウトで記述されている。その為、レシピでは、このコメントアウトされている対象のパラメタを探し、設定したい内容に置き換え、最後にリロードする。

 

ruby_block "Edit /etc/sshd_config" do
  block do
    rc = Chef::Util::FileEdit.new("/etc/sshd_config")
    rc.search_file_replace_line(/^#ChallengeResponseAuthentication.*$/, "ChallengeResponseAuthentication no"
    rc.write_file
  end
  notifies :reload, "service[sshd]"
end

service "sshd" do
  supports :reload => true
  action :nothing
end

 

ポイント

  • "rc = ~"の”rc"は任意の文字列
  • "/^#ChallengeResponseAuthentication.*$/"の部分は、マッチングさせたい条件を"/"で囲まれた部分にRuby正規表現で記述する。
  • ruby_blockの後の""には、任意の文字列を設定できるが、ランリスト中の他の名称と重複しないようユニークにする。そうしないとコンパイルで警告となる。

【Chef Tips 1】 カーネルパラメータの設定(sysctl.conf)

 ファイルを編集する場合、主にTemplateリソースを使用する。しかし、一部の定義のみ入れ替えたい、ファイルを丸ごと入れ替えたくない、といった場合には、ruby_block+FileEditユーティリティが役立つ。

 以下は、”net.core.somaxconn"(カーネルがキューイング可能なパケットの最大個数)が定義されていなかった場合、ファイルの最終行に定義を追加、最後にリロードするというもの。

 

ruby_block "Edit /etc/sysctl.conf" do
  block do
    rc = Chef::Util::FileEdit.new("/etc/sysctl.conf")
    rc.insert_line_if_no_match(/^net.core.somaxconn.*$/, "net.core.somaxconn = 1000"
    rc.write_file
  end
  notifies :run, "execute[Reload /etc/sysctl.conf]"
end

execute "Reload /etc/sysctl.conf" do
  command "sysctl -p"
  action :nothing
end

 

ポイント

  • "rc = ~"の”rc"は任意の文字列
  • ”insert_line_if_no_match”の部分のメソッドには、いくつかの種類がある。詳しくはこちらを参照。
  • Chefのバグで、"insert_line_if_no_match"を2回以上使うと、最初のものしか有効にならない。そのほかのメソッドについては、何回でも使用可能。
  • "/^net.core.somaxconn.*$/"の部分は、マッチングさせたい条件を"/"で囲まれた部分にRuby正規表現で記述する。
  • ruby_blockの後の""には、任意の文字列を設定できるが、ランリスト中の他の名称と重複しないようユニークにする。そうしないとコンパイルで警告となる。

Hadoopって何だ?

 以前から気になっていた「Hadoop」。これっていったい何?早速調べてみた。

 

大規模データ分散システムを支えるJavaフレームワーク

 Hadoopは、大規模データの分散システムを支えるJavaソフトウェアフレームワークらしい。Googleのデータセンターで利用されているクラウド基盤システム(BigtableやMapReduce)の論文をヒントとし、Yahoo!のメンバーが主体となり開発されたもの。

 

オープンソースソフトウェア

 Hadoopは、Google File System(GFS)とMapReduceのオープンソース実装版である。全てJavaで記述される。

 

何の為に使うのか?

  複数のマシンに処理を分散させることで、1台で数日かかっていた処理を1日で終わらせるといったことが可能になる。

 Hadoopには以下のような特徴がある。これを見ると分かるように、少ないデータを扱う場合にHadoopを使うのはもったいないし、データに信頼性を求めるなら、従来どおりRDBを使いなさい、となる。

 

  向いているシステム

  • フル・スキャンするバッチ処理を行うシステム
  • TB、PBクラスの大規模データを扱うシステム
  • データウェアハウス等の情報系システム
  • コモディティ・サーバーを使用した、スケールアウト構成のシステム

 

  向いていないシステム

  • オンライントランザクション処理(OLTP)行うシステム
  • ランダムアクセスを行うシステム
  • 厳密なデータ整合性が求められるシステム
  • 信頼性を求められる基幹システムや業務システム

 

主なコンポーネント

 Hadoopは、主に以下のコンポーネントで構成される。

 

  MapReduce

 処理を記述するプログラミングモデル。

  HDFS

 ファイルシステム。複数マシンを1つのストレージとして扱う。HDFS上に構築されるデータベースとして、『HBase』がある。

 

アーキテクチャ

 ざっくりとしたアーキテクチャは図の通り。

 MapReduceレイヤでは、JobTrackerがクラスタのジョブスケジューラおよびアロケータとして機能し、個々のスレーブノードにおけるTaskTrackerへのジョブ割り当てを行う。

 HDFSレイヤでは、Name nodeがファイルのメタデータ("場所")を管理し、Data nodeが実際のデータを保持する。

 



Chef Clientのインストール

 前回準備したknife bootstrapの仕組みを利用して、Chef Clientをインストールしてみる。

 

環境など

 今回のChef Clientのインストール対象ノードの環境と、Chef Clientのバージョンは以下の通り。

  OS

CentOS 6.4 ※ちなみに、Chef Serverのノードも同一OS

Chef Clientのバージョン

11.4.0 ※ OPSCODE社のホームページから、RPMをダウンロードしておく。

 

SSHの自動ログインの設定

 knife bootstrapでは、sshの自動ログインを利用する為、事前にChef Serverノードの公開鍵をChef Clientインストール対象ノードに設定しておく必要がある。

 まずは、以下をChef Serverノードで実行する。

※ Chef Serverノードにて実施

# ssh-keygen -t rsa
   Generating public/private rsa key pair
   :
   Your public key has been saved in ~/.ssh/id_rsa.pub.
   :

 

 次に、Chef Clientノードの~/.ssh/authorized_keysにChef Serverノードで作成した公開鍵(id_rsa.pub)の中身を追記する。

※ Chef Clientインストール対象ノードにて実施

# vi ~/.ssh/authorized_keys

 

Chef ClientのRPM配置

 今回は、インターネット非接続環境でのインストールなので、knife bootstrapを使用する場合でも、インストール対象ノード上にRPMが事前に配置されている必要がある。

 そこで、scpでChef Serverノードからインストール対象ノードの/tmpにRPMを配置してやる。

※ Chef Serverノードにて実施

# scp /root/chef-repo/.chef/rpm/chef-11.4.0-1.el6.x86_64.rpm xxx.xxx.xxx.xxx:/tmp

  ※ 今回は、/root/chef-repo/.chef/rpmというディレクトリにRPMを準備しておいた。「XXX.XXX.XXX.XXX」は、インストール対象ノードのIPアドレス

 

knife bootstrapの実行

 準備が整ったので、早速実行してみる。

※ Chef Serverノードにて実施

# knife bootstrap XXX.XXX.XXX.XXX --template-file /root/chef-repo/.chef/bootstrap/centos-client.erb
Bootstrapping Chef on XXXX

Chef Client finished, 0 resources updated

  ※ /root/chef-repo/.chef/bootstrap/centos-client.erbは、前回準備したknife bootstrapのテンプレートファイル

 

インストール結果の確認

 以下のコマンドで、Chef Serverが今回インストールしたChef Clientを認識できているかを確認してみる。

※ Chef Serverノードにて実施

# knife client list
XXXX
chef-validator
chef-webui

 

 上記の「XXXX」にChef Clientのインストール対象ノードのホスト名が表示されていればOK!