Wantedlyサマーインターン
書くの苦手だけど書こうかな〜と言っていたらTwitterを捕捉されてしまい引くに引けなくなったので3年ぶりぐらいにブログを更新しています。(案の定なかなか書けず完全に乗り遅れました。早く書けるようになりたい。)
先日、3週間のWantedlyのサマーインターンにインフラコースで参加してきました。
WHY
ブログやイベントなどでWantedlyは早くからGoやKubernetesを本番投入しまくっているらしい、というのを知ったのがWantedlyに興味を持ったきっかけでした。それから時は流れ、今年のサマーインターンの募集を見て面白そうだな〜、と思い応募しました。
余談としてインフラとバックエンドどちらのコースにするかはかなり悩んだのですが、インターンコースの こんな人は是非
のところ見て自分じゃん、と思いインフラに決めました。
WHAT
取り組んだ内容
今回参加したインターンは、初日に課題を決定して3週間かけて一つの課題を解決するもので、私は「毎日機械学習のモデルの学習をKubernetesの上で行いDockerのイメージのビルドからデプロイまで行う仕組みを作る」という課題を選択しました。
課題を進める過程で必要な要件や仕様をミーティング等を通じて洗い出し、調査し、構築を進めました。 最終的にはWantedlyのKubernetesクラスタ上で既に稼働している 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 Mondayと Gophers Code Reading Party に何度か参加しました。面白かったです。社外の人でも参加できるらしいので興味ある人は参加してみてはいかがでしょうか(?)
ご飯
画像はモーメントにまとめたので良かったらみてください。 UXが良いと言われるカレーうどん屋、白金台のファミレス、美味しい和食屋など色々行けました。どれも美味しかったです。普段の学生街に比べて断然相場は高いですが・・・。 twitter.com
終わりに
(2日以上||就業型)インターンに参加したのは初めてでなおかつKubernetesを業務として触った事はなかったのですが無事成果を出す事ができてホッとしています。
ところで、ちょうどKubernetesのRBAC周りをちょうどインターンのArgo周りで触っていたおかげでインターン期間中にあった ICTSCの300点問題 を即解答する事ができ5位だったので非常にラッキーでした。閑話休題。
周りにいる社員さんも優秀な方ばかりで刺激を沢山受けました。Infra Squadのリーダーの koudaiiiさん と1on1をさせてもらったり、他squadの方とランチに行かせてもらったりと交流を行う機会が豊富にあり、色々なお話を聞けて面白かったです。
これからも頑張っていくぞ!と思える最高のインターンでした!
技術的な話のおまけ
せっかく色々調査したので共有しよう、という事で軽く書いておきます。
ツール群
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とはいえprivilegedをつけるかseccompやAppArmorの無効化をする必要あり
- cf. https://github.com/moby/buildkit
非常に便利なツールで良い感じでした。 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.io がManifest V2, Schema 2 という最新のイメージの仕様に対応していなかったためです。 ここら辺のissueに詳細があります。
quay.ioに問い合わせをしたところ数週間以内に対応予定とのことでしたが記事執筆時点ではまだ対応されていないようです。上に挙げたツールの中で古い仕様にも未だ対応しているのはDocker in Dockerだけでした。(DockerでもManifest V2, Schema 1はdeprecatedだから早くイメージレジストリの方を対応してもらってね。みたいなメッセージが出ます。)
最も大きな理由は身も蓋もない感じとなってしまったのですがそれ以外の理由もあります。
Wantedlyでは開発者の負担を減らすためにDockerイメージのビルドなどもCLIツールで共通化され、Wantedlyのコンベンションに沿った仕組みを搭載しています。これらのツールは当然Dockerを想定しているため他のツールを利用する場合には新しいビルド手法も保守していく必要が出てきます。
また、Argoではsidecarとしてメインのjobの他で同時にコンテナを動かして置くことができるようで、公式に dindを行うexample がありました。同一コンテナ内に設置するのは少し抵抗がありましたがsidecarにできるとかなりスッキリします。
privilegedをつけることと以上のことを天秤にかけた結果dindを採用するに至りました。