MySQL Beginners Talk #1に参加してきたので、そのメモ
参加してきました。思い切りそのままメモ転載。
初心者向けMySQLの始め方 - tmtmsさん
- MySQLはオープンソース(GPL)なRDBMS
- たいていのLinuxには含まれている
- 今なら5.5系を使いましょう
- 公式バイナリを使うのがいい
- 設定ファイル(my.cnf)は読まれる場所は全部読まれて、あと勝ちになるので注意が必要
- skip-name-resolve, innodb-file-per-tableとかshow-warningsとか
- skip-name-resolveをしておくと、クライアントが接続してきたときに逆引きしなくなる
- mysqld_safeは最近は安定しているので使わなくてもいいと思う
- kill -9 はダメ、絶対!
- 待受ポートはTCP:3306とUNIX Socket:/tmp/mysql.sock
- localhostとの接続にはsocketを使う
- パスワードの設定はプロンプトの画面で set password [for user@host] = password('hogehoge');
- -pの後ろに空白は要らない
- (初期状態では)匿名ユーザ(適当な名前のユーザ)はパスワードなしでtest DB(information_schema)にアクセスできる
- 気持ち悪いので消しておいたほうがいい(基本的には自分自身からしか繋げないけど)
- root@localhostだけ残して消しても問題ない
- たいていは grant all on DB名 to user@host; で権限を与えれば良い
- 細かくもできるがDB単位くらいで
- 127.0.0.1とlocalhostは違うよ!
- 日本語
- 初心者は黙って utf8
- [mysqld] character-set-server = utf8 / [mysql] default-character-set = utf8
- アプリなどは、それぞれで指定
- 初心者は黙って utf8
- charset と collation
ORACLEさん、ハイパー宣伝タイム
MySQLインストールお作法 - @meiji さん
- あまりよく考えずにソースからインストールするのはやめましょう
- 本に書いてあるからってダメ!絶対!
- 公式のバイナリがいいよ
- RPM全部入りのやつもあります
- Windowsはbitを気にすればいいだけ
- インストール時のcharset周りのpath周りだけ気をつけてね
- データとバックアップ/バイナリログは別の場所(ディスク)にしておこう
MySQL日本語利用徹底入門 - @nippondanjiさん
- 文字コードとは
- 文字を符号化したもの
MySQLと文字コード
- 複雑
- 文字コードの実装が柔軟だから
- utf8mb4
- JIS X 0213:2004
- 照合順序
- 文字の並び順
- ソートや比較の処理に影響
- show collation
- 文字コードがセッションごと/テーブルごと/カラムごとに異なるかも
- 照合順序の指定
- カラムであればcollate utf8_binのように指定
- 確認方法
- 文字コード関連のオプション
- character_set_server
- character_set_database
- character_set_connection
- character_set_client
- character_set_results
- クライアントに返される結果に含まれる文字コード
- character_set_system
- character_set_filesystem
- default_character_setはserver側の文字コード指定では使えない(MySQL5.5以降)
- クライアント側では使える
文字コード関係のトラブル
まとめ
- 自動変換が起こらないようにする
- 迷ったらすべてutf8いで統一する
- showコマンドやinformation_schemaで色々捗ります
- 鍵本が近日増刷予定!
LTセッション
studio0340_comさん
- スロークエリどうにかならない?
- innodb_buffer_poolを増やして対応
- 本当に改善って言っていいの?
- innodb_buffer_poolを増やして対応
- インデックス使っていないスロークエリを探せ!
- min_examined_row_limit
- 指定行以上のテーブルから読み込んだクエリをスロークエリに記録する
これがデフォルト10000行以上デフォルト値は0なので記録されない。潜在的な性能劣化をさせる危険性を秘めているクエリを見つけるために10000行とかにしておく。ただ、これを超えないと記録されないので、値の設定は吟味が必要。
- min_examined_row_limit
- mysqldumpではまった
- ダンプ中に更新が走ったものは、その間(ロックされている間)は更新されない
- dump-slave
- ダンプ中はreplicationが止まる!
- パッチができて、対応(実際はFlush logsに関するもの)
Beginnerならきっと役立つMaster-Slave環境 - @yut148さん
- Paasで無料なのもあるよ!
- ただ使うだけなら自前で環境作らなくてもよいのではないかということ
- 流れるデータには注意
MySQL Casual Talks - @myfinderさん
1台から500台までのMySQL運用(Beginners編) - @kazeburoさん
- Livedoorは基本的には開発者がサーバを見てきた
- サービスごとに差が生まれる
- いくない
- 仮想化によるサーバ集約で4桁台あったサーバが400台に
- 基本的にはMySQL 5.1.x
- 必ずinnoDB-pluginを使う
- Fast Index Creation 様さま!
- 必ずinnoDB-pluginを使う
- my.cnfを共通化
- セットアップツールの提供
- よくあるチューニングを施してある
- セットアップツールの提供
- my-moder.cnf
- 標準のはいまいち
- オレオレmy.cnfに自身がある人いない?
- No MyISAM
- 絶対に使わない
- kill -9 しても壊れない
- xtrabackup
- ログ系のテーブル
- Expire処理を忘れるとひどいことに
- 必ず消すことを忘れないように!
- 件数が多くなると、削除するほうが大変です!削除戦略をしっかり立てておきましょう。
- Expire処理を忘れるとひどいことに
- モニタリング
- 必須です
感想など
@tmtmsさんのお話は、初めて触る方がどんなことに注意しながら使っていったらよいかという視点で、実際に動かしてある程度何かをしてみるまでの導入部分をすべて網羅しているんじゃないかなと思いました。自分のように触り始めてある程度たった人でも、基本的な部分を見なおしてみるのにはすごくいい機会になりました。
さすがに@nippondanjiさんの話はBeginnerの枠を超えていたような気がしなくも無いですが、最初に文字コード周りの話を理解しておくことでハマりポイントを減らすことができるので、いいですね。さすがエンジニア目線だけでなくサポート目線も持っている方だなぁと、あっけにとられながらも勉強させていただきました。鍵本は増刷されたらぜひとも購入させていただきたいと思います(まだ買ってないのかなんて言わないで><)。
自分は大規模なサービスでMySQLを使ったことが無いですし、ガチなチューニングなんかもしたことがないので、ペラッペラな知識や経験しかないのですが、こういった基礎的な部分を再確認させてもらえる機会があったのはすこくプラスになりました。ガチュアルと呼ばれる人たちに少しでも近づけるよう、最低限基礎は染み込ませておきたい。
追記
- 2012.06.11コメントでの指摘を受けて min_examined_row_limit のところを修正
CloudWatchからAWSの費用を視覚化してみた(の補足的情報だけ)
お久しぶりのエントリは、「Estimated Charge with CloudWatchを試してみました « サーバーワークス エンジニアブログ」こちらの記事をパクリ参考にさせていただきました。
詳しくは、サーバーワークスさんのブログエントリを参照してもらえば問題ないのですが、ちょっとはまったところがあるのでその点について触れておきます。
ハマったポイント
口座番号は整数で。
元記事やgistのソースでは、
ACCOUNT_NUMBER = 'YOUR_ACCOUNT_NUMBER'
のように示されているので、口座番号(Account Number)を文字列として定義してしまっていましたが、それではうまく動かずかなりハマりました。口座番号は整数で以下のように書きましょう。
ACCOUNT_NUMBER = 123456789012
dimentionsのLinkedAccountはConsolidated Billingを利用しており、かつ個別のアカウントの金額を取得したい場合のみ
こちらもハマった点。個人用アカウントは特に別アカウントがあるわけではなく、Consolidated Billing (複数アカウントの一括請求)を使っていないので、そもそも 「LinkedAccount」というdimentionは存在しないようだ。さらには、Consolidated Billingを使っている場合でも、全アカウントのトータルコストを取得したい場合には、LinkedAccountを指定してはいけない。
Consolidated Billingを使用していない、または、Consolidated Billingを使っていて合算した費用が知りたい場合
下のように、dimentionsには{"Currency"=>"USD"}のみを指定する。
data = acw.get_metric_statistics(options={:dimentions => {"Currency"=>"USD"}, :measure_name => "EstimatedCharges", :namespace => "AWS/Billing", :start_time => starttime, :end_time => endtime, :period => 86400})
Consolidated Billingを利用していて、個別アカウントの費用が知りたい場合
こちらは、サーバーワークスさんの例の通り、LinkedAccountを指定する。
data = acw.get_metric_statistics(options={:dimentions => {"LinkedAccount"=>ACCOUNT_NUMBER, "Currency"=>"USD"}, :measure_name => "EstimatedCharges", :namespace => "AWS/Billing", :start_time => starttime, :end_time => endtime, :period => 86400})
グラフを重ねる
元記事の方で使われているグラフライブラリのGruffは簡単にグラフを重ねられるので、トータル(LinkedAccount指定なし)と個別アカウント1と個別アカウント2をまとめてグラフ化なんてことも楽チン。
それぞれの金額遷移のリストを取得しておいて、以下のようにするだけ。
total_charge_list = 取得処理やらソート処理 acc1_charge_list = 取得処理やらソート処理 acc2_charge_list = 取得処理やらソート処理 graph_file = "#{Time.now.strftime('%Y-%m-%d')}-charge_graph.png" g = Gruff::Line.new g.title = "AWS Cost" g.marker_font_size = 15 g.data("Total", total_charge_list) g.data("account1", acc1_charge_list) g.data("account2", acc2_charge_list) g.labels = {0 => '5days ago', 1 => '4days ago', 2 => '3days ago', 3 => '2days ago', 4 => 'yesterday'} g.write(graph_file)
これで、3つの線グラフを重ねたpngファイルが作成されます。簡単ですね。
最後に
参考にさせていただいたサーバーワークスさん、本当にありがとうございました!これで色々はかどります。
あと言いたいこととして、PythonのAWS APIライブラリのbotoは非常に素晴らしいのですが、CloudWatch周りだけはいかんせん弱い。というか、EC2用の機能の一部としてしか提供されていないので、EC2インスタンスに関する値しか取得できないのです。どうか、boto.ec.cloudwatchのような形ではなく、boto.cloudwatchのような感じで、全namespaceを扱えるようにしていただけると更にはかどって仕方なくなります。
CloudWatch周りの何かをするときだけPHPのSDKを使ったり、今回はRubyのSDK(というよりはRightScaleのライブラリ)を使っているので、全く統一感がなくてよろしくないなあと思いつつも色々手を出してみているのが現状です。
それでは、botoがCloudWatchのすべてのnamespaceを扱えるようになることを祈りながら、今日はこのへんで。
※間違いなどありましたら、ご指摘ください。
Mercurialの名前付きブランチを試してみた
連投ですが、hbstudy #33のMercurialハンズオンで課題として挙がっていた、名前付きブランチを簡単にですが試してみました。
※defaultブランチは、ハンズオンの中で使っていたものをそのまま使っています。
名前付きブランチを作る
$ hg branch test_named_branch
適当にファイルを更新してコミット
$ vi glossary.rst $ hg commit -m "modified glossary.rst"
リポジトリサーバにpush ※新しく作ったブランチをpushするときは --new-branch が必要
$ hg push http://localhost:8000 --new-branch
再び適当に編集してコミット
$ vi glossary.rst $ hg commit -m "add contents to glossary.rst"
defaultブランチとコンフリクトするように編集してコミット
$ vi remote.rst $ hg commit -m "modified remote.rst"
変更内容をpush
$ hg push http://localhost:8000/
defaultブランチに切り替え
$ hg update default
変更内容をpull ※updateをしても特にファイルに変更は生じない
$ hg pull http://localhost:8000 $ hg update
ブランチの内容をマージ
$ hg merge test_named_branch
コンフリクト内容を解決
$ hg resolve --list $ vi remote.rst $ hg resolme --mark remote.rst
マージした内容でリポジトリサーバにpush
$ hg commit -m "merged test_named_btanch to default branch." $ hg push http://localhost:8000/
こんな感じで簡単にブランチ作成やブランチでの変更作業、切り替え、マージなどができました。
うん、簡単。
hbstudy#33のMercurialハンズオンに参加してきました
はい、とてつもなく久しぶりのブログです。最近ブログネタになるようなことをほとんどしていませんです。
4/28(土)に開催された hbstudy #33 に参加してきたので、レポート的なものを書いておこうかと思います。
バージョン管理の必要性
- ファイルの変更の5w1h(いつ、どこで、だれが、何を、なぜ、どうやって)がわかる
バージョン管理が必要なファイル
- サーバの設定ファイル
- デプロイスクリプト
- 環境構築のためのプロビジョニングスクリプト
- ドキュメント
など編集するものすべて
バージョン管理すると
- 変更の経緯がわかる
- セットアップが職人技じゃなくなる
- どのファイルが変更されたかすぐにわかる
- .bakとかできなくなる
- 心の平穏w
インフラ向きのバージョンな管理システムは
- git
- [o] 手軽にバージョン管理
- [o] 他のサーバと履歴を共有
- [o] チェンジセット
- [o] ブランチ
- [x] コマンド体型が他と違う(モヒカン向け)
- [x] Windowsで使うにはmsysが必要
- Mercurial
- [o] 手軽にバージョン管理
- [o] 他のサーバと履歴を共有
- [o] チェンジセット
- [o] ブランチ
- [o] Windowsサポート
- [x] githubをサポートしていない
どこででも使えるMercurialいいよ!!
癖も少ないし!
Mercurial
- Mercurial = 水銀
- なのでコマンドは hg (元素記号)
分散バージョン管理システム
- 手軽にバージョン管理
- あとからサーバを準備して、他サーバとの共有も可
- ローカルコミット
- ネットワーク・アンリーチャブルでも使える
- 手軽なブランチングと安全なマージ
- コミット済みの変更をマージするので安心
特徴
- gitに比べてシンプル
- リビジョングラフがすべて
- 分岐はブランチ
- エクステンション
- pythonで拡張可能
- 便利な機能はエクステンションなので、有効にしないとダメ(同梱されているものもすべて無効化されている)
- 履歴改変系もエクステンション
- 安全な履歴管理
- 履歴は神聖
- 改変可能かどうかを示す phase という安全弁
- 危険な履歴改変はエクステンションを有効にする必要あり
- rebase, transplant, mq
履歴改変
履歴改変はpushしていないもののみ可能 → push 後は誰が触っているかわからない
- コミットログをあとから変更
- コミット忘れの追加など
- コミットを移動する
用語など
資料を参照
ハンズオン
各自で進めましょう!
- 課題のダウンロード
- おすすめ.hgrcをベースに.hgrc設定
- 基本操作
- リポジトリサーバを使う
基本操作
- Blockdigのリポジトリをcloneして、ログやリビジョングラフを見てみる
- 深夜2時過ぎにcommitしてる!
- 課題用ディレクトリでリポジトリを作成
- hg init
- 今あるファイルをリポジトリに追加
- status -> add -> status -> commit -> status
- 少しずつファイルを変更しながら、コマンドの使い方を覚える
- 編集 -> diff -> status -> commit
- (直前の)コミットの取り消し
- commit -> rollback -> revert
- 直前以前のコミットを取り消すにはbackuoutを使う
- commit -> rollback -> revert
- マルチプルヘッドを作る
- prarentsで現在のリビジョンを確認(Nとする)
- 編集 -> commit -> update N -> 編集 -> commit -> update N -> 編集 -> commit -> glog でリビジョングラフを確認
- マルチプルヘッドをマージ
- merge
- ヘッドが3つ以上ある場合は merge REV のようにリビジョン番号を指定する
- マージしたらコミット
- マージツールが起動してしまう場合は update --clean で元に戻して、 merge --tool=internal:merge をする
- merge
- マージの取り消し
- update --clean
第1回 アマゾン ウェブ サービス(AWS)オープンセミナー@VOYAGE GROUP に参加してきました (2012/03/21)
最近めっきりブログを書かなくなってきていますが、とりあえず生きています。
ただ、ちょっと業務に追われてブログに書けるネタが無かったくらいです(´;ω;`)
先日、2012年3月21日に開催された、「第1回 アマゾン ウェブ サービス(AWS)オープンセミナー@VOYAGE GROUP」に参加してきたので、そのレポート的なものを。
ustされてたんだから、書いても大丈夫だよね?
開始時刻を間違えていて遅刻したので途中からです。
間違いなどありましたら、ご指摘ください。
事例とデモで学ぶはじめてのAWS -アマゾンクラウドの最新動向-
AWSの大谷 ( @shot6 ) さんによる発表。(多分)初めて大谷さんの実物を大谷さんとして認識して見たのが、この時。
事例: netflix
- ビジネスアジリティを優先事項と考えてAWSを採用
- DCを利用していると、サービスの成長にDCの成長が追いつかない
- 工夫(独自paasを構築)
- ミドルティアロードバランサ
- リージョン間レプリケーション
- 映像のマスターテープのデータはS3に
- そこから各種デバイス向けのencodingはEC2で
AWSの意義
改善 + 革新
質疑応答
- EMRのデータをS3に上げるときは50MBからいのチャンクにしたほうが早い(アップロードは)。
- 解析は大きなデータのほうがいい。
実例で学ぶAWS -オーディエンスデータプラットフォームcosmiを例に-
主催のadingoの中の人、岩川さんによる発表
クックパッドはAWSで動いてます
クックパッドの成田 ( @mirakui ) さんのよる発表。
画像配信、サイト高速化を担当しているとのこと。
AWSへの移行
- バレンタイン対策(一番少ない時の倍くらいのアクセス)
- 当時インフラエンジニアが二人
- 今は五人
- 3倍ルール(3倍は耐えられる様にしておく)
- 物理ハードの面倒だけで、他にやりたいことができない。
- 今は物理サーバはない!
- リソースあたりのコストは増
- 箇条投資がなくなったので、結果あまり変わらず
- 物理作業からの開放
- ビジネススピードアップ
利用方法
- Base AMI + puppetで構築
- tofu(自作)でサムネイル作成
- 画像はすべてS3に
- 何がすごいって、S3がスゲー!
- 画像はすべてS3に
- R53(・∀・)イイ!!
質疑
- Q: Cloud FrontではなくAkamaiなのはなぜ?
- A: その時はAKAMAIのが早かったし、ずっと使っていてノウハウがあったから。価格としても、性能の割には安い。
- Q: R53がなぜいい?
- MySQLスナップはどれくらいの頻度?取る時にはサービスはどうしてる?
- A: 一日均等に4回。スナップを取る専用のスレーブがあって、スナップ取得時にはデーモンを止めて、レプリケーションも止める。
- Q: ネットワークまわりのトラブルはある?
- A: これまでは特にない。インスタンスがいきなり死ぬほうが多い。結構頻繁に。DBマスタに起きたこともあるけど、マルチマスタ構成にしたりしているから、長時間の停止はない。
HerokuはAWSで動いてます
Herokuエバンジェリストの相澤さんによる発表。
話したいことがたくさんあったらしいが、ustされていたため口を閉ざしてしまわれた。残念。
Herokuの構成
サポート
Herokuは基本英語での対応だが、ayuminさんに連絡すれば、日本語で対応してくださるとのこと。
質疑
- Q: 東京リージョンは?
- A: テクニカルには動かせるが、様々な政治的理由がある。あとはどれだけ使ってもらえるか。お金を払ってくれるユーザさんの声が鍵。
odstudy 2012.02 「エンジニアのための提案力向上セミナー」 in qpcon のメモ
2012.02.25のqpstudy系の勉強会が一同に介したカンファレンスに参加してきました。その中で聴講した odstudy の「エンジニアのための提案力向上セミナー」のメモです。ほとんど書き写しになっちゃいましたが、そこはまとめ力のない私を笑って済ましていただければとw
話者
- teian-lab 式町久美子さん (APMP)
teian-lab
- 提案力を高めたいヒトタチによる提案力を高めるための勉強会
- いろんな業界/業種でノウハウ、経験を共有
- 内容
- 提案書の書き方
- 提案計画の仕方
- プレゼンテーション
- 大事にしたいこと
- 頑張り過ぎない
- 自分もみんなも楽しむ
どのような提案?
- 上司への改善提案
- お客様への提案
- コンペ
- どう考えても負け試合になりそうな場合とかにどう対応していくか
- 将来チェレンジしてみたいこと
どうやって書くの?
- 提案戦略
- エグゼクティブサマリー
- ストーリーボーディング
- FAB (Feature, Advantage, Benefit)
提案戦略
- 説明が通じない
- 的を外す/話す相手を間違える
- いつも話している人(現場)のレベルに合わせるのではなく、その上司(決済者)に届くように
- 承認を得られない
- 伝え方がよくないのかも
戦略策定
- 優位性
- 自分の提案でなければならない理由を見つけて伝える
- 調整
- 提案相手を取り巻く環境
- プロジェクト名、背景、ニーズなど
- 社内の場合は、どういう経路でニーズが生まれているか(誰の要望が背景にあるか)とか
- 強み・弱み分析
- 自社/競合
- 自社でなければならない理由
- ディスカウントできないときに、ギャップを埋めるために何ができるか
- 要求を満たすためにできること
- 優位性を導き出す
- プロジェクト管理とか
- どれだけ相手を理解しているか
- 伝えるべき相手
- 立場に寄って関心事が違う
- 誰に提案をするのか
- 技術のわからない人に、細かい技術を説明するのはNG.Issueをどれだけ満足させられるか、予算はどれくらいか
- ホットボタン
- 顧客にとって最も重要なこと
- 伝えるべき相手
エグゼクティブサマリー
- 短時間で提案内容が理解できるもの
- ココだけ読めば8割のない様が理解できる
- 全ページの1割以内
- お客さんと相談しながら作ると良い
ベネフィット
- お客さん目線のベネフィット
ポイント
- 相手の要求にダイレクトな答えが出せているか
- 他社との違いが明確に打ち出せているか
- 製品の機能や使い方だけの説明になっていないか(自分主体の言葉)
- 相手主体の言葉を使う
ストーリーボーディング
伝わりやすいストーリーを書き始める前に考える
- ホットボタンや評価基準への答えをわかる位置に見せる
- 1章で要求に対する回答をまとめておく
- ちゃんと内容の整合性があるか
- 2章以降で話す詳細説明が、1章で伝えたissueへの回答から外れることがないか
- 資料を作る人の間での連携
- 1枚は「必ずこれを入れるべき(1章との整合性の担保)」を指定しておく
執筆者向けガイド
- テンプレートを作って渡す
- ここにベネフィットを書くなど
- RFPから外れることが無いように必須要件は記載しておく
読み手を惹きつける
- ベネフィットから書く
FAB (Feature Advantage Benefit)
- 特徴
- 利点
- 利益
相手にとってのベネフィットを先に述べる
- 固有の問題解決に対してどう役立つか
- 仕様から書かない
- エンジニアは仕様から書きがち
- 何が得なのかは理解されない
質問
- 技術的な内容ではなく、金額で決まってしまう場合にどういう提案の仕方がいいのか?
- 自分たちでなければならないような関係を作るように、そういうアクションを会社全体で作っていく。
- この技術でないとお客さんの要求が満たせないというような関係を作れるか
- ここはちょっと質問者が求めてる回答とは違ったような空気だった。
- 仕事をしてる時に気をつけていること
- お客さんの状態を事実に基づいて判断したいので、営業さんにそれが本当に事実なのか(営業フィルタがかかっていないか)を聞き出すようにする
- チーム全体(営業、SEなど話を聞いてきた人+それ以外の人)で要求を共有するようにする
まとまらないまとめ
- 自分のやったことをアピールする発表と違って、「提案」は相手からの「要求」があってそれに対する「回答」である
- 自分(たち)がやったこと/できること(仕様)を事細かに説明するのは、要求者側からするとあまり意味のあるものではない
- 誰に対して(現場の人間だけではなく、決済者全員)響く内容にするかが重要
- 何よりも、「要求」に対する「回答」を全面に押し出して、わかりやすく伝える
- 「回答」の中にはFABを含める
- ヒアリング内容に個人のフィルタがかからないように、要求を聞くときは立場の違う複数人(営業とSEとか)で聞き、帰社後に関係者全員で共有することで認識のズレが起こらないようにする。
といったところでしょうか。
自分は対お客さんに提案をしたことは(ほぼ)ないのですが、対社内(上司)では苦労をしているので聞いた内容を生かしていければいいな思う所存にございます。
ChefでのMySQLパスワードの扱い
opscodeのリポジトリにあるMySQLのcookbookでは、rootユーザやレプリケーション用のユーザのパスワードをランダムに生成して設定している。
opscode の recipe の特徴
このランダムという点をカバーするべく、うまい仕組みが組み込まれている。
パスワードを設定するところは
node.set_unless['mysql']['server_root_password'] = secure_password
といった形で、attributeに設定されていない場合はランダムに生成するという事をして、2度目以降も同じパスワードとなるようになっている。
2回目以降も同じパスワードを保証するために、もうひとつの技が
unless Chef::Config[:solo] ruby_block "save node data" do block do node.save end action :create end end
ここの node.save というやつ。
普通であれば、recipe(run_list)の実行がすべて完了するまではattributeがサーバに保存されないんだけど、このメソッドを使うことで、即時に保存される。これで、万が一rootのパスワードが設定されたあとのどこかでコケても、同じパスワードで設定を続けることができる(上のコードにあるようにchef-soloのときは実行されないけど)。また、masterは途中でコケたけど、スレーブはそこで設定された(であろう)であろうパスワードを使ってセットアップだけは続けることができる。
これはよく考えられた仕組みですよね。
Encrypted Data Bag
ただ、ランダムであれば推測されづらくていいかもしれないけど、好きなパスワードを設定したいし、アプリからのアクセスを考えるとすべてのサーバでアプリ用ユーザは共通にしておきたいといった要望もある。また、提供されているrecipeのままだったりattributeにそのまま設定してしまうと、平文のパスワードがattributeの一覧から確認できてしまう。
そんな時に便利なのが、Encrypted Data Bagという平文で保存したくないデータをChefに保持しておくための機構。Encrypted Data Bag を使うために必要なのはencrepted_data_bag_secretと呼ばれる共通鍵だけ。
※やってることはOpscodeのサイトに書かれていることと全く同じです。
共通鍵の作成
# openssl rand -base64 512 | tr -d '\r\n' > /etc/chef/encrypted_data_bag_secret
これをEncrypted Data Bags利用する各クライアントと共有する。共有方法は初回セットアップであれば、knifeコマンドのbootstrapで指定してあげれば良い。その方法は後ほど。
knifeコマンドで暗号化されたデータをdata bagsに保存
passwordというdata bagにmysqlという項目を作成します。ここで指定するmysqlというのは、data bagのIDとなり、これは暗号化されません。
# knife data bag create --secret-file /etc/chef/encrypted_data_bag_secret passwords mysql [editorが開くので以下のように入力して保存] { "id": "mysql", "user": "root", "pass": "your_password" }
※EDITOR環境変数を設定していないとErrorになります。
作成したdata bagを確認してみましょう。
# knife data bag show passwords mysql { "id": "mysql", "pass": "trywgFA6R70NO28PNhMpGhEvKBZuxouemnbnAUQsUyo=\n", "user": "e/p+8WJYVHY9fHcEgAAReg==\n" }
userとpassが暗号化されて保存されています。
では、復号化して表示してみます。
# knife data bag show --secret-file /etc/chef/encrypted_data_bag_secret passwords mysql { "id": "mysql", "user": "root", "pass": "your_password" }
先程入力したものが表示されました。
Recipeから Encrypted Data Bagのデータを呼び出す
実際に recipe からdata bagの値を呼ぶには、以下のような感じにしてあげます。
共通鍵を直接指定する場合
mysql_data = Chef::EncryptedDataBagItem.load("passwords", "mysql", secret) user = mysql_data["user"] password =mysql_data["pass"]
共通鍵ファイルがデフォルトの /etc/chef/encrypted_data_bag_secret に配置されている場合はsecretを指定しなくてもOK
mysql_data = Chef::EncryptedDataBagItem.load("passwords", "mysql") user = mysql_data["user"] password =mysql_data["pass"]
ここで、ユーザ名やパスワードを node['mysql']['user'] とやってしまうと、せっかく暗号化して保存されているユーザ名とパスワードが平文でattributeに登録されてしまいますので、やめたほうがいいと思います。data bagに保存されているので、次回以降に変わるという事も無いですしね。
recipe内で定義したローカル変数のままだとテンプレートに渡せないので、templateリソースの中で以下のように定義すればテンプレート内で呼び出せる。
template "hoge" do source "hoge.erb" ... variables( :user => user, :pass => pass ) end
これでめでたくattributeに平文のパスワードが登録されることなく、自分の好みのパスワードが設定出来ました。
bootstrap で encrypted_data_bag_secret を渡す
初回セットアップのサーバの場合には、validation.pemやchef_server_urlを新規クライアントに設定するために bootstrap の仕組みを利用する。この中で、encrypted data bagの共通鍵をセットアップするサーバに配置することができる。
以下のようにbootstrapファイルに書く。
( cat <<'EOP' <%= encrypted_data_bag_secret %> EOP ) > /etc/chef/encrypted_data_bag_secret
encrypted_data_bag_secret など、bootstrap で使用される値などは、knifeを実行するノードのknife.rbに設定されているものが利用される。そのため、encrypted_data_bag_secretファイルの場所もknife.rbに指定しておく必要がある。
encrypted_data_bag_secret "/etc/chef/encrypted_data_bag_secret"
これで、knifeコマンドからbootstrapファイルをして初期実行をすれば、recipeを実行するクライアントでも問題なくdata bagを復号化できる。
(追記:2012-02-12 16:25) recipe内のローカル変数をテンプレートで使うための記述を追記。