LoginSignup
13
13

More than 5 years have passed since last update.

これから始めるChefのチュートリアル 応用編

Posted at

はじめに

本記事はこれからはじめるChefのチュートリアル 基本編の続編です。
はじめにこれからはじめるChefのチュートリアル 基本編を実施してから進めてください。

環境構築 その5 パッケージインストール

パッケージをインストールしてみます。
今回はnginxを例にするので以下のクックブックを作成します。

$ bundle exec knife cookbook create nginx -o site-cookbooks/

内容を記載します。

site-cookbooks/nginx/recipes/default.rb
# yum install nginx
package "nginx"

以下のようにも記載できます。

site-cookbooks/nginx/recipes/default.rb
package "nginx" do
  action :install
end

nodeに追加します。

nodes/chef-centos65.json
{
  "run_list": [
    "ruby",
    "nginx"
  ]
}

サーバーに反映します。
簡単ですね!

$ bundle exec knife solo cook chef-centos65

と、思ったら以下のエラーが発生しました。

No candidate version available for nginx

前回の記事で定義したyum-epelがここで役立ちます。

nodeyum-epelを追加します。
これによってEPELリポジトリが使えるようになります。

nodes/chef-centos65.json
{
  "run_list": [
    "ruby",
    "yum-epel",
    "nginx"
  ]
}

この状態にして再実行します。

$ bundle exec knife solo cook chef-centos65

確認してみます。

$ ssh chef-centos65
$ service nginx status
nginx is stopped
$ exit

パッケージが入りました。

環境設定 その6 パッケージの設定

この状態ではnginxは起動してません。
早速起動する命令を書きましょう

site-cookbooks/nginx/recipes/default.rb
package "nginx"
service "nginx" do
  # 使用できるオプションを指定
  supports status: true, restart: true, reload: true
  # 実際に行うコマンド
  action [:enable, :start]
end

この状態にして再実行します。

$ bundle exec knife solo cook chef-centos65

確認してみます。

$ ssh chef-centos65
$ service nginx status
nginx (pid  12345) is running...
$ exit

起動してますね。
ここからnginxの設定を書いていきます。

※サーバーに入り込んで設定を追加していっても良いのですが、前回にも書いたように冪等性を保てなくなります。
ここは全てchefでやりましょう。

まず以下のファイルを作成します。

site-cookbooks/nginx/templates/default/nginx.conf.erb
user              nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/vhost.d/*.conf;
}

上記のものはインストールされたnginx.confに記載されていた設定ファイルから、コメント部分を取り除いてinclude /etc/nginx/vhost.d/*.conf;を追加したものになります。

Nginxの設定内容を知りたい方はこちらを読んでください。
今回は設定ファイルの書き換えなどの方法を学ぶためのものなので、内容は何でも良いです。

このファイルを実際に配置します。

site-cookbooks/nginx/recipes/default.rb
package "nginx"

service "nginx" do
  supports status: true, restart: true, reload: true
  action [:enable, :start]
end

# テンプレート機能を使用
template "nginx.conf" do
  # 配置する箇所(上記の"nginx.conf"部分に以下を記載してもOK)
  path "/etc/nginx/nginx.conf"
  # 使用するテンプレートを指定
  source "nginx.conf.erb"
  # 権限を指定
  owner "root"
  group "root"
  mode 0644

  # 配置後に再起動を促します。
  notifies :reload, "service[nginx]"
end

# ヴァーチャルホストの設定を配置するディレクトリを作成しておきます。
directory '/etc/nginx/vhost.d' do
  owner 'root'
  group 'root'
  mode  0755
end

この状態にして再実行します。

$ bundle exec knife solo cook chef-centos65

確認してみます。

$ ssh chef-centos65
$ service nginx status
nginx (pid  12345) is running...
$ cat /etc/nginx/nginx.conf
上記で記載した内容が表示される。
$ ls -l /etc/nginx/
# vhost.dが指定した権限で作成されている。
drwxr-xr-x. 2 root root 4096 12月  3 09:00 2015 vhost.d
$ exit

このようにchefのレシピではファイルの作成やディレクトリの作成ができます。
また、権限の指定などもできます。

深い階層のディレクトリを作る場合

深いディレクトリを作るときには以下の方法で行えます。

directory '/dir1/dir2/dir3' do
    owner 'root'
    group 'root'
    mode '0600'
    # このメソッドを指定すると「mkdir -p」のように作成できる。
    recursive true
end

ただし、この方法では最後のディレクトリのみ権限が付与されるので間のディレクトリにも権限を付与させたい場合は以下のように行う。

%w[
    /dir1
    /dir1/dir2
    /dir1/dir2/dir3
].each do |path|
    directory path do
        owner 'root'
        group 'root'
        mode '0600'
    end
end

環境構築 その7 設定ファイルの汎用化

rubyを知っている人は気づいたかもしれませんが、templateで使用しているファイルはerbファイルになってます。
なので、この中でもプログラムを書くことができます。

今回は変更できる事を確認するためにworker_processesを変更してみます。

nodes/chef-centos65.json
{
  "nginx": {
    "worker_processes": 2
  },
  "run_list": [
    "ruby",
    "yum-epel",
    "nginx"
  ]
}

templateを一部変更します。

site-cookbooks/nginx/templates/default/nginx.conf.erb
user              nginx;
worker_processes  <%= node["nginx"]["worker_processes"] %>;
...(略)

テンプレートの中身を変えてchefを実施します。

$ bundle exec knife solo cook chef-centos65
...
    --- /etc/nginx/nginx.conf   2015-12-02 09:14:33.395852109 +0000
    +++ /etc/nginx/.nginx.conf20151203-15729-niu7bb 2015-12-03 01:51:58.174817582 +0000
    @@ -1,5 +1,5 @@
     user              nginx;
    -worker_processes  1;
    +worker_processes  2;

     error_log  /var/log/nginx/error.log;
     pid        /var/run/nginx.pid;
...

このように変更点を教えてくれます!
素晴らしいですね。

実際に確認してみます。

$ ssh chef-centos65
$ cat /etc/nginx/nginx.conf
user              nginx;
worker_processes  2;
...
$ exit

変更されてますね。

あとは、未設定の場合の対応を行います。

site-cookbooks/nginx/attributes/default.rb
default["nginx"]["worker_processes"] = 1

だいぶ色々な事ができるようになってきました。
ここまでできればほとんどのサーバー構築はできるようになっているかと思います。

環境構築 その8 ユーザー作成

初めのユーザーをそのまま使っても良いのですが、chefが操作するユーザーは強力なのでできれば他のユーザーを用意したいところです。

なので、ユーザーを追加するレシピを作成します。
ここでは鍵認証で接続できるユーザーを作成します。

鍵の作成

まずは鍵を作成します。
鍵を作るときに~/.ssh/id_rsaを上書きしないように注意してください。
上書きすると取り返しがつかない事になると思いますので、注意してください。

# 鍵を配置するフォルダを作成します。
$ mkdir ssh
# 鍵を作成します。
$ ssh-keygen -t rsa
# この質問に対してEnterを押さないこと。「ssh/id_rsa」を入力してください。
Enter file in which to save the key (/Users/ユーザー名/.ssh/id_rsa): ssh/id_rsa
# パスフレーズは不要です。Enterを押してください。
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:
# 公開鍵を表示します。
$ cat ssh/id_rsa.pub
ssh-rsa AAAAB3***.local

作成した鍵は後で使用します。
ssh-rsa AAAAB3***.localと書かれた長い文字列をコピーしておきます。

ユーザー作成のレシピを作成

ユーザー作成用のレシピを作成します。

$ bundle exec knife cookbook create user -o site-cookbooks/

ユーザー作成のレシピを作成します。

site-cookbooks/user/recipes/default.rb
# 適当なグループを作成します。
group "test_grp" do
  gid 403
end

# SSHでログインするためのユーザーを作成します。
user "ssh_user" do
  uid 403
  gid 403
end

# 公開鍵を設置するフォルダを作成します。
directory "/home/ssh_user/.ssh" do
  mode 0755
  owner "ssh_user"
end

# 公開鍵を設置します。
file "/home/ssh_user/.ssh/authorized_keys" do
  mode 0644
  owner "ssh_user"
  # 先ほどの公開鍵を貼り付けます。
  content "ssh-rsa AAAAB3***.local"
end

# オーナーを変更しておきます。
directory "/home/ssh_user" do
  mode 0755
  owner "ssh_user"
end

作成したレシピをnodeに追加します。

nodes/chef-centos65.json
{
  "run_list": [
    "user",
    "ruby",
    "yum-epel",
    "nginx"
  ]
}

それではchefを実施してみます。

$ bundle exec knife solo cook chef-centos65

現在作成したユーザーがログインできるか確認します。

$ ssh ssh_user@192.168.33.10 -i ssh/id_rsa
[ssh_user@localhost ~]$
$ exit

ログインできることが確認できました。
これで、ユーザー作成も完成です。

※今回はパスワードを設定しないのでruby-shadowは使用してません。

汎用化

今回は説明を割愛しますが、今まで同様で必要に応じて汎用化しておくとレシピが使いやすくなります。

Capistranoを使う方へ

Capistranoを使う方は、ここで作成した鍵を使用する事になると思います。
なので、ディレクトリ構成も少し考えると良いと思います。

例えば、以下のような構成にするなどの工夫をすると環境用構築一式を管理できるようになります。

・アプリ名のディレクトリ(git管理)
 ∟chef・・・アプリのサーバーを構築するchefレシピを保管
 ∟capistrano・・・アプリをデプロイするcapistranoを保管
 ∟user・・・デプロイユーザーの鍵を保管

sudoやssh制限について

今までの知識があれば/etc/sudoersを変更する事も簡単に行えると思います。
また、rootユーザーのSSH禁止(/etc/ssh/sshd_config)などもできるようになっていると思います。
本記事では扱いませんが、必要に応じてやってみてください。

いままではSSH制限やrootユーザーに関わる変更はとても怖い変更でした。
しかしchefを使っていれば、事前に仮想OSで実験する事ができる上にその後失敗する事がありません。
こういう利点を生かしてchefをどんどん使っていけると良いですね。

クックブックの探し方

ここまでできればサーバー構築で困ることはほとんどないはずです。
その気になれば自前で全て書くこともできると思います。
しかし、それは車輪の再発明になるかもしれません。

世の中のクックブックはここから探せます。
CHEF SUPERMARKET

ここまで作成した過程でBerkshelfを入れているので、積極的に活用していきましょう!

roleの使い方

最後になりますが、roleの説明を簡単にします。
今までのチュートリアルのやり方だとnodeファイルが膨大になる可能性があります。

小規模で使うならroleは不要ですが、大規模で使用する場合はroleを使うとうまくまとめてレシピを管理することができます。

例えば以下のような構成のときに微妙に違うnodeを書く必要が出てきます。

webサーバー2台・・・ユーザー設定とapacheやtd_agentなどを入れたい。
アプリサーバー2台・・・ユーザー設定とnginxやruby、mysql::clientなどを入れたい。
DBサーバー1台・・・ユーザー設定とmysql::serverなどを入れたい。
監視サーバー・・・ユーザー設定とnginxやrubyなどを入れたい。

このようなサーバー構築をすると、基本的に導入するレシピは同じだけど上乗せしているレシピがちょっとづつ違うなどでnodeを書くのが大変になってくる。

例えば以下のような長いnodeを書いて、各サーバーに合わせて増減する・・・なんてぞっとしないだろうか?

{
  "run_list": [
    "yum",
    "yum-epel",
    "ntp",
    "monit",
    "nagios",
    ...
    "user",
    "ruby",
    "nginx",
    "apache",
    "mysql",
    "imagemagick"
  ]
}

このような時はroleを使うと便利だ。
roleはこのようなレシピをまとめてくれる存在だ。

roleの分け方

roleroles/配下に配置できる。
例えば基本的な構成はbase.jsonに書いて、Webサーバー用の構成はweb.jsonに書くなどとすれば先ほどのnodeは以下のように短くなる。

{
  "run_list": [
    "role[base]",
    "role[web]"
    "imagemagick"
  ]
}

このように目的別にroleを作っておくとレシピの管理が楽にできる。
また、roleにもdefault_attributesと言う項目があり、汎用的に使用している変数を定義することができる。
そして、その値をnodeで上書きすることもできるので、便利だ。

作ってみる

とりあえず、今まで作ってたものをroleに移してみよう。

nodes/chef-centos65.json
{
  "run_list": [
    "user",
    "ruby",
    "yum-epel",
    "nginx"
  ]
}

あんまり恩恵がないけど、ruby以外のレシピをserverロールとして作ってみる。

roles/server.json
{
  "name": "server",
  "description": "this is test",
  "chef_type": "role",
  "json_class": "Chef::Role",
  "default_attributes": {
    "nginx": {
      "worker_processes": 3
    }
  },
  "run_list": [
    "user",
    "yum-epel",
    "nginx"
  ]
}

nginxのworker_processesを3にしてroleを作成するロールを作る。
nodeでロールを読み込む

nodes/chef-centos65.json
{
  "run_list": [
    "ruby",
    "role[server]"
  ]
}

それではchefを実施してworker_processesが変更されることを確認する。

$ bundle exec knife solo cook chef-centos65

中身を確認してみる。

$ ssh chef-centos65
$ cat /etc/nginx/nginx.conf
user              nginx;
worker_processes  3;
...

変更されてますね。
念のためnodeで上書きができるかチェックしてみます。

nodes/chef-centos65.json
{
  "nginx": {
    "worker_processes": 2
  },
  "run_list": [
    "ruby",
    "role[server]"
  ]
}

実行すると以下のように変更されることが確認できます。

$ bundle exec knife solo cook chef-centos65
$ ssh chef-centos65
$ cat /etc/nginx/nginx.conf
user              nginx;
worker_processes  2;
...

roleの設定項目について

roleの設定項目は基本的に以下の形式になると思います。
(というか、僕自身が他をしらない・・・)

  "name": "server",
  "description": "this is test",
  "chef_type": "role",
  "json_class": "Chef::Role",
  • name・・・このロールの名前を入れます。半角スペースなど使えない文字があるので注意してください。
  • description・・・ロールの説明を記載します。

まとめ

いかがだったでしょうか?
chefにはまだまだ様々な機能がありますが、このチュートリアルをひととり行えば大抵の事には対応できるようになると思います。

本記事が誰かの役に立てれば幸いです。

筆者について

筆者はTownsoftを屋号に活躍(?)しているフリーランスです。
お仕事の依頼なども受けてますので、お気軽にご連絡ください。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13