デバッガでRedisのコードを読んでみよう

こんにちは、エンジニアの松崎 啓治(まつざき けいじ)です。
インターネット上ではこのIDで活動しています。 @futoase

先日、社内でエンジニア向けに「デバッガでRedisのコードを読んでみよう」というテーマの勉強会が開かれました。せっかくの機会なので、その内容をご紹介します。

勉強会スライドへのリンク

デバッガでRedisのコードを追いかけるメリットとしては以下のようなものがあります。

  • gdbを使ってRedisのコードをstep実行することで、どのタイミングでRedisのStorage(memory領域)からデータを取得できるのか体験から学べる
  • Redisだけではなく、nginxやMySQL、PostgreSQLなどgdbを利用してstep実行を行えるものであれば、今回の勉強会の手法を元に同じように体験から学ぶことができる

デバッガで追いかけるための準備

プレゼン資料で取り上げられている環境はLinux (ディストリビューションはUbuntu)ですが、公開されているDocker imageを利用することで、docker for Macやdocker for Windowsなど、非Linux環境でもRedisのデバッグ体験を行うことが可能です。

Docker imageの準備

プレゼン資料を作成した浅羽により、Redisのデバッグ環境を行えるDocker imageを作成するためのDockerfileをGithubにて公開しています。

github.com

また、Docker imageについてDocker Hub上に公開しています

docker コマンドを利用し、docker pullを行いましょう。

> docker pull futoase/redis-debug-4.0

docker imageの取得が終わったら、docker runコマンドでdocker containerを立ち上げましょう。

> docker run -it -p 9876:9876 \ 
  --privileged --cap-add=SYS_PTRACE \ 
  --security-opt seccomp=unconfined \
  futoase/redis-debug-4.0:latest /bin/bash
root@f76f0abef015:/# 

docker runに渡している各種オプションは、ptrace システムコールを呼び出すために必要なものとなっています。1

Redis Serverを立ち上げる

早速、先程立ち上げたcontainer内で、Redis Serverを立ち上げましょう。

root@c2407feddaa5:/# cd /root/redis-4.0.11/src
root@f76f0abef015:~/redis-4.0.11/src# 
root@01789e2f2a4e:~/redis-4.0.11/src# ./redis-server --port 9876 --protected-mode no --daemonize no
12:C 28 Sep 07:23:21.739 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
12:C 28 Sep 07:23:21.740 # Redis version=4.0.11, bits=64, commit=00000000, modified=0, pid=12, just started
12:C 28 Sep 07:23:21.740 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.11 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 9876
 |    `-._   `._    /     _.-'    |     PID: 12
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

12:M 28 Sep 07:23:21.745 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
12:M 28 Sep 07:23:21.745 # Server initialized
12:M 28 Sep 07:23:21.747 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
12:M 28 Sep 07:23:21.748 * Ready to accept connections

gdbを利用しRedis Serverに対してattachをする

Redis Serverに対してattachを行います。今回、gdbではなく、cgdb2を利用します。 今度は、docker execコマンドを利用し、先程立ち上げたdocker containerでcgdbを立ち上げます

> docker ps | grep redis-debug
f76f0abef015        futoase/redis-debug-4.0:latest   "/bin/bash"              11 minutes ago      Up 11 minutes       0.0.0.0:9876->9876/tcp               peaceful_chebyshev
> docker exec --privileged -it f76f0abef015 /bin/bash
> cgdb -p 12 # 12はredis-serverのprocess id で、先程redis-serverを起動したときにterminalで表示されたもの

cgdbの起動が終わると以下のようになります。

cgdbが起動した様子のスクリーンショット

この状態で、プレゼンにあるsetCommandにbreak pointを貼ってみましょう。

(gdb) b setCommand
Breakpoint 1 at 0x558b0346b63b: file t_string.c, line 98.
(gdb) c
Continuing. 

合わせて、redis-clientを起動します。起動する対象は、docker containerを立ち上げているホストマシン、 例えばあなたがMacBookを利用して立ち上げているなら、そのMacBookのターミナル上で立ち上げます。

ターミナルにコマンドを打ち込み、docker container上のredis-serverに接続しましょう。

> redis-cli -p 9876
127.0.0.1:9876>

合わせて、SETコマンド 3を redis-clientから発行してみます。

127.0.0.1:9876> SET hoge 1234

この時、cgdb側で特定のbreakpointで処理が止まっている状態になります。

スクリーンショット:breakpointで処理が止まり、画面上部にはブレークポイント周辺のコードが表示されている

この時、next コマンドや、step コマンドを実行することで、next実行(関数レベル)、step実行(関数実行をネストして見る)ことが可能になります。

スクリーンショット:nextやstepコマンドを実行している様子のgifアニメ

cgdbを利用し、関数の実行処理を追いかけることで、ソースコードリーディングに対し C言語未経験者でも読みといていくことが可能となります。

p コマンドを利用することで、ランタイムで評価中の変数の値について確認することもできます。

スクリーンショット:pコマンドでretval変数の値を確認している

ミドルウェアのソースコードを読む体験

MySQL、nginx及び今回のRedisなど、ミドルウェアのソースコードをgdbを利用し、 読む体験を行うことでどの処理にボトルネックがあるのか、どのタイミングでwhile loopに割り込みが入るのか など順を追っていくことができるようになります。このような体験を得るために、今回のように環境そのものをDocker image化し、 ソフトウェアインストールなどの設定をしなくても済むようにすることで、気軽に体験できる点がよかったです。

freeeのiOSアプリをSiri Shortcutsに対応させた話

こんにちは。モバイルエンジニアの高野です。

iOS 12がリリースされましたね!様々なアップデートがありますが、とりわけ目立って幅広いアプリで活用できそうなのはやはりSiri Shortcutsではないでしょうか。

ということで、弊社のiOS版クラウド会計freeeでも早速Siri Shortcutsに対応したバージョンを本日リリースしました!

Developers blogですので今回はどのようにこの機能を開発していったかを紹介します。

どんな機能?

Siriに「口座を同期して」と話しかけて口座の同期を開始する様子

弊社のプロダクトには、クレジットカードや銀行口座の明細をAPIなどから取得する同期機能が備わっており、定期的にバックグラウンドで明細取得されます。しかし、任意のタイミングで明細を取得して、最新の状態で会計処理をしたい時もしばしばあります。

今回はこの機能をSiri Shortcutsに対応させて、好きなタイミングでSiriを使って簡単に明細取得をできるようにしました。

Siriに「口座を同期して」と話しかけると、登録してあるクレジットカード・銀行口座の同期を開始し、新しい明細の取得が完了したらPush通知で知らせてくれる、という体験になります。

もちろん、Shortcutに対応させたことで、Siriに話しかける方法だけではなく、Spotlightのサジェスト・場合によってはロックスクリーンにもShortcutが表示される(ロックスクリーンに表示される条件はブラックボックスですが)ことになります。

WWDCのセッションの中で、Shortcutとして提供する機能はアプリ内で繰り返し行われる重要な機能が適していると言及されていましたが、今回それにピッタリの題材になったかなと思います。

Siri Shortcutsに対応させるために行うこと

ここから、今回の機能のために必要だった作業の流れを紹介していきます。

まずSiri Shortcutsに対応させるための開発には、SiriKitを利用します。SiriKitにはIntents frameworkとIntents UI frameworkが含まれています。

対応するにあたって参照したドキュメントは以下です。
SiriKit | Apple Developer Documentation

また、Appleが提供するサンプルコードであるSoup Chefも参照しました。
Soup Chef: Accelerating App Interactions with Shortcuts | Apple Developer Documentation

Intentの定義

さて、ではまずはIntentを定義します。IntentというのはSiriが受け付けられるリクエストのことを指します。

今回は「口座を一括同期する」と言うIntentが必要なわけですが、システムが標準で提供する特定ドメイン(MessagingやPayment等)のIntentとは合致しないため、カスタムインテントを作っていきます。

Intent Definition fileという新たに追加された形式のファイルを使って、Intentのタイトルやサブタイトル、パラメータ、リクエストに対してのレスポンスを定義していきます。このファイルはXcode 10~の「File > New > SiriKit Intent Definition File」から作成できます。

Intent Definitionを作成している様子のスクリーンショット

今回の定義は非常にシンプルで、タイトルや説明文などを記述しているだけです。CategoryにStart・Do・Run・Goなど汎用的な物が指定できるため、幅広いアプリでSiri Shortcutに対応させることができますね。

Intent Definition fileでIntentの内容を定義してからビルドすると、Intent Definition fileの内容に基づいたprotocolやclassを定義するコードが自動生成されます。 このコードのコンフリクトを避けるため、Intent Definition fileを開いた状態にし、XcodeインスペクタのTarget Membershipパネルで

  • 共有Framework(詳しくは後述します)の設定を”Intent Classes”
  • App、App Extensionの設定は”No Generated Classes”

と設定します。そうすることで、共有Frameworkに向けてのみコード生成されるようになり、コンフリクトが避けられます。

Intents App Extension

次に、Siri経由のリクエストをハンドリングするためのApp Extensionを用意します。

ユーザーからのリクエストに対して常にアプリを起動して反応する場合、このApp Extensionを作る必要はありません。ですが、ユーザーのリクエストに反応して何らかの処理をバックグラウンドで行いたい場合は、このIntents App Extensionを用意する必要があります。
バックグラウンドで処理を完了できれば、ユーザーはそれまで表示していた画面から離れることなくアクションを実行でき、より良いユーザー体験を提供することができるため、基本的にはIntents App Extensionを用いてバックグランドでタスクを完了できるようにした方がいいのではないかと思います。

Intents App Extensionの役割の大部分は、Siriとアプリが提供するShortcutを機能させるロジックとの橋渡しになります。今回私が実装した内容も、部分的に省略していますがだいたい以下のようなレベルの簡素な物です。

import Intents
import OurPrivateFramework

class IntentHandler: INExtension, FreeeFetchWalletableTransactionsIntentHandling {
  override func handler(for intent: INIntent) -> Any {
    return self
  }
  
  func handle(intent: FreeeFetchWalletableTransactionsIntent, completion: @escaping (FreeeFetchWalletableTransactionsIntentResponse) -> Void) {
    // 口座同期を開始するAPIにリクエストを送る
    APIClient.callTheAPI { success in
      completion(FreeeFetchWalletableTransactionsIntentResponse(code: success ? .success : .failure, userActivity: nil))
    }
  }
}

Siriからの要求をハンドリングするメソッドが、自動生成されたprotocolで定義されているので、そのメソッドの中で共有Frameworkに実装されたロジックを実行する感じです。
前述の、Intent Definition fileのスクリーンショットに「User confirmation required」という項目がありますが、Shortcutの実行前にユーザーに確認を促すべきアクションなどの場合はこれにチェックを入れ、IntentHandlerでconfirmするメソッドを実装する形になります。

注意点として、UIApplicationDelegateapplication(_:continue:restorationHandler:)はIntents App Extensionを提供しないアプリにおいてSiri経由のリクエストハンドリングする場合にも呼び出されるAPIですが、仮にIntents App Extensionを用意していたとしても、バックグラウンドでの処理ができなかった場合などに対応するため、application(_:continue:restorationHandler:)は実装するように、とドキュメントに書かれています。

Shared Framework

次に、AppとApp Extensionの間で共有する機能をこの共有Frameworkに実装します。「Intentの定義」のところで少し触れた共有Frameworkのことですね。Intent Definition fileを元に自動生成されるコードも、前述したTarget Membershipの設定を変更し、このFrameworkに含まれるようにします。

弊社のアプリでは、Siriから実行するための口座同期を開始するAPIの定義などがこのFrameworkに含まれています。

Siri対応に限らずApp Extensionを提供する際にはいずれにしろこのようなFrameworkが必要になることが多いですし、仮にApp Extensionに対応していないアプリでも、サービスのコアとなる機能をこのレイヤーに切り出しておくと設計としても良いのではないかと思います。

ShortcutのDonation

最後の仕上げとして、Shortcutとして提供したい機能をSiriに提供します。アプリ内でSiri Shortcutsに対応させる機能が利用される度にDonationするコードを実行します。ドキュメントによると、この時の時刻や位置等の環境を元にSiriがサジェストしてくれるようになるということです。

ただし、Siri経由でその機能が実行された場合は、システムは暗黙的にそのことを認知するようで、明示的にDonationする必要なありません。
逆にユーザーが一度も行ったことのないアクションを提供はしてはならず、将来的にユーザーが行う可能性の高いアクションについてはRelevant ShortcutsとしてSiriに提供するようにと書かれています。

アクションは、NSUserActivityINInteractionを使ってSiriに提供できますが、今回はINInteractionを使って、以下のようなコードでDonationしました。

let intent = FreeeFetchWalletableTransactionsIntent()
INInteraction(intent: intent, response: nil).donate { _ in }

エラー処理など省略していますが、Donationするのに最低限必要なコードはこれだけです。
これを、アプリ内で口座の同期ボタンがタップされる際に実行しておくようなイメージです。

Add to Siri

さて、ここまで行えばSiri Shortcutsには対応できていて、SpotlightやロックスクリーンへのShortcut表示は行われる下地が整った状態になります。 ここで更にSiriらしく、アプリ内で任意の音声フレーズを今回作成したShortcutに割り当て、音声でShortcutを実行できるようにする方法を紹介します。

まずはIntents UI frameworkに含まれるINUIAddVoiceShortcutButtonを使って、Add to Siriボタンを画面に表示します。
INUIAddVoiceShortcutButtonのイニシャライザは、enumとして定義されるINUIAddVoiceShortcutButtonStyleを引数として受け、それに応じてボタンの外観を変更します。現時点ではblack, blackOutline, white, whiteOutlineが定義されており、その中からアプリに合う物を選ぶことになります。

let button = INUIAddVoiceShortcutButton(style: .white)
view.addSubView(button)

表示はこのようになります。

Add to Siriボタンのスクリーンショット(白背景と黒背景)

INUIAddVoiceShortcutButtonのdelegateを設定しておくと、このボタンがタップされた時にdelegateのpresent(_:for:)メソッドが呼ばれます。その引数に渡されるINUIAddVoiceShortcutViewControllerを表示することで、フレーズを登録する画面がをユーザーに提供することができます。すでにフレーズが登録されている場合は自動的にボタンのラベルが変化し、ボタンをタップすると、編集画面を起動するためのpresent(_:for:)メソッドが呼ばれます。

現時点でINUIAddVoiceShortcutButtonのリファレンスに載っているサンプルコードだと、ボタンにaddTargetで設定したセレクタでINUIAddVoiceShortcutViewControllerインスタンスを作って画面に表示している箇所があり、この理由は分かりませんが、delegateを使ったほうがシンプルに書けると思います。

まとめ

大まかにではありますが、会計freeeでSiri Shortcutsに対応した際の流れを紹介しました。

弊社のモバイルチームではHack dayという、いわゆる20%ルール的な制度を設け、その中でエンジニアが自律的に作りたいものを作っていけるようにしています。実は今回のSiri Shortcuts対応はその中から生まれた機能です。この制度を使ってこれまでに色々な機能のリリースや、開発基盤の整備などが行われています。

ということで、freeeのモバイルチームではやっていきによってfreeeのプロダクトをもっとよくしてくれる仲間を募集しています!

スモールビジネスの未来をアプリで切り拓くモバイルエンジニア募集! - freee 株式会社のモバイルエンジニア中途の求人 - Wantedly

jobs.freee.co.jp

リモート勤務で、人の言葉を忘れ始めてしまいました — 九岡 佑介 (mumoshu) インタビュー(後編)

こんにちは id:ymrl です。おととい公開した前編に引き続き、freeeでSREエンジニアとして働く九岡佑介(@mumoshu)さんのインタビューをお楽しみください

mumoshuさんの写真

人の言葉を忘れ始めてしまいました

— ところでmumoshuさんはfreeeでも珍しい、地方からのリモート勤務をされているわけですけど、リモートでのやりづらさはないですか?

最初の数ヶ月は五反田の本社で勤務していたんですけど、いまは完全にリモートで月に1〜2回東京に来る生活をしています。ほとんどの開発メンバーが五反田にいるのでもともと月1回は本社に来るという約束になっていたんですが、いまのところ東京での登壇の予定などがよくあるので、それに合わせて本社に出社しています。

freeeメンバーとのやり取りほとんどがWorkplace上でやっていて、ずっとオンラインでやりとりしてきた人とこのあいだのオフサイト(社員合宿)で初めて会って、顔と名前がようやく一致するなんていうこともありました。やりとりは非同期的なテキストコミュニケーションが多いんですが、自分はついミーティング中に仕事しちゃうタイプなので、都合のいいときに非同期に話が来る状態のほうがやりやすいです。基本的にコミュ障なんだと思うんですよね。

自分みたいなタイプはマネージメントする立場からはやりづらいと思うんですけど、それでもチームの理解があることと、自分がこっちのほうが向いているなと思えること、そして人から指示されて動くような内容の仕事ではないというのが、リモートで仕事ができている理由のように思います。

リモートで働くようになって困ったことといえば、人と喋る機会が減って人の言葉を忘れ始めてしまいました(笑)。もともとあんまり喋らないほうなんですが、リモート勤務だとその傾向がもっと強まってしまって、朝に家族と話して、子どもを保育園に預けるときに先生に挨拶すると、あとはお昼にカレー屋さんでカレーを注文するくらいしか喋らなくなっちゃうんですよね。

そういう話をマネージャーとの1 on 1で話したら「リモートランチ」というのをセットしてもらえるようになりました。毎週いろんな人とビデオ会議を繋ぎながらご飯を食べているんですが、そのたびにそんなに話したことのない人と話せるので助かっています。

やっていき・のっていき

— freeeでの仕事の進め方はどうですか?

自分の所属しているSREチームはそんなに人数が多くないんですが、その中でいくつかのプロジェクトをやっているので、その関係で兼務兼務兼務みたいな感じで話をすることが多いです。

他のチームのエンジニアとは、Kubernetesを導入するプロジェクトで交流することが多いですね。で、デプロイが終わるとそのプロジェクトの人とは仕事上は疎遠になったりします。もちろん寂しさがないわけではないんですが、職人芸を発揮して離れていくというのは業務上の責任は果たせていると思うし、ある意味で理想的だと思うんですよ。

いちおう人なので、人との関わりは持ちつづけたいと思っているんですけどね。人間として矛盾しているかもしれません。日々出会いと別れですね。そんな感じで、常に職人芸を発揮できるものを探しつづけないといけません。

freeeでの仕事は、全体的にやりやすいなと思っていて、とにかくメンバーの「やっていき・のっていき」の精神がこの規模になっても感じられるのはすごいですよね。ふつうは会社の規模が大きくなったら、その人の仕事の範囲を越境したときのインパクトは大きくなるのでやりづらくなるはずなんですけど、そのあたりに貪欲な人が多いなと思っています。こういうのは一人のエンジニアの力ではぜったいに作れない文化で、すごくいいなと思っています。

そういう文化さえあればKubernetesだろうが何だろうが、新しくて良さそうなものなら何でも入れられるなって気がしますね。Kubernetesを入れようっていう話をしても背中を押してくれない人が誰もいなかったし、入社2日目のまだ何もよくわかってないような状態で出たミーティングで、もうKubernetesの導入が決まってしまったんですよ。あれはびっくりしました。

上手くいっているものを変えるのって、普通ならわかりづらいと思うんです。そういうときって「変えないと死ぬ」派と「今うまくいってるならいいじゃん」派に分かれて、前者がベンチャー的だなと思うんですけど、freeeはその二択という感じでもなくて、特徴的だと思います。暑苦しい人ばかりだとコンフリクトしそうだし、バランスがいいのかな。

インタビュー風景

職人が必要でなくなるときのために

— 最後に、mumoshuさんがこれからやっていきたいと思っていることををお聞きしたいんですが、将来目指しているものとかはあったりするんですか?

たぶんひととおりKubernetesの導入が上手くいってくると、Kubernetes職人みたいなかたちでインフラエンジニアがやることって無くなっていくと思うんですよ。いま社内に「Linux担当」っていう人はいないじゃないですか。あまりにもデファクトになった技術ってそうなっていくと思うんですよね。そうするとKubernetes担当の人としては一社では生きていけなくなってくるだろうし、生存戦略として他のこともやっていかなきゃと思っています。

そういう中で、機械学習のプラットフォームを作るのには興味があります。

大学院のときに自然言語処理をやっていて、テキストを解析して機械学習にかけて人間にとって意味のある結果を出す分野のことをやっていました。生データを加工して学習データを作って、それをモデルにして高速に問題を解いたりすることをしていました。

それをプロダクションに載せるっていう夢を持ってWeb業界に入ったんですけど、一転二転してインフラエンジニアやってるんですよね。

最近はどこもかしこも機械学習って言っていて、10年前とはあまりに世界が違うなと。そのわりに面倒臭さって変わってなくて、10年経ってこのままならKubernetesの次を探すときもこの泥臭いままなのかな、やることが残っていそうな匂いがしています。

それから、どこの会社の社内システムでもググれば大体のことはわかる、という世界を作ることにも興味があります。どこの会社でも何らかの自動化や効率化をしてきていると思うんですけど、それは会社によってだったり、やった人によってだったり、やり方に違いがあるんですよね。これまで何度か転職をしてくるたびに、「あ、これはあの会社とはこう違うんだな」というのを実感することを繰り返してきています。

でも、たとえばAWSを使っていて、EC2だとかRDSだとかElastiCacheの使い方のズレってそんなにないですよね。やっぱりAPIが切られているとそのAPIとして用意されている中でしかズレないのでキャッチアップしやすいですよね。

どこの会社のシステムもそういう風に同じAPIを軸に組まれていたら、もっとキャッチアップしやすい人材流動性の高い社会になると思うし、いろんな会社に首を突っ込みやすくなると思っています。そういう社会にしたいなと思っています。

いまSREチームとして他のチームの人から相談を受けるときも、社内独自でやってしまっている工夫についてはまだまだ眠っている暗黙知がある気がしていて、答えなければいけないプレッシャーにウッとなることがあります。Kubernetesのことは何を聞かれてもだいたいググって出てくるので、簡単だし怖くないんですけど。

freeeにはそういうところも期待しています。いつになるかはわからないけど、最終的には一社に一人freee担当がいて、そういう人が一人いるだけでいろんなシステムが自動化・効率化されていって会社が回る、みたいな世界を作れるといいですよね。

とはいえそういうfreee担当そのうちLinux担当とかKubernetes担当みたいになってそうですけど。やっぱりまずは職人芸の世界があって、それがだんだん職人が要らなくなっていくみたいな世界観をもって生きています。

インタビュー風景


長きにわたったインタビューでしたが、お付き合いいただきありがとうございました。

freeeではmumoshuさんのような職人気質のエンジニアを積極採用中です!!

jobs.freee.co.jp

jobs.jobvite.com

www.wantedly.com

Kubernetesでアプリエンジニアが勝手にやれるインフラを作りたい — 九岡 佑介 (mumoshu) インタビュー(前編)

こんにちは!freeeでエンジニアをやっている id:ymrl です。

ふだんマイペースに更新しているこのfreee Developers Blogですが、たまにはfreeeで働く個性豊かなエンジニアを紹介したいなと思い、第一弾として最近AWS Container Heroに就任したSREエンジニアで、kube-awsをはじめとするOSSのメンテナーとしても知られる九岡佑介(@mumoshu)さんにインタビューしてみました。Kubernetesの話やリモートワークの話を聞いていたら内容が盛り盛りになってしまったので前後編でお送りしようと思います。

mumoshuさんの写真

転職するごとにレイヤーが下がっていった

— mumoshuさんはこれまでKube-AWSの開発をされてきて、それもあって先日AWS Container Heroにも就任されたわけですけど、もともとKubernetesまわりのことをしはじめたのはいつ頃、どういうキッカケだったんでしょうか?

やりはじめたきっかけは、Chatworkのメッセージ基盤をScalaに移植するプロジェクトでした。このプロジェクトはアプリケーション側がずいぶんチャレンジングだったんですが、実はインフラもチャレンジングで、そこで採用したのがKubernetesでした。

そのころのインフラは社内で内製していたソフトウェアがあって、当時のChatworkをメンテナンスしていくのには最適化されていたんですが、Akka HTTPとScalaで作った新しいアプリケーションを動かすには不向きでした。また、当時のチームの構成としてアプリケーションエンジニアが多くそのモチベーションも高かったので、もっとプログラマブルで、アプリケーションエンジニアが使いたくなるようなインフラにして、その力を最大化できるものを求めていました。ちょうどそのときに使いやすそうだったのがKubernetesでした。

自分がかつてアプリケーションエンジニアあがりのインフラエンジニアなこともあって、そのころの自分が「これならインフラも見ようかな」と思えるインフラを構築したいと考えていました。自動化のしやすさや、必要だと思っている機能がひととおり揃っていて、自分たちで作りこまなくても使える状態というものが理想でした。

—アプリケーションエンジニアとしての経験が、いまのmumoshuさんのインフラエンジニアとしてのありかたに繋がっているんですね。なぜアプリケーションエンジニアからインフラエンジニアになったんでしょうか?

新卒のときは大手メーカー系の会社で、エクセルと電話を使って開発のディレクションをするような仕事をしていました。自分では全くコードを書かない仕事だったんですが「これなら自分が書いたほうが早いな」と思うこともしばしばありました。

そんなある日、社内で他の人から「あなたは優秀なのに、こんなことをしていていいのか?」と叱責されたのが最初のきっかけでした。自分でも「この仕事は全然面白くないな」と感じていたときだったので、考えた結果「自分で書こう」と思いました。

それから1年くらいその会社でプロダクションコードを書きました。当時HTML5とかCSS3とか、prototype.jsとかjQueryみたいな技術が出始めた頃で、いろんな会社のAPIをマッシュアップしてWebサービスを作っていました。

その頃はフロントエンドのことばかりをやっていた感じで、インフラのことなんて何も知りませんでした。エクセルを埋めて社内システムに登録して、あとは不明点などを電話で相談しているといつの間にかインフラが構築されている、という感じでした。そのときの「インフラわかんない感」を繰り返したくないなとか、その頃インフラもやっていたらこんな感じであってほしかったな、というのを未だに追いかけているのかもしれないです。

そのあと転職をするに従って、だんだん扱うもののレイヤーが下がっていきました。

2社目にいたときにScalaのPlay Framework 2に傾倒していて、自分の気にいった技術を社内で使ってもらうための外堀を埋める活動として、ドキュメントの翻訳をやったり、登壇をしたり、いろいろなことをしてきました。その一環でちょっとだけインフラを触ったのが自分にとって初めてのインフラでした。といっても他の人がAWSを設定したのをチョロっと触っただけだったので、今思えば「そんなところからよく初めたな……」という感じですけど。

インフラエンジニアとして仕事をするようになったのは3社目で、当時その会社ではじめてScalaを採用するというタイミングでした。そこで2社目でScalaを使っていたということでインフラに起用され、デプロイの自動化やモニタリングの仕組みなどをわからないなりに構築する機会を得ました。ここでそれまで触ってこなかったインフラの世界に一気に触れることができました。

その次の会社は、会社のエンジニアとしては5人目、自分がはじめての専任のインフラエンジニアという感じで、このときにはほぼアプリケーションコードを書かなくなっていました。このときの仕事はいろいろと大変でしたが、この経験がいまに一番生きていると思います。

インタビュー風景の写真

freeeに来たのは大きなチャレンジがあるから

— そのあと、現在も技術顧問をしているChatworkに行かれて、そしてfreeeに来たわけですけど、なぜfreeeを選んだんでしょうか?

Chatworkでは1年以上かけてKubernetesを導入するという大きなチャレンジがあって、あれは自分と、当時のチームでしかできないとても大きなチャレンジだったと思います。このチャレンジをやりきった上で、もっと大きなチャレンジをしたいと思うようになりました。

そこでChatworkには技術顧問として関わりつつ、本業としてそういう大きなチャレンジを探しているときに出会ったのがfreeeでした。

freeeには「規模」と「セキュリティ」という大きなチャレンジがあると思っています。freeeで扱う会計などのデータは、法律でどう守られるべきなのかが定められていたり、それ専用の監査のやり方が用意されているような情報です。そういうものが流れるシステムの監査に耐えられるインフラをKubernetesで作るのはとても大変なことだと思っています。

KubernetesをはじめとしたContainer Orchestrationの世界では、こういった厳しい監査のあるセキュリティ施策は未知の領域で、後付け後付けで改善されていっているんですが、それでもまだまだ進化の余地が残されているなと感じています。

規模の話でいうと、10人くらいで開発・運用を回しているような小規模なシステムでは、求められる要件が何であれKubernetesはオーバーキルなんですよね。しかし100人とかになってくるとカオスになってきて、「間違えることができない」が重要になってくるはずです。そういうときにKubernetesの、必要な機能が一通り揃っていて、それを組み合わせて使えばOKという特徴が生きてくると思っています。

自分は「ただ引き継ぐ」ことができない性格で、ついつい作りこみをして技術的負債を残してしまうので、そういう意味でも一通り揃っている機能から必要なものを選んで使えるKubernetesは合っているなと思っています。Kubernetesはやりすぎる余地があまりないし、もしやりすぎてしまってもその成果をOSSにしちゃえれば技術的負債にならないので(笑)。

そういったものを使いこなして、別次元の監査が要求されるような世界でも、開発者の生産性を落とさず監査に耐えられるような状態を作れたらいいなと思っていて、そんなチャレンジはfreeeでしかできないと思いました。

インフラは職人芸の世界

—— 自分にできないような大きなチャレンジの舞台として、今のmumoshuさんはインフラエンジニアをされているわけですが、自分はインフラのほうが向いていると思うようなところはあったりするんでしょうか?

インフラのほうが、職人芸が残っている分野な感じがしているんですよね。新しい技術が出てきたときに、最初は職人が絶対に必要になると思うんです。

Kubernetesもそうなんですけど、新しい技術を使うためにはどうしても必要とされるスキルセットが違うし、たくさんのことを憶えなければいけないですよね。そこまでして使いたい人というのはなかなか現われないと思うんです。でも、そんな中で物好きな人が勉強して使えるようになると、その人がその会社で最初の職人になるんですよね。

インフラの世界は、そういう職人芸が必要なものがまだまだたくさんあるのが面白いところかなと思っています。

インフラエンジニアとしては、アプリケーションエンジニアだった頃の自分が欲しいインフラを作っていきたいということを常に考えています。Kubernetes自体の運用はまだ職人芸というか特殊技能なんですが、その上でアプリケーションエンジニアが勝手にサービスを動かすということができるといいですよね。サーバーの台数を調節するなんていうのもアプリケーションエンジニアが勝手にやれるようにできるし、勝手にやったほうが絶対良いものになると思っています。それができるのがKubernetesだと思っています。

自分がアプリケーションエンジニアだったら、やっぱり人に押しつけられたものを使わされるのは嫌ですしね。これまで使ってきた仮想マシンベースのインフラと、Kubernetesベースのインフラを用意して、各自が使いたい方を自由に選べて、それをSREがサポートできる。そんな座組にできたらいいなと思っています。

mumoshuさんの写真


前編、いかがでしたでしょうか。リモートワークや未来の話で盛りあがったインタビューは後編に続きます。後編は明後日に公開予定です。お楽しみに!

2018/09/14追記: 後編を公開しました!

developers.freee.co.jp


jobs.freee.co.jp

www.wantedly.com