Chefで既存手順のレシピを書く4(DBサーバ)

おつかれさまです。小宮です。

前回に引き続きdbserverのレシピについて書いていきます。
のこってるのはmunin、zabbxとserverspecでのテストだけです。もうすこしの辛抱です。

webと同じくバージョン固定インストールなので、外部レシピは基本的に使わない方向とする

・mysqlのインストールと起動と自動起動の有効化

[shell]# cd /root/chef-repo/site-cookbooks/mysqld/recipes

mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms

mkdir -p ../templates/default/etc/init.d

mkdir -p ../files/default/etc/init.d

mkdir -p ../files/default/root

mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/etc/logrotate.d

mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/opt/{backup,bin}

scp -Cp xxx-db02:/opt/bin/mysql-back.sh /root/chef-repo/site-cookbooks/mysqld/files/default/opt/bin/

cp -p /etc/logrotate.d/mysqld /root/chef-repo/site-cookbooks/mysqld/files/default/etc/logrotate.d/

scp -Cp xxx-db01:/etc/init.d/mysqld ../files/default/etc/init.d/

scp -Cp xxx-db02:/etc/my.cnf ../templates/default/etc/

cp -p /root/.path_to_file ../files/default/root/

cd /opt/src/rpms/

tar czf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-rpm.tar.gz ./db-rpm/

tar czf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-tools-rpm.tar.gz ./db-tools-rpm/

tar tzf /root/chef-repo/site-cookbooks/mysqld/files/default/usr/local/src/rpms/db-rpm.tar.gz

vi ../templates/default/etc/my.cnf

diff /etc/my.cnf ../templates/default/etc/my.cnf

53c53

< server-id = 100

server-id = <%= node[‘mysqld’][‘server_id’] %>

vi ../../../nodes/10.0.0.241.json

↓nodeにserver_idのattributeを書いときます(server_idはレプリケーションするnode毎に変える必要がある為 { “mysqld” : { “server_id” : 103 }, “run_list”:[ “role[dbserver]” ] }

cd /root/chef-repo/site-cookbooks/mysqld/recipes

vi mysqld-server.rb

package “perl-DBI” do not_if “rpm -qa|grep perl-DBI” action :install end

package “perl-TermReadKey” do not_if “rpm -qa|grep perl-TermReadKey” action :install end

cookbook_file “/tmp/db-rpm.tar.gz” do source “usr/local/src/rpms/db-rpm.tar.gz” mode 0644 end

cookbook_file “/tmp/db-tools-rpm.tar.gz” do source “usr/local/src/rpms/db-tools-rpm.tar.gz” mode 0644 end

filename = “db-rpm” filename2 = “db-tools-rpm” script “install_mysqld” do not_if ‘rpm -qa|grep mysql-server’ interpreter “bash” user “root” code «-EOL cd /tmp tar xzf /tmp/#{filename}.tar.gz rpm -i /tmp/#{filename}/_rpm rpm -i /tmp/#{filename}/5.5.27/mysql_rpm tar xzf /tmp/#{filename2}.tar.gz rpm -i /tmp/#{filename2}/m*rpm EOL end

cookbook_file “/etc/init.d/mysqld” do source “etc/init.d/mysqld” mode 0755 end

template ‘/etc/my.cnf’ do owner ‘root’ group ‘root’ source ’etc/my.cnf’ end

service “mysqld” do supports :status => true, :restart => true, :reload => :true action [ :enable, :start ] end

cookbook_file “/etc/logrotate.d/mysqld” do source “etc/logrotate.d/mysqld” owner ‘root’ group ‘root’ mode 0644 end

directory ‘/opt/bin/’ do owner ‘root’ group ‘root’ mode ‘0755’ action :create end

directory ‘/opt/backup/’ do owner ‘root’ group ‘root’ mode ‘0755’ action :create end

cookbook_file “/opt/bin/mysql-back.sh” do source “opt/bin/mysql-back.sh” owner ‘root’ group ‘root’ mode 0755 end

#cron “mysql-backup” do

minute “31”

hour “4”

day “*”

month “*”

weekday"*"

command “/opt/bin/mysql-back.sh”

action :create

#end[/shell]

・mysqlのユーザ作成
opscodeのレシピは初心者には読むのとエラーのデバッグが大変なので使わないことにしました。
参考:
ChefでMySQLをインストール
ChefでのMySQLパスワードの扱い
今日から使い始めるChef
chef で mysql のユーザやデータベースを管理する

[shell]# vi site-cookbooks/mysqld/recipes/mysql-users.rb #include_recipe “openssl” #include_recipe ‘database::mysql’

#mysql_connection_info = {:host => “localhost”,

:username => ‘root’,

#:password => node[‘mysql’][‘server_root_password’]}

:password => ‘’}

#mysql_database “xxx_db” do

connection mysql_connection_info

action :create

#end

xxxadm_data = Chef::EncryptedDataBagItem.load(“mysqlusers”,“xxx_admin”) root_data = Chef::EncryptedDataBagItem.load(“mysqlusers”,“root”) repl_data = Chef::EncryptedDataBagItem.load(“mysqlusers”,“repl”) myuser_o = xxxadm_data[“user”] mypass_o =xxxadm_data[“pass”] myuser_ro = root_data[“user”] mypass_ro =root_data[“pass”] myuser_re = repl_data[“user”] mypass_re =repl_data[“pass”] #mysql_database_user “#{user}” do

connection mysql_connection_info

password “#{password}”

database_name “*”

host “[#{host}, %, localhost]”

privileges [:all]

action [:create, :grant]

#end # mysqlconn = “mysql -u root” script “create_msql_xxxadm” do not_if “ls /root/.path_to_file” #not_if “#{mysqlconn} -p #{mypass_ro} -e ‘select count() from mysql.user where user=\‘repl\’;’” interpreter “bash” user “root” code «-EOL #{mysqlconn} « EOF grant all privileges on *. to #{myuser_o}@’%’ identified by “#{mypass_o}”; grant all privileges on . to #{myuser_o}@‘10.0.0.%’ identified by “#{mypass_o}”; grant all privileges on . to #{myuser_o}@’localhost’ identified by “#{mypass_o}”; grant all privileges on . to #{myuser_ro}@‘10.0.0.%’ identified by “#{mypass_ro}”; grant all privileges on . to #{myuser_ro}@’localhost’ identified by “#{mypass_ro}”; grant replication slave, replication client on . to #{myuser_re}@‘10.0.0.%’ identified by “#{mypass_re}”; grant replication slave, replication client on . to #{myuser_re}@’localhost’ identified by “#{mypass_re}”; drop database test; delete from mysql.user where password=’’; flush privileges; EOF EOL end

script “create_pfile” do not_if ’ls /root/.path_to_file’ interpreter “bash” user “root” code «-EOL echo “#{mypass_ro}” > /root/.path_to_file chown 400 /root/.path_to_file EOL end[/shell] ※EOFが行頭じゃないとエラーでます。

・replication構築のレシピ(テストできてないので注意)

まだテストはできていないのですが、実際の手順をレシピ化するにはどうしたらいいか考えてみたところ以下のようになりました。
 bashでやるしか思いつかない。
 サードパーティのレシピを調べて完全に解読するのは時間がかかりそうで
 理解してないものを使うのは大変危険な行為なのでとりあえずそれでいくことにする。
  stgサーバでバックアップとってるのはstgのdbなのでそれは使わず、
  db02とかで取ってる最新のdumpファイルをremote_fileとかで持ってきて投入して、
  移行に使うかもしれないためmaster-data=2でとってるデータなので、
  dumpファイルに入ってるGHANGE MASTER TO構文をzgrepとかで抽出して変数に入れて
  mysql -eとかで変数渡してマスタを見させて読み取り専用有効にして、
  replicationスタートする感じになるのかと思われる
  とりあえずreplication_setup.shとか作って実行させる方向で。
  allで取ってるデータ入れるんだったらmysqlスキーマでユーザも丸ごと入るから、、
   databagsで暗号化とかしなくてもよかったのかもしれない。(いまさら)

レプリケーションセットアップするシェルを書く
[shell]# vi replication_setup.sh ——————————- #!/bin/bash

BACKUP_SRV='10.0.0.222'
BACKUP_PATH='/opt/backup'
BACKUP_FL='mysqldump_3306_&quot;`LANG=C;date +%y%m%d`&quot;.sql'
MSQL_USER=root
MSQL_PASS=`cat /path_to_file`
MSQL_CONN=&quot;mysql -u ${MSQL_USER} -p${MSQL_PASS}&quot;
MSQL_CMD_RO='set global read_only=1;'
#MAIL_TO='hoge@isao.co.jp'
MAIL_TO='hoge@isao.net'
MYHOST=`uname -n`
DATETIME=`date +%Y%m%d_%H:%M:%D`

if [ -s /tmp/${BACKUP_FL}.gz ];then
 :
else
 echo &quot;replication setup faild&quot;|mail -s `uname -n`_`date +%Y%m%d_%H:%M:%S` ${MAIL_TO}
 exit 0
fi

gunzip /tmp/${BACKUP_FL}.gz
${MSQL_CONN} &lt; /tmp/${BACKUP_FL}
CHANGE_MASTER=`cat /tmp/${BACKUP_FL}|head -30|grep 'CHANGE MASTER TO'|sed -e 's/^-- //g'`

${MSQL_CONN} -e &quot;stop slave;&quot;
${MSQL_CONN} -e &quot;${CHANGE_MASTER}&quot;
${MSQL_CONN} -e &quot;${MSQL_CMD_RO}&quot;
${MSQL_CONN} -e &quot;start slave;&quot;

echo `${MSQL_CONN} -e &quot;show slave status\G&quot;`|mail -s `uname -n`_`date +%Y%m%d_%H:%M:%S` ${MAIL_TO}

exit 0
-------------------------------

chmod +x replication_setup.sh

mkdir /root/chef-repo/site-cookbooks/mysqld/files/default/tmp

mv replication_setup.sh /root/chef-repo/site-cookbooks/mysqld/files/default/tmp/[/shell]

<br>
uriとかでないのでremote_fileを使えないし権限的に新規サバからscpで取りに行くのは無理なので、<br>
stgから毎日取りに行くことにしたほうがいいのかも<br>
それとも鍵認証セットアップのレシピを書いて先に実行させる感じにしようかどうしようか。<br>
<br>
とりあえずstgから毎日取りに行くことにする<br>

[shell]# mkdir -p /root/chef-repo/site-cookbooks/mysqld/files/default/opt/{backup,bin}

vi /opt/bin/get_dbbkup.sh

-------------------------
#!/bin/bash

CHEF_BKUP_PATH=/root/chef-repo/site-cookbooks/mysqld/files/default/opt/backup
BACKUP_SRV='10.0.0.222'
BACKUP_PATH='/opt/backup'
BACKUP_FL='mysqldump_3306_&quot;`LANG=C;date +%y%m%d`&quot;.sql'
scp -Cp root@${BACKUP_SRV}:${BACKUP_PATH}/${BACKUP_FL}.gz ${CHEF_BKUP_PATH}

exit 0
-------------------------

chmod +x /opt/bin/get_dbbkup.sh

crontab -e

crontab -l

--------------
# get db backup data for chef slave setup.
0 6 * * * /opt/bin/get_dbbkup.sh &gt; /dev/null 2&gt;&amp;1
--------------[/shell]
<br>

レプリケーション停止検知スクリプトをfilesに置いとく
[shell]# scp -p xxx-db02:/opt/bin/rep_fail_mail.sh /root/chef-repo/site-cookbooks/mysqld/files/default/opt/bin/[/shell]
レプリケーションセットアップ用レシピを書く
[shell]# cd /root/chef-repo/site-cookbooks/mysqld/recipes

vi replication.rb

----------------------------
dumpfile = mysqldump_3306_&quot;`LANG=C;date +%y%m%d`&quot;.sql
cookbook_file &quot;/tmp/#{dumpfile}.gz&quot; do
  source &quot;opt/backup/#{dumpfile}.gz&quot;
  mode 0644
end

script &quot;setup_replication&quot; do
  interpreter &quot;bash&quot;
  user        &quot;root&quot;
  code &lt;&lt;-EOL
    /tmp/replication_setup.sh 
  EOL
end

cookbook_file &quot;/opt/bin/rep_fail_mail.sh&quot; do
  source &quot;opt/bin/rep_fail_mail.sh&quot;
  mode 0755
end

cron &quot;rep_fail_mail&quot; do
  minute &quot;0-59/15&quot;
  hour &quot;*&quot;
  day &quot;*&quot;
  month &quot;*&quot;
  weekday&quot;*&quot;
  command &quot;/opt/bin/rep_fail_mail.sh&quot;
  action :create
end
----------------------------[/shell]

・HAの構築設定に関して

社内で利用されているのは主に3タイプあり、Heartbeat連携、MHA、VIP手動切替。
で、今回はVIP手動切替(一番ダウンタイムが長くデータロストが発生しやすい残念なタイプ)となる。
3台目以降のDBにVIPを付ける必要性は特に感じられないが、2台とも壊れたときの為に
念のためVIP付与スクリプトを転送だけするレシピを用意しておくことにする。(ロールには入れない)

[shell]# scp -Cp xxx-db02:/opt/bin/eni_vip_up.sh /root/chef-repo/site-cookbooks/mysqld/files/default/opt/bin/

# vi vip-attach.rb

cookbook_file “/opt/bin/eni_vip_up.sh” do source “opt/bin/eni_vip_up.sh” mode 0755 end

#script “eni_vip_up” do

interpreter “bash”

user “root”

code «-EOL

/opt/bin/eni_vip_up.sh

EOL

#end —————————–[/shell] ※間違ってロールに入れてしまったときのために転送したスクリプトの実行はコメントインしておく

クックブックのシンタックステスト
[shell]# knife cookbook test mysqld[/shell] FATAL:エラーがでなければOKと思われる

今回はここまでです。長々読んでいただいてありがとうございました。
次回はmuninとzabbixのレシピになります。