俺の備忘録

技術系を中心に日々忘れていく事柄を記録したい。。。

Vagrantで構築した仮想マシンへredmineを構築する手順

結構はまったのでメモを残す。

やりたかったことは、vagrantで構築した仮想マシン上へバージョンアップやプラグインの確認用のredmineを作成したかった。

前提環境

OS: OS X 10.9.2(Marvericks)
Mem: 4GB
ruby: 2.0.0-p343(rbenv)
vagrant: 1.4.3
chef-solo: 11.10.2

事前の準備

vagrant、chef-soloのインストール
今っぽい Vagrant + Chef Solo チュートリアル - Qiitaを参考にしました。
boxには、CentOS6.5を使用しました。
ついでに、Berkshelf+Chef Soloの環境も整えておきます。

vagrantユーザでsshログインができるようになっていればOK。
このままのOSの状態だとロケーションがUTCになっていました。ので、これも変更しておきます。(これもcookbookにしておくべきか?)

$ sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

dateコマンドでJSTとなっていればOK。

これで、cookbookを作成する環境が整いました。

Cookbook作成

rubyのインストール

rbenv環境のrubyをインストールする。
[chef-repo]/Berksfile

site :opscode
	
cookbook 'ruby_build'
cookbook 'rbenv', github: "fnichol/chef-rbenv"

chef-rbenvを利用して、rbenv環境を構築する。
インストールは、1.9系、2.0系および2.1系をインストールしておいた。インストールバージョンは、お好みで。

[chef-repo]/site-cookbooks/ruby/recipes/install.rb

include_recipe "rbenv::system"
include_recipe "ruby_build"
	
rbenv_ruby "1.9.3-p484"
rbenv_ruby "2.0.0-p353"
rbenv_ruby "2.1.0"
rbenv_global "1.9.3-p484"
	
# rbenvグループを作成して /usr/local/rbenv
# の実行権限をvagrantユーザに追加する
group "rbenv" do
    action :create
    members "vagrant"
    append true
end
	
# インストールしたrbenvのグループを変更する
execute "change install ruby group" do 
    command "chown -R :rbenv /usr/local/rbenv"
    action :run
end
	
# 各rubyバージョンにbundlerをインストールする
rbenv_gem "bundler" do
    rbenv_version "1.9.3-p484"
end
rbenv_gem "bundler" do
    rbenv_version "2.0.0-p484"
end
rbenv_gem "bundler" do
    rbenv_version "2.1.0"
end
	
###
### デフォルトのBox設定では、kernel関連の
### パッケージがインストールされないように
### 設定されているので、その制限を解除しておく。
### kernel-develパッケージがインストールできないため。
###
file '/etc/yum.conf' do
    _file = Chef::Util::FileEdit.new(path)
    _file.search_file_replace_line('exclude=kernel', 		'#exclude=kernel¥n')
    content _file.send(:contents).join
    action :create
end.run_action(:create)

さらに、この設定がないとcookbookに落としてきた外部のrecipeが実行できません。ここに関しての情報が少なくはまりました。

[chef-repo]/site-cookbooks/ruby/metadata.rb

:
:
depends 'ruby_build'
depends 'rbenv'
mysqlのインストール

ここでも外部レシピを使用するので、Berksfileに以下を追加する。
[chef-repo]/Berksfile

:
:
cookbook 'mysql'
cookbook 'database'
:
:

redmine用にmysqlをインストールします。確認用なので、サクッとインストールと設定だけを行います。

[chef-repo]/site-cookbooks/redmine-mysql/recipes/install.rb

include_recipe "mysql::server"
	
cookbook_file "/etc/mysql/conf.d/mysql.cnf" do
    souce "mysql.cnf"
    mode 0644
    notifies :restart, "service[mysql]", :immediately
end

include_recipe "database::mysql"

# コネクション定義
mysql_connection_info = {
    :host => "localhost",
    :username => "root",
    :password => node['mysql']['server_root_password']
}

# redmine用のデータベース作成
mysql_database "db_redmine" do
    connection mysql_connection_info
    action :create
end
	
# redmine用データベースのユーザを作成
mysql_database_user "user_redmine" do
    connection mysql_connection_info
    password "xxxxxxxx"
    database_name "db_redmine"
    privileges [:all]
    action [:create, :grant]
end

このレシピにもdependsを追加

[chef-repo]/site-cookbooks/redmine-mysql/metadata.rb

:
:
depends 'mysql'
depends 'database'
passengerのインストール

外部レシピのpassenger_apache2を使用して、passengerのインストールを行おうとしたのですが、ここで問題が発生しました。
rbenv環境のrubyをしようしてpassengerのconfを生成しようと四苦八苦したのですが、結局うまくいかず、passenger_apache2のレシピをコピーするような形で独自のレシピを作成して対応しました。
こういう場合、どう対応するのがいいのでしょうか?うまい解決法がわからんなぁ。
passengerのコンパイルhttpdのインストールはここで実行します。

[chef-repo]/Berksfile

:
:
cookbook 'passenger_apache2'
:
:

apache2のレシピを使用するために、Berksfileに追加しておく。

[chef-repo]/site-cookbooks/passenger/recipes/install.rb

include_recipe "apache2"
	
include_recipe "build-essential"
node.default['passenger']['apache_mpm'] = "prefork"

case node['platform_family']
when "arch"
    package 'apache'
when "rhel"
    package "httpd-devel"
    if node['platform-family'].to_f < 6.0
        package 'curl-devel'
    else
        package 'libcurl-devel'
        package 'openssl-devel'
        package 'zlib-devel'
    end
else
    apache_development_package = if %w( worker threaded ).include?             node['passenger']['apache_mpm']
                'apache2-threaded-dev'
            else
                'apache2-prefork-dev'
            end
    %W( #{apache_development_package} libapr1-dev libcurl4-gnutls-dev ).each do |pkg|
        package pkg do
            action :upgrade
        end
    end
end

rbenv_gem "passenger" do
    version node['passenger']['version']
end

rbenv_script "passenger_module" do
    code <<-CODE
        passenger-install-apache2-module --auto
    CODE
end

ruby_block "passenger variables set" do
    block do
        #テンプレートの設定値をrbenvのパスへ上書きする
        passenger_version = "#{Chef::Recipe::PassengerConfig.build_directory_for_version(node['passenger']['version'])}"
        node.default['rbenv']['gems_dir'] = %x[ source /etc/profile; /usr/local/rbenv/bin/rbenv exec gem environment gemdir ].chomp
        node.default['passenger']['root_path'] = "#{node['rbenv']['gems_dir']}/gems/passenger-#{node['passenger']['version']}"
        node.default['passenger']['module_path'] = "#{node['passenger']['root_path']/#{passenger_version}/apache2/mod_passenger.so"
    end
end

template "#{node['apache']['dir']/mods-available/passenger.load" do
    cookbook "passenger"
    source "passenger.load.erb"
    owner "root"
    group "root"
    mode 0644
end

template "#{node['apache']['dir']/mods-available/passenger.conf" do
    cookbook "passenger"
    source "passenger.conf.erb"
    owner "root"
    group "root"
    mode 0644
end

link "#{node['apache']['dir']}/mods-enabled/passenger.load" do
    to "#{node['apache']['dir']}/mods-available/passenger.load"
end
	
link "#{node['apache']['dir']}/mods-enabled/passenger.conf" do
    to "#{node['apache']['dir']}/mods-available/passenger.conf"
end
redmineのインストール

Redmine 2.5をCentOS 6.5にインストールする手順 | Redmine.JP Blogを参考にレシピを作成。

[chef-repo]/site-cookbooks/redmine/recipes/install.rb

# 設定
REDMINE_HOME = "/var/lib/redmine"
REDMINE_VERSION = "2.3-stable"

# ImageMagick,ヘッダファイル,日本語フォント類のインストール
package "ImageMagick" do
    action :install
end
package "ImageMagick-devel" do
    action :install
end
package "ipa-pgothic-fonts" do
    action :install
end
package "libuuid-devel" do
    action :install
end
package "wget" do
    action :install
end

# redmineをSVNリポジトリからダウンロードする
subversion "redmine" do
    repository "http://svn.redmine.org/redmine/branches/#{REDMINE_VERSION}"
    destination "#{REDMINE_HOME}"
    action :sync
end

template "#{REDMINE_HOME}/config/configuration.yml" do
    owner "root"
    mode 0644
    source "configuration.yml.erb
end

template "#{REDMINE_HOME}/config/database.yml" do
    owner "root"
    mode 0644
    source "database.yml.erb"
end
	
# redmineで使用するgemパッケージをインストールする
rbenv_script "bundle install" do
    cwd "#{REDMINE_HOME}"
    code %{bundle install --without development test --path vendor/bundle}
end

# redmineの初期設定を行う
rbenv_script "init redmine" do
    cwd "#{REDMINE_HOME}"
    code <<-EOC
        bundle exec rake generate_secret_token
        RAILS_ENV=production bundle exec rake db:migrate
    EOC
end

# redmineのディレクトリをapacheユーザへ変更
execute "change redmine dir" do
    cwd "#{REDMINE_HOME}"
    command "chown -R apache:apache #{REDMINE_HOME}"
end

# railsアプリケーションとしての設定
include_recipe "rails"

web_app "redmine" do
    cookbook "passenger"
    template "web_app.conf.erb"
    docroot "#{REDMINE_HOME}/public"
    servername "hogehoge"
    server_alias ["fugafuga", "hogefuga"]
    rails_env "production"
end


テンプレートの設定
内容はほぼ固定で適当に記述してあるが、将来的に可変にできるとよろしいでしょう。

[chef-repo]/site-cookbooks/redmine/templates/default/configuration.yml.erb

production:
    email_delivery:
        delivery_method: :smtp
        smtp_settings:
            address: "localhost"
            port: 25
            domain: "vagrantup.com"
    rmagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf

[chef-repo]/site-cookbooks/redmine/templates/default/database.yml.erb

prodcution:
    adapter: mysql2
    database: db_redmine
    host: localhost
    username: user_redmine
    passowrd: [password]
    encoding: utf8

ここでもdependsの設定を追加する

[chef-repo]/site-cookbooks/redmine/metadata.rb

:
:
depends 'rails'
depends 'passenger_apache2'
depends 'redmine-mysql'


最後に、node.jsonにつらつらと実行するレシピを書いて実行します。
結構時間がかかりますが、rubyの構築からredmineのインストールまでひととおり行えます。
はまりどころは、rbenvを使用してpassengerのコンパイル、インストールを行おうとすると、chef-soloで使用しているrubyが使用されて思うようにいかなかったところです。ここに関しての解決方法がもう少し、スマートにできるといいのですが。

knifeでredmine環境を構築してみる

chef-soloの学習を兼ねてredmineの環境をvagrant上に構築してみます。

実行環境:
ruby 2.0.0-p353
knife 0.11.0
chef-solo 11.xx.xx

構築環境:
CentOS 6.5
ruby-2.0.0p353
redmine_2.5
mysql

で構築してみます。

まず、rbenvの環境を構築。
その後、rubyをインストール
で、passenger+apache2でWebサーバを構築し、
mysqlをインストールしてDBを構築。
最後に、redmineを入れて動かしてみる。

これで、素のredmineが完成するはず。

プラグインをインストールして、
その後、稼働中のredmineのデータをインポートしてみる。

こんな予定。

VirtualBoxでLinuxMint15Xfce版をマルチディスプレイ化

いろいろググッていろんな方法で試しましたが、結局これでうまくいきました。

xrandrを使う方法

ホスト環境 Windows7Pro
ゲスト環境 Linux Mint15 Xfce版(64bit)

VirtualBox仮想マシンの設定
設定 > ディスプレイ > ビデオタブ ディスプレイ数 = 2

これで、まずゲスト環境自体をマルチモニタに接続した状態にする。

続いて、ゲスト環境内での設定。
ゲスト環境内のディスプレイにVBOX0とVBOX1というのが見えればOK
そしてXrandrを使用して設定しました。

設定コマンドを以下のように作成
/usr/bin/xrandr --output VBOX1 --right-of VBOX0

このコマンドを実行するとマルチディスプレイに対応することができました。
ただし、ログアウトすると設定が消えてしまうのでこれを、自動で毎回実行するように設定しました。

設定箇所は、『設定』→ 『セッションと起動』から、『自動開始アプリケーション』タブ内にコマンドを追加しました。

名称等は、適当に設定して上記コマンドを$HOMEにスクリプトとして作成(実行権限を付与、一応)。

これで、ログインしなおしてもうまくいくようになりました。

解像度の追加は、うまくいかなかったのでウィンドウを最大化しておいてシームレスモードにして使用しています。



ついでに・・・シームレスモードで起動できるようにショートカットを作成
"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "仮想マシン名" --startvm "仮想マシンUUID" --fullscreen --seamless
でいけた。

fluentを使ったログ集約

アプリケーションサーバのログを集約するのにfluentを利用してみたのでその備忘録。
構築手順を以下にまとめてみます。

構成

アプリケーションサーバから、各種のログをログ集約サーバへ送信する。
対象となるOSは、AmazonLinux

リポジトリの追加
[treasuredata]
name=TreasureData
baseurl=http://packages.treasure-data.com/redhat/$basearch
gpgcheck=0
ユーザの作成

fludentのユーザを作成します。ユーザ名は、td-agent

# groupadd -g xxx td-agent
# useradd -u xxx -g td-agent -s /sbin/nologin td-agent

udi,gidは各サーバで同一のものを設定する

fluentのインストール

yum .confにプロキシの設定があることを確認
※普通に外へ出れるのなら必要なし。
インストールバージョンは、1.1.13でした。
ltsvを使用したいので、対応したバージョンを導入しました。

# yum install td-agent
プラグインをコンパイルするためのgcc,makeをインストール
# yum install make gcc
fluentdプラグインのインストール
# /usr/lib64/fluent/ruby/bin/fluent-gem update -p http://xxxx.xxx.xxx.xx:yyyy
# /usr/lib64/fluent/ruby/bin/fluent-gem install -p http://xxx.xxx.xxx.xxx:yyyy fluent-plugin-forest
# /usr/lib64/fluent/ruby/bin/fluent-gem install -p http://xxx.xxx.xxx.xxx:yyyy fluent-plugin-config-expander
# /usr/lib64/fluent/ruby/bin/fluent-gem install -p http://xxx.xxx.xxx.xxx:yyyy fluent-plugin-file-alternative
POSファイル用のディレクトリ作成
# mkdir /var/log/td-agent/pos
# chown td-agent:td-agent /varlog/td-agent/pos
ログを読めるように権限設定を変更
# chgrp td-agent /var/log/messages
# chgrp td-agent /var/log/secure
# chgrp td-agent /var/log/cron
# chgrp td-agent /var/log/tomcat/
# chgrp td-agent /var/log/nginx/

# chmod g+rx /var/log/messages
# chmod g+rx /var/log/secure
# chmod g+rx /var/log/cron
# chmod g+rx /var/log/tomcat/
# chmod g+rx /var/log/nginx/
nginxの設定追加

nginxのログをltsv形式で出力するためにログフォーマットに以下を追加

log_format ltsv    'hostname:$hostname'
                   '\ttime:"$time_local"'
                   '\thost:$remote_addr'
                   '\tforwardedfor:"$http_x_forwarded_for"'
                   '\treq:$request'
                   '\tstatus:$status'
                   '\tsize:$body_bytes_sent'
                   '\treferer:$http_referer'
                   '\tua:"$http_user_agent"'
                   '\treqtime:$request_time'
                   '\tcache:$upstream_http_x_cache'
                   '\truntime:$upstream_http_x_runtime'
                   '\tvhost:$host'
                   '\tcookie:"$http_cookie"'
                   '\tut:$upstream_response_time'
                   '\tcs:$upstream_cache_status';
アプリケーションのログを出力する設定

アプリケーション側には、fluent-logger-0.2.6を使用してfluentへ出力する。
ただし、これだけだと使いずらいのでfluent-appenderを使用してlog4jの設定で出力をできるようにしました。

fluent-appenderも以下のように多少手を加えた。
- stackTraceを出力できるようにした。
- ホスト名をログに含めるようにした。
- ミリ秒単位の日時をログへ追加した。

fluentdの設定

送信側の設定の設定は、大体こんな感じ。
サーバ設定

<source>
  type forward
  port 24224   # default
</source>
<match *.**>
  type forward
  retry_limit 5
  flush_interval 5s
  <server>
    host 111.111.111.111
    port 123123
  </server>
</match>

個別の設定
syslogの送信設定

<source>
  type config_expander
  <config>
    type tail
    format syslog
    path /var/log/messages
    pos_file /var/log/pos/messages.pos
    tag ${hostname}/syslog.messages
  </config>
</source>

nginxのアクセスログの設定

<source>
  type config_expander
  <config>
    type tail
    format ltsv
    time_format "%Y/%m/%d:%H:%M:%S %z"
    path /var/log/nginx/vhost.access.ltsv.log
    pos_file /var/log/nginx/vhost.access.ltsv.log.pos
    tag nginx.access.vhost.${hostname}
  </config>
</source>

catalina.outのログ設定

<source>
  type config_expander
  <config>
    type tail
    path /var/log/tomcat/logs/catalina.out
    pos_file /var/log/tomcat/logs/catalina.out.pos
    tag ${hostname}/catalina.out
    format /^(?<message>.*$)/
    time_format "%Y-%m-%d %H:%M:%S %z"
  </config>
</source>


受信側の設定は、こんな感じでやって見ました。まだ工夫の余地があるかも。
syslogの受信設定

<match */syslog.messages>
  type forest
  subtype file_alternative
  <template>
    path /var/log/syslog/messages.%Y%m%d.log
    output_include_time true
    output_include_tag  true
    output_data_type attr:host,ident,pid,message
    add_newline true
    field_separator SPACE
    localtime
    flush_interval 1s
  </template>
</source>

nginxのアクセスログの設定

<match nginx.access.vhost.*>
  type copy
  <store>
    type stdout
  </store>
  <store>
    type forest
    subtype file_alternative
    <template>
      path /var/log/nginx/nginx-vhost-access.%Y%m%d%H.log
      flush_interval 1s
      field_separator SPACE
      localtime
    </template>
  </store>
</match>

tomcatのログの設定

# 追加のアペンダーを出力
<match log4j-appender.*>
  type copy
  <store>
    type stdout
  </store>
  <store>
    type forest
    subtype file_alternative
    <template>
      path /var/log/tomcat/logs/app-common.%Y%m%d%H.log
      output_data_type attr:time,hostname,thread,level,loggerName,message
      add_newline true
      field_separator SPACE
      flush_interval 1s
      time_format "%Y-%m-%d %H:%M:%S.%3N"
      localtime
    </template>
  </store>
</match>
#catalina.out
<match */catalina.out>
  type copy
  <store>
     type stdout
  </store>
  <store>
    type forest
    subtype file_alternative
    <template>
      path /var/log/tomcat/logs/catalina.%Y%m%d.out
      output_include_time true
      output_include_tag true
      output_data_type attr:message
      add_newline true
      field_separator SPACE
      flush_interval 1s
      localtime
    </template>
  </store>
</match>

ひとまず、こんな設定で運用をしてみて様子見です。

AWS EC2へFluentdのインストール

オートスケーリングで追加・削除されるサーバは不特定であるためログの収集もしくは、一定期間前のログが参照できなくなる可能性がある。そのような事態を回避するためにログを外部ストレージへ移動できないかと考えていました。

世の中、便利なものがあるようでしたのでそちらを参考に自分の問題も解消できるか検証してみました。

 

いろんなところで紹介されていますが、自分でもやってみたのでその備忘録。

目的: AutoScalingを使用しているサーバのログをS3へ保存したい。

対象OS: Amazon Linux

 インストール前に…

OS用アカウントにtd-agentユーザを作成

IAMユーザにtd-agentを作成(S3へのアクセス)

 

Fluentdのリポジトリを/etc/yum.repos.d/td.repoへ追加

 

[treasuredata]

name=TreasureData

baseurl=http://packages.treasure-data.com/redhat/$basearch

gpgcheck=0

 

 td-agentのインストール

$sudo yum install td-agent

1.1.11がインストールされました。

 

プラグインをインストール

プラグインは、以下のものをインストールしました。とりあえずは、ログを収集したいのでブログ等で紹介されているものをチョイスしました。

今後、自分に必要そうなものがあれば別途インストールしたいと思います。

 

※参考にした記事:http://dev.classmethod.jp/cloud/amazon-linux-fluentd-setup-plugin/

 

$sudo /usr/lib64/fluent/ruby/bin/gem update

$sudo /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-forest

$sudo /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-config-expander

$sudo /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-tail-multiline

 

ログ収集のために権限を変更

$sudo chgrp -R td-agent /var/log/nginx

$sudo chgrp -R td-agent /var/log/tomcat

$sudo chgrp -R td-agent /var/log/messages

$sudo chgrp -R td-agent /var/log/secure

$sudo chgrp -R td-agent /var/log/cron

 

$sudo chmod -R g+rx /var/log/nginx/

 

$sudo chmod -R g+rx /var/log/tomcat/

$sudo chmod -R g+rx /var/log/messages

$sudo chmod -R g+rx /var/log/secure

$sudo chmod -R g+rx /var/log/cron

 

 

まずは、練習

最近、AWSを利用する機会が増えて、徐々にですがAWSの機能を活用できている気がします。

しかし、自分の能力以上にAWSの進歩が早く追いつきません。。。

 

やはり、理解を深めるためにも業務内・外でやったことをアウトプットして移行と一念発起しました。

今後は、技術的なまとめを溜めていけるようがんばろうと思います。