Tsuzu's Notes

主にIT系備忘録

Wantedlyサマーインターン

書くの苦手だけど書こうかな〜と言っていたらTwitterを捕捉されてしまい引くに引けなくなったので3年ぶりぐらいにブログを更新しています。(案の定なかなか書けず完全に乗り遅れました。早く書けるようになりたい。)

先日、3週間のWantedlyのサマーインターンにインフラコースで参加してきました。

WHY

ブログやイベントなどでWantedlyは早くからGoやKubernetesを本番投入しまくっているらしい、というのを知ったのがWantedlyに興味を持ったきっかけでした。それから時は流れ、今年のサマーインターンの募集を見て面白そうだな〜、と思い応募しました。

余談としてインフラとバックエンドどちらのコースにするかはかなり悩んだのですが、インターンコースの こんな人は是非 のところ見て自分じゃん、と思いインフラに決めました。

WHAT

取り組んだ内容

今回参加したインターンは、初日に課題を決定して3週間かけて一つの課題を解決するもので、私は「毎日機械学習のモデルの学習をKubernetesの上で行いDockerのイメージのビルドからデプロイまで行う仕組みを作る」という課題を選択しました。

課題を進める過程で必要な要件や仕様をミーティング等を通じて洗い出し、調査し、構築を進めました。 最終的にはWantedlyKubernetesクラスタ上で既に稼働している Argo というWorkflow Engineに乗っかる形にし、機械学習、Dockerイメージビルド、デプロイをそれぞれ一つのジョブとして順番に実行する仕組みを採用しました。単にYAMLを書けばいいのかな?と思っていたらデプロイ処理をKubernetes側から行うのはWantedlyで過去あまり行われてきたことはないようで、一部のコンベンションの変更等が必要になり、関連するツール等の変更も行いました。

PoCができた段階で再びミーティングを行い、workflowのYAMLってほとんどテンプレート化できるしYAMLを自動生成できたら保守面でもユーザ面でも嬉しいよね、という話になり残り一週間を切った段階で新しいリポジトリが生えてツールを作ることになった時には結構焦りました。

そんなこんなで元々問題提起されていたプロジェクトになんとか導入を終え、バタバタしたり何度もリトライしながら最終日の成果発表直前にプロダクション環境で無事学習からデプロイまでが行われることを確認できました。 また、そのプロジェクトの agatanさん に作成した仕組みを喜んでもらえたので非常に嬉しかったです。

文字に起こすと大したことはないのですが途中では悩むことが多く、メンターの munisystemさん に質問したり、指摘されたりしながらなんとか進められました。ありがとうございました!

より技術的な話も書きたいのですがここに書くと長くなるので後述します。

カルチャーなど

非同期コミュニケーション

印象的だったのはSlackのチャンネルに流れるのはお知らせや通知等が主で、多くの作業やコミュニケーションがGitHubをベースとして非同期で行われていることでした。最初は戸惑いましたがSlackでメンションを飛ばす時の申し訳なさなどが軽減されて慣れてくると快適に思えるようになり良かったです。

Infra Squad

Wantedlyではチームの小単位をsquadと呼んでいるそうです。

今回私が取り組んだ課題は元々アプリケーションのsquadから上がっていた課題でした。Infra squadが他squadとコミュニケーションが取れていることで開発チーム側が抱えるそういった課題を協力しつつ解決しやすくなっているのが良いな、と感じました。

Wantedlyでのインフラの歴史も聞く事ができ、どういった経緯やモチベーションでその技術を採用してきたか、なども聞けて面白かったです。これから来る技術の見極め力の高さに驚きました。

社内勉強会

週1回のペースで社内勉強会が開催されており私は Microservices MondayGophers Code Reading Party に何度か参加しました。面白かったです。社外の人でも参加できるらしいので興味ある人は参加してみてはいかがでしょうか(?)

ご飯

画像はモーメントにまとめたので良かったらみてください。 UXが良いと言われるカレーうどん屋、白金台のファミレス、美味しい和食屋など色々行けました。どれも美味しかったです。普段の学生街に比べて断然相場は高いですが・・・。 twitter.com

終わりに

(2日以上||就業型)インターンに参加したのは初めてでなおかつKubernetesを業務として触った事はなかったのですが無事成果を出す事ができてホッとしています。

ところで、ちょうどKubernetesのRBAC周りをちょうどインターンのArgo周りで触っていたおかげでインターン期間中にあった ICTSCの300点問題 を即解答する事ができ5位だったので非常にラッキーでした。閑話休題

周りにいる社員さんも優秀な方ばかりで刺激を沢山受けました。Infra Squadのリーダーの koudaiiiさん と1on1をさせてもらったり、他squadの方とランチに行かせてもらったりと交流を行う機会が豊富にあり、色々なお話を聞けて面白かったです。

これからも頑張っていくぞ!と思える最高のインターンでした!

オリジナルTシャツと修了証
Tシャツ欲しいな〜と思ってたらもらえたカッコイイTシャツと修了証。良い

技術的な話のおまけ

せっかく色々調査したので共有しよう、という事で軽く書いておきます。

ツール群

Kubernetes上でDockerイメージをビルドするための機構としていくつかのツールを検討したのですが最終的にはDocker in Dockerを採用しました。ある程度詳細に調査したツール群に軽く触れておこうと思います。

kaniko

  • Google謹製のDockerイメージビルドツール
  • デーモンを持たずkanikoのコンテナ単体でビルドする事ができる
  • 特殊な権限がいらない(privilegedやseccomp、AppArmorなどのsecurity contextを変更する必要なし)
    • Dockerfileをパースしてkanikoと同じ環境でRUNを直接実行する
    • (詳細な調査はできていないがS3などのcredentialが読めてしまうリスクが高くなりそう)
  • contextとしてローカルのファイル以外にS3、GCS、Gitなどが指定できる
  • cacheを勝手にやってくれる

といった特徴がありました。pullからpushまでを勝手にやってくれるのはかなり便利で今回のような一連のworkflowの一部のjobとしてのビルドやCIで使うには便利そうという印象を受けました。 マルチステージビルドも対応しているのですが並列で動作しなかったりそのステージを跨ぐ度にアーカイブする処理が入ったりでパフォーマンス的には余りよくありませんでした。

BuildKit

  • moby謹製のビルドツール
  • Docker 18.06からDOCKER_BUILDKIT=1で使えるやつ
  • 高速、セキュア、高機能
  • 並列化やキャッシュをいい感じにやってくれる
  • buildkitのデーモンを起動する事で使える
  • rootless対応(experimental)

非常に便利なツールで良い感じでした。 rootlessで使いたかったものの、私が試したところだとKubernetes上でrootlessではうまく動作しませんでした。seccomp周りの設定っぽいですが具体的な理由までは調査できませんでした。

dind(Docker in Docker(Kubernetes))

  • Dockerのコンテナ内でDockerを動かす
  • rootlessのイメージもあるが何れにしてもprivilegedが必要
  • いつものDockerが使える

なんてことはない普通のDockerをコンテナ内で動かすものです。普段普通はDockerでイメージをビルドする上、CI等でもDockerでイメージをビルドするため安心感があります。デフォルトではHTTPSで通信するデーモンが起動するためHTTPで利用するためには環境変数でDOCKER_TLS_CERTDIRを空で上書きする必要がある点に注意が必要です。ただしrootlessであってもprivilegedは必須です。

dindを採用した理由

これらのツールを調査した上でdindを採用した最も大きな理由はWantedlyで採用されているイメージレジストリquay.ioManifest V2, Schema 2 という最新のイメージの仕様に対応していなかったためです。 ここら辺のissueに詳細があります。

github.com

quay.ioに問い合わせをしたところ数週間以内に対応予定とのことでしたが記事執筆時点ではまだ対応されていないようです。上に挙げたツールの中で古い仕様にも未だ対応しているのはDocker in Dockerだけでした。(DockerでもManifest V2, Schema 1はdeprecatedだから早くイメージレジストリの方を対応してもらってね。みたいなメッセージが出ます。)

最も大きな理由は身も蓋もない感じとなってしまったのですがそれ以外の理由もあります。

Wantedlyでは開発者の負担を減らすためにDockerイメージのビルドなどもCLIツールで共通化され、Wantedlyのコンベンションに沿った仕組みを搭載しています。これらのツールは当然Dockerを想定しているため他のツールを利用する場合には新しいビルド手法も保守していく必要が出てきます。

また、Argoではsidecarとしてメインのjobの他で同時にコンテナを動かして置くことができるようで、公式に dindを行うexample がありました。同一コンテナ内に設置するのは少し抵抗がありましたがsidecarにできるとかなりスッキリします。

privilegedをつけることと以上のことを天秤にかけた結果dindを採用するに至りました。

フェルマー方程式/Fermat(JOI2007春合宿Day2 2nd)

春合宿まで精進するぞって言ってし始めたんですが結構始めから躓いていて早速数学に苦しめられています。(本選参加記はもう少ししたら書きます。)
Fermatも理解できず、LatteMaltaさん(@latte0119)に教えていただいてなんとか理解できたので忘れないうちに備忘録としてまとめます。(ありがとうございました!)

続きを読む

JOI2016/2017予選参加記

最後ということもあり書きます。
JOI(情報オリンピック)は中一から参加しているのでもう5回目ですね・・・。時の流れは早いものです。 前回、前々回は本選まで出場していますがいずれもそこで敗退しています。

事前準備

今回はいくつかのツールを事前に準備して挑みました。具体的には

  • テストケースの入力ファイルをダウンロードフォルダから自動分配するプログラム
  • 計5つのテストケースを実行ファイルの標準入力に渡して実行し結果をファイルに書き込むプログラム
  • 一度提出したファイルとローカルに残っているファイルが一致しているかを確認するプログラム。(結果として公式が公開した答えと自分の答えを照合するプログラムにもなりました。)

などです。
5回目にもかかわらず少し戸惑いながらなんとかログインなどの準備を完了しました。

1

JOI予選1問目恒例ifでとく感じの問題ですね。a≠0なので0を基準に考えればOKです。 gist.github.com

2

これもJOI予選2問目恒例forと配列でとく感じの問題ですね。 問題を勘違いしてやたらバグらせてしまったのが反省。 gist.github.com

3

O(NMD)で問題ないので3重ループしてあげれば終わりです。 gist.github.com

4

ここで難易度が急上昇してビビる。とりあえず問題を読んでDPっぽいなとは思いつつまだ思いつかなかったので飛ばして5問目。

5

UnionFindとかDBS/BFSとか考えて微妙にうまくいかなかったのでなにも考えず遡るようにsetでゴリ押すコードを書いたらケース5でも5sほどで終わってしまいまぁいいかとなってそのまま4問目へ。

gist.github.com

4

考察をすると最終的な状態を決めてしまえばどれを移動すればいいかが求められることがわかる。最終的な状態の並び方はM!通りあるがこれをbitDPで処理してやるとO(2M)で良いことがわかる。また、状態を確定させた時にいくつを移動しなければならないかはあらかじめ累積和を利用して数えておくことができる。

gist.github.com

6

ダイクストラに寒暖の異なる部屋に入れるまでの時間、寒暖、経過時間を持っておけば良さそうだとは思ったがそれでうまくいく確証と計算量がオーバーしそうな予感がしてそのまま終了。

結果

まだ結果は出ていませんが自分で答え合わせをした感じだと解いたところは全部あっていたようで5完(500/600点)でした。今回は各ツールのおかげでだいぶスムーズにできました。
本選にも出場できると思うので後悔の無いよう頑張ろうと思います。

カード情報が盗まれたっ!と一人で慌てていた話

自戒も含めて文字に起こす。

12月4日の夜、私はデビットカードを利用している銀行のインターネットバンキングにログインした。 そこで異変にすぐ気づいた。使った記憶がないのに口座から1万円以上なくなっていたのだ。慌てた私は不正利用の可能性を考えそこですぐにデビットを停止した。

f:id:tsuyochi23182:20161205191248p:plain
見てみると12月3日の夜にVisaデビットで13800円が利用されていた。しかし私は全く利用した記憶がない。いよいよ不正利用の可能性が高まってきたぞと思いつつ利用明細を開くとAmazonからの請求になっていた。 盗んだカードをAmazonで利用したりするだろうかと疑問に思いつつ自身のAmazonアカウントの注文履歴を見てもそのような請求は見当たらなかった。まぁAmazonなら返金される可能性も高いだろうし安心だと考えとりあえずAmazonのカスタマーサポートに連絡をしてみようかと考えていた時ふと13800円とはなんの金額なんだろう、と気になったのだ。 まぁそう簡単にヒットするわけはないだろうと思いつつGoogleで「Amazon 13800」と検索。しかしここで予想を裏切られた。f:id:tsuyochi23182:20161205184811p:plain
あっ...(全てを理解

時を遡ること数ヶ月前、国内のAmazon CloudDriveの無制限プランが解放された。無制限のクラウドドライブを渇望していた私は一目散に無料体験に飛びついた。その際にカード情報を登録する必要があったのだが、とりえあず入力して使ってみたところ思ったよりも速度が出ず実用的でないと判断したため金を払う価値はないと感じた。私はここでなぜか体験プランの終了を押すのではなく支払い情報から自分のカードを無くしておくことで体験プランが終了すると同時に支払いが完了せず勝手に終了してくれるだろうと考えていた。

しかし実際にアクセスしてみると実際支払いが完了していた。どうやらAmazonで普段買い物をするために登録しているカード情報から支払いが行われてしまったらしい。まさかそっちの情報から引き落とされるなど予想だにしていなかった。

仕方ないのでAmazon CloudDriveのカスタマーサポートに連絡をしてこの旨を伝えた。 このメールを送ったのは確か23時過ぎで、まぁ翌朝には返信が来るだろうと期待していた。しかしなんと日付が変わって2時ごろに返信があった。 まさか夜中にサポートしてくれるとは思っていなかったためとても驚いた。
結果はOK。 f:id:tsuyochi23182:20161205190328p:plain
ありがとうAmazon!今後はこのようなことがないように気をつけます...。

(今回事実に気づく前に一度銀行の方にも連絡を入れてしまい慌てて、なんでもありませんでしたという謝罪の連絡を入れ直したりしており、多くの人にご迷惑をおかけしてしまいました。この場を借りて謝罪を述べさせていただきます。申し訳ございませんでした。)

Node.JSでアンプをLAN経由で操作

以前家の今のテレビを父が購入した際、なぜか導入されたMarantz NR1604。(今や家で使う人は私一人のみでとてももったいない。)
NR1604はDLNAやネットワークラジオ、AirPlay*1などの機能をサポートしており、その一環としてLAN経由で操作ができるようになっている。
f:id:tsuyochi23182:20160709181127p:plain:w400

このNR1604は、音質などに疎い私には十分満足のいくものであり、よく家に一人でいる時にAirPlayを利用して音楽を流している。
NR1604は電源が切れている状態でもLANには接続されており、AirPlayで再生を開始すると自動的に電源が入るようになっている。
しかし、AirPlayが終了した後でも自動で電源が切れる機能はないため、私はよく電源を切り忘れてしまう。アンプは非常に熱を持つためよろしくない。

そこでタイマーをセットして指定された時間になるとLAN経由で電源を落とすスクリプトを軽く組んでみた。以下、開発環境。

まず、LAN上に存在するNR1604のIPアドレスを取得するところから始めた。プログラム内にIPアドレスを直で書いてもよかったが、度々変動していることもあったので動的に取得させることにした。
LAN上のデバイスのIPアドレスを取得する方法として、DLNAでよく使われているUPnPなどがあるが、今回はAppleが開発したBonjourを用いた。(そもそもUPnPをNR1604をサポートしているかは不明)
Node.JSにはBonjourを利用するなんとマルチプラットフォームなライブラリを公開してくれている人がいたため、開発はスムーズに行うことができた。Node.JSなんでもライブラリあってすごい!本当に。
Bonjourを利用して、サービスの種類をAirPlay(raop.tcp)にしてやると、以下のようにデバイスの情報が取得でき、その中にIPアドレスも書いてある。
f:id:tsuyochi23182:20160709183705p:plain:w400

あとは指定の時間にCronJobが発火するようにセットし、このIPアドレスに対してHTTPリクエストを送信するだけで電源を切ることができた。
今更ながらリクエストを送るために今回は既存をライブラリを用いたがそのライブラリが古いものであったため、バグ修正に追われて自分で書いた方が圧倒的に楽だったのが残念。
(一応コードを貼り付けますが基本的にmarantz-avrがおかしいのでまともに動きません。)
これで気兼ねなくMarantzアンプを使えるようになったので満足。

Marantz NR1604 Auto PowerOff

*1:Appleが開発した、iOS/macOSなどでサポートされているLAN経由で音声、ビデオなどを転送する機能。