Knife-ZeroによるVM間(CentOS & Amazon Linux)の環境構築

フロントエンドエンジニアの小松です。

今回はやや背伸びをしてバックエンド寄りの内容になりますが、Knife-Zeroによるサーバーの環境構築に挑戦してみました。


ちなみに、今回は本物のサーバーで試す勇気がなかったのでVagrantによるVM間で実施しました。

目次

Chefとは?

「サーバー設定ツール」「サーバー環境構築ツール」「自動構築フレームワーク」など呼び方は様々ですが、サーバーのセットアップや更新をコードで管理・自動で反映することができるツールでです。


同じようなツールとして Ansible 等が挙げられますが、基本的にできることは同じみたいです(Ansibleの方が手順がシンプルなようですが…)

(それでもChefを試すことにしたのは、名前がなんとなくイケてると思ったからです)

Knife-Zeroとは

ChefとKnifeの関係性ですが、関連する単語が多かったり解釈の違いが多々あるようなので未熟者は詳細については言及を控えます…


ざっくりとした理解なのですが、 Knife-Zeroとはスタンドアロン形式で稼働させるChef(Chef-Zero)を、リモートから一元管理・実行することができるツールです。

(以前はKnife-Soloというスタンドアロン形式で実行するためのツールがあったのですが、非推奨となり現在ではChef本体のlocalモードで代用するようになっています。)


上記とは別にChefはChef Serverを立てて集中管理する形式もありますが、管理するサーバーが少数なのであればKnife-Zeroを用いた方が手早く構築できそうです。

今回の完成図イメージ

途中でわざわざ図にするほどでも無いことに気がつき手を止めた結果、中途半端なものが仕上がりましたが、これは完成イメージです。

いずれのサーバーもVagrantで構築した仮想環境になります。

Knife-Zero実行側の環境

OS: CentOS(6.7)

IP: 192.168.33.10

user: vagrant

password: vagrant

必要なもの: Chef DK/Knife-Zero

Chef DKはChefとそれに関連するツールをパッケージングしたものです

構築対象側の環境

OS: Amazon Linux AMI release 2017.03

IP: 192.168.33.11

user: vagrant

password: vagrant

必要なもの: 特になし


最終的にAmazon Linux側のサーバー内で sl -F コマンドを実行して汽車が空を飛べば完成です!


それでは早速進めていきましょう。

VM作成(Knife-Zero実行側)

Vagrantの説明とインストールについては省略します。


まずCentOS(6.7)のboxを追加しておきます。

vagrant box add centos67 https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box


次に、任意のディレクトリを作成して中に入ります。

自分はknife-zeroという名前のディレクトリにしました。

$ mkdir knife-zero
$ cd knife-zero/


先ほどインストールしたCentOSのboxでinitします。

$ vagrant init centos67


ディレクトリ配下にVagrantfileというファイルが生成されますので、エディタで開きます。

$ vim Vagrantfile

# config.vm.network "private_network", ip: "192.168.33.10"のコメントアウトを開放します。

これでssh接続する際にIP:192.168.33.10でアクセスできるようになりました。


ここまできたら、エディタを閉じて下記のコマンドを実行します。

$ vagrant up


無事にVMが起動したらvagrantのsshでアクセスし、サーバー内にアクセスできたら一旦OKです。

$ vagrant ssh

VM作成(構築対象側)

こちらも同じようにVMを立ち上げるのですが、OSとIPが違います。


まずは先ほど同様、任意のディレクトリ作って中に入ります。

$ mkdir amazon
$ cd amazon/
$ vagrant ssh


下記コマンドでAmazon Linuxのboxのダウンロードとinitを行います。

$ vagrant init mvbcoding/awslinux


そしてこちらもVagrantfileをいじってIPを設定します。

# config.vm.network "private_network", ip: "192.168.33.10"のコメントアウトを開放して、下記のようにします。

config.vm.network "private_network", ip: "192.168.33.11

IPの末尾を11に変更しています


こちらもVMが立ち上がればOKです。

vagrant up

ssh接続

Knife-Zeroはssh経由で対象サーバーにアクセスし処理を実行します。

ので、Knife-Zero実行サーバーに構築対象側サーバーの秘密鍵を渡しておく必要があります。


今回はVM間の通信なのでVagrantが発行している鍵を使います。

$ cd amazon/
$ vagrant ssh-config

vagrant ssh-configで下記のように該当VMのssh周りの情報が表示されます。

Host default
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/komatsu/vagrant/amazon/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

ここで必要なのがIdentityFileに記載されているprivate_keyのパスです。


これをKnife-Zero実行サーバーの~/.ssh/以下に配置する必要があるのですが、今回はscpで直接送ってしまいます。

scpの記述は下記の形式のようです。

scp -i 送信先サーバーの秘密鍵パス 送信するファイルのパス ユーザー@送信先のIPアドレス:ディレクトリ

Knife-Zero実行サーバーにsshでアクセスし、上記private_keyのパスを設定し、送信先として構築対象側サーバー情報を設定すると下記のようになりました。

scp -i /Users/komatsu/vagrant/knife-zero/.vagrant/machines/default/virtualbox/private_key /Users/komatsu/vagrant/amazon/.vagrant/machines/default/virtualbox/private_key vagrant@192.168.33.11:~/.ssh


無事に送信されたか確認します。

$ cd amazon/
$ vagrant ssh
$ find ~/.ssh/private_key

試しにKnife-Zero実行サーバーから構築対象側サーバーにsshで入ってみます。

$ ssh -i ~/.ssh/private_key 192.168.33.11

Last login: Tue Jul 31 08:34:28 2018 from 10.0.2.2
[vagrant@localhost ~]$ ssh -i ~/.ssh/private_key 192.168.33.111
Last login: Tue Jul 31 07:49:31 2018 from 10.0.2.2

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.03-release-notes/
30 package(s) needed for security, out of 39 available
Run "sudo yum update" to apply all updates.
Amazon Linux version 2018.03 is available.
[vagrant@localhost ~]$

$ exit

無事確認できたら、exitして元のサーバーに戻っておきます。

Knife-Zeroのインストール

sshでアクセスできるようになったので、あとはKnife-ZeroからChefを実行するだけです。

ということで、Knife-Zero実行サーバーに入っておきます(上記でexitしたままであれば不要です)。

$ cd knife-zero/
$ vagrant ssh


まずは、Chef本体が必要ですのでインストールしていきます。

Chef DKというChefを使う上で必要なものがセットになっている便利なrpmパッケージがあるのでwgetで落として開きます。

$ wget https://packages.chef.io/files/stable/chefdk/3.1.0/el/6/chefdk-3.1.0-1.el6.x86_64.rpm
$ sodo rpm -Uvh chefdk-3.1.0-1.el6.x86_64.rpm


次はKnife-Zeroを落とします。

chefとセットでgemも手に入ったのでそちらからインストールを実行します。

chef gem install knife-zero


これで必要なツールのインストールは完了です!

リポジトリ作成

Chefを実行する際の設定ファイル群をラップしているものがリポジトリと呼ばれているようです。

下記のコマンドだけでKnife-Zero実行サーバーのrootディレクトリにリポジトリが出来上がります。

$ chef generate repo chef-repo


無事generateされたら中に入り、Knifeの設定ファイルを作成します。

$ cd chef-repo/
$ mkdir .chef
$ echo 'local_mode true' > .chef/knife.rb

local_mode trueですが、今はChef-Soloは非推奨となっているので、Chefのlocalモードを使用するよう記述しています。

※他にも色々と設定を記載できるのですが、今回はこれで十分です。


これでリポジトリの最低限の設定は完了しました。

構築対象側サーバーにChefをインストールする

Knife-ZeroはChefをリモートで操作するツールなので、構築対象側サーバーにもChefが必要となります。

そこでknife zero bootstrapコマンドを使うことで対象サーバーにChefをインストールさせることが可能です。

下記の構文になります。

$ knife zero bootstrap 反映先IP -x ユーザー名 -i 反映先サーバーの秘密鍵パス --sudo


ということで、chef-repoディレクトリに入った後、今回の設定に沿った内容で実行します。

$ cd chef-repo/
$ knife zero bootstrap 192.168.33.11 -x vagrant -i ~/.ssh/private_key --sudo

上記完了後、下記コマンドを実行することでNode(反映先)に追加されたか確認できます。

$ knife node list

自分の場合は名前を指定しなかったので localhostという名前で登録されました。


念の為、構築対象側サーバーに入りChefがインストールされたか確認します。

$ cd amazon/
$ vagrant ssh
$ chef- (タブを押してchef-soloなど候補ができたらOK!)

レシピの作成

ここまできたら、あとはレシピを自由に書いてリモートサーバーに反映するだけです。

SLを構築対象側サーバーにインストールすることが目的なので、そのレシピをcookbooks以下に作成していきます。

今回自分はslという名前のcoolbookにしました。

$ cd chef-repo/
$ chef generate cookbook cookbooks/sl


generateが完了したら、chef-repo/cookbooks/sl/recipes/default.rbをエディタで開き、下記を貼ります。

package "sl" do
  action :install
  options "--enablerepo=epel"
end

レシピの記載ルールについては割愛しますが、slパッケージをepelリポジトリも対象にした上でinstallするという内容になります。


エディタを閉じ、node(対象)の実行レシピに上記のslレシピを設定します。

$ knife node run_list add localhost sl

chef-repo/nodes/localhost.jsonを開き、run_listにslが設定されていればOKです。

構築対象側サーバーにSLをインストール

これで準備は全て揃いました!

デプロイの構文は下記になります。

knife zero converge 'node名' --attribute knife_zero.host -x ユーザー名 -i 反映先サーバーの秘密鍵パス --sudo

--attribute knife_zero.hostの記述によって反映先のIPが指定されています

ということで、今回は下記のようになりました。

knife zero converge 'localhost' --attribute knife_zero.host -x vagrant -i ~/.ssh/private_key --sudo


実行すると…

WARN: #<Chef::Deprecated::LocalListen:0x00000000078f2e40>
192.168.33.11 Starting Chef Client, version 14.3.37
192.168.33.11 resolving cookbooks for run list: ["sl"]
192.168.33.11 Synchronizing Cookbooks:
192.168.33.11   - sl (0.1.0)
192.168.33.11 Installing Cookbook Gems:
192.168.33.11 Compiling Cookbooks...
192.168.33.11 Converging 1 resources
192.168.33.11 Recipe: sl::default
192.168.33.11   * yum_package[sl] action install
192.168.33.11     - install version 0:5.02-1.6.amzn1.x86_64 of package sl
192.168.33.11
192.168.33.11 Running handlers:
192.168.33.11 Running handlers complete
192.168.33.11 Chef Client finished, 1/1 resources updated in 20 seconds

WARNが出てますが、とりあえず成功したようです。

SLを走らせる

では最後に、反映側のサーバーにアクセスして下記を実行します。

$ cd amazon/
$ vagrant ssh
$ sl -F


すると…

無事にSLが空を飛んだら完成です!

あとがき

今回はかなり駆け足かつ最低限の設定だけをしましたが、実案件では下記の対応が必要そうだなと感じました。

  • リポジトリをgit管理
  • Knife-Zero実行側サーバーにアクセスする際のセキュリティ強化
  • 設定系ファイルを充実させてコマンドをシンプルにする
  • 管理するサーバーの情報の所在について明確にする

また、そもそもChefじゃなくてAnsibleItamaeの方が手軽なのでは…と感じてしまったので、そのあたりの比較もしていきたいです。


今回はVM上での作業だったので、次回は勇気を出してEC2で実行してみたいと思います。

この記事を書いた人 komatsu 糖質制限と筋トレに目覚めて肉体改造しながらrails学習に励むフロントエンドエンジニア
好きなもの アニメ/プロテイン
TOP