256bitの殺人メニュー

インフラエンジニアだったソリューションアーキテクトなくわののブログ。こちらのBlogは個人の意見となっていて会社とは全く関係ありません。お約束です。[twitter:@kuwa_tw]めんどくさがりが重い腰を上げて何かをアウトプットすることにどれほどの意味があるのかを試してみたいブログでもある。

Terraformを使ってEC2のAutoScalingやろうとしたらちょっとつらいんじゃないかなってなった話

どうもどうも乙カレー様です。桑野です。
びっくりするほどブログ書いてなくてびっくりしてます。半年書いてないやん。


Terraformを使っていたりするんですが、最近EC2のAutoScaleを入れようとして辛いことがあったりしたのでちょっとまとめてみます。

Terraform

Terraformは言わずとも知れたHashicorpさんのプロダクトですね。
インフラ構築をコード化してGithub等でレポジトリ管理することによって履歴管理や、プルリクエストベースの構築ができるのが売りだったりします。

TerraformでのAutoScale時のハマりどこ

端的にいうとこの2つです。

  • Terraform経由で実行した際のLaunchConfiguration(イカLC)とAutoScalingGroup(イカASG)の削除の順番が逆
  • LC内のuser_data更新で一網打尽になる
Terraform経由で実行した際のLaunchConfiguration(イカLC)とAutoScalingGroup(イカASG)の削除の順番が逆

何が悪いかといいますと、この2つは依存関係があるので、ASGを削除する前にそれが紐付いてるLCを削除しようとするとまだAttachされてるよってエラーが出て止まるわけです。
なので、ASG->LCの順で削除してくれればいいんだけど、実際には逆でしか動いてくれない。

* ResourceInUse: Cannot delete launch configuration launchconfig-test because it is attached to AutoScalingGroup autoscalinggroup-test
        status code: 400, request id: [12345678-1234-1234-1234-123412341234]


となると。

GithubのIssueとかでも同じような議論があってlifecycle { create_before_destroy = true }をつけたらいいぜって言ってる人もいるけど、作成タイミングの違いだからやっぱりうまく動かない。

LC内のuser_data更新で一網打尽になる

じゃあ2個作って交互に更新して行ったらええんちゃうんかでバージョン管理する。
これでOKでしょ。

# 古いLC
resource "aws_launch_configuration" "launchconfig_test_v1" {
  name = "launchconfig-test-v1"
  image_id = "${var.amis.api}"
  key_name = "${var.aws.key_name}"
  instance_type = "t2.micro"
  security_groups = ["${var.security_groups.asgtest}"]
  iam_instance_profile = "asgtest"
  associate_public_ip_address = 0
  user_data = "${file("user_data/app_userdata.sh")}"
}
# 新しいLC
resource "aws_launch_configuration" "launchconfig_test_v2" {
  name = "launchconfig-test-v2"
  image_id = "${var.amis.api}"
  key_name = "${var.aws.key_name}"
  instance_type = "t2.micro"
  security_groups = ["${var.security_groups.asgtest}"]
  iam_instance_profile = "asgtest"
  associate_public_ip_address = 0
  user_data = "${file("user_data/app_userdata.sh")}"
}

ぼくが気付かなかっただけだけど、この場合はuser_data/app_userdata.shが更新されるとどっちも再作成になって⊂ミ⊃^ω^ )⊃ アウアウ!!

* ResourceInUse: Cannot delete launch configuration launchconfig-test because it is attached to AutoScalingGroup autoscalinggroup-test-v1
        status code: 400, request id: [12345678-1234-1234-1234-123412341234]

TerraformでのAutoScale時する時のベストプラクティス?

じゃあどうしたらいいんだって話ですが、一旦色々考えたり話したりした挙句こんな感じになりました。

  • ASG, LC, user_dataはバージョニングする
  • 追加/削除時の作業順を厳密に指定する
    • 1. user_data作成
    • 2. 新LC, ASG作成
    • 3. 旧ASGの desired_capacity を0にして既存系のインスタンス削除する
    • 4. 旧ASGを削除する
    • 5. 旧LCを削除する

この手順だと実際にApplyするのは、2. 3. 4. 5.で4回です(2. と3. はまとめられますがそれでも3回)。多いですね。

3.の時の設定の状態
# 古いLC
resource "aws_launch_configuration" "launchconfig_test_v1" {
  name = "launchconfig-test-v1"
  image_id = "${var.amis.api}"
  key_name = "${var.aws.key_name}"
  instance_type = "t2.micro"
  security_groups = ["${var.security_groups.asgtest}"]
  iam_instance_profile = "asgtest"
  associate_public_ip_address = 0
  user_data = "${file("user_data/app_userdata_v1.sh")}"
}
# 古いASG(この後削除する)
resource "aws_autoscaling_group" "autoscalinggroup_test_v1" {
  availability_zones = ["ap-northeast-1c"]
  name = "autoscalinggroup-test-v1"
  max_size = 0
  min_size = 0
  health_check_grace_period = 300
  health_check_type = "ELB"
  desired_capacity = 0
  force_delete = true
  launch_configuration = "${aws_launch_configuration.launchconfig_test_v1.id}"
  vpc_zone_identifier = ["${var.subnets.asgtest}""]
  load_balancers = ["${aws_elb.asgtest.name}"]
  tag = {
    key = "Name"
    value = "app-asg"
    propagate_at_launch = true
  }
  tag = {
    key = "SERVER"
    value = "APP"
    propagate_at_launch = true
  }
}
新しい設定
# 新しいLC
resource "aws_launch_configuration" "launchconfig_test_v2" {
  name = "launchconfig-test-v2"
  image_id = "${var.amis.api}"
  key_name = "${var.aws.key_name}"
  instance_type = "t2.micro"
  security_groups = ["${var.security_groups.asgtest}"]
  iam_instance_profile = "asgtest"
  associate_public_ip_address = 0
  user_data = "${file("user_data/app_userdata_v2.sh")}"
}
# 新しいASG
resource "aws_autoscaling_group" "autoscalinggroup_test_v2" {
  availability_zones = ["ap-northeast-1c"]
  name = "autoscalinggroup-test-v2"
  max_size = 4
  min_size = 2
  health_check_grace_period = 300
  health_check_type = "ELB"
  desired_capacity = 2
  force_delete = true
  launch_configuration = "${aws_launch_configuration.launchconfig_test_v2.id}"
  vpc_zone_identifier = ["${var.subnets.asgtest}""]
  load_balancers = ["${aws_elb.asgtest.name}"]
  tag = {
    key = "Name"
    value = "app-asg"
    propagate_at_launch = true
  }
  tag = {
    key = "SERVER"
    value = "APP"
    propagate_at_launch = true
  }
}

で、

この人は何故ここまで頑張ってTerraformを使う必要があるのだろうか、、、っていう部分は聞かないでください!
でもやってて開発者の人にもサーバ構成を共有するとか、インスタンス作成部分とかは作業してこっちでもプルリクエストベースでのコードレビュー(構成レビュー)させてもらえるのは非常にいいと思ってます。


そして、バージョン0.6以降で上手く使えるようになることを祈っていますね。。。


でも ↑ この時よりは状況良くなっていると思います!貢献していきたい。

テラフォーマーズ 13 (ヤングジャンプコミックス)

テラフォーマーズ 13 (ヤングジャンプコミックス)

じょうじょ

2014年の記事アクセスランキング!

大晦日もおつカレー様です。
2014年によく読まれた記事のランキングを出してみようと思い立ったのであります。


ドゥルルルルルルルルルルル、、、、

ドン!

というわけで、

来年もよろしくおねがいしまーすʕ•̫͡•ʕ*̫͡*ʕ•͓͡•ʔ-̫͡-ʕ•̫͡•ʔ*̫͡*ʔ-̫͡-ʔ


ゆく年くる年 吟醸酒 720ml

ゆく年くる年 吟醸酒 720ml

シェルスクリプトだけでMySQLからMongoDBへの移行しちゃう

このエントリは、MySQL Casual Advent Calendar 23日目のエントリです。

どうもどうも乙カレー様です。桑野です。
お酒が入ってるとわけわかんないことをいうことがおおいんですが(ごめんなさい)
さてブログ書こうと思ってアドベントカレンダーのページ見なおしたらなんか書いてあるんですよね。

MySQLだっつってんだろ。
ということで何書こうかなと思ってたんですが、ネタ記事としてシェルスクリプトだけでMySQLからMongoDBへの移行しちゃうのをやろうかと思います。
誰得なのかということであれば俺得です(∗ᵒ̶̶̷̀ω˂̶́∗)੭₎₎̊₊♡ウケトレィ!


と言うかなんか怒られそう、、、ごめんなさいごめんなさいネタが思いつかなかったんですホントですm(_ _)m

ちゅーわけでテストテーブル作ってみる。

まずは移行元のMySQLにテーブル作ってみましょ。
適当に。

mysql> CREATE DATABASE d1;
mysql> use d1
mysql>  CREATE TABLE t1 (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(20),
   nosql VARCHAR(30),
   price INT UNSIGNED,
   created_at DATETIME
 );
mysql>  INSERT INTO t1 (name, nosql, price, created_at)
   VALUES ("kuwa_tw", "mongodb", 10, now());
mysql> INSERT INTO t1 (name, nosql, price, created_at)
   VALUES ("oranie", "cassandra", 100, now());
mysql> INSERT INTO t1 (name, nosql, price, created_at)
   VALUES ("kakky_h", "hbase", 1000, now());
mysql> INSERT INTO t1 (name, nosql, price, created_at)
   VALUES ("la_luna_azul", "riak", 1500, now());
mysql> INSERT INTO t1 (name, nosql, price, created_at)
   VALUES ("saeoshi", "voldemote", 2000, now());
 mysql> SELECT * FROM t1;
 +----+--------------+-----------+-------+---------------------+
 | id | name         | nosql     | price | created_at          |
 +----+--------------+-----------+-------+---------------------+
 |  1 | kuwa_tw      | mongodb   |    10 | 2014-12-23 21:14:39 |
 |  2 | oranie       | cassandra |   100 | 2014-12-23 21:14:40 |
 |  3 | kakky_h      | hbase     |  1000 | 2014-12-23 21:14:41 |
 |  4 | la_luna_azul | riak      |  1500 | 2014-12-23 21:14:42 |
 |  5 | saeoshi      | voldemote |  2000 | 2014-12-23 21:14:43 |
 +----+--------------+-----------+-------+---------------------+
 5 rows in set (0.00 sec)

ほいできました。

移行しましょう。

MySQLのデータをCSV出力

シェルスクリプトというか、まずはCSV出力でしましょ。

$ mysql -h localhost -u root -p pass d1 -e "SELECT * FROM t1" | tr "\t" "," >> ./dump.sql

全テーブルやりたかったらforで回したりしたらいいんじゃないですかね!

$ for t in `mysql -h localhost -u root  d1 -e "show tables from mysql;" | awk 'NR!=1{ print $1}'`
do
   mysql -h localhost -u root -p pass d1 -e "SELECT * FROM ${t}" | tr "\t" "," >> ./dump_${t}.sql
done

こんなのが出ました。

 cat dump.csv
 id,name,nosql,price,created_at
 1,kuwa_tw,mongodb,10,2014-12-23 21:14:39
 2,oranie,cassandra,100,2014-12-23 21:14:40
 3,kakky_h,hbase,1000,2014-12-23 21:14:41
 4,la_luna_azul,riak,1500,2014-12-23 21:14:42
 5,saeoshi,voldemote,2000,2014-12-23 21:14:43
CSV出力を修正

これでもうMongoDB食わせられるんですが、DateがStringになっちゃってるので変換してみましょう。
MongoDBのextended json formatのページを参照に修正してみましょう(CSVだけど)

$ awk -F, -v OFS=, 'NR!=1{tmp="ISODate(\""substr($5,1,10)"T"substr($5,12,9)"+0900""\")";$NF="";print $0tmp ; next} NR=1{print $0}' dump.csv  > dump_fix.csv
 id,name,nosql,price,created_at
 1,kuwa_tw,mongodb,10,ISODate("2014-12-23T21:14:39+0900")
 2,oranie,cassandra,100,ISODate("2014-12-23T21:14:40+0900")
 3,kakky_h,hbase,1000,ISODate("2014-12-23T21:14:41+0900")
 4,la_luna_azul,riak,1500,ISODate("2014-12-23T21:14:42+0900")
 5,saeoshi,voldemote,2000,ISODate("2014-12-23T21:14:43+0900")

こうなったら成功です。

MongoDB へのインポート

最後はmongoimportコマンドでMongoDBにいれるだけ!

$ mongoimport --host localhost --port 27018 -d d1 -c t1 --type csv --file dump_fix.csv --headerline --drop
connected to: localhost:27018
2014-12-23T22:34:53.535+0900 dropping: d1.t1
2014-12-23T22:34:53.539+0900 imported 5 objects
  • mongoimportのオプションの意味
    • --host 接続先ホスト
    • --port 接続先ポート
    • -d database
    • -c collection
    • --file 読み込むファイル
    • --type ファイルタイプ
    • --hederline 最初の行をヘッダとして見る(フィールド名になる)
    • --drop インポート前にコレクションをDROPする(若干危険)

入った入った!クララも立った!
、、、と言うことでデータみてみましょう。

$ mongo --host localhost --port 27018
 MongoDB shell version: 2.6.4
 connecting to: localhost:27018/test
 > use d1
 switched to db d1
 > db.t1.find()
 { "_id" : ObjectId("54996816e0035c426fd71b2c"), "id" : 1, "name" : "kuwa_tw", "nosql" : "mongodb", "price" : 10, "created_at" : "2014-12-23T21:14:39+0900" }
 { "_id" : ObjectId("54996816e0035c426fd71b2d"), "id" : 2, "name" : "oranie", "nosql" : "cassandra", "price" : 100, "created_at" : "2014-12-23T21:14:40+0900" }
 { "_id" : ObjectId("54996816e0035c426fd71b2e"), "id" : 3, "name" : "kakky_h", "nosql" : "hbase", "price" : 1000, "created_at" : "2014-12-23T21:14:41+0900" }
 { "_id" : ObjectId("54996816e0035c426fd71b2f"), "id" : 4, "name" : "la_luna_azul", "nosql" : "riak", "price" : 1500, "created_at" : "2014-12-23T21:14:42+0900" }
 { "_id" : ObjectId("54996816e0035c426fd71b30"), "id" : 5, "name" : "saeoshi", "nosql" : "voldemote", "price" : 2000, "created_at" : "2014-12-23T21:14:43+0900" }

どうでしょう。はいっております。これは奇跡。
ということでありまして、MySQLからMongoDBに移行したい、なんていう珍しい方がおりましたら是非こんな感じで試してみてはいかがでしょうか。


ただし責任は取れませんが、、、(怪談的な終わり方)


追記

で、締まったかと思ったんですが、、、すいません、、、上記の方法でもISODateでは入ってませんでした、、、。

変換する場合はmongo shellに入って、

db.t1.find({ },{ "created_at": 1 }).forEach(function(document){

    var newDate = ISODate( document.created_at );

    db.t1.update(
        { _id: document._id },
        { "$set": { "created_at": newDate } }
    );
})

という感じでできると思います、、、シェルスクリプトだけでできてないしなんなのこれ、、、もう、、、。

> db.t1.find()
{ "_id" : ObjectId("54998426e0035c426fd71b7b"), "id" : 1, "name" : "kuwa_tw", "nosql" : "mongodb", "price" : 10, "created_at" : ISODate("2014-12-23T12:14:39Z") }
{ "_id" : ObjectId("54998426e0035c426fd71b7c"), "id" : 2, "name" : "oranie", "nosql" : "cassandra", "price" : 100, "created_at" : ISODate("2014-12-23T21:14:40Z") }
{ "_id" : ObjectId("54998426e0035c426fd71b7d"), "id" : 3, "name" : "kakky_h", "nosql" : "hbase", "price" : 1000, "created_at" : ISODate("2014-12-23T21:14:41Z") }
{ "_id" : ObjectId("54998426e0035c426fd71b7e"), "id" : 4, "name" : "la_luna_azul", "nosql" : "riak", "price" : 1500, "created_at" : ISODate("2014-12-23T21:14:42Z") }
{ "_id" : ObjectId("54998426e0035c426fd71b7f"), "id" : 5, "name" : "saeoshi", "nosql" : "voldemote", "price" : 2000, "created_at" : ISODate("2014-12-23T21:14:43Z") }

というわけで、これでOKですm(_ _)m


エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド



MongoDBイン・アクション

MongoDBイン・アクション

新しいwiredTigerストレージエンジンの始め方とその他のストレージエンジンについて

どうもどうも乙カレー様です。桑野です。
風邪です:(;゙゚'ω゚'):<寒い


MongoDB Advent Calendar 2014 - Qiitaの19日目です!

MongoDB2.8の目玉機能であるところのプラガブルなストレージエンジン、その中でも先日MongoDB社が買収したwiredTigerについては気になる所なのでとりあえず使い方メモまで書いてみますた。*1

wiredTigerとは

wiredTigerとはWiredTiger社で開発を進めていたデータストアで2.8ではMongoDBのストレージエンジンとして採用される予定だったのですが、そこから一転MongoDB社に買収されるという形になりました。今までのmmapv1(従来)形式のデータストアから置き換えになる方向なのではないかと思われます。ということでちょいとやってみようと。

試してみよう

現在MongoDB2.8のRC3まで出てますが、これであればwiredTigerは使えます。

$ cd /opt
$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.8.0-rc3.tgz
$ sudo tar zxvf mongodb-linux-x86_64-2.8.0-rc3.tgz
$ mkdir -p /var/lib/mongodb/mmapv1 /var/lib/mongodb/wt
$ chown -R mongodb. /var/lib/mongodb
YAML形式設定ファイル

そしたら次にMongoDBの設定。まずは普通に起動してみましょう。
YAML形式の設定ファイルが使えるようになったので勉強兼ねてそれで。(今までの設定ファイルも使えるよ)

# mongodb_mmapv1.conf
storage:
   dbPath: "/var/lib/mongodb/mmapv1"
   engine: "mmapv1"
   journal:
      enabled: true
systemLog:
   destination: file
   path: "/var/log/mongodb/mongodb_mmapv1.log"
   logAppend: true
processManagement:
    fork: true

起動

/opt/mongodb-linux-x86_64-2.8.0-rc3/bin/mongod -f /etc/mongodb/mongod-mmapv1.yml


普通のもんごっすわw

wiredTiger 起動用の設定ファイル

次はいよいよwiredTigerです。設定ファイルを書きましょう。

# mongodb_wt.conf
storage:
    dbPath: "/var/lib/mongodb/wt"
    engine: "wiredTiger"
    wiredTiger:
        blockCompressor: "none"
systemLog:
   destination: file
   path: "/var/log/mongodb/mongodb_wt.log"
   logAppend: true
storage:
   journal:
      enabled: true
processManagement:
    fork: true

起動

/opt/mongodb-linux-x86_64-2.8.0-rc3/bin/mongod -f /etc/mongodb/mongod-wt.yml


設定項目も諸所用意されているので主要なオプション紹介します。(最新の状態は公式サイトまでm(_ _)m)

# mongodb_wt.conf
storage:
    dbPath: "/var/lib/mongodb/wt"
    engine: "wiredTiger"
    wiredTiger:
        collectionConfig:
            blockCompressor: "snappy"
        engineConfig:
            cacheSizeGB: 2
            checkpointDelaySecs: 60
            statisticsLogDelaySecs: 5
            journalCompressor: "snappy"
            directoryForIndexes: true
systemLog:
   destination: file
   path: "/var/log/mongodb/mongodb_wt.log"
   logAppend: true
storage:
   journal:
      enabled: true
processManagement:
    fork: true
  • blockCompressor: コレクションデータの圧縮 "none|snappy|zlib"
  • cacheSizeGB: WiredTigerのキャッシュ量。デフォルトは1G or フィジカルメモリの半分
  • checkpointDelaySecs:  チェックポイントの間隔ジャーナル有効にしてないと最大この秒数のデータが失われる可能性がある。デフォルトは60Sec。
  • statisticsLogDelaySecs:  統計ログの出力間隔、デフォルトは0(記録しない)
  • journalCompressor:  ジャーナルファイルの圧縮。 "none|snappy|zlib"
  • directoryForIndexes: indexとcollectionをディレクトリで分けるようにする。デフォルトはfalse(無効)

ほかにどんなストレージエンジンがあるの?

見た感じこんなのがあるっぽい。

devnullストレージエンジン

insertとかしても何も記録されなかった。MySQLでいうBlackhole。
使い道、、、あるかなぁ、、、。

inMemory(inMemoryExperiment)ストレージエンジン

Experimentってあるので実験段階なんだろうけどメモリDBとして使うためのストレージエンジンぽい。Cappedで使っている用途はもはやこれでもいいんじゃないかと思わなくもない。

RocksDB(rocksExperiment)ストレージエンジン

RocksDBをバックエンドに持つストレージエンジン。使う時間なかったのでよくわからんw

今日はこんなところで勘弁してやらぁ(ください)

もうちょいやりたかったんですが、今日が終わりそうなのでとりあえずここまで。。。

( `)3')▃▃▃▅▆▇▉ヴェェェェェェエェエエェェェェェェエェエエェェヴェェェェェェエェエエェェェェェヴェェェェェェエェエエ


MongoDBイン・アクション

MongoDBイン・アクション


モンゴ流 スカルプエッセンス Deeper 60ml

モンゴ流 スカルプエッセンス Deeper 60ml

*1:もうちょいやりたかったんですが、、、

#mysqlcasual MySQL Casual Talks vol.7に行ってガチカジュアルな話してきた

どうもどうも乙カレー様です。桑野です。

MySQL Casual Talks vol.7に言ってまいりました!
思えば長いこと出れておらず久々の出席でしたが、今回はなんといっても @ さんの4.0移設の話が間違いなくNo.1ですね、、、面白い&色々背筋が寒くなる話でしたね、、、4.0なんてどこにあるんでしょうね、え?あm(自主規制)


そして、LTですが初めて MySQL Casual Talks お話することが、、、でき、、、ま、、、し、、、た!
といっても、サイトに名前出てなかったのでなんか嫌な予感はしていたんですが、数に入ってなかったんではないかという疑惑はありつつ行きましたがやっぱり入ってなかった感じがします(;・∀・)


ということで異様なスピードでしゃべることになりましたが、とりあえずNVMFS+Compressionためしてみたというところの途中経過のお話をさせていただきました。
最近だとRDSやらで物理サーバ上でMySQLを使ってない人も多いのかなーと思いつつお話しておりましたがどうなんでしょうね。



@Skypeさらされたり、資料に入れられたりとIT芸人化の激しい昨今。
IT芸人でーすって笑いが取れるのはいいことなのか、、、どうなのか、、、と若干悩ましいところではありますが、モンゴハラスメントとともに強く耐えていきたいと思っています。(Cassandra放棄さんと違ってぼくはモンゴを放棄したわけではございません!)


最後に会場提供のLINEの方々をはじめスタッフのみなさま。
そしてこの方 @ さん、乙でしたー!

#isucon 4 に初参加してラッキーパンチで失格になってきました

なんで勝負!!!って盛り上がっちゃうんでしょうね。
はい、乙カレー様です。くわのです。


ISUCON4に初参戦してきました!
ISUCON毎回みてて面白そうだなーと思っていたんですがなんとなく気が引けたり予定が合わなかったりで出れてなかったのですが、会社でTOTECに参加して6位になったりしてちょっと悔しかったり面白かったりしてきたので今回初参加してきました。
大分記憶が薄くなってしまったので思い出しつつ書いていきます。


@, @の3人メンバーででてきました。
言語はNode.jsです。

チームでやったこと(覚えてる限り)

とりあえずサーバ環境を見たり、デフォルト状態のRubyのベンチ結果、デフォルトのNode.jsの結果までみて、Nginxのログと、general_log出したりしてクエリ確認してみる。DBはusersとlogin_logしかテーブル無い。

インデックス

login_logに、

  • ip, succeededの複合インデックス
  • user_id, succeeded, idの複合インデックス

を入れてみたタイミングでだいたいMySQLはまあいいんじゃねって感じになった。
ので、あとは様子見つつアプリの確認などしつつmy.cnfやサーバのリソース確認していた。

MySQLバージョンアップ

DBが大したことなかったので5.7にあげてみたけどほぼ意味なかった。

静的ファイル切り出し

Nginx側で静的ファイルの切り出しをして、Nginxで返すように変更。

tmpfs化

MySQLのデータ領域のtmpfs化

OSパラメータ系
  • my.cnf
  • nginx.conf
  • kernelパラメータ

の変更

ハッシュ計算のスキップ

DBにハッシュ値を入れた

セッションのキャッシュ化

memcached導入

この段階の点数

30000超えてる位だったと思う。

ラッキーパンチ

17時半くらいから
memcachedにセッションキャッシュ入れたりしつつ平行して@さんがbenchmakerの最適値を見たりしてたのですが、その中で期せずしてこれに引っかかって不当に高い点になっていたというのがありました。
その時はなんか実行が長いなとは思ってたのですが、元々1分で終わる前提っていう仕様をしらなかったのもあって、そうかーなんかすげーけどとりあえず時間も無いしそれはそれでやってこうってなりまして。その結果5位に入ってしまいました。確か62000くらいだったと思います。

からの失格

それでもジャッジ的に本戦出れる感じだったんですが、ここをみていただけるとわかるように

「もんご博士(RX有〼)」の7チームは、サーバ再起動後に、再起動前と /report の出力内容が変わってしまっていたり、 /report 自体が動作しなかったりすることが確認され、失格といたしました。

「もんご博士(RX有〼)」の7チームは、サーバ再起動後に、再起動前と /report の出力内容が変わってしまっていたり、 /report 自体が動作しなかったりすることが確認され、失格といたしました。

「もんご博士(RX有〼)」の7チームは、サーバ再起動後に、再起動前と /report の出力内容が変わってしまっていたり、 /report 自体が動作しなかったりすることが確認され、失格といたしました。

皆さんわかってますよね。tmpfs入れてちゃんとデータの保存ができるようになってなかったのです、、、かなしい。
そしてラッキーパンチでもくやしい。

benchmaker2での追試

32000でした。これでは本戦出れないですのでまあ良かったかなーって清々しい気分です。いや、嘘です。ちょっとだけくやしい。

教訓

障害対応じゃないんだからもっと攻めるべきだったなーというのは反省しています。
言い訳すると初めての参加だったので自由度が把握できてなかった部分はあるかもしれない。。。(言い訳すんな)

  • 判断は早く、かつ競技の面もあるので大胆さも大事
  • 役割わけるのもあるだけど全員コードを最初に読み込んでおく事
  • レギュレーションは読み込んでチームメンバーで共有しておく <- イマココ

終わってみて

集中して疲れたけど楽しいいいいいいいいいいいいいいいいいいいいいいいいいいいん!って感じだった。
実際参加してみてから皆さんのブログを読ませていただいたりして大変刺激になりました。

今回は残念なラッキーパンチだったので次回はカッチリ本戦行ったるマン。

お疲れ様でした

ご迷惑おかけした @さんはじめ運営の方々本当にお疲れ様でした!
楽しいISUCONありがとうございます!
本選出場者の方々も頑張ってください!

にしても

ばばさんにも言われたけどここはネタ的にもワンチャンMongoDBだったよなー。って思わなくもないですw


ではではー三(卍 〓ω〓))卍


Cookbookの管理を楽にするBerkshelfの使い方( ー`дー´)キリッ とか。

子供が生まれたり、職場では人事改革が行われたり、@さんがスマートフォンアプリエンジニアになったりと、生活が激変しつつある今日この頃みなさまいかがお過ごしでしょうか。
はい、乙カレー様です。くわのです。


職場ではずっとchef-server 1本で来ていたわけなのですが、ちょっと前からchef solo+Berkshelfを使い始めたりしている私達がいます。
きっとみなさんchef-serverとか強がりやがってやっと素直になりやがったなと思っていることでしょう。
(Chef-serverも使い方で便利ですよ)


ドキュメント読んだらいいのかと思ったりもするんだけどBerkshelfのドキュメントがあんま綺麗じゃなくて困るというw
ちゅーことで、ざっくり使い方を整理しました。あ、Berkshelfのバージョンは3です。

Berkshelf

BerkshelfはCookbookの依存性を管理するためのソフトウェアです。
主な目的としては2つあり、

  • Cookbookの依存性の確保
  • Cookbookのバージョン管理

です。
例えば、Webサーバを構築するための[webserver]という、Cookbookがあったとして、[webserver]は、nginxを使用するために[nginx]のCookbookに依存しているような場合などです。
更にCookbookバージョンが変わることによる冪等性の確保のため、Cookbookのバージョン管理も行えます。

Berkshelfのインストール

割愛、、、bundleとかで。

$ cat Gemfile 
source 'https://rubygems.org'

gem "berkshelf"
$ bundle install

Berkshelf用のCookbookのひな形作成

Berkshelfを実行するためのCookbookのひな形作成

$ berks cookbook berks-cookbook

Berkshelfの設定

まずは基本的なBerkshelfの動作設定についてですが、これはconfig.jsonに設定します。
デフォルトだとワーキングディレクトリ ~/.berkshelf/ 以下の config.json にあります。


なくてもデフォルトで動きますが、Githubに繋ぎたい場合等は設定が入りますので指定してください。


ちなみに、berkshelfのワーキングディレクトリを変更したい場合は環境変数 BERKSHELF_PATH を指定します。

ex.)
export BERKSHELF_PATH=/usr/local/etc/berkshelf/
config.jsonの設定項目

こんなかんじです。

- chef.chef_server_url - Chefサーバの管理画面URL
- chef.node_name - ChefのClientNameの設定、デフォルトはknifeがあればそこから取得
- chef.client_key - clientキーの設定。
- chef.validation_client_name - validateキー(Chefにおけるrootみたいなもの)の設定
- chef.validation_key_path - validateキー(Chefにおけるrootみたいなもの)ファイルの場所
- vagrant.vm.box - Vagrantで使用するBoxの名前の指定(default: Berkshelf-CentOS-6.3-x86_64-minimal)
- vagrant.vm.box_url - VirtualBoxのBoxのあるURLの指定 (default: https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box)
- vagrant.vm.forward_port - host->guestでforwardするportの設定
- vagrant.vm.provision - Chefのprovisionerの指定、chef_solo or chef_client. (default: chef_solo)
- ssl.verify - SSL接続を確認するかどうか。(default: true)
- cookbook.copyright - 新しいCookbookを生成する際に含めるコピーライト表示
- cookbook.email - 新しいcookbookが作成された時にメールを飛ばす先. デフォルトはknifeがあればそこから取得
- cookbook.license - 新しいcookbookで使用するライセンス。 デフォルトはknifeがあればそこから取得
- github - Github credentials 必要なcookbookをダウンロードするときに使うものをHashのArrayで入れる。

Berksfile

次に取得するCookbookを指定するためのBerksfileを設置。
Berksfileに記述するCookbookはコミュニティクックブック、Berks-API、Gitレポジトリ、LocalFilePathなどを指定する事ができます。

Berksfileの設定項目

Berksfileの記述ですが、下に例を貼りました。
コミュニティCookbook等のBerks-API経由のものに関してはバージョン指定が可能ですし、Gitレポジトリ管理しているものに関してはTag指定での取得が可能です。
一般的にコミュニティCookbookはバージョン=Tag指定になっているものが多いので自分たちで作る際もそれに習っておくのが良いね。うん。
berkshelfの公式のAPI指定は前まではapi.berkshelf.comだったんですが、Supermarketのリリースにともなってhttps://supermarket.getchef.comに変更になったようです。
また、自分たちでBerks-APIを立てることもできます。依存関係を一括管理する場合は自分たちのBerks-APIを立てるのがいいと思います。
その場合はひろせさんのこちらの記事が参考になります(ありがとうございます)

# Berks-API指定
# source "https://api.berkshelf.com"
source "https://supermarket.getchef.com"

# コミュニティクックブック
cookbook 'yum'

# コミュニティクックブック(バージョン指定)
cookbook 'yum-epel' , ">= 0.4.0"

# Gitレポジトリ
cookbook 'ca_sysctl', git: 'http://git.example.com/ca-cookbooks/ca_sysctl.git'

# Gitレポジトリ(tag指定)
cookbook 'ca_td-agent', git: 'http://git.example.com/ca-cookbooks/ca_td-agent.git' , tag: "1.0.0"

# LocalFilePath
cookbook 'webserver', path: '/Users/kuwano/cookbook/directory/somewhere/webserver'
cookbook 'nginx-test', path: '/Users/kuwano/cookbook/directory/somewhere/nginx-test'
cookbook 'apache-test', path: '/Users/kuwano/cookbook/directory/somewhere/apache-test'

主要なコマンドの使い方

berksコマンドの主要な使い方について。コマンドリファレンス的な物があんまり無いんだよね、、、なんでか、、、。

Berkshelfの使い方の流れ

Berkshelfでの作業の流れは大体このようになるかと思います。

  • Berkshelfのひな形作成(berks cookbook berks-cookbook)
  • Cookbookのインストール(berks install)
  • (Cookbook記述作業)
  • Cookbookのアップデート(berks update [Cookbook名])
  • Cookbookのインストール(以下繰り返し)
Berksfileのバージョン確認

berks versionコマンド。

$ berks version
3.1.1
Berksfileのひな形作成

上でもやったberks cookbookです。

$ berks cookbook berks-cookbook
      create  berks-cookbook/files/default
      create  berks-cookbook/templates/default
      create  berks-cookbook/attributes
      create  berks-cookbook/libraries
      create  berks-cookbook/providers
      create  berks-cookbook/recipes
      create  berks-cookbook/resources
      create  berks-cookbook/recipes/default.rb
      create  berks-cookbook/metadata.rb
      create  berks-cookbook/LICENSE
      create  berks-cookbook/README.md
      create  berks-cookbook/CHANGELOG.md
      create  berks-cookbook/Berksfile
      create  berks-cookbook/Thorfile
      create  berks-cookbook/chefignore
      create  berks-cookbook/.gitignore
         run  git init from "./berks-cookbook"
      create  berks-cookbook/Gemfile
      create  .kitchen.yml
      append  Thorfile
      create  test/integration/default
      append  .gitignore
      append  .gitignore
      append  Gemfile
      append  Gemfile
You must run `bundle install' to fetch any new gems.
      create  berks-cookbook/Vagrantfile
cookbookのインストール

まず、Cookbookをberkshelfのワーキングディレクトリへとインストールしましょう。
berks installコマンドを使用します。
ここでインストールしたCookbookが実際のchef soloで使用されるCookbookとなります。

Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Fetching 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Using 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Installing apt (2.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing ark (0.8.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing build-essential (2.0.4) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing chef_handler (1.1.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing consul (0.2.3) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing cron (1.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing erlang (1.5.4) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing golang (1.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing rabbitmq (3.2.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing redisio (1.7.1) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing rsyslog (1.12.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing runit (1.5.10) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing selinux (0.8.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing sensu (1.0.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing ulimit (0.3.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing windows (1.31.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum (3.2.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-epel (0.3.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-erlang_solutions (0.2.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-repoforge (0.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)


このタイミングで作成される、Berksfile.lockにインストールされたCookbookのバージョンや、依存関係の情報が含まれています。
Berksfile.lockファイルが既に存在していればその記述バージョンのCookbookがインストールされます。

DEPENDENCIES
  apt
  consul
  cron
  selinux
  sensu
  webserver
    git: http://git.example.com/ca-cookbooks/webserver.git
    revision: 998d3e415e43c900e3f043513fa72bff6b1441c0
  yum
  yum-epel

GRAPH
  apt (2.4.0)
  ark (0.8.2)
  build-essential (2.0.4)
  chef_handler (1.1.6)
  consul (0.2.3)
    ark (~> 0.8.0)
    golang (~> 1.3.0)
    runit (>= 0.0.0)
    yum-repoforge (>= 0.0.0)
  cron (1.4.0)
  erlang (1.5.4)
    apt (>= 1.7.0)
    build-essential (>= 0.0.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
    yum-erlang_solutions (>= 0.0.0)
  golang (1.3.0)
  rabbitmq (3.2.2)
    erlang (>= 0.9.0)
  redisio (1.7.1)
    ulimit (>= 0.1.2)
  rsyslog (1.12.2)
  runit (1.5.10)
    build-essential (>= 0.0.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
  selinux (0.8.0)
  sensu (1.0.0)
    apt (>= 0.0.0)
    rabbitmq (>= 2.0.0)
    redisio (>= 1.7.0)
    windows (>= 1.8.8)
    yum (>= 0.0.0)
  ulimit (0.3.2)
  webserver (0.1.1)
    apt (>= 0.0.0)
    rsyslog (>= 0.0.0)
    selinux (>= 0.0.0)
    sensu (>= 0.0.0)
    yum (>= 0.0.0)
    yum-epel (>= 0.0.0)
  windows (1.31.0)
    chef_handler (>= 0.0.0)
  yum (3.2.0)
  yum-epel (0.3.6)
    yum (~> 3.0)
  yum-erlang_solutions (0.2.0)
    yum (~> 3.0)
  yum-repoforge (0.3.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
新しいバージョンのCookbookがないか確認

コミュニティクックブックはすごいスピードでリリースされるので、インストールしたタイミングから新しいCookbookが出てることも少なくありません。新しいCookbookの存在を確認するにはberks outdatedを使います。
もしCookbookの更新があればこのように出力されます。

$ berks outdated
The following cookbooks have newer versions:
  * ark (0.8.2 => 0.9.0) [https://supermarket.getchef.com]
  * consul (0.2.3 => 0.3.0) [https://supermarket.getchef.com]
  * erlang (1.5.4 => 1.5.6) [https://supermarket.getchef.com]
  * golang (1.3.0 => 1.4.0) [https://supermarket.getchef.com]
  * sensu (1.0.0 => 2.0.0) [https://supermarket.getchef.com]
  * windows (1.31.0 => 1.34.0) [https://supermarket.getchef.com]
  * yum (3.2.0 => 3.2.2) [https://supermarket.getchef.com]
  * yum-epel (0.3.6 => 0.4.0) [https://supermarket.getchef.com]
Cookbookを最新状態に更新

berks updateコマンドを使用する事でberks outdatedで示されたような変更を適用する事が出来ます。
berks updateを引数を指定しなければ、全Cookbookの強制アップデートになりますが、これを行うとCookbookの挙動が変わった場合に動作が意図したものでなくなる場合があるので、テストなどを行った上で実行しましょう。


実行時にBerksfile.lockが更新されます。


berks update [Cookbook名]
とすることで、Cookbook毎にアップデートが可能なので、アップデートが必要なCookbookのみアップデートするようにしましょう。

実行例としてはこのような感じになります。

$ berks update
Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Fetching 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Using 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Using apt (2.4.0)
Using ark (0.8.2)
Using build-essential (2.0.4)
Using chef_handler (1.1.6)
Installing consul (0.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using cron (1.4.0)
Installing erlang (1.5.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using golang (1.3.0)
Using rabbitmq (3.2.2)
Using redisio (1.7.1)
Using rsyslog (1.12.2)
Using runit (1.5.10)
Using selinux (0.8.0)
Installing sensu (2.0.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using ulimit (0.3.2)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Installing windows (1.34.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum (3.2.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-epel (0.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)


個別に実行した場合はこのようになります。

$ berks update webserver
Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using apt (2.4.0)
Using ark (0.8.2)
(snip)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using windows (1.34.0)
Using yum (3.2.2)
Using yum-epel (0.4.0)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)
現状使用されているCookbookを一括で出力

berkshelfで取得したCookbookを実行するための一般的な方法としてはknife soloが一般的だと思いますが。
各サーバにCookbookを直接配ったり、CI用途等でサーバにCookbookをおきたいときがあるかもしれません。


その場合にはberks vendorコマンドでCookbook群を出力します。
デフォルトではberkshelf実行ディレクトリ配下のberks-cookbook/ディレクトリに出力されます。

$ berks vendor
Resolving cookbook dependencies...
Using apt (2.4.0)
Using ark (0.8.2)
Using build-essential (2.0.4)
Using chef_handler (1.1.6)
Using consul (0.2.3)
Using cron (1.4.0)
Using erlang (1.5.4)
Using golang (1.3.0)
Using rabbitmq (3.2.2)
Using redisio (1.7.1)
Using rsyslog (1.12.2)
Using runit (1.5.10)
Using selinux (0.8.0)
Using sensu (1.0.0)
Using ulimit (0.3.2)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using windows (1.31.0)
Using yum (3.2.0)
Using yum-epel (0.3.6)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)
Vendoring apt (2.4.0) to /Users/akuwano/berksdir/berks-cookbooks/apt
Vendoring ark (0.8.2) to /Users/akuwano/berksdir/berks-cookbooks/ark
Vendoring build-essential (2.0.4) to /Users/akuwano/berksdir/berks-cookbooks/build-essential
Vendoring chef_handler (1.1.6) to /Users/akuwano/berksdir/berks-cookbooks/chef_handler
Vendoring consul (0.2.3) to /Users/akuwano/berksdir/berks-cookbooks/consul
Vendoring cron (1.4.0) to /Users/akuwano/berksdir/berks-cookbooks/cron
Vendoring erlang (1.5.4) to /Users/akuwano/berksdir/berks-cookbooks/erlang
Vendoring golang (1.3.0) to /Users/akuwano/berksdir/berks-cookbooks/golang
Vendoring rabbitmq (3.2.2) to /Users/akuwano/berksdir/berks-cookbooks/rabbitmq
Vendoring redisio (1.7.1) to /Users/akuwano/berksdir/berks-cookbooks/redisio
Vendoring rsyslog (1.12.2) to /Users/akuwano/berksdir/berks-cookbooks/rsyslog
Vendoring runit (1.5.10) to /Users/akuwano/berksdir/berks-cookbooks/runit
Vendoring selinux (0.8.0) to /Users/akuwano/berksdir/berks-cookbooks/selinux
Vendoring sensu (1.0.0) to /Users/akuwano/berksdir/berks-cookbooks/sensu
Vendoring ulimit (0.3.2) to /Users/akuwano/berksdir/berks-cookbooks/ulimit
Vendoring webserver (0.1.1) to /Users/akuwano/berksdir/berks-cookbooks/webserver
Vendoring windows (1.31.0) to /Users/akuwano/berksdir/berks-cookbooks/windows
Vendoring yum (3.2.0) to /Users/akuwano/berksdir/berks-cookbooks/yum
Vendoring yum-epel (0.3.6) to /Users/akuwano/berksdir/berks-cookbooks/yum-epel
Vendoring yum-erlang_solutions (0.2.0) to /Users/akuwano/berksdir/berks-cookbooks/yum-erlang_solutions
Vendoring yum-repoforge (0.3.0) to /Users/akuwano/berksdir/berks-cookbooks/yum-repoforge


tar.gz形式で出力したい場合はberks packageコマンドを使います。

$ berks package
Cookbook(s) packaged to /Users/akuwano/berksdir/cookbooks-1407290309.tar.gz


これらを実行したいサーバ等に持って行くことで単体での実行を行うことができます。

あるCookbookが他のどのCookbookから使われているか表示

berks contingent で調べることが出来ます。

$ berks contingent yum
Cookbooks in this Berksfile contingent upon 'yum':
  * sensu (1.0.0)
  * webserver (0.1.1)
  * yum-epel (0.3.6)

この場合、Cookbook[yum]は、webserverと、yum-epel, sensuから使われている事がわかります。

Cookbookのメタ情報表示

Cookbookのメタ情報を表示するコマンドはberks info [Cookbook名]です。

$ berks info yum
        Name: yum
     Version: 3.2.0
 Description: Configures various yum components on Red Hat-like systems
      Author: Chef
       Email: cookbooks@getchef.com
     License: Apache 2.0
   Platforms: redhat (>= 0.0.0)
              centos (>= 0.0.0)
              scientific (>= 0.0.0)
              amazon (>= 0.0.0)
              fedora (>= 0.0.0)
インストールされてるCookbook表示

現在インストールされてるCookbookを表示するのはberks listです。

$ berks list
Cookbooks installed by your Berksfile:
  * webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
  * apt (2.4.0)
  * ark (0.8.2)
  * build-essential (2.0.4)
  * chef_handler (1.1.6)
(snip)
  * yum-epel (0.3.6)
  * yum-erlang_solutions (0.2.0)
  * yum-repoforge (0.3.0)
Cookbookの検索

berks search [Cookbook名で]コミュニティクックブックを検索できます。

$ berks search redis
php-redis (0.1.1)
redis (3.0.4)
redis-package (1.0.0)
redis-test (0.2.0)
redis2 (0.5.0)
redis_2_cookbook (0.3.3)
redisio (1.7.1)
現在使っているCookbookの実際のサーバ上での位置を表示する

Berkshelfを使っていると、~/.berkshelf/cookbooks/に同じような名前のCookbook(hoge-22a4059e11eab1f727ddf38f1160e04285e26cf9
hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9 とか)が増えてきて、どっちが使ってる奴だよ、みたいになることがたまーにあるんですが、berks show 使うと今使っているCookbookが出力されます。

$ berks show hoge
/Users/akuwano/.berkshelf/cookbooks/hoge-22a4059e11eab1f727ddf38f1160e04285e26cf9


ということで、hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9 は消しても問題ないわけですね。( ´∀`)つ ミ● <-[hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9]

おまけ1:CookbookのChef Serverへのアップロード

もし、Berkshelfで使ったCookbookをChef-serverにアップロードしたい場合はberks uploadコマンドを使います。
Cookbookの管理にBerkshelfを使って、実行はchef client経由でしたい。バージョン管理はChef-server側で行いたい、等の場合はberks uploadしましょう。

$ berks upload
おまけ2:Cookbookの依存関係を画像出力

berks vizコマンドを使用すると管理しているCookbookの依存関係を図示したものが生成されます。
graphvizをインストール(brew等が簡単)してから実行してください。


こんなん↓

つかれた

最後の方ちょっと(ちょっと?)雑になってんなと思った方。それは正しい。
Berkshelfをこれから使う方にちょっとでも役に立てばいいなーとか思ったり思わなかったりします。


ではではー三(卍 〓ω〓))卍


Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)