🐳

2021年に今更コンテナ入門した僕の最初の一歩

2021/06/06に公開2

はじめに

最近までコンテナは使うだけだった僕が2021年に真面目にコンテナ入門をしたので、どうやって入門し始めたか、結果今どうなったかを書いておこうと思います。
今となってはコンテナと1口に言ってもKubernetes Docker podman runcなどなど様々な難しい単語が飛びかっています。CloudNativeという単語もよく聞きますね。コンテナだけあってコンテナ界隈は海のように広いですね。
壮大なコンテナ界隈の海を僕がどうやって最初にチャレンジしてみたか参考に慣れば🙏
結論として入門した結果はこちらです。
https://github.com/containers/youki

コンテナ入門するきっかけ

2020年くらいまでの僕はDockerを使う程度の知識、namespaces(7)cgroups(7)というLinuxカーネルの機能が使われているらしいということしか知りませんでした。Kubernetesも略し方や発音で時々話題になることを知っていることと簡単に触ったことがある程度でした。
そんな僕がコンテナ入門しようと思ったきっかけのニュースはこれでした。このニュースがあまりピンとこなかったので若干の危機感を覚えて入門しようと思いました。
https://thinkit.co.jp/article/18024

最初に出会った本

タイムラインで話題になっていたこちらの本を手始めに読んでみました。と言うか今の所この本しか読んでいません。この素晴らしい本の筆者の徳永さんには感謝です。
https://www.amazon.co.jp/dp/4297118378
この本の素晴らしいところはDockerの使い方だけではなく、コンテナの仕組みを説明してくれているところでした。むしろ、ぼくはこういう本がでるのをずっと待っていた感はありました。
この本ではコンテナ標準仕様の1つであるOpen Container Initiative Runtime Specificationについて触れていました。この仕様は低レベルコンテナランタイム、つまりnamespaces(7)cgroups(7)を利用してコンテナを実際に作成する層の仕様書です。低レベルコンテナランタイムはDockerpodmanから使われるソフトウェアで一般的に一番有名なのはGoで実装されているruncです。
そして標準仕様も読んでみた僕は「作れそう!!」となりました。ちなみに仕様書はそこまでたくさんのことは書かれていないです。その後に気がついたんですが、実際の仕様書は実質runcのコードです。runcのコードを読むことになります。 コンテナランタイムは誰でも作れると言うと嘘になりますが、manを読めたりするエンジニアならおそらくなんとなく作れそうとなると思います。そしてなんとruncというリファレンス実装と呼ばれているお手本の実装もあります。作れるものが明確になると作ってみるのが、一番楽しくて自分に合っているので作り始めました。
ちなみにですが、コンテナ入門はやはり海がおすすめです。
https://twitter.com/utam0k/status/1339456740115374080?s=20

コンテナランタイムを作ってみる

私はRustに慣れていたので、Rustで作り始めました。ただ、のちのちこのRustという選択肢がたまたま良い方向に運びました。作ったコンテナランタイムはこちらです。今はもうcontainersのレポジトリになっていますが、最初は僕個人がオーナーのリポジトリでした。それについては後述します。
https://github.com/containers/youki
基本方針は仕様書を読んでそれっぽく作る感じです。仕様書には「create start deleteなどのサブコマンドを受け付けてこんな感じの動作してね。」みたいなのが書かれているのでそれ通りに作っていきます。
そして、仕様書通りに作れているかテストするツールとしてruntime-toolsというのを仕様書を管理しているコミュニティが作ってくれています。めっちゃありがたいですね。僕はこれを使って作っていきました。
そして動きました。実はcgroups(7)がなくてもnamespaces(7)とマウント周りさせ動かけば動かすことができます。動くとモチベーションがあがるのでまずは動くようにするのがおすすめです。
https://twitter.com/utam0k/status/1355709762759888900?s=20
実装の難しいポイントはttyを扱う関係でprintデバッグが困難である点でした。

結局コンテナランタイムを作って何がわかったのか?

  • コンテナの実態とは何なのか?
  • 現状のコンテナ界隈の仕組み
  • runcのコードへの理解

そしていまとこれから

そして縁があり、podmanやcrunを実装しているcontainersに所属することになりました。
https://twitter.com/utam0k/status/1400765043168350213?s=20
最初の頃はお遊びでしたが、今はどうやったら後発でいい感じにコンテナランタイム界隈に貢献できるか考えています。まさかこんなことになるとは思っていませんが、containersに所属している方々は主にRedHadの方々でコンテナのプロです。その方たちの意見を聞きながら、いろいろ試して価値のあるものにしていきます。
ここでは僕が作っているコンテナランタイムのモチベーションやどんな機能を作っていくかは話が逸れすぎるので書きません。詳しくはissueやREADMEを覗いてみてください。近いうちにそういう記事も出すつもりです。
OSSなのでいつでも一緒に楽しんでくれるコントリビューターを募集しています。興味あるけど、「自分本当に実装できるのかな...」という気持ちは僕もすごいわかるなのでDMか何かで聞いてもらえればできる限りissueを用意してみたりするのでよかったらぜひ。good first issueも用意しています。
たまには、コンテナを使うだけではなくどういう動作なのか知ってみるのはどうですか?きっともっとコンテナとはなにかわかり、沼にハマっていきます。溺れないようにしましょう。
そして僕はまだKubernetesを何も知らない...

Discussion

inductorinductor

僕の書いた記事だ!言及ありがとうございます :)

TenForwardTenForward

すごすぎる。どんどんコンテナ沼にハマって(^^)深い濃い内容を教えてください。