ほわいとぼーど

ぷろぐらまのメモ帳

(ネタ)Slack+Hubotでファイルアップロードする話

深遠な理由*1によりファイルアップロードをSlack経由で行いたい。
アップロード先はAWS S3なのですが、ここではAWSの世界にファイルを持ち込むまでを書きます。
普通、ファイルアップロードしたいとなれば入り口としてWebサーバ的なものが必要ですが、
ちょっとした要件にはセキュリティコストが高くついて面倒。
SlackやGithubといった既に利用している外部サービスに乗っかればその辺のコストを省略できる、
というのが後付の狙い。

どうしたかというと、Slackのファイルアップロード機能でアップロードします。
その際にコメントに特定のキーワードを付与すると、
Hubotが裏でファイルダウンロードしてS3にアップロードします。
HubotはAWSの中にいる前提です。簡単・強引な仕様。

hubot-slackにはそういう機能はないので、生のAdapterで書きます。
要点抜粋のソースは以下。

request = require 'request'
fs = require 'fs'

module.exports = (robot) ->
  robot.adapter.client?.on? 'raw_message', (msg) ->
    if msg.type is 'message' and msg.subtype is 'file_share' and msg.text.match(/uploaded a file: \<\S+\> and commented: !fileupload/)

      filename = msg.file.url_download.split('/').pop()
      filepath = "work/#{filename}"
      file = fs.createWriteStream(filepath)
      channel = robot.adapter.client.getChannelByID msg.channel
      request
        .get(msg.file.url_download)
        .on 'error', (err) ->
          console.log "#{err}"
        .pipe(file)
        .on 'close', (resp) ->
          # post process
          robot.send {room: channel.name},  "<@#{msg.user}>: Complete file download: #{filename}"

アップロードの際のコメントは、
「uploaded a file: <filename> and commented: (comment)」
という形になるので注意が必要。
上記の例ではコメントに「!fileupload」と付ければ実行されます。
工夫すれば複数のアップロード先も制御できそう。

mgs.file.url_download でSlackにアップロードされたURLが取れるので、ダウンロードします。
この例ではrequest使ってます。後は似るなり焼くなり。
adapter.clientを使うのでchannelとかuserは自分で取得する必要があります。

欠点として、ファイルアップロードを別の場所(S3とか)にしたいのにSlackにも残ってしまう。
終わったら削除したかったのだがBotだと削除できないらしい。
ファイルサイズとかも危険なので上限をチェックするようにはしてます。
後はファイルが重複しないようにtmpdir作ったり終わったら消したり、
細かい所は割愛してますがケア必要です。

*1:「Slackからサクッとファイルアップロードできたりしないの?」と言われたとか

Kibana4 + dstat の話

あらまし

以前に、『dstatをkibanaで可視化+3.0.0milestone5新機能』という エントリでKibana3+dstatを使った可視化について書いたのですが、この中で構築の肝としてfluent-plugin-mapがありました。 Kibana3だと同一グラフ内に同一レコードの複数のfieldを含めることが出来なかったので、 fluent-plugin-mapを使って同一@timestamp+各fieldという別々のレコードとして分割登録しました。 このやり方は@kazeburoさんも記事にされたことにより 同様の方法を利用する人が意外といるようなのですが、 Kibana4では同一グラフ内に同一レコードの複数fieldを含めることが出来るのでレコード分割する必要がありません。 性能はわかりませんがdocument数や容量は分割する場合と比べると減ると思います。 ただしfluent-plugin-dstatはネストしたjsonを返すので平らにしてあげる必要があってfluent-plugin-flatten-hashを使います。

設定とか

fluentdの設定は以下。

<source>
  @type dstat
  tag dstat
  option  -ams
  delay 5
</source>

<match dstat>
  @type flatten_hash
  add_tag_prefix flattened.
  separator _
</match>

<match flattened.dstat>
  @type elasticsearch
  type_name       dstat
  host            localhost
  port            9200
  logstash_format true
  logstash_prefix dstat
  flush_interval  3s
</match

それからMapping template

$ vi template_dstat.json
{
  "template": "dstat-*",
  "mappings": {
    "dstat": {
      "properties": {
        "@timestamp" : {
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        "dstat_dsk/total_read" : { "type" : "double" },
        "dstat_dsk/total_writ" : { "type" : "double" },
        "dstat_memory_usage_buff" : { "type" : "double" },
        "dstat_memory_usage_cach" : { "type" : "double" },
        "dstat_memory_usage_free" : { "type" : "double" },
        "dstat_memory_usage_used" : { "type" : "double" },
        "dstat_net/total_recv" : { "type" : "double" },
        "dstat_net/total_send" : { "type" : "double" },
        "dstat_paging_in" : { "type" : "double" },
        "dstat_paging_out" : { "type" : "double" },
        "dstat_swap_free" : { "type" : "double" },
        "dstat_swap_used" : { "type" : "double" },
        "dstat_system_csw" : { "type" : "double" },
        "dstat_system_int" : { "type" : "double" },
        "dstat_total_cpu_usage_hiq" : { "type" : "double" },
        "dstat_total_cpu_usage_idl" : { "type" : "double" },
        "dstat_total_cpu_usage_siq" : { "type" : "double" },
        "dstat_total_cpu_usage_sys" : { "type" : "double" },
        "dstat_total_cpu_usage_usr" : { "type" : "double" },
        "dstat_total_cpu_usage_wai" : { "type" : "double" },
        "hostname" : { "type" : "string", "index" : "not_analyzed" }
      }
    }
  }
}

$ curl -XPUT 'localhost:9200/_template/tmptelate_dstat' -d @template_dstat.json

templateは特定のパスに置いておくと自動的に読まれるのですが、 再起動が必要になるので最近はtemplate APIを呼ぶようにしてます。 変更結果を確認もできますし。
(既存のindex mappingが即時変更されるわけではありません)

mappingでなくfluent-plugin-typecastを使って先に型を定義してしまう方法もあります。
私はmappingでdoc_valuesやStringにnot_analyzedを設定することが多いのでElasticsearchでは共通的にmapping作成するようにしてます。 mappingを作るにはまず一旦設定なしでデータを入れてみてできたmappingを見て変更するとわりと簡単にできます。

curl localhost:9200/<index>?pretty

Kibana4の設定

Visualize Line chartの設定画面です。

f:id:a3no:20150823224924p:plain

add metricsでY軸を複数設定できます。

f:id:a3no:20150823224927p:plain

複数表示できましたね。

f:id:a3no:20150823224929p:plain

cpuやmemory, swapはArea chartの方がいいかもしれませんね。
設定方法は一緒です。

f:id:a3no:20150823224932p:plain

Vertical bar chartなんてのも。

f:id:a3no:20150823224934p:plain

レコード分割せずに複数のfieldを同一グラフに表示できました。

結論

dstat + fluentd + kibana4(Elasticsearh)ではレコード分割する必要がない。
(ただし構成上の話で性能はわかりません)

sample

github.com ansible-hands-onを再利用して構築検証用Vagrantfile作りました。

番外

grafana + influxdbの場合はレコード分割が必要(?自力では調べてない)なので その場合はwinebarrelさんの記事を参考にするといいと思います。

YAPC::Asia Tokyo 2015に参加した話

YAPC::Asia Tokyo 2015に参加した話

f:id:a3no:20150823202626p:plain

f:id:a3no:20150823202636p:plain

2015/08/20-22に東京ビックサイトで開催されたYAPC::Asia Tokyo 2015に参加してきました。

参加メモ:
YAPC参加メモ 8/20 前夜祭
YAPC参加メモ 8/21 1日目
YAPC参加メモ 8/22 2日目

今週はhatenaの人と話す機会があったり前日がrebuild meetupだったりと、 個人的にあったまってたしすごく期待感のある滑り出しでした。 前夜祭はこれで前夜祭かーという内容で、自分の参加した中ではベストトークはJxckさんなんだけど、 次くらいにtagmorisさんが来てもおかしくないと思ったりもする。 自分の場合、perl書かないしインフラ方面に現在の趣向が偏ってるので、 参加したトークは半分くらいインフラ関連だったりということはあったんだけど、 逆にそういったトークが多いのもクラウドの時代を反映してるのかもしれないし、 perlのもつ特性やコミュニティがそういう状況にマッチしてるのかもと思ったりもした。

f:id:a3no:20150823202648p:plain

f:id:a3no:20150823202643p:plain

2130人が関わるTech系カンファレンスってなかなか無いですよね。 名前をよく聞くような人達もたくさん歩いていて、YAPCって色んな意味で愛されているんだなと思う。

f:id:a3no:20150823202651p:plain

2日目のsongmuさんのトークは朝一にも関わらず30分前に自分がついた時には既に席の6割が埋まっていて 最終的に立ち見状態だった。休みの日の朝一から参加するのはdevops tokyo以来な気がする。

f:id:a3no:20150823202703p:plain

YAPCの歴史を紡いだ人達の昔話にみんな興味津々で大盛況。

無限コーヒーとか無限弁当とか、2k規模の開催も含めて運営の人達はすごいと思う。 トークで聴いた中にSpaceApps運営話があって本当に色々な知見が詰まっていたんだけど YAPCの規模は更にもっと色々あるんだろうなぁとか。
湯村さんも941さん makiさんブログ参考にしたって言ってましたね。

LTのレベルが高すぎて、自分が思っていたLTはなんだったんだっていう。 YAPCあるあるでもハードル上げすぎって話題になってましたね。 LT芸人という単語が頭をよぎったとか無かったとか、、、

f:id:a3no:20150823202653p:plain

10回目にして一区切り。次回の奇跡はおきるのか。
人はbuilderscon.ioに新たな夢を見るのか。
また機会があれば参加したいですね。皆様おつかれさまでした。

YAPC参加メモ 8/22 2日目

YAPC参加メモ 8/22 2日目

Mackerel開発におけるScalaとGo、そしてPerl songmuさん

  • 趣味CPANIZE
  • Mackerelの開発
  • 新機能 外形監視 外部からクローリング監視
  • オンプレ構築 AWS障害とは無関係
  • LVS nginx scala redis postgreSQL Graphite
  • Angular typescript
  • Scala Go JavaScript Perl Ruby
  • Play Framework
  • Scala 静的型システム使いたい
  • 関数型楽しい
  • Option便利 Nullのない世界
  • コンパイルの遅さストレス<=>バグ混入率は低い
  • 大き目のものをカッチリ作るのにむいてる Scala
  • Mackerel-agent Golang
  • Golang 常駐プロセスに向いてる
  • URL外形監視
    • job queue: redis
    • 外形監視ワーカーサブシステム 切り出すと単体の状況が見れる
  • Graceful restart
    • github.com/braintree/manners
    • githubb.com/lestrrat/go-server-starter HTTP server(daemon)を簡単に作れる -> ?
  • Mackerelのサイトは はてなブログで運用している
  • paranoidhttp 内部DNSへの解決を禁止する
  • Golang
    • ロスコンパイル ちゃんとやると意外と大変
    • 書き捨てしづらい
    • 実用言語としての割り切り perl
    • 継承よりコンポジショん
  • MackerelにおけるHaskell
    • プロファイラ 劇的に毅然
  • リリースの自動化
    • Travisがgit pushする 止めれるようにしておく
    • 自動化機構は負債になりやすい? 肥大化 テスト困難
    • ツールをテストする ツールの責務をわける 手元で実行できるように
    • Github Deploy keys-
  • perl 全部Scalaだと大変 前段にやわらかいWebServerあったほうがいい
  • ruby: fluentd-plugin-mckerel / mackerel-client
  • はてな東京のエンジニア 1年で6倍!(6人)
  • QA
    • 言語の適材適所すると属人化しない? なりがちだが、レビューさせたり書いてもらう
    • Golang vendoring? 外部ライブラリは今の所慎重に使ってるので困ってない
    • buildスクリプトperlGolangレポジトリに入っているのは?
      • perl好きだし、軽いし違和感ない
    • deploy時間 最短20分だがテストもするので1時間とか

Mackerelはお世話になってるのでメモはけっこう飛び飛び、、、だったのだが 開発環境周りの話はそんなに聴いたことなかったのですごいためになった。 ServerはAWSじゃないんすね (それもそうか)

NASA主催の世界最大級ハッカソンSpaceAppsを運営した話 湯村さん

  • SpaceApps (International SpaceApps Challenge)
  • 衛星コレクション
  • 事務局はSpaceAppsのために結成 ボランティア
  • キャパ ハッカソンなので多ければいいわけでもない
  • スポンサー 参加費は不可のルール
  • 無断キャンセル対策 以降お断り文言掲載
  • 運営の情報共有 Timezoneが違うので1日3回MTG開催、どれかに参加
  • コミュニケーション重要 MTG後に食事したりとか。
  • ドキュメンテーション大事 やったことを全部書き出す 941ブログ Makiさん
  • イベントの運営側に参加してみよう
  • QA
    • 事務局長の仕事とは やる人がいないもの全部

世界で2番目くらいの規模のイベントだけど今まで知らなかったので参考になった。 イベント弱者だけど機会があれば・・・

Docker3兄弟について アルパカ大明神さん

  • Docker Machine / Docker Compose / Docker Swarm
  • Docker Toolbox
  • causion!!! all beta vesrion
  • Docker Machine: VagrantのDockerバージョンみたいなもの?
    • cloud上も同じIFで操作できる
  • Docker Compose: YAML定義から管理
    • extends 他のYAMLをincludeできる
  • Docker Swarm: filters strategies
  • Usecase
    • 開発環境配布 docker-compose.ymlもレポジトリに配布しておく
    • volumeでローカルと同期して、、、
    • Multi cloud cluster ?
  • zenbutsuさん
  • 開発環境としては十分利用可能

Docker早く使えるようになりたい。開発環境として十分というのは心強い。

3分でサービスのOSを入れ替える技術 hsbtさん

  • YAPC通らなかったペパボ社員->ペパボテックカンファレンス
  • 3ヵ月後にCM時にサービスを落とさないようにして?
    • Web+DB
    • 謎サーバ 単純平行ではない 数台ごにょごにょ
    • scale automatic 高速
    • 特命チーム
  • Scale out
    • old: golden image 秘伝のタレ
    • host情報を起動後に書き換える 手で。手順書 半日
    • できたらつなぎかえる 5-6台 tanpopo work
    • Scietific linux 6.x <- 火を噴く
    • new: puppet
    • 書きかけだった <- 書き換えた
    • ローカルモデルからagentモデルへ
    • コード化できた
  • Automation
    • sshを使わない 何でもできるものに制限を課すとイノベーションが起こる
    • cloud-init: YAML(userdata?)で起動時実行できる run_cmdは使わずpuppetに寄せた
    • Applicationはhostname/ipに依存しない 処理はIaaSからAPI取得
    • hostname情報みたいなのを消してImage登録自動でする
  • 稼動するとなかなかUpgradeできなくなるので、先にRails4にした。
  • いきなりHerokuみたいなことをすると爆発するので目も前のものを着実に自動化
  • 高速スケールアウト
    • 上記まででも1時間
    • capistrano3導入
    • Rails Bundle (内製) pull型 S3
    • Consul+consul-alert: nagios弱者、、、
    • mackerel: 1Roleに50+host, retire API -> shutdown init
      • 「公式がサポートして技術者の努力が全部無駄になりましたw」
    • fluentd
    • thor: sub commandを作れる
    • 人間が予測しなくてもよいアーキテクチャを使いましょう
    • 手作業にしない
    • ここまでで20-30分
  • 番外:Antipopさん Youtuberになりたい
  • 手順を分類 Slow Operation, Fast Operation
    • Minimal image (phase1)
    • 起動しただけでRailsが走るImage (phase2)
    • 重い処理の区切りごとにImageを作る->Packerで
    • Packer
      • Image creation の手前でServerspec実行
  • Infra CI: Drone CI->puppet
    • refactoring puppet manifests
  • BlueGreenDeploy
    • AWSはELB、OpenStackはnginx+consul-template,nginx-mruby
  • 今後
    • image作成の自動化
    • docker
  • QA:
    • ScaleするとDB等にかかる負荷はどうみてるのか? 1->10ということはないのでまだ大丈夫
    • Scaleout trigger: TV parameterから

ここでもConsul。Consulの話3回も聴いたし何か当たり前になってきてそう。 ちょうどこの前お試しで組み込んだばかりなので聴けてすごい捗るし、 どうやってこの仕組みを考えたかの背景まで聴けて参考になった。

【特別企画】YAPCあるある(仮)

立ち見なのでメモなし。 面子見てアッと思って直前に飛び込んだけど期待を裏切らなかった。 サラッと色々名言が飛び出してた気がする。動画ないのかな? yusukebeさんが緊張してた気がしてこの面子だとそりゃそうかっていう。 YAPC初参加組だけど楽しめました。

HTTP2 時代の Web jxckさん

これも立ち見。入れ替え時に前の席行こうとして失敗するという。 日本だしまたチャンスあるかもしれないしBrad Fitzpatrick見るべきかもとも思ったが、 Jxckさんのトークは本当にうまいしわかりやすいしワクワクするので聴きに来てしまった。 そしてめっちゃ満足している。社内勉強会に来てくれないかなとか思ってしまう。

Lightning Talks Day 2

めちゃくちゃ面白かったし、思った以上にレベルも高かった。 というか色々突き抜けてた。 完全にエンターテイメントだったので酒ありで再演を要求したい。 (すいません、調子にのりました)

クロージング

おつかれさまでした!

感想

すごい充実していた気もするし、しかし自分の参加の仕方は普通の勉強会の延長でしかなくて、 もっとスピーカの人達と交流したりした方がいいんだろうなぁと思う。 それでも今回のお祭りの一端に関わる事ができて良かった。 勉強会で発表できるようになるのは目標だけどおっさんになり過ぎたので 若い人が発表するのを酒飲みながら野次飛ばして聴くくらいがいいのかも。 (というgdgdな感想も酒飲みながら書いてます)

ともかく今回YAPCに関わった皆様、歴代のYAPCに関わった皆様もありがとうございました。お疲れ様でした。

YAPC参加メモ 8/21 1日目

YAPC参加メモ 8/21 1日目

メリークリスマス Larry Wall

いきなりホビット物語と指輪物語から入っていてオーディエンスが付いてきてなさげではあった。
バスには注意して欲しい。
よくわかってないけど正規表現の話?で$1が$0になるよって言ってて、
それって大丈夫なんだっけって少し思った。

世界展開する大規模ウェブサービスのデプロイを支える技術 aerealさん

  • Miiは全てhtml game内からもブラウザを起動して表示している
  • ゲーム内からも投稿できる
  • JP/US/EU
  • DB multi-master + region replication
  • PCからは全世界USにつながる
  • タイムライン、共感、通知はマルチサービスREST API
  • Miiverse deploy
    • capstrano2 + Git
    • region超える+台数が多くて同時git pull耐えられない
    • slave+random accessで分散
    • git slaveを各regionに配置 lsyncdの監視上限に到達してしまった Capstrano
      • Mackerel利用し、同じRoleを設定
      • AutoScaleは事前にpoolしたマシンを利用している
      • deployは一時的に全台あげて実施して不要分は落としている
  • 開発フロー
    • 初期 redmine -> 最近 GithubEに移行中 コードレビュー
    • Gitが2台になり同期ツール必要
      • hesokuri, ghm検討し新規開発することに
  • 新git同期システム
    • JSON over HTTP API
    • git pull & git push
  • 今後のデプロイ
    • 一般課題
      • deployに必要なものを全てcommit必要 repo肥大化
      • ビルドする場合、時間かかる
    • Miiverse課題
      • 台数 git負荷
      • region
    • consul + stretcher
    • jenkins build->s3->consul+stretcher
    • perf git: 1149 s consul+stretcher: 29 s
      • 40倍
  • QA
    • git同期システムおよび周辺->perl5 デプロイ周期 2週間+bugfix
    • pull型で一台だけ失敗した場合の検出?->失敗時の処理も書ける
    • pull req mergeは同期システムを導入した箇所では使えるようになった
    • codedeploy: 時期的に検討してない
    • consulのつらいところ: 各イベントの集約が難しそう。完了をそろえるのが?
    • どのくらいの規模からconsul? 30くらいからGit pullきつくなる

数年前からよくregion間運用の例としてウォッチしてたので聴けて良かった。
多チーム連携してるせいか課題や性能値がハッキリしててわかりやすい。

Consulと自作OSSを活用した100台規模のWebサービス運用 fujiwaraさん

  • Lobi スマホ向けコミュニティ プレイ実況とかも
    • 2010- AWS US 4台, 2011- 自社 4-20台, 2013- AWS max 100 AutoScale
  • hostの種類多い
  • perl, node.js, Go
  • AWS移行時の悩み DNSがない Chefで/etc/hosts
  • AutoScaleしたい
  • 内部DNSの代わりとしてConsul検討
  • failedだとDNS引ける left(自分から離脱したとき)は無理
  • rawってつけるとBodyだけ帰ってくる Base64decodeいらない
  • 全ての問い合わせをLeaderが処理する => stale modeにすると他も応答する
  • Consule server 2CPU 20MBMEM 2GBDisk
  • root command投げれないようにユーザプロセスにして、、、
  • 1年以上運用しているがAgentが落ちたりしたことはない
  • オペミスでLeader選出できない台数まで減らすと崩壊する・・・・
  • モンストにLobi SDKが入った=>大量の動画が、、、
    • Spot Instance + 自前AutoScale
  • クラスタ内でuniqueな名前が必要
  • Stretcher
    • AutoScaleするにはpullでないと、、、
  • Rolebackしやすい eventで前のMANIFEST指定しなおすだけ
  • Deploy完了を待つには->kv dashboard
    • 100台が失敗で100個ログ流れないようにkvsに入れて管理
    • trigger
  • Consul lock を使うと部分実行できる => BlueGreen
    • あるいはRole分ける
  • server内

完全に前のMiiverseの発表の課題解決みたいになっててお得感ある。 自分の場合は台数はそこまでじゃないけど、種類が多くてpushは指定がつらい感じ出てきて pull(remote trigger)が気になっていてconsulの説明が詳しくてありがたかった。
kv dashboardの意図も自分の懸念と合致していて色々タイムリー。Stretcherも検討したいなー。

Conway's Law of Distributed Work caseywestさん

  • remote で作業を行う様々なツール
  • remoteしていてもためにOfficeに来るの重要
    • 他に人がいることを意識する 機会
    • 意図的にremoteの人もchatやvideo chatの議論に巻き込む
  • 分散チームにもCAP定理
  • 分散化されたシステムを作るには分散化されたチームが必要(?)
  • なぜJIRAが嫌いか?
    • Administratorが全ての設定やWorkflowを変えれてしまう
    • 今まで自分が見ていたものが変わってしまう。
    • confluenceのhosted jiraだと、制限があるので安心
  • remote workだと働きすぎたりしないか?
    • 自分のスケジュールを厳しく管理
    • 帰宅を促す
    • 責任分担
  • Google docsGoogle等は信用できるのか?
    • 信じている
    • hipchatは履歴を暗号化してない過去があった
    • S3に関しては状況に応じて適用を変えるルールを決めた
  • code review とペアプロを同時にするか?自分はどちらかにすることが多い
    • 選択的にやる
    • ペアプロしてれば十分だが、第3の目が必要であればリクエストをかける
  • Timezoneに差がある場合はどうするのか?
    • 難しい いくつか方法があるう
    • いくつかの場所に人をまとめる 特定の機能をまとめて担当させる
    • 個人がばらばらの場合は非常に難しい
  • meetup頻度?
    • min:4半期に1回 
    • remoteで難しいこと 2つ
      • 人間関係の構築
      • 長期的なプランニング
  • languageが異なる場合の効果的なコミュニケーション
    • あまり体験がないが、英語ベースでやっていた
  • smartphoneでのChat 特にVacations
    • もちろん便利
    • 休みの時には気をつける 置いておく

英語+通訳だけど非常にわかりやすい内容だった。(翻訳も鬼)
すごい特殊なことをしてるわけではなく、でも色々と気を配ってるようなイメージ。
remoteやってみたいけど集中力がなー。悩ましい。

うっかりをなくす技術 karupaneruraさん

立ち見だったのでメモなし 自分の趣向的に運用期待だったのでプラグラマーかーという(当たり前)
「リーダブルコード読んどけ」はアグリー

感想

LT...は部屋に入れずに帰った。
前の時間の最後、部屋を出る人が多くて感じ悪かったがこういう事かと。
中に着てたYAPC TシャツにLT時になろうと思ってたのだが。。ちょっと残念だった。

いくつか見たいけど満室で無理なものもあって、明日はもっと激戦なのでYAPC半端ねーなー、すげーわーって感想(小並感)
以前にチケット買ったのに来なかった時もあってすごい損した気になってきた。
今回は個人スポンサーに何故かしたけどそれだけの価値はあると思った。

YAPC参加メモ 8/20 前夜祭

YAPC参加メモ 8/20 前夜祭

言語開発の現場 ペパボ柴田さん

  • ruby開発の現場の裏側紹介
  • MatzはDirector 数年はrubyコードは書いていない
  • 担当領域はあったりなかったり。
  • サポートしてくれる人が居ればサポートOSになる
    • Windowsの方がOX Xよりサポート早いかも?
  • rubyは日本人コミッタが多く日本内で決められているように海外から見られているので 対面で英語でやるDeveloper Meetingを毎月開催してる
    • 松本さんも毎月出る機会
  • 大変なこと:リリース この前も2時間のつもりが4時間かかった

言語開発ってruby以外はほぼ海外なので、身近に日本語でこういった内容をシェアしてもらえるのは貴重。
ruby committersがC programmerというのは言われてみればそうだけど面白い。

はてなブックマークのトピックページの裏側 skozawaさん

大盛況で立ち見状態で床に座って声だけ聴いてた。なので雰囲気だけ。

  • 本文の生成?が30分かかる 6ノード
  • ニュースタイトルからの生成が主なのでおかしなトピックが生成されてることはあまりない
    • 判定は今のところはまだ主観
  • 時系列を含めれるようにしたい。

Elasticsearchの知見はお面白そうなので後で見てみたい。 社内で誰か見てそう。

我々にできるOSSとそのコミュニティの育てかた tagomorisさん

既に酔っ払ってメモなし!
作れないけど貢献はしたいので参考になる。
プルリク一応英語で書くようにしてるけど、相手がどう思っているかは・・・
質とコミュニティ発展の関係性に関する和田さんの質問が深すぎてヤバイ。

あっ、perlの話聴いてないぞ・・・

Ansible Dark Side

Ansibleは非常にシンプルかつ強力なツールですが、 様々な設定方法・書き方が許容されるがゆえにやり過ぎると収集がつかなくなります。 そんな若干やりすぎかもしれない設定の一部を晒してみます。 タイトルは若干大げさですが、お勧めするような設定ではないという自虐的な意味を込めてます。

production/staging environment variables

Ansibleである程度の規模のプロビジョニングをするようになると 公式DocumentにもあるBest Practices に倣うと思いますが、 この時課題の1つとなるのがproductionとstagingで異なる環境変数をどう管理するかです。

検索してみると何種類かのやり方がHitするのですが、うちでやっている方法も書いてみます。 このやり方はAnsible始めた頃に同僚から教えてもらった方法です。

inventory/
    production/
        group_vars/
            all
            group1
            group2
        hosts
    staging/
        group_vars/
            all
            group1
            group2
        hosts
roles/
site.yml

group_vars + hostsファイルという構成を productionとstagingのそれぞれのディレクトリに作ります。 こうするとallはproduction全体・staging全体を表すことになるので、 それぞれに適用したい変数を設定できますし、 group1、group2も環境毎の値を設定できます。

実行する際は、

ansible-playbook site.yml -i inventory/production/

デメリットはproduction/staging共通の設定であっても2箇所に書く必要があることです。 そのためパスは少し深くなりますがinventoryというディレクトリの中に両方を入れて、 ネストしてみせることで両方設定する必要がある、 というのを意識しやすくしています。 (並び順がバラけるのを防ぐ意味もある) 自分は更にlocalというディレクトリも作って 手元のvagrant上でレシピをテストする時に使ってます。 (.gitignoreで登録対象からは外す)

大外に共通用のgroup_vars作ればいいかもしれませんがgroup_varsが複数個所にあると 管理が更に煩雑になる気もするのでこのくらいが自分には限界の気がします。

large repository management

サービスがある程度の規模になってきてチームで運用が分かれたり、 小規模でも複数のサービスを同時に運用するようになると、 レシピの管理単位を分割したくなります。 一方で、共有したいRoleも当然あります。 以下を参考にしてディレクトリ構造を組みました。

参考: Ansible オレオレベストプラクティス

参考にしつつ試行錯誤して自分なりの設定を加えています。

common-roles/
    vars/
    filter_plugins/
    roles/
        jdk/
        nginx/
        mackerel_agent/
team1/
    inventory/
    roles/
        app1/
    ansible.cfg
    site.yml
team2/
    inventory/
    roles/
        app2/
    ansible.cfg
    site.yml
$ cat team1/site.yml

- hosts: app
  sudo: yes
  vars_files:
    - ../common-roles/vars/xxx_vars.yml
  roles:
    - jdk
    - nginx
    - app1
    - mackerel_agent

参考サイトと異なるのはcommon-rolesのRoleもteam1のRoleも同じように指定できるところ。 これを実現するためにansible.cfgを各実行ディレクトリに置いています。

$ cat team1/ansible.cfg

[defaults]
roles_path = ../common-roles/roles/
filter_plugins = ../common-roles/filter_plugins

関係ある設定はこんな感じでcommon-rolesのパスを設定すると、 設定したパスのRoleと実行ディレクトリ配下のRoleの両方読んでくれます。 filter_pluginsも同様に出来ました。 同様には出来なかったのがlibraryのパス設定で、 これは要するにmoduleを読むパスなんですが、 設定するとそのパスのみが有効になってしまい、 Ansible組み込みのmodule群が使えなくなってしまったので、 libraryに関しては実行ディレクトリ配下か、Role内にのみ置いて使っています。 それから共通で使うvars_fileみたいなのはそんなに数多くないし 相対パスで指定してます。

Ansibleは本来はもっとシンプルに運用可能なツールで、 library, group_vars, roles, xxx_plugins みたいな決まった名前のディレクトリを 実行ディレクトリ配下に置いていると勝手に読んでくれるので、 可能ならansible.cfgとか使わずに済んだ方がスッキリできるとは思います。 (接続性の設定とかは別)

Include various settings

mackerelとかtd-agentとか横断的に利用し、 かつ複数の設定をもつようなRoleがあります。 パターンの種類が少ないうちは種類ごとに分けたファイルをinclude + whenで 処理していました。

roles/
    mackerel_agent/
        tasks/
            configure_a.yml
            configure_b.yml
            main.yml

$ cat main.yml

- include: configure_a.yml
  when: mackerel_agent_type == 'aaa'
- include: configure_b.yml
  when: mackerel_agent_type == 'bbb'

この手法は分岐条件が少ないうちはまぁなんとかなりますが、 パターンが増えてくると徐々に扱いづらくなってきます。 ソースも見づらくなってきますし、実行時のログがwhenの場合は実行されない条件でも skippedとしてログに出てしまうので実行結果が読みにくいです。

解決策としては2種類考えました。

1つはincludeするファイル名を変数化することです。

- include: configure_{{ mackerel_agent_type }}.yml

しかし課題もあり、group_varsでこの変数を指定しようとすると失敗します。 理由は、変数を読む順番のためだと思っています。

参考: Ansible の変数の優先順

group_varsよりplaybook role parameterの優先順の方が早いので、 playbook role parameterを読み取るためにincludeしようとして そんなファイルは無い、となります。 playbook vars (site.ymlの先頭にvars:で書く)で指定するとうまくいきます。 playbook毎に適用種類は決まる気がするので 今は一旦この方法でやろうと考えていています。

記事を書いているうちにもう1つの案が実はよりよく感じてきました。 もう1つの案とはRoleを分けることです。 Ansibleを運用する場合、多くの場合でRoleを適宜分割することは良い案です。 特にサービスに依存するような設定を行う場合、 ミドルウェアのインストールのような汎用的な部分と、 ミドルウェアの設定をサービスに合わせて行う部分は分けた方が良いです。 更に後者から前者にDependencyを設定しておけば後者のみ指定でよくなります。

roles/
    mackerel_agent/
    mackerel_agent_serviceA/
    mackerel_agent_serviceB/

$ cat site.yml

roles:
  - mackerel_agent_serviceA

デメリットはRoleが複数増えてしまうことと、共通の変数を設定しているような場合に 設定箇所が散らばってしまうことでしょうか。 共通のRoleがやたら増えるのも困るので今は1つ目の案で考えています。 (refactoring now...)

以上、3つほど運用パターンを晒してみました。 これらは決して勧めているわけではなく、 多分、ここまでやる前に構成や運用を見直した方が良い気がするのですが、 こういった事も出来るよ(やっちゃってるよ)という記事でした。

ちなみにちょっと気になって、 初心者Chefアンチパターン を久々に見返したらほぼ当てはまっていて今回の内容もだいぶやばいかも。。