UZABASE Tech Blog

〜迷ったら挑戦する道を選ぶ〜 株式会社ユーザベースの技術チームブログです。

モンスト、スマニュー、Wi2の運用秘話多数! 「SRE Lounge #3」レポート

株式会社ユーザベースのSPEEDA Japan Company、Site Reliability Engineering (SRE) Teamの川口です。 先日、「SRE Lounge #3」という勉強会を開催しました。 発表企業4社のみ参加の非公開な会でしたが、ここでしか聞けないようなディープな話題が満載でした。

目的

「SRE Lounge」は、

  • 各社SREチームの取り組み事例の共有(情報交換・発信)
  • SREそのものについて議論し、知見を深める

といったことを目指して行われている勉強会です。

開催の背景や、そもそもSREとは何かについては、「SRE Lounge #1」の記事を参照してください。

開催日時

2018年5月17日(木) 午後7時30分 開始

会場

今回は、ミクシィ様本社のコラボレーションスペースをお借りしました。 広くておしゃれなカフェのような雰囲気で、窓からの眺めも良く、渋谷の夜景がきれいでした。 ランチや社内の打ち合わせだけでなく、今回のようなセミナーやイベントにも使用されているということです。

f:id:uzabase:20180522233522j:plain
会場のミクシィ様本社コラボレーションスペース

参加企業

※発表順

発表内容

当日のスケジュールは以下の通りです。

  • 各社の取り組み事例等の発表と質疑応答(各社20分程度)
  • 発表を踏まえた意見交換会(30分程度)

ピザやお酒を取りながら、終始和やかな雰囲気で行いました。

f:id:uzabase:20180522234242j:plain
スマートニュース様の発表を真剣に聞く皆様

ユーザベース 

企業・業界情報プラットフォーム「SPEEDA」のシステム構成の変遷を紹介しました。

サービスの成長に伴い、プロダクトチーム(dev)とSREチーム(ops)のやり取りでのオーバーヘッドが多くなったため、 開発チームだけでCI/CDまで完結出来る環境を構築しました。 具体的には、Kubernetes+Rancherの構成となっています。 クラスタレベルロギングアーキテクチャを採用し、各APから出力されたJSON形式のログを、fluentd経由でバックエンドのBigQueryに格納していることも特長です。

質疑応答では、アラート発生時の一次調査担当や、システム環境の統制などが多く挙がり、どの企業でも苦労されているようです。

当日発表資料:SRE Lounge#3 UZABASE

ワイヤ・アンド・ワイヤレス様

「Wi2」などのWi-Fiサービスを提供されるワイヤ・アンド・ワイヤレス様には、 サービス提供環境のオンプレミス環境からクラウド環境移行への歩みについて、詳しく紹介いただきました。

オートスケーリングやコスト削減を期待してクラウドを導入したものの、なかなか思惑通りにいかず苦労されたそう。 しかし、少しずつ安定し、知識も得られてきたということで、サーバレス化やAWSの新しいサービスの利用も進めているとのことです。

Wi-Fiサービスならではの苦労も少なくない中、今後もアグレッシブに挑戦していきたいそうです。

当日発表資料:Sre wi2 20180517

f:id:uzabase:20180522234647j:plain
ワイヤ・アンド・ワイヤレス様発表中

スマートニュース様

ニュースアプリを提供されるスマートニュース様には、SREチームで担当されている膨大な業務範囲から、「モニタリング」「障害振り返り」の2つを紹介いただきました。

モニタリングでは、各リソースに適した様々なシステムを駆使しての監視を行っているということで、各社で参考になる部分も多かったと思います。

障害振り返りでは、障害発生時のインシデントレポート作成や、事後のインシデントレビューを行っており、再発防止策のトラッキングも工夫されているようです。 また、インシデントレビューの読書会も検討されているそうで、この辺りはまた詳しく聞いてみたいです。

質疑応答では、ニュースアプリならではの話題として、プッシュ通知時のアクセス集中対策の話が盛り上がりました。

当日発表資料:SRE at SmartNews

ミクシィ様

最後に、ミクシィ様のXFLAGスタジオから、「モンスターストライク」(モンスト)用に構築されているマルチクラウド環境について紹介いただきました。

「モンスト」のようなソーシャルゲームでは、例えばイベント期間だけ爆発的にアクセスが増えるため、サーバを短期間だけ増強する必要があります。 元々はオンプレミス環境で運用していましたが、最適な構成を模索するうちに、複数のクラウド環境を併用するに至ったそうです。 そのためのネットワーク構成や管理面での工夫や、各クラウドごとの癖についての話もありました。

SNSからの大規模サービス構築・運用ノウハウのあるミクシィ様ならではの内容で、当社とはスケールの違う話にワクワクしました。

当日発表資料:モンストのマルチクラウドについて / sre-lounge-at-xflag

発表を終えて

各企業のサービス内容やSREチームの守備範囲、SREに対する考え方など、これまでのSRE Lounge以上にバラエティーに富んでいて、とても興味深かったです。 また、各社の発表内容がディープで、質疑応答や意見交換会も大変活発でした。 当初予定していた時間を大幅に超えてしまいましたが、皆様多くのものを得られたのではないかと思います。ありがとうございました。

「SRE Lounge」は、今後も開催していく予定です。 興味を持たれた方や、発表してみたいという企業の方は sre@uzabase.com までメールにてご連絡ください。 また、Facebookの「SRE community」でも情報共有、交流を行っています。非公開グループですが、お気軽にご参加いただければ幸いです。

f:id:uzabase:20180522231824j:plain
今回参加いただいた各社の皆様

仲間募集!!

ユーザベースのSPEEDA SREチームは、 「No Challenge, No SRE, No SPEEDA」 を掲げて業務に取り組んでいます。

「挑戦しなければ、SREではないし、SREがなければ、SPEEDAもない」という意識の元、ユーザベースのミッションである 「経済情報で、世界をかえる」 の実現に向けて、日々邁進しています。

少しでも興味を持ってくださった方はこちらまで!

JaSST'18 Tokyoに参加してきました!!

こんにちは、ユーザベースのPDT(Product Development Team)です。

我々PDTは今年3月7日と8日にJasst’18 Tokyoに参加してきました。 今年のJaSSTではユーザベースはスポンサーとして協賛したので、私たち社員は無料で参加することができました。大変ありがたい話です。 今年もたくさんのセッションがあり、たくさん有用なお話が聞けました。 今回は私たちが参加したセッションについて紹介していきたいと思います。

各セッションの紹介

A1. 基調講演 「Advances in Continuous Integration Testing at Google」

Googleで長年CI/CDに取り組んできたJohn Micco 氏による講演でした。

Testing Scale at Google :

  • 420万件のテストが継続的に実行されている
  • 1日に1億5000万件のテストが実行されている(1日平均35回テスト実行)
  • 99%のテストがパスする

講演資料の2Pより http://jasst.jp/symposium/jasst18tokyo/pdf/A1.pdf

まず規模感とテスト文化の説明があり、Googleは翻訳関連とUX関連のテスト以外はすべて自動テスト化されているらしく本当に圧倒的でした。。。 次に、これだけのテストをどうやって実行するのかのための施策として、必要なリグレッションテストケースの選定の話。 そして2日目のTutorialの内容でもあるテストメトリクスの分析について説明されていました。 定期的に実行される自動テストの結果から、バグを生んだコミットを探す方法やFlakyTests(不安定なテスト)を探すためのアプローチをかなり詳しく聞けてとても興味深かったです。

質疑応答では、マニュアルと自動テストの費用対効果の質問が結構出ていましたが、自動テストは当然なのでマニュアルテストとかありえない的な回答。日本のソフトウェア開発にこの文化が根付く日が早く来てほしいです。

E2. やってみよう!探索的テスト〜ハイクオリティな妄想の高速ループ〜

Jasst ’17 Hokkaidoの実行委員中岫さんと根本さんによる、ハンズオン形式の探索的テストのセッションでした。

このセッションではherokuに設置されたWebアプリケーションに対して、実際にみんなで探索的テストをやってみるといった内容でした。私は開発者なので、普段は「期待通りに動いていること」を保証するテストなら自動テストで行なっています。しかし、バグを叩き出すことを目的としたテストはあまり経験がないので非常に新鮮な体験なりました。ちなみに多い人は20個ほどバグを発見できたそうですが、私は2個でした(笑)。

最後に他の方達とどんなバグを出したかを話す時間がありましたが、そこで出たバグの内容の違いに驚きました。私が見つけようとしていたバグは、システム自体が使い物にならなくなるようなバグのみでした。しかし、他の方はユーザにとって使い勝手が悪いと感じる仕様や、通常の運用ではしないような入力を与えたことで発生する事象もバグとして記録していました。開発のエンジニアとテストエンジニアとの間でテストの視点が全く違うのだなぁと感じました。

C4-1. 探索的テストにおけるストーリーベースのアプローチ

NTTデータ熊川さんによる探索的テストに関する研究発表でした。

タイトル的にアジャイル開発でよく聞く「ストーリー」のことかと思いましたが、ここでのストーリーは本来の意味の物語をさしています。人間は自身の体験を物語形式のパターンとして当てはめる傾向があるらしいです。熊川さんの手法は探索的テストで利用するチャーターを物語の形式にすることで、テスターの知識や経験を探索的テストに反映させやすくするというアプローチを取っていました。

結果としては、従来手法より圧倒的に優れた訳ではありませんでしたがアプローチそのものは非常に面白いと思いました。

C4-2. NGT記法を応用した不具合分析からのテスト補強

ベリサーブ吉川さんによる、足りないテストケースを補うためのアプローチに関するセッションでした。

NGTとはテスト観点図を作成するための表記法です。吉川さんはテスト観点ではなく、発見した不具合の持つ要素にたいしてNGTを適用して不具合分析を行い、導出した要素から別のテストケースを作る手法を提案していました。結果としては提案手法を使うことで、既存のテストケースだけでは取り逃がしていた可能性のある不具合を見つけることができていました。

個人的には不具合の持つ要素も結局はテスト観点になるのではないかと思います。本来、テストに必要になりそうな要素ならなんでもテスト観点になり得ます。なので不具合そのものはテスト観点でないにしてもそこから導出される要素はやはりテスト観点だと考えられます。そういう意味では、このセッションの本質はテストフェーズでテストアーキテクチャを見直しませんか?という提案ではないかと思いました。

D4.「無料で始める!「龍が如く」を面白くするための高速デバッグログ分析と自動化」

元ゲームプログラマであり「龍が如くスタジオ」専属QAエンジニアの阪上さんによる、テストの自動化とそのログ解析方法についてのセッションでした。

セッションのメイントピックは kibana + fluentd + elasticsearch を組み合わせたデバッグログの分析だったのです、その前段として、自動テストでゲームを全クリできるほど自動化されているというのが衝撃でした。実際にキャプチャ/リプレイでオートメーションされたテストのデモも見れて面白かったです。 自動テストをバグ出しのために使うだけでなく、テスト結果を分析してゲームのチューニングに利用しているという1つ上のレベルの取り組みをされていて日本企業でここまで成功している事例があることに驚きました。

B5. ケーススタディで学ぶ仕様の書き方

川口さんによる、形式手法に関するセッションでした。

形式手法は仕様を厳密なルールで記述することで、仕様の曖昧さを排除できたり、仕様の矛盾をプログラムで自動的に発見できるなど非常に高度な手法です。川口さんは組み込みシステムの振る舞いの仕様を状態遷移図を使って形式化し、それに対してモデル検査をかけて曖昧な点や矛盾をなくすアプローチについて説明していました。

しかし、このセッションで最も有用だったのは形式手法そのものより、既存のシステムにたいして新しい機能を追加しなければならない状況で、1から仕様書を作成するときのノウハウを共有していただけたことだと思います。具体的にどうするかというと、新しい仕様については全て状態遷移図を書きます。その時に既存の部分と密接な関わりがあるならば、新しい仕様の状態遷移図に対して既存の仕様の要素を追加します。つまり、新しい部分は全て記述し、既存の部分は必要な分のみ追加するということです。既存の部分に対してまで、網羅的に仕様書を作っているとコストがかかりすぎるのでこのようなアプローチが重要なようでした。

E5. 海外のテスト技術動向 ~カンファレンス、国際会議、海外テストチームの現場から~

パネリスト:辰巳さん、松尾さん、山口 さんによる海外のカンファレンスや海外でのテストチームの編成に関するセッションでした。

辰巳さんのパートでは、海外のソフトウェアテストのカンファレンスについて概要と歴史などを紹介されていました。 2018年も海外でこんなにカンファレンスがあるようです。http://www.softwaretestingmagazine.com/software-testing-conferences/

やはり日本よりも海外のほうがだいぶ先行していることを改めて感じました。 印象に残ったのは、どうやって情報収集しているのかという質問に対して「SNSやネットでひたすら追いかけている」と応えていらっしゃったことです。興味があるものに関して言語を超えて情報収集し、そこから更に発信していく姿勢にとても刺激を受けました。

続いて、山口さんのパートではSTARWESTとAgileTestingDaysに実際に参加した感想を発表されていました。 STARWESTはディズニーランドホテルでやってるとのこと。参加費がJaSST’の8倍くらいかかってるのに参加者は同じくらいいるそうです。 ソフトウェアテスト製品のベンダーがスポンサーにたくさんついていて、講演者も多いとのこと。講演者と講演後に個別に質問などができる機会が設けられているが質問というより営業に近いと言っていたのも日本とは違うなという印象でした。

最後に、松尾さんが海外にテストチームを組成する際の経験談についてお話しされていました。Uzabaseでも海外開発チームの組成を進めていますが、やはり大変なところは採用というのは共通してるようです。実際に自分で海外企業の面接を受けてみて知見をつけてから採用活動に取り組んでいるというお話もされてました。優秀な人材を見つけるにはちゃんと調査や準備が大事ということですね。

セッションを通じていえるのは、日本にとどまらず海外の事例に学ぶ姿勢を持つのが大切だということです。パネラーの方々のように積極的に良いものを探し出して取り込んでいけると理想的ですね。

A7. 招待講演 「私が経験したソフトウェアテストの変遷」

現在のソフトウェア開発にいたるまでの「技術的変遷」とTDD、CI/CDのお話し。柴田さんご自身の富士ゼロックス、リコーでデジタル複合機の開発をされた際の経験談についての講演でした。

前半では、過去の偉大なエンジニアたちがいかにしてTDDにいったたのかをわかりやすく説明されていて、その意義を再認識しました。最初にテストコードを実装してからプロダクトコードの実装をすることで、開発者へのフィードバックループをいかに短くし、すぐにバグや設計ミスをすぐに修正できるようにする、というTDDの手法はUzabaseでも導入していますが、品質とスピードを担保するためにすごく考えられて作られた手法なのですね。過去の偉人に感謝。

後半のご自身のマルチスレッドプログラミングに関するトライ&エラーの経験談で印象にのこったのが、開発者全員が毎晩自動テストを実行していたところ、3か月前にコミットされたコードに問題があることが発見されてとのお話しでした。これも自動テストがなければ絶対見つからないよねって感じで自動テストってほんとに大事だと思わされました。 自動テストを大切な資産ととらえて開発チームみんなで認識してメンテナンスしGREENにし続けていかなければと強く感じました。

終わりに

いかがだったでしょうか。 JaSSTでは本当にたくさんのセッションがあり、非常に勉強になります。 周りきれなかったセッションもありますがそちらもきっと為になる話が聞けのではないかと思います。

JaSST'18 Tokyoゴールドスポンサーとして協賛しました!

こんにちは! SPEEDAのテストエンジニアをやっている工藤です。

ユーザベースとして、2018/03/07(水)ー03/08(木)に開催された JaSST'18 Tokyo を協賛いたしました。
今回は協賛した理由とそこから読み取れる弊社でテストエンジニアとして働くことの価値を書きます。

f:id:kudogen:20180320101504j:plain

JaSST Tokyoとは

JaSST Tokyoとは業種や職種を問わずソフトウェアテストに関心がある方が一同に集まる、国内最大のソフトウェアテストシンポジウムです。
JaSST’18 Tokyoには2日間で延べ1600人を超えるエンジニアが参加し、一時Twitterのランキングで6位になるなど大盛り上がりのカンファレンスでした。
当日盛会の様子は下記からご覧ください。
JaSST Tokyo実行委員ブログ
JaSST'18 Tokyoレポートページ

ゴールドスポンサーとして協賛した理由

この度は、

SPEEDA開発でも様々なOSSを利用したりとコミュニティ活動の恩恵を受けているので、このような活動をサポートすることでコミュニティに還元していきたい。

という想いでゴールドスポンサーとして協賛いたしました。

元々SPEEDA開発では、エンジニアがコミュニティ活動などに積極的に関わることが推奨されています。
そんな背景もあり、私(工藤)もJaSST Tokyoの実行委員として活動しておりました。

特にテストはSPEEDA開発において最も大事にしていることの一つなので、ゴールドスポンサーという形でソフトウェアテストのシンポジウムを協賛できたことはとてもうれしく思っています。

SPEEDAプロダクトチームでテストエンジニアとして働くことの価値

今回、JaSST Tokyoを協賛・参加して改めて「SPEEDAプロダクトチームでテストエンジニアとして働くことの価値」について考え、以下に挙げてみました。

  • 基本的に各チームに権限が委譲されているので自動テストや新技術の導入はエンジニアドリブンで行うことができる
  • テストを下に見るような変な風潮はない
  • チームとしてテストを大事にしているからこそ、テストエンジニアとしては価値を出しやすい
  • 常にチームとして技術的なチャレンジを行っているので、エンジニアとして成長しやすい環境がある
  • テストエンジニアも開発チームの一員となって動くので、開発側の知識もつけていける
  • 前述の通り、コミュニティ活動などに理解があり、推奨されている

今後もSPEEDA開発として、JaSSTのみならず様々なコミュニティ活動に貢献していきたいと思っています。

現在、技術的にチャレンジしたい、成長したいテストエンジニアを募集しております!
少しでも気になった方はこちらまで

はじめてのDuct

 SPEEDA開発の中村です。今回の内容は,弊社主催のclj-ebisu #2で発表した「実践Duct(仮)」です。 ClojureのサーバサイドフレームワークDuctを業務で使って学んだことを紹介します。 connpass.com 勉強会で発表した資料はこちらです。

 はじめに,Ductのコアで使われているフレームワークIntegrantを紹介し, サーバサイドでIntegrantを使って感じた課題についてお話しします。 次に,課題に役立つDuctのmoduleのしくみと作り方を説明します。 想定読者は,Clojureを書いたことがあってDuctを使ったことがない方です。

目次

Integrantのつかいかた

 Integrantは,アプリケーションのモジュール構成をmapやednのようなデータで表現するためのDIフレームワークの一種です。 Integrantは,アプリケーション起動時にデータが示すモジュールの依存関係を解決し,アプリケーションを初期化します。 Integrantのドキュメントでは,データで構造が表現されたアプリケーションをデータドリブンアーキテクチャと呼んでいます。

 まず,例題を通してIntegrantのイメージをつかみましょう。とりあげる例題は,ヘルスチェックを行うringサーバのハンドラを初期化する処理です。 get-healthは引数に与えられたURL先のステータスを問い合わせる関数と考えてください。

(def endpoint “http://localhost/health”)

(defn handler [request]
  (get-health endpoint))

(defn -main []
  (jetty/run-jetty handler {:port 3000}))

なんてことはないプレーンなコードですが,変数や関数のスコープが必要以上に大きいという問題があります。 mainhandlerに,handlerendpointに依存しており,本来mainからendpointが見える必要はありません。 しかし,mainendpointがグローバルなスコープを持っているため,お互いに参照できるようになっています。 関数のスコープは呼び出される関数だけから見える大きさで十分です。

 Integrantは,このスコープと依存解決の問題をクロージャで解決します。 次の2つのコードは上のコードをIntegrantで再実装したものです。 この2つのコードは,上段がdefmethodで囲まれたモジュールの実装で,下段がモジュール間の依存関係の定義するednです。 依存するオブジェクトをdispatchの引数として関数に与えることで,Integrantはスコープを小さくします。

(defmethod ig/init-key :ebisu/hanlder
  [_ endpoint]
  (fn [request] (get-health endpoint)))

(defmethod ig/init-key :ebisu/jetty
  [_ {:keys [handler] :as options}]
  (jetty/run-jetty handler options))
{:ebisu/handler “http://localhost/health”
 :ebisu/jetty {:handler #ig/ref :ebisu/handler
               :port 3000}}

 この依存関係を宣言するednが,コンフィグレーションマップと呼ばれるアプリケーションの構造を定義するデータです。 マップの最上位の各キーはそれぞれモジュールであり,キーの値はモジュールの初期化に必要な別モジュールや値です。 #ig/refを使えば別のキーワードを参照できます。 ここでは,ハンドラはURLに依存し,jettyサーバはハンドラとポート番号に依存するという関係があります。

 アプリケーションを初期化するには,コンフィグレーションマップをintegrant.core/initに渡します。

(integrant.core/init 
  (integrant.core/read-string (slurp "config.edn")))

initは,最上位のキーの値がマルチメソッドの返り値に置き換わったマップを返します。 上の例であれば,initは,マップにある:ebisu/handlerget-healthを本体で呼び出す高階関数に置き換わったマップを返します。

 余談ですが,IntegrantもDuctもClojureのライブラリをたくさん作られているweavejester先生の作品です。 本稿ではDuctより先にIntengrantについて説明しますが,IntegrantはDuctより後に生まれたフレームワークです。 Integrantが担っているDuctの機能には,もともとComponentが使われていました。 後に,先生は何かに不満を覚えたのか,Componentを使っていた部分をIntegrantに置き換えました。

Integrantなせかい

 これまでみたように,Integrantは,モジュールの実装(defmethodの本体)とアプリケーションの構造(コンフィグレーションマップ)にプログラムを分離します。 次は,分割の後ろにある考え方を説明します。

 Integrantは,Arachneから影響を受けて作られたため,Arachneの考えを受け継いでいます。 Arachneの世界観を詳しく知りたい方は,Clojure eXchange 2016での作者によるプレゼンテーションを観るとよいでしょう。 プレゼン前半のテーマは,フレームワークとライブラリの違いです。 自分たちのコードを呼び出す側にあるのがフレームワークで呼び出される側にあるのがライブラリ, そしてフレームワークはアプリケーションの構造を規定する,という主張でした。 テーマの後ろには制御の反転やハリウッドの法則があります。

 IntegrantはArachneのアイデアをベースにしているので,Integrantにも,アプリケーションの構造を定義する役割があります。 モジュールを指すシグネチャがあれば,アプリケーションの構造(モジュールの依存関係)を宣言できます。 モジュールの実装はアプリケーションを実際に起動するまでいりません。 このように,モジュールの実装とモジュール間の依存関係は別の関心事とみなせることができます。 それゆえに,関心の分離にしたがって,Integrantは,モジュールの実装とモジュールの依存関係をマルチメソッドとコンフィグレーションマップに分けています。

Integrantでこまること

 弊社では,Clojureで作るものは主にWebアプリケーションです。 Webアプリケーションには,ルーティングやDBアクセスなどドメインを問わず実装すべきものがあります。 フルスタック系のWebフレームワークであればこれらをサポートしているものもありますが,Integrantにはありません。 使いたい機能があれば,自分でそれをIntegrantのモジュールにする必要があります。

Ductのmodule

 DuctはIntegrantをベースとするサーバサイドのフレームワークです。 フレームワークとしてIntegrantと同じ役割を果たし, module1と呼ばれる形式でアプリケーションを問わずよく使われる機能を提供しています。 moduleを使えば,Integrantで必要だったボイラープレートコードを減らせることができます。 有名なmoduleはductのリポジトリのREADMEで紹介されています。 github.com

Ductでこまること

 上のサイトを見た方は気づいたかと思いますが,執筆時点においてmoduleの数は多くありません。 moduleを使えばボイラープレートコードを減らすことができますが,なければどうしようもありません。 アプリケーション間で再利用したいコードがあり,その機能を担うmoduleがないのであれば,moduleを自分で作るしかないでしょう。

 ところが,module同様に,moduleを作るための参考資料もまた少ないのです。 いざmoduleを自作してみようとしたところ,情報が少なくて困りました。 そこで,moduleの作成する上で知っておくと役立つmoduleの振る舞いと作り方について紹介します。

Ductによるコンフィグレーションマップの展開

 moduleのしごとは,アプリケーションのig/init-keyマルチメソッドを呼び出す前にコンフィグレーションマップにエントリを追加したり, 追加したエントリに対応する実装(マルチメソッド)を提供したりすることです。 Integrantではアプリケーションの初期化手順は

  1. (read step) コンフィグレーションマップを読み込み
  2. (init step) init-keyマルチメソッドを呼び出す

という2手順に分解できます。 Ductにはread stepとinit stepの間にprep stepがあり,prep stepでコンフィグレーションマップが展開されます。

 一例として,logging moduleが,コンフィグレーションマップを書き換える過程を追ってみましょう。 moduleは,自分たちで作るモジュールと同様,Integrantのキーワードにすぎません。 logging moduleの場合は:duct.module/loggingです。 以下では,devで開発環境用のコンフィグレーションマップを読み込んで初期化処理をread stepまで進めています。

$ cat resources/ebius/config.edn
{:duct.module/logging {}
  ...}
$ lein repl
user => (dev)
:loaded

 次にprepでprep stepまで進めます。 configを評価すると展開後のコンフィグレーションマップを確認できます。

(dev) => (prep)
:prepped
dev => (pprint config)
{:duct.logger/timbre {:level :debug,
                             :appenders {: ...}
 :duct.logger.timbre/spit {:fname “logs/..”}
 :duct.module/logging {}
 ...}

コンフィグレーションマップにログのレベルや出力先が追加されました。 logging moduleはロギングライブラリtimbreを利用するため,追加されたキーワードにはtimbreが含まれています。

 最後にgoを呼び出すことで,展開後のコンフィグレーションマップに従い初期化されたWebサーバが起動します。

(go)
:duct.server.http.jetty/starting-server
{:port 3000}
:initiated

Ductのmoduleのつくりかた

 ここまでで,外から見たmoduleの振る舞いを確認しました。 次は,Google pubsubを非同期pullで購読するためのmoduleの実装duct.module/messageを作り,moduleの振る舞いの実装方法を紹介します。

 例題で扱うのは,公式のpull サブスクライバー ガイドにあるjavaコードです。 プロジェクトIDとサブスクリプションIDで指定したキューからのメッセージの受け取り処理を開始するプログラムです。 このJavaコードは,Clojureで次のように書き直せます。

(def s-name // -> moduleに
  (SubscriptionName/create “project-id” “subscription-id”))

(def receiver // -> ig/init
  (reify MessageReceiver
    (receiveMessage [this message consume]
      (println (. message getData)))))

(def subscriber
  (Subscriber/newBuilder s-name receiver))

(. (. subscriber build) startAsync) // -> protocol

s-nameで購読するキューを指定,receiverでメッセージを処理し, subscriberが受信したメッセージをreceiverに渡しています。 moduleが担う処理はドメインを問わず行うべき処理なので,s-nameを文字列から作る処理をmodule化することを目指しましょう。

 leiningenプロジェクトをDuctのmoduleにするには,srcに以下のようなマップが書かれたファイルduct_hierarchy.ednを作る必要があります。

{:duct.module/message [:duct/module]}

コンフィグレーションマップのキーワード間には継承関係を定義でき, これにより,クラスの継承と同じ考え方でコンフィグレーションマップの抽象度を上げることができます。 全てのmoduleのキーワードは,:duct/moduleを継承する必要があり, 上のコードはduct.module/messageduct/moduleの子キーワードであることを宣言しています。

 prep stepでは,duct/moduleを継承するキーワードのマルチメソッドが呼ばれます。 このマルチメソッドは次のように:fnをキーとするマップを返す必要があります。

(defmethod ig/init-key :duct.module/message
  [_ options]
  {:fn (fn [config]
    (core/merge-configs
      config ; ユーザが書いたコンフィグレーションマップ
        {:duct.message/pubsub ; 追加するキー
          {:logger (ig/ref :duct/logger)}}))})

:fnの設定すべき値は,コンフィグレーションマップを受取り新しいコンフィグレーションマップを返す関数です。 prep stepでのコンフィグレーションマップの書き換えは,:fnの関数適用の結果です。 上のコードは,ユーザが定義したコンフィグレーションマップに:duct.message/pubsubをキーとするエントリを追加しています。 merge-configsは引数に渡されたマップをマージし,マージ後のマップを返します。

 コンフィグレーションマップに追加したキーワード:duct.message/pubsubを追加したので, moduleには,このキーワードのマルチメソッドも含める必要があります。

(defmethod ig/init-key :duct.message/pubsub
  [_ {:keys [p-id s-id] :as opt}]
  (assoc
    opt
    :s-name
    (SubscriptionName/create p-id s-id)))

購読したいキューを指定するにはプロジェクトIDとサブスクリプションIDが必要なので, ユーザにはduct.message/pubsubの値にIDを書いてもらうようにします。 これでmoduleの出来上がりです。

 最後に,作ったmoduleを実際に使ってみます。 まず,キューのIDとmoduleのキーワードを含んだコンフィグレーションマップを作ります。

{:duct.message/pubsub {:p-id "project-id"
                       :s-id "subscription-id"}
 :duct.module/message {}
 :ebisu.boundary/message #ig/ref :duct.message/pubsub}

マルチメソッドでは,コールバックと購読の開始処理を書いています。 s-nameには,moduleにあるSubscriptionName/createの返り値が渡ります。

(defprotocol Receiver
  (start [this])
  (stop [this]))

(defrecord PubSubReceiver [subscriber]
    Receiver
    (start [this]
      (. subscriber startAsync))
    (stop [this]
        (. subscriber stopAsync)))

(defmethod ig/init-key :clj-ebis2.boundary/message [_ {:keys [s-name]}]
  (let [subscriber (. (Subscriber/newBuilder
                       subscription-name
                       (reify MessageReceiver
                         (receiveMessage [this message consumer]
                           (println (.. message getData toStringUtf8))
                           (. consumer ack)))) build)]
    (let [receiver (->PubSubReceiver subscriber)]
      (start receiver)
      receiver)))

参考資料

  1. Duct Framework and supporting libraries
  2. Arachne: building a framework in Clojure
  3. Productive Duct
  4. Enter Integrant: a micro-framework for data-driven architecture with James Reeves
  5. Duct, Covered

  1. 本稿の前半でモジュールと表現しているIntengrantのマルチメソッドとは異なるものなので,英語表記にして両者を区別します。

hbstudy#82 の「SRE大全:ユーザベース編」で話をしてきました。

こんにちは。ユーザベースのSPEEDAで、SREチーム内のソフトウェアエンジニアをしている @tkitsunai です。

f:id:kitslog:20180319164521j:plain

3月15日(木)に、株式会社ハートビーツ様が主催している「hbstudy#82」で、「SRE大全:ユーザベース編」というお題目の下に、弊社のSREチームの4人で様々なSREの取り組みについて発表してきました。

SRE大全というお題目は、日本企業でのSREチームを立ち上げたとして界隈で有名なメルカリさんも発表しており、前回はクックパッドさんの発表でした。 今回、日本企業のTech Companyとしても有名な方たちと肩を並べることができ、知名度がまだまだ低いユーザベースのSREチームにとっては身に余る光栄でした。

我々が今回SREチームとして発表してきた内容は以下となります。

  • 「UZABASEのSREについて」 羽山 雄偉
  • 「ソフトウェアエンジニアリングによるToil削減」 橘内 孝幸 ( @tkitsunai )
  • 「FullGCとの闘い」 久保 裕史 ( @hirofumikubo )
  • 「On-premise Kubernetes on Rancher」金屋 泰士

発表資料は1つだと長いので小分けにしています。

「UZABASEのSREについて」 羽山 雄偉

「ソフトウェアエンジニアリングによるToil削減」 橘内 孝幸 ( @tkitsunai )

「FullGCとの闘い」 久保 裕史 ( @hirofumikubo )

「On-premise Kubernetes on Rancher」金屋 泰士

会場の方から質問も頂きまして、

  • 「他のSRE大全では、10数名でもきついという話を聞いたが、10名で回すのはどうか。」
  • 「トイルの計測について、差し込みの割合について定義はあるか?また、計測の精度はどうか。」
  • 「K8SをPrometheusで監視しているということだが、Rancherの監視はどうしているか。」
  • 「Prometheus自体の監視は?」

などなど、10名での運用体制についてや後半ではRancher成分が多めな印象でした。

YoutubeLiveでの配信もあり、hbstudyさんのチャンネルにも公開されていますので、そちらから会場の様子などを含めた全編を閲覧することができます。

www.youtube.com

インフラエンジニア勉強会 hbstudy - YouTube

(余談)

私のパートでは、めちゃくちゃ緊張してしまって声が震えるし真っ白になるしで、軽くトラウマレベルでした。 スピーカ慣れしてる人たち、本当に尊敬します。精進あるのみ。。。

仲間募集中!

ユーザベースのSPEEDA SREチームは、No Challenge, No SRE, No SPEEDA を掲げて業務に取り組んでいます。 「挑戦しなければ、SREではないし、SREがなければ、SPEEDAもない」という意識で、日々ユーザベースのMissionである、「経済情報で、世界をかえる」の実現に向けて邁進しています。

少しでも興味を持ってくださった方はこちらまで!

SRE Loungeについて

昨日の記事のSRE Loungeについてもどんどん他社様を巻き込んでおり、コミュニティの活性化を進めています。 是非、うちのSREはこんなことやってるよーと共有して頂ける企業様が居ましたら sre@uzabase.com 宛にご一報下さい。

Chatwork、CrowdWorks、スタディスト、ユーザベースでSRE Lounge #2 を開催しました

こんにちは、ユーザベース SREチームでインターンをしております杉田です。 1/17(水)に始動したSRE Loungeの第二弾として、3/13(火)にSRE Lounge #2を開催しましたので、 今日はその模様を投稿します。

そもそも「SREとは?」といったことや、SRE Lounge開催の背景については、 SRE Lounge #1の記事に詳しく書きましたので、 ぜひご覧下さい。

今回も前回と同様に、

  • SRE取り組み事例の共有(情報交換・発信)
  • SREについて議論し、知見を深める

といったことを目的として開催しました。

開催日時

3/13(火) 19:00〜

開催場所

今回はChatWork様の東京オフィスをお借りして開催しました。 スクリーン付きのシアタールームがあったり、文字通り間近に東京タワーを眺めることが出来たりと、 とても素敵なオフィスでした。

f:id:ksksgtt:20180314193353j:plain
ChatWork様のオフィス

f:id:ksksgtt:20180314193926j:plainf:id:ksksgtt:20180314193959j:plain
会場の様子

参加企業

コンテンツ概要

  1. 各社の取り組み事例等の発表と質疑応答(各社20分程度)
  2. 発表を踏まえた座談会(30分程度)

ピザやChatWork様が提供して下さった飲み物で軽食をとりつつ行いました。

各社の取り組み事例等の発表と質疑応答

各社の発表内容を発表資料と共に以下にまとめます。

ChatWork様

マイクロサービスアーキテクチャを積極的に取り入れ、Kubernetes環境を運用しているとのことでした。 現在は新しいシステムはKubernetesで稼働させ、既存システムについてもKubernetesへ絶賛移行中とのことです。 また、サービスメッシュ(Envoy/Istio/Linkerd...)の採用検討もされており、非常に勉強になりました。 個人的には、技術負債(レガシー)をマイナスに捉えるのではなく、今までビジネスを支えてきた「レジェンド」なアプリケーションという風に敬意を持って呼ぶという点が心に刺さりました。

当日発表資料:microservicesとSRE (第2回 SRE Lounge)

www.slideshare.net



CrowdWorks様

Monitoringに対する取り組みとして、DatadogやAWS CloudWatch、その他周辺ツールの活用をしつつ、 さらにDatadogに連携するツールcyqldogを開発しているとのことでした。 また、Infrastructure as Codeの取り組みとして、ChefやTerraformを採用しつつ、 Terraformで作成したサーバーと、秘伝のタレ化したサーバーの差分を検出してくれるajimiを使って、コード化をスムーズにしているそうです。 OSSを活用するだけでなく、独自のソフトウェアを積極的に開発しOSS化している点は、弊社も見習いたいところです。

当日発表資料:SRE at CrowdWorks



スタディスト様

Monitoringでは、Fluentd・ElasticSearch・Kibanaの組み合わせやstackdriver・newrelicを、Infrastructure as CodeではAnsible・Serverspecを活用されているとのことでした。 さらに、組織的な取り組みとして、はてな様でも実施されているPerformance Working Groupという取り組みを行い、 SRE以外のチームメンバと計測数値や情報を共有し、議論する場を定期的に設けているとのことでした。 パフォーマンスを上げるためにSREだけで全ての範囲をカバーすることは難しく、SRE以外の開発メンバーの協力を必要とする機会は多々ありますので、こういった場を設けることは非常に大事なことだと思いました。

当日発表資料:デブサミ2018 で伝えきれなかった 快適なマニュアル作成共有を支えるSite Reliability Engineering



ユーザベース

ユーザベースの発表は今回で2回目なので、焦点を絞って日々発生するデータエラーについてどんな取り組みをしているか紹介しました。弊社が提供しているSPEEDAのプロダクトの要はデータです。一言にデータと言っても多種多様なデータの種類・形式を取り扱うため、データの抜け漏れやデータ同士の競合など考慮すべき点は多くあります。これをエラーが発生してから対応するのではなく、SREとしてvalidationを高度化し、先手を打つための仕組み作りについて発表しました。

当日発表資料:SRE Lounge#2 UZABASE



まとめ

形式は前回と同様ですが、発表後の懇親会の中で、各参加企業の

  • 異なる規模やSREとしての体制・内部事情
  • SREとして取り入れているノウハウ
  • 目指そうとしているSREのあり方

といったことをざっくばらんに共有し、議論する場を設けたことで、知識はもちろんお互いの交流を深めることが出来、非常に密度の濃い勉強会となりました。

SRE Loungeは、今後も継続して開催する予定ですので、もし興味を持ってくださり、参加を希望される企業の方はこちらまでご連絡ください。

f:id:ksksgtt:20180314180656j:plain
集合写真

f:id:ksksgtt:20180314180740j:plain
今回参加したユーザベース SREチームメンバー

仲間募集!!

ユーザベースのSPEEDA SREチームは、No Challenge, No SRE, No SPEEDA を掲げて業務に取り組んでいます。
「挑戦しなければ、SREではないし、SREがなければ、SPEEDAもない」という意識で、日々ユーザベースのMissionである、「経済情報で、世界をかえる」の実現に向けて邁進しています。

少しでも興味を持ってくださった方はこちらまで

【k8s合宿】 Kubernetesのメトリクスを取得する 〜PrometheusにGrafanaを添えて〜

こんにちは、SPEEDAのSREチームの阿南です。前回から少し時間が経ってしまいましたが、今回はKubernetesのメトリクス取得についてです。本番環境でkubernetesを運用する際、ポッドがどの程度リソースを消費しているのか、クラスター自体のリソースは大丈夫かなど常に把握しておく必要があります。ただ、Kubernetesってどう監視すればいいのって疑問ありますよね。PrometheusとかGrafanaとかよく出てきて概要は理解できるんだけど、実際どう構築すればいいの、とお悩みの方に役立つ記事にしたいと思います。ちなみに弊社ではRancher上にKubernetes環境を本番で利用していますが、大枠は今回紹介するような構成で運用しています。

構築する環境

f:id:tanan55:20180301095238p:plain

利用する環境はGKEです。まずKubernetesクラスターの中にPrometheusを構築し、メトリクスを取得します。さらに、クラスター外部にfederation用のPrometheusを構築し、Grafanaでメトリクスを可視化します。概要をざっくりと箇条書きすると、下記のようになります。

【クラスター内部(図の左側)】

  • KubernetesクラスターにPrometheus ポッドを稼働させる

  • Prometheus ポッドでクラスター内のメトリクスを取得する

  • NodeExporter ポッドをDaemonSetで稼働させ、Node(GCEインスタンス)のメトリクスを取得

  • Prometheus ポッドで取得したデータについては保持期間を1日とする

【 クラスター外部(図の右側)】

  • federationを使ってクラスター外部のPrometheusから値を取得

  • Grafanaでメトリクスを可視化

本記事では、まずKubernetesクラスターの中にprometheus ポッドを稼働させて値を取得するところまで紹介し、federationやGrafanaでの可視化周りは次回記事で紹介したいと思います。

構築手順

前回同様手順は別途まとめていますのでこちらをご参照ください。

Kubernetesの認証方式について

GKEのKubernetesバージョン1.8からはRBACがデフォルトで適用されているため、Prometheusで監視をする際に監視に必要な権限を与えてあげる必要があります。 さて構築する際のポイントですが、まずは自分自身のアカウント(kubectlを実行するユーザ)にcluster-adminを付与します。

$ gcloud info | grep Account
$ kubectl create clusterrolebinding anan-cluster-admin-binding --clusterrole=cluster-admin --user=sample-owner@sample-project.iam.gserviceaccount.com

cluster-adminを設定する理由は、kubectlを実行するユーザの権限より強い権限をroleとして設定することはできないためです。 ちなみにbindingには、clusterrolebindingrolebindingの2つがあり、それぞれ適用範囲をクラスター全体にするか、細かく設定するかを選択できるようになっています。この辺りの設計は利用するサービスや会社によって最適な設定が異なると思いますので、ぜひ事例があれば聞いてみたいですね。 次にPrometheus用にサービスアカウントを作成します。

$ kubectl create serviceaccount prometheus --namespace monitoring

このサービスアカウントに対して、参照権限を付与します。ここで、resourcespods, services, deploymentなどのリソースを表し、verbs がそのリソースに対する操作を表します。Prometheusは全てのリソースに対して参照権限を与えたいので、resources* とし、verbsget, watch, list の動作を許可します。nonResourceURLsはエンドポイントの権限設定なので、細かく設定する際は/api等のエンドポイントを指定します。今回はnonResourceURLs*、verbsをgetとしてエンドポイントに対してGETリクエストを許可します。これでread_onlyな形で権限を作成することができました。 Prometheusの監視について、secrets等は閲覧権限不要のため内容を修正しました。ご指摘いただいた方ありがとうございます!

gist.github.com

GKEの場合1.7まではデフォルトのサービスアカウントで全てのリソース、操作が許可されていました。Kubernetes v1.8からRBACがstableになっているのでGKE側でもこの辺りの変更が入っているようです。まだPrometheusにはたどり着いておりません。序盤からハマリどころ満載で、楽しくなってきました。

ConfigMap設定

ConfigMapにPrometheusのconfigファイルを設定します。最初のglobal設定で、メトリクスの取得間隔を指定しています。ポイントとして、 kubernetes_sd_configs を利用してメトリクスの取得先をdiscoveryできるようにしています。このservice discoveryの設定を利用することにより、サーバが追加になったりした際にも自動的にそれを検知しメトリクスを取得できるようになります。Prometheusの強力な機能ですね。

gist.github.com

kubernetes_sd_configsの中身については正直いきなり理解するのは難しいと思いますので、とりあえず細かい説明は置いて次に進みます。

Deployment設定

PrometheusのDeploymentの設定ですが、ここで最初に作成しておいたサービスアカウントが登場します。下記16行目にserviceAccountName: prometheusの記載があります。これを指定することで、全てのリソースに対する参照all-readerができるようにしています。ちなみに、サービスアカウントを作成するとsecretにca.crt、tokenというデータが作成されます。このsecretはポッドが起動した際に、自動的に/var/run/secrets/kubernetes.io/serviceaccount の配下にマウントされます。これをPrometheusのconfigに指定することでAPI Serverの認証をパスできるようにしています。先ほどのConfigMapの設定でca_filebearer_token_fileによくわからないパスが出てきましたがシークレットがマウントされていたんですね。この辺りの仕様は公式ドキュメントに記載がありますので見てみるといいと思います。Deploymentにサービスアカウントを指定しなかった場合、defaultのサービスアカウントが適用されますので、認証が通らずメトリクスの収集ができなくなります。だからと言って権限を全解放すると色々な事故が起こる可能性がありますし、後からこの認証を入れていくのはかなりしんどいと思います。最初から正しく仕事をする。頑張りましょう。

gist.github.com

Service設定とポート解放

Prometheusのサービスを公開します。今回はNodePortモードでノードの30001番ポートを解放しています。つまり、http://<Prometheus 稼働中 Node IP>:30001 にアクセスするとPrometheus ポッドの9090番ポートに接続されるので、Prometheusにアクセスするためには30001番のポートをGCPのネットワーク設定で解放しておく必要があります。GCPの管理コンソールのVPC ネットワーク > ファイアウォールルールからポートを解放してください。ちなみに、本記事では手間を省くためにNodePortモードを利用しておりますが、Production環境等ではInternalのLoadBalancerを利用した方がノードに依存することがなくなるため運用しやすいと思います。

最後に、Prometheusにアクセスしてみて下記のようにサービスディスカバリができていれば完了です! f:id:tanan55:20180305183938p:plain 結構難しいですよね。。。弊社の本番環境でもPrometheusを利用していますが、正直全てのメトリクスを把握できないほどの種類を取得しています。それだけ細かく取得できているのは素晴らしいのですが、どうやって可視化するのか迷いますよね。次回はそんな方にオススメのGrafana周りを紹介しますのでご興味のある方は楽しみにしていてください。

お知らせ

SREチームでは「No Challenge, No SRE, No SPEEDA」を掲げ、ユーザベースグループのミッションである「経済情報で、世界をかえる」の実現に向けて、日々業務に取り組んでいます。 興味を持ってくださった方はこちらをご確認ください。

また、2018/03/15(木)にハートビーツ社主催で「SRE大全:ユーザベース編」 が開催されます。Youtube Liveでも配信されますのでご興味ある方はぜひご覧ください。

ユーザベースで社内ハッカソンを初開催しました

f:id:uzabase:20180217001643p:plain

はじめに

ryoqunこと小野寺です。突然ですが、うだるような熱狂的なハック、最近してますか?僕らのそんな刺激的で情熱的な一夜限りの思い出を今日はレポートしたいと思います。

ユーザベースでは2017年12月15日に社内ハッカソンを開催しました。初開催にも関わらずとても楽しかったので、その取り組みについて紹介したいと思います。

今回の社内ハッカソンがユーザベースでの栄えある1回目の開催です。大好評に終わり、こういったエンジニアの社内イベントは継続的に開催していくことになりました。

聞くだけに終わらない「Tech Meeting」にするために

「エンジニアみんなが等しく能動的に技術に向き合う時間にしたい」

この思いを実現したいがために、板倉というエンジニアから今回のハッカソンは立案され、開催されました。その根底には、週次のエンジニア全体ミーティング(いわゆるTech Meeting)の本来の意義を、180度違う角度から解決したいという熱意が板倉にあったためでした。

これまでの弊社のTech Meetingは持ち回りで担当者が何らかのテーマで発表をするというものです。

そこには、「話す」、「聞く」という参加者の二分があり、「聞く」側の中ではさらに、「質問する」、「聞いているだけ」というさらなる二分があり、 Tech Meetingに参加しているエンジニア各人の時間の濃さにムラがあるのが課題でした。ユーザベースグループという組織において、それは望むところではなく、そこに強い問題意識を持ったのが彼でした。

弊社におけるTech Meetingの意義とは、「技術」を軸にエンジニア同士が交流すること。だからこそ、あえてTech 「Meeting」でなくてもよいのでは?その問題提起から、四半期分のTech Meetingの時間をまとめ、1日まるまる時間を確保し社内ハッカソンを開催することになりました。

ちなみにそのような大胆な改革であっても、(あるいは、ならばこそ)すんなり挑戦よいとなりました。というのも、ユーザベースの7つのルールに「自由主義で行こう」や「迷ったら挑戦」とあり、基本的に社員のWillが尊重されるからです。

そして同じような問題意識に共感し、ハッカソンを運営したいと手を上げたメンバーを加え、板倉を中心に数名の運営チームが組成されました。

自由と挑戦を念頭に、ユーザベースらしいハッカソンを。

まず、ハッカソンのお題はありません。つまり開発テーマは完全に自由です。作るものの制限はなく何でもOKでした。この背景には、できるだけレギュレーションとして制約を設けずに運営側の思いとして個々人が好きな技術に能動的に触れてほしいというのがあったためです。

結果、業務に関係あるものから、関係無いものまで、具体的にはゲームからチャットボットに至るまで、実に色々なものが作られました。

さらに、チーム分けはランダムに極力「混ざる」ようになりました。ユーザベースが大きくなるのにつれ事業部間のエンジニアの距離が遠のいてしまうのを解消したいという運営チームの思いから、有志がなんとなくいつも通りにまとまるのではなく、基本的には運営チームによって決めました。ただ、参加者の志向性をまったく考慮しないわけではなく、興味ある技術や趣味を参考とするためにアンケートを取りました。

そして、当然のごとく、最終発表後には表彰と賞品の贈呈「アリ」とのことでみんなは俄然やる気がでます。

ハッカソンの日程は、告知から打ち上げまで、大きくは次のように進んでいきました。

f:id:uzabase:20180217001028p:plain

  • 10/2: ハッカソン開催の発表
  • 10/18: ハッカソンのチーム分け発表
  • 10/30: チーム別中間発表(チームごとの取り組む開発内容の発表)
  • 12/14: ハッカソン開催宣言(18:00〜)
  • 12/15: チーム別最終発表&表彰&打ち上げ(17:00〜)

では、時系列順に足早になりますが、写真を織り交ぜつつ説明していきたいと思います!

10/2: まさかのハッカソン開催の告知

f:id:ryoqun:20180131212300p:plain

今日も代わり映えの無いTech Meetingの発表の最後に突如出たこの素っ気ないスライド一枚から全ては始まりました。

まず、突然に、4QではTech Meetingの代わりにハッカソンをするという発表がありました。当然、発表直後はざわつきました。

ともかくも、Tech Meetingの時間枠を集めてハッカソンにしてしまうという発想が非常に新鮮で、みんなの不安と期待と野望(?)の中で、ここから物事は動き出しました。

10/18: どきどきのチーム発表!

f:id:ryoqun:20180131094856j:plain

まずはともかく、ハッカソンをやるにはチーム分けから始まります。2〜6人のチームが合計が15チームができ、ユーザベースグループのエンジニアが総動員した結果、55名とかなりの大規模です!

前述の通り、チームの構成はなるべく事業をまたぐよう意識されました。この工夫にはエンジニアの交流を増やしたい狙いがありました。ただ、個人の希望も考慮するため、ハッカソン告知後に興味のある技術や趣味のアンケートは参考のために事前に実施されました。そして、運営メンバーも各チームのメンバーとして実際のハッカソンに参加しました。これもまた運営チームの思いの現れです。つまりは、Tech Meetingでの「聞く側」と「話す側」の二分構造と同じような「運営側」と「参加側」の二分構造の発生を避けるためでした。

チーム分け後、各チームのメンバーは基本的には初対面です。自己紹介したり、キックオフランチに行くチームもありつつ、各チームは早急に何を作るのかを中間発表に向けて決めなければなりません。もちろんチームの各メンバーの持ち味を活かしつつ!

10/30: 夢が膨らむチーム別中間発表!

チーム発表後、お互いのチームが何を作るかの噂が流れたりして、そわそわしつつ、ついにこの日に各チームが発表しお互いが何を作るのかが明らかになりました。

前述の通り、お題は完全自由で実に多彩な案が出ました。Slackのボットから簡単なWebサービス、はたまたゲーム、音声認識、IoTなどなど、やはり最新技術を取り入れたチームが大半です。

どのチームの企画もチームの特色があり、ひねったアイディアばかりで新規性や革新性があり、発表内容を聞いているだけでワクワクしました。

そして、この中間発表以降、本気で賞を取りにいこうとしたチームは先行して開発に着手し始めました。

12/14: 前夜祭的な開催宣言!

f:id:ryoqun:20180131134910j:plain

準備したチームがありつつも、ついにハッカソンの開催が宣言されました!

f:id:ryoqun:20180131213222j:plain

ちなみにこんな感じでお祭り感UP!ということで趣ある方法で成果発表の順番は決められました。

がっつりハック!各チームの開発風景

f:id:ryoqun:20180131213846j:plainf:id:ryoqun:20180131212926j:plainf:id:ryoqun:20180131213111j:plain

みんなが楽しそうに各チームが1つの目標の元で開発しています。最新技術や、技術を使っての誰かために問題解決が好きなんだなと思えた瞬間でした。

ぎりぎりまで粘った上での成果発表!

f:id:ryoqun:20180131213659j:plain f:id:ryoqun:20180131214332j:plain

ハッカソンなので完璧さは求められません。大事なのは、とりあえず動くものを作ること。その心意気で、みんな発表開始直前の直前まで開発していましたが、時間は無情で成果発表の時間となりました。

今回のハッカソンのテーマは「楽しく」なので、最後まで追い込んでまで必死に開発したご褒美というわけで、ビール片手の乾杯から成果発表はスタートしました。

各チームの発表持ち時間は5分で、うまく動いて歓声があがったり、ツッコミが入ったりしながらもテンポよく和気あいあいと進んでいきます。やはりデモを披露するチームが多かったです。

そして、成果発表後、交流の時間が設けられ、気になるチームのところに行って話したり、デモを試したり、逆に興味を持ってくれたエンジニアにデモを見せたりしました。

そして、各賞にふさしいと思うチームへの投票も終え、ついに、どきどきの表彰タイムです!果たして自分のチームは選ばれたのでしょうか??

表彰!

泣いても笑っても結果が全て。以下の通りで各チームがそれぞれ受賞しました!!

今回の賞は合計4つでした。エンジニアみんなが投票して選ぶ「Good Idea賞」、「Tech賞」、「最優秀賞」の3つと、サプライズでユーザベースグループのCTOの竹内さんからの「特別賞」がありました。

「Good Idea賞」

f:id:ryoqun:20180131135706j:plain

まず、「Good Idea賞」に輝いたのは、「Slaxフレンズ制作員会」というチームで、Slackの中でUnixコマンドの思想に則ったコマンドライン環境を提供するという一風変わったBotを作りました。ちょっと補足すると例えばSlack上でtail -n100 @ryoqun | grep "ハッカソン"と入力すると、ある特定の人の直近100件の発言から特定ワードで絞り込んで表示するというBotです。

「Tech賞」

f:id:ryoqun:20180131140214j:plain

次に、「Tech賞」に輝いたのは、「チームPon!」というチームで、ARと体を動かすというのを組み合わせたホッケーのようなゲームを作っていました。対戦もでき、スマホがコントローラー代わりになり、ブラウザからゲーム状況も見えたりとARKitを使った本格的なARと同時にゲームとしての完成度も十分でした。

「最優秀賞」

f:id:uzabase:20180207211449j:plain

では、栄えある「最優秀賞」に輝いたのは、「もんめ」というチームで、社内ポータルをリニューアルさせました。なんといっても開発成果のインパクトが一番でした。ユーザベースでは社内ポータルとしてCrowiを使い始めているのですが、それをフロントエンドを中心にデザイン含め、大規模にリニューアルしました。Reactを使って書き換え、オープンソースも予定しているとのことで期待も高まります。

「CTO特別賞」

最後に、サプライズだった「CTO特別賞」に輝いたのは2チームでした。

1チーム目は、「私立恵比寿中学水樹奈々がかり」というチームで、Google Homeで、アイドルのライブイベント当日の移動等の準備に便利な音声操作のツールを作りました。

2チーム目は、「UBHome」というチームで、Raspberry Piと各種音声認識や発声APIを使ったIoT的な音声受付システムを作りました。

無事に終わり、金曜夜、あとはやることといったら…

そして、成果発表開始時よりアルコール解禁になっていたのもあり、ウォーミングアップ(?)も済ませ、睡眠不足のテンションで意気揚々に、有志で打ち上げへと恵比寿の居酒屋に繰り出していくのでした〜。

「(ハッカソンを通して)仲良くなれた。楽しかった」

開催後のアンケートから抜粋すると以下のようなものがありました。

「運営お疲れさまでした!最後の発表会で予想を遥かに越えて、けっこうみんなが真面目に取り組み、良いものができたと思います!」

「普段業務で会話することがない人とも、短期間ではあったものの1つの目標に向かって協力できたことで仲良くなれたな、と思いました。」

「久しぶりにコーディングに集中しすぎて発表の時に疲れましたがめっちゃくちゃ楽しかった!!」

ありきたりかもですが、こういう反応こそを引き出せたのは、その当たり前を多くの苦労で実現した運営チームの尽力あってのことだと思います。

「みんなが楽しめたならOK!(運営は大変だった…)

開催後日、最後に板倉より以下のメッセージがありました。

「告知時に話をしましたが、今回のハッカソンはみんなが能動的に参加できるように考えたものです。撮影した写真の中では、ハッカソン当日はみなさん笑顔が多く、良い時間が過ごせたのではないかと思います。上記の目的が少しは達成できていたのであれば良かったです!」

という形で初開催のハッカソンは無事に幕を閉じました。

また、最初から完璧な運営できたわけではなく、反省として、「もっとお祭り感を運営チーム働きかけて作りだせたのではないか」、「チーム間の取り組みへの温度感のムラをもっと埋められないか」、「受賞したいと思えるような賞品にできたのでないか」などがありました。

まとめ

ユーザベースでは、「経済情報で世界をかえる」というミッションの実現のため、エンジニアが共に力を合わせ自由闊達で働ける環境を作ろうとしています。

ユーザベースはグループとして、ただそのミッションために存在し、そのミッションで束ねられた組織の団結力は非常に重要であると考えています。そのためにも、エンジニアという1つの職能という横串の切り口で、今回のようなレクレーションイベントを通し、結束力を高められたのは本当によかったです。

さらに朗報で、今回の社内エンジニアイベントに続き、次は社内ISUCONを開催しようということが決定しています。

最後になりますが、ユーザベースでは、絶賛エンジニアを大募集中なので興味ある方は是非とも応募してください!

【k8s合宿】 Kubernetesのログ分析環境を作る

こんにちは、SPEEDAのSREチームでエンジニアをしている阿南です。SPEEDAのSREチームでは、昨年末kubernetesについて理解を深めるために合宿を行いました。やり方はA〜Cの3チームに分けて、それぞれのチームでkubernetesに関することを調査、構築するという形式で、今回はAチームが実際にやってみた内容についてブログを書きたいと思います。(それぞれのチームでかなりボリュームがあるので、複数回に渡って連載的な形でお届けしたいと思います。) Aチームでは、kubernetesを本番環境に投入するにあたり、ログ収集周りをあまり調査できてないなと感じ、GCP上に環境を作ってみることにしました。

構築する環境

f:id:uzabase:20180115151549p:plain

GKEでKubernetesクラスターを構築し、その上にwordpress(Apache) + MySQLコンテナを稼働させました。ログ収集と言っても、kubernetesクラスター自体のログとその上で稼働するコンテナのログでは取得する設定も若干違ってきますので、今回はコンテナのログを収集する環境を作りました。 またポイントとして、GKEの公式DocumentではStackdriverにログを送ってBigQueryにエクスポートするという構成が紹介されているのですが、BigQueryに直接送る構成はあまり情報がなく、SPEEDAのコアな部分はオンプレ環境で運用しているため、BigQueryに直接送る構成にしました。

構築手順

ログを収集するという単純な環境ですが、意外と設定項目が多いです。手順を一つずつまとめるとかなり分量があるため、設定内容も含めてgithubに手順をまとめました。

github.com

1から構築してみたいという方はぜひご参考にしてください。 本ブログ内では、私が重要だと思った点や注意点のみ記載したいと思います。

クラスター構築

GKEは下記コマンドのみでkubernetesのクラスターを構築することができます。

$ gcloud container clusters create sample-cluster

デフォルトではGCEのインスタンスが3台起動し、そのVMを利用してkubernetesのclusterが作成されます。

wordpress + MySQL構築

続いて、wordpress + MySQL です。こちらについては、GCPの公式ページのステップ2〜5を参考にしました。wordpressのコンテンツファイルやDBのデータを永続化するために、 volumes で外部ディスクを指定し、containersvolumeMounts でマウント設定しています。

gist.github.com

Fluentdイメージの作成

利用するイメージは、GCPのリポジトリを参考にイメージを作成すればOKです。ポイントとして今回はbigqueryに直接ログをアップロードするため、gemfileで、fluentdのバージョンをv0.14に変更し、fluent-plugin-bigqueryを追記しています。このgemfileを保存して、docker buildしてください。 fluentd.conf の設定は全てConfigMapで記載します。

gist.github.com

ConfigMap設定

ConfigMapは、設定情報(環境変数やファイル)を定義できるkubernetesの機能です。これを使うと、kubernetes上でコンテナを実行した際に、ConfigMapに設定した情報を読み取ってくれます。例えば、fluentdのイメージをDocker単体で実行した場合、configをホストマウントしたりしますよね。kubernetesだとホストが頻繁に変わる可能性もあるのでホストマウントするわけにもいきません。そのような場合に、ConfigMapを利用すればconfigをimageに含めなくてもよくなり、ノードが変更した時にも追従できるということでクラスターのノードを捨てやすくなると思います。

gist.github.com

実際のfluentdの設定についてはファイルを確認して頂ければと思いますが、注意点としてfluent-plugin-bigqueryの現在のバージョンでは inject セクションが追加されているようです。過去のブログ記事で設定にinjectがないものもあり、そのまま設定するとBigQueryのtimeだけnullになってしまうことになりますのでご注意を。

<inject>
    time_key "time"
    time_format "%s"
</inject>

DaemonSet設定

DaemonSetはクラスターの各ノードにコンテナをデーモンで動作させることができるkubernetesの機能です。コンテナのログは各ノードに出力されるようになっています。このDaemonSetを利用してfluentdを各ノードに稼働させ、各ノードのログを収集します。

gist.github.com

長いので、かなり省略していますが、 volumes で先ほど設定した configMap を指定し、 containersvolumeMounts に設定しています。これで、ConfigMapで定義したファイルをfluentdが起動時に読み込み、ログ収集ができるようになります。

f:id:uzabase:20180115173310p:plain

ちなみに、下記コマンドでwordpressのpodと同じノードで稼働しているfluentdのpodを確認し、shellを起動するとfluentdのログを見ることができます。うまくfluentdのログがアップロードできない等の場合は見てみるといいかもしれません。

$ kubectl get pods -o wide
NAME                         READY     STATUS    RESTARTS   AGE       IP           NODE
fluentd-gcp-v2.0-5t96f       1/1       Running   0          5h        10.52.2.9    gke-sample-cluster-default-pool-a7431f33-rqbs
fluentd-gcp-v2.0-j45c7       1/1       Running   0          13m       10.52.0.13   gke-sample-cluster-default-pool-a7431f33-4x57
fluentd-gcp-v2.0-wmv3h       1/1       Running   0          5h        10.52.1.10   gke-sample-cluster-default-pool-a7431f33-nv5h
mysql-3368603707-ng8pr       1/1       Running   0          6h        10.52.0.7    gke-sample-cluster-default-pool-a7431f33-4x57
wordpress-3479901767-tc9p6   1/1       Running   0          6h        10.52.0.8    gke-sample-cluster-default-pool-a7431f33-4x57

$ kubectl exec -it fluentd-gcp-v2.0-j45c7 /bin/sh
# tail -f /var/log/fluentd.log

最終的に、下記のようにアップロードされました。現状だと全てのコンテナログが同じテーブルにinsertされてしまいますので、この辺りは別途テーブルやfluentdを細かく設計した方が良さそうです。

f:id:uzabase:20180118112409p:plain

まとめ

ログをアップロードするために必要な設定を見ていきました。使ってる機能が意外と多いので、少し時間がかかりましたが、本番環境で運用するにはマストの機能ばかりかと思います。また、fluentdから直接BigQueryに送ることにより、マルチクラウドでも対応できるし、OutputをBigQueryから他サービスに変更(もしくは追加)することも簡単にできますので、シーンに応じて使い分けできると思います。結構つまづいたのがfluentdで、jsonログをparseし、特定のキーに対してさらに複雑な加工をしたい場合にちょうどいいプラグインが見つからなかったのでその辺りは調査、もしくは、自分でプラグインを作るのもありかなと思います。 次回以降で、データの可視化やkubernetesのメトリクス収集等も紹介していきますのでこちらも乞うご期待。

お知らせ

SREチームでは「No Challenge, No SRE, No SPEEDA」を掲げ、ユーザベースグループのミッションである「経済情報で、世界をかえる」の実現に向けて、日々業務に取り組んでいます。 興味を持ってくださった方はこちらをご確認ください。

クローズドな勉強会 SRE Lounge始動!

はじめまして、SPEEDA SREチームの久保です。

今回当社のSREチームとハートビーツ社が共同で、1/17(水)に他社を巻き込んで、SRE LoungeというクローズドなSRE勉強会を開催したので、シェアしたいと思います。

SREとは?

Site Reliability Engineeringの略で、日本語に訳すと、「サイト信頼性エンジニアリング」です。 簡単に説明しますと、IT Proの記事にありますように、

SREとはコーディングやソフトウエアエンジニアリングによって、ハードウエアを含めたシステム全体の性能や可用性、セキュリティを高める活動全般を指す方法論

を指します。

ユーザベースのSPEEDA SREチームとしては、
従来のようなDevとOpsに役割やプロセスが分かれており、それぞれのエンジニアが各々の役割だけにコミットする状態ではなく、ソフトウェアの設計、開発・構築、デプロイ、運用、改善といったソフトウェアの一連のライフサイクルのすべて(DevとOps全体)に焦点を当て、サイトの信頼性の向上にコミットするために、ソフトウェアエンジニアリングによってプロダクトの改善を行う。

と解釈し、プロダクト全体の改善に日々努めています。

SRE Loungeの開催背景・趣旨

O'ReillyのSRE本にもありますようにSREはGoogleのDevOpsであり、必ずしも各社にとっての最適解ではあるとは限りません。

また、SREチームを持つ企業各社によって、SREとしての取り組みも様々なのが現状です。 SREチームを構成するメンバーのエンジニアとしてのバックグラウンドも会社によって異なります。 ユーザベースのSPEEDA SREチームでは、ソフトウェアエンジニアとインフラエンジニアが1:1ですが、その比率は企業によって様々です。

そのため、既に各地で開催されているような一方向の講座形式の勉強会ではなく、 双方向に取り組みのシェアや課題の共有などができる、双方向のインタラクティブな場が必要と考え、今回SRE Loungeという名前で企画しました。

SRE Loungeのコアコンピタンス

  • 1回の勉強会で複数社のSRE取り組み事例を知ることができる
  • 少人数のクローズドな場にすることで、双方向なコミュニケーションが取りやすいこと(=質問がしやすく、参加者-発表者間で議論ができる場)

勉強会ゴール

  • SRE取り組み事例の共有(情報交換, 発信)
  • SREについて議論し、知見を深める

開催日時

1/17(水)19:00〜で、 ハートビーツ様のラウンジをお借りして開催しました。

ハートビーツ様の会場はとても素敵な場所でした。代表の藤崎さんのこだわりで作られたとのことです。羨ましい! f:id:hir023:20180122104731j:plain f:id:hir023:20180121203821j:plain

参加企業

コンテンツ概要

  1. 各社SRE関連の取り組み事例紹介&質疑応答 (各社20~25分)
  2. 意見交換会、ディスカッション(with ビール・ピザ) (30~40分)

コンテンツ

各社それぞれのSREの取り組み事例を知ることができ、非常に濃い時間でした。 簡単に各社の発表内容をシェアしたいと思います。

ハートビーツ社

  • happoというツールを独自で作成し、自動でNagiosのメトリクスを収集し、かつ自動でメトリクス設定するツールなども開発して監視している。
     参考:heartbeats.jp
  • トイルの削減方法としては、nagiosのアラートをslackに通知し、スレッド単位で対応している。

当日発表資料:https://speakerdeck.com/abnoumaru/sre-lounge-20180117



dely社

  • 障害対応訓練(dely Apollo Program)という、過去に発生した障害と同じ状況を生み出し、インフラエンジニア以外のエンジニアにその復旧作業に取り組んでもらう。復旧作業での作業をすべてメモし、なぜその作業を行ったかをヒアリングし、振り返るプログラムを実施している。

当日発表資料:https://www.slideshare.net/motonobufukao/dely-sre-principles



eureka社

  • AWS環境で、Packer × Ansible × Terraformで、プロビジョニング用のAMIを作成し、そのAMIベースでインスタンスを作成。一度起動したインスタンスには変更を加えない構成にしている。

当日発表資料:https://speakerdeck.com/takuya542/ji-sok-de-nacui-ruo-xing-jian-zhi-topatutimanezimentoshou-fa-falseshao-jie-1



ユーザベース

  • プロジェクトチーム編成方法や開発手法(TDD、DDD、クリーンアーキテクチャなど)を取り入れて、手動運用のオペレーションの自動化など、 SRE内でのソフトウェア開発を行っている事例を紹介。

当日発表資料:https://speakerdeck.com/tkitsunai/software-development-in-uzabase-sre




このような形で、各社発表後のビールを片手にピザを食べながら行ったディスカッションでは、当初21:30で解散の予定が23:00まで続くという盛り上がりを見せ、参加された方の満足度が非常に高い勉強会となりました。

今後のSRE Lounge

今後のSRE Loungeとしては下記のように考えています。

  • SREをテーマで、所属関係なく、横のつながりを生み出すコミュニティを作っていく(SREコミュニティ化)
  • どこか1社が主導してSRE Loungeを企画するというよりも、SREコミュニティ内の各社が主体となって、自律的に分散的に企画されるような形を目指す
  • そして様々な会社のオフィスで開催する

もし興味持ってくださり、参加希望の企業はこちらまでご連絡ください。

最後に

第2回開催の話も挙がりましたので、ぜひ今後も継続して開催していきたいと思います。

f:id:hir023:20180121203940j:plain
集合写真
f:id:hir023:20180121203932j:plain
今回参加したユーザベース SREチームメンバー




仲間募集!!

ユーザベースのSPEEDA SREチームは、No Challenge, No SRE, No SPEEDA を掲げて業務に取り組んでいます。
「挑戦しなければ、SREではないし、SREがなければ、SPEEDAもない」という意識で、日々ユーザベースのMissionである、「経済情報で、世界をかえる」の実現に向けて邁進しています。

少しでも興味を持ってくださった方はこちらまで