とりとめも

藻類が学んだり感じたりしたことを未来の自分のために書き留めるところ

Chef-Zero勉強記録 その1 環境準備と初めてのレシピ

はじめに

Chefを勉強します。その記録です。
経緯は前回記事をご覧ください。

また、今回のお勉強は、Conohaの解説ページを参考に進めていきます。このはちゃんすごい。

今回やること

環境

Vagrant:1.9.1
BOX:bento/centos-7.3

仮想マシンの準備

以下2台の仮想マシンを作成します。

①chef環境用
 chefのあれこれを設定する

②本番環境(仮)  ①で設定したchefによってあれこれされてしまうマシン

以後、①をchef環境、②を本番環境と呼ぶことにします。①でchefのCookbookを作り、knifeを使って②に設定を適用するわけです。

まずはこれらの仮想マシンVagrantで準備していきます。
使うBOXはどちらも前述のbento/centos-7.3としていますが、CentOS7なら大きな差は無いと思います。

①chef環境の準備

ローカル環境の適当なディレクトリでvagrant initします。

$ pwd
/Users/marimosan/chef

$ vagrant box list
bento/centos-7.3              (virtualbox, 2.3.2)

$ vagrant init bento/centos-7.3
(なんかいろいろ出力)

$ ls
Vagrantfile

Vagrantfileを編集します。
たいしたことはしないですが、①・②間で通信できるようにホストオンリーアダプタでいい感じのIPを設定しておきます。

#Vagrantfileに以下を記述
config.vm.network "private_network", ip: "192.168.56.10"

内部ネットワークじゃないとVM間通信はできない、みたいな話を見かけたのですが、Private Networkでも問題なさそうです。

②本番環境の準備

①とやることは同じです。

$ pwd
/Users/marimosan/dev_env

$ vagrant box list
bento/centos-7.3              (virtualbox, 2.3.2)

$ vagrant init bento/centos-7.3
(なんかいろいろ出力)

$ ls
Vagrantfile
#Vagrantfileに以下を記述
config.vm.network "private_network", ip: "192.168.56.11"

疎通確認

VMvagrant sshし、①から②、②にから①にそれぞれpingが通ることを確認。

と、なぜわざわざ書くかといえば、初期状態では思うように疎通できなかったからです。

繋がらない場合

状況を確認したところ、各VMip aしても先ほど設定したIPのethが存在していないようでした。こんなときはネットワークをリスタートしてみます。

$ sudo systemctl restart network.service

chefのインストール(①chef環境)

chef-dkのインストー

chefの関連ツールをまとめてインストールできるのがchef-dk(chef Development Kit)らしいです。
chef-dkを使わない場合、個別にgemで導入することになるほか、chef-dkにしか入っていないインターフェースも存在するそうな。

以下のような特徴があるようです。

  • Ruby環境を内部に持っている
    • Rubyを別途インストールする必要がない
    • Rubyインストール済みの場合も、環境を汚すことがない
  • chefコマンドを使えるようになる
    • 一例として、chef gemによりchef-dk内部のruby環境にgemを導入できる

これは使うしかない。ということで①chef環境で以下コマンドを叩きます。

$ sudo yum install https://packages.chef.io/files/stable/chefdk/1.4.3/el/7/chefdk-1.4.3-1.el7.x86_64.rpm

最新バージョンのダウンロードリンクは公式サイトから探しました。

https://downloads.chef.io/chefdk

$ chef -v
Chef Development Kit Version: 1.4.3
chef-client version: 12.19.36
delivery version: master (41b94ffb5efd33723cf72a89bf4d273c8151c9dc)
berks version: 5.6.4
kitchen version: 1.16.0
inspec version: 1.25.1

なんかいろいろ入ってる。

chef-zeroとknife-zeroのインストール(①chef環境)

chef-dkの環境を利用して、chef-zeroとknife-zeroを入れます。

$ chef gem install chef-zero knife-zero

knife-zeroの設定

chefリポジトリを作る

chefリポジトリ:Nodeの構成情報を管理する場所

適当な作業用ディレクトリで以下を実行します。

$ chef generate repo chef-repo
(いろいろ作られてるっぽいメッセージが出力)
$ ls chef-repo
LICENSE  README.md  chefignore  cookbooks  data_bags  environments  roles

このchef-repoディレクトリで、リモートホストの登録やCookbookの作成を行なっていくことになります。

knife-zeroの設定ファイル

knife-zeroの作者様の解説を読みながらうにょうにょと進めていきます。

http://knife-zero.github.io/20_getting_started-ja/

chef-repoディレクトリにknife.rbを作って、設定を書き込みます。

local_mode true
chef_repo_path   File.expand_path('../' , __FILE__)

knife[:ssh_attribute] = "knife_zero.host"
knife[:use_sudo] = true

knife[:automatic_attribute_whitelist] = %w[
  fqdn
  os
  os_version
  hostname
  ipaddress
  roles
  recipes
  ipaddress
  platform
  platform_version
  cloud
  cloud_v2
  chef_packages
]

Nodeの登録とchef-clientインストー

②本番環境にchef-clientをインストールします。chef-clientとは、chef-zeroでのリモートプロビジョニングを行うためのコンポーネントのようです。
また、①chef環境に、「②本番環境がはNodeだ」!ということを登録してあげます。
上記2点は、①chef環境でknife zero bootstrapコマンドを使うことで同時に行われます。

$ knife zero bootstrap 192.168.56.11 --ssh-user vagrant --node-name production_host
(いろいろメッセージ)
$ ls
LICENSE    chefignore  conf.rb    data_bags     nodes
README.md  clients     cookbooks  environments  roles
$ ls nodes
production_host.json

このJSONファイルが、Nodeの設定情報らしいです。使うRecipeの情報などはここに追記していきます。
–node-nameで指定した名前がnode名になりますが、–node-name無しの場合はターゲットのホスト名がそのまま使われます。

$ knife node list
production_host

$ knife node show production_host
Node Name:   production_host
Environment: _default
FQDN:        localhost
IP:          10.0.2.15
Run List:    
Roles:       
Recipes:     
Platform:    centos 7.3.1611
Tags:        

動作確認

bootstrapが完了すると、node名を使用していろいろできるようになります。

$ knife search node "name:production_host"
1 items found

Node Name:   production_host
Environment: _default
FQDN:        localhost
IP:          10.0.2.15
Run List:    
Roles:       
Recipes:     
Platform:    centos 7.3.1611
Tags:        

$ knife ssh "name:produc*" --ssh-user vagrant hostname
192.168.56.11 localhost.localdomain

knife zero convergeではレシピの反映等を行うようですが、今はまだ何のレシピも登録していないため、とりあえず叩いて何やら動くのをみてみます。

$ knife zero converge "name:produ*" --ssh-user vagrant
(いろいろメッセージ)

続いて、以上で登録したNodeに適用するためのRecipeを作ってみます。

Cookbookを作ってみる

お試しCookbookを作ります。
このあたりの流れは先のConohaちゃん解説記事に従い、NginxをインストールするCookbookを作ることにします。
ただし、Conohaちゃん記事そのままではエラーとなる点があった(恐らく環境起因)ので、少しだけ手順を追加しています。

Nginxインストール用Cookbook作成

$ ls cookbooks/
README.md  example
$ knife cookbook create nginx
(いろいろメッセージ)
$ ls cookbooks/
README.md  example  nginx
$ ls cookbooks/nginx
CHANGELOG.md  attributes   files      metadata.rb  recipes    templates
README.md     definitions  libraries  providers    resources

recipesディレクトリに、レシピファイルを作成してきます。

Recipe作成

方針(Conohaちゃん記事からの変更点)

epelではなくNginxリポジトリからインストールする

基本的に前述のConohaちゃん記事準拠ですが、あの記事ではepelリポジトリを使ってnginxをインストールしようとしていました。
今回のNodeではepelリポジトリは未登録のため、記事そのままのレシピではエラーとなります。
なのでepelリポジトリを使用可能とするレシピもあわせて書きます・・・と言いたいところですが、せっかくなので、epelリポジトリではなくNginxのリポジトリから新しいNginxをインストールするレシピにしたいと思います。

Nginxリポジトリの設定方法は下記の記事を参考にさせて頂きました。

また、Conohaちゃん記事ではiptablesの設定も同レシピに含めていましたが、iptablesがまだOSに導入されていないため、割愛することにします。(このほうがまずはレシピも読みやすいと思うので)

作っていく

Nginxインストールレシピ

$ pwd
(略)/chef-repo/cookbooks/nginx/recipes
$ vi default.rb

default.rbに以下を書きます。(default.rbははじめから存在しますが、上書きして大丈夫)

#リポジトリを設定するためのrepoファイルを作成
#templateリソース:sourceで指定したファイル内容をNodeに作成する
template 'nginx.repo' do
  path    '/etc/yum.repos.d/nginx.repo'
  source  'nginx.repo.erb'
  mode    0644
  user    'root'
  group   'root'
end

#nginxをインストールする
#packageリソース:yumでインストールする
package 'nginx' do
    action [ :install ]
end

#nginxのサービスを起動する
#serviceリソース:サービスの管理を行う
service 'nginx' do
    supports [ :restart, :reload ]
    action [ :enable, :start ]
end

コメント内で書いている通りですが、Nginxリポジトリを設定するためのrepoファイルはtemplateリソースで作成しています。
templateリソースではファイルを作成でき、その内容は別途templatesディレクトリ内にファイルを作って用意してあげます。そのファイルをsourceで指定しているわけですね。

なので、必要なファイルをtemplatesディレクトリに作成します。

repoファイル作成用テンプレートファイル

$ pwd
(略)/chef-repo/cookbooks/nginx/templates/default
$ vi nginx.repo.erb

ここでnginx.repo.erbを作成します。

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

以上でレシピの準備はOKです。

Nodeへのレシピの登録

先に登録したproduction_hostのJSONファイルに、「このNodeではこのRecipeを使うぞ!」という情報を追加してあげます。

$ knife node run_list add production_host 'recipe[nginx]' 
production_host:
  run_list: recipe[nginx]

これでnginxインストールのレシピが登録された、はずです。
nodes/production_host.jsonのお尻のほうにrun_listというパラメータがあるので見てみます。

$ tail nodes/production_host.json
(略)
  "run_list": [
    "recipe[nginx]"
  ]
 }

あった。

また、knife searchコマンドでもrun_listが確認可能です。

$ knife search node "name:production_host"
1 items found

Node Name:   production_host
Environment: _default
FQDN:        localhost
IP:          10.0.2.15
Run List:    recipe[nginx]
Roles:       
Recipes:     nginx, nginx::default
Platform:    centos 7.3.1611
Tags:       

あった。

長い道のりでしたが、これでNginxをインストールする準備が整いました。

インストールの実施

レシピを反映する!!

先ほども使ったknife zero convergeを使います。今度はrun_listに登録されたnginxレシピがNodeに反映されるはずです。

$ knife zero converge "name:production_host" -x vagrant
(いろいろメッセージ)

なんかできたっぽいメッセージが流れたはず。

なお、knife zero convergeですが、この処理を収束(converge)と呼ぶそうです。
つまり、run_listに登録したレシピの状態に収束させる、という理解で合ってると思います。
ChefにおけるRecipeとは、「処理の流れ」というより「状態」を記述するものらしいです。そう考えると、反映ではなく収束という言葉は的確っぽいですね。

確認する(②本番環境)

②本番環境に移り、rootユーザーであれこれ確認してみます。

$ nginx -v
nginx version: nginx/1.12.0
$ systemctl status nginx
● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since(以下略)
$ ls -l /etc/yum.repos.d/nginx.repo
-rw-r--r--. 1 root root 99 Jun 25 12:08 /etc/yum.repos.d/nginx.repo

できてるっぽい!!!!

おわりに

Chefのインストールから、簡単なレシピでのNginxのインストールまでを行いました。
Chef-Zeroを使ったプロビジョニングの流れは、大まかに以下のようです。

  • Chef環境にChef-Zeroやknife-zeroを導入
  • 管理対象サーバーにknife zero bootstrapする
    • Chef環境への対象Node登録
    • 対象Nodeへのchef-clientインストー
  • レシピを作る
  • 対象Nodeのrun_listにレシピを登録する
  • knife zero convergeで、登録したレシピに収束

次回以降は今回学んだ内容をもう少し掘り下げたり、Berkshelfなるものを使ったりしていきます。
とりあえず今思いつく範囲ですが、以下のようなことをやっていけば、少しはChefを活用できるようになるでしょうか。

  • Berkshelfについて知る
  • レシピを作れるようになる
    • 各種リソースをはじめとする記法の理解
  • roleとは何か