Dockerって何? って聞かれたときの解説、の解説

2021/05/25に公開
8

TL;DR

  • Dockerは仮想化であるコンテナの実装の一種
  • ただし、広義のDockerはOCI系コンテナの総称
  • アプリの配布と実行の仕組みと思えばOK
  • コンテナによりIaCや一貫したデプロイ、H/Wの効率的な利用がしやすくなる

※ コメントでいくつか指摘があったので記事を更新しました。ご指摘ありがとうございました!

はじめに

おそらく過去幾度となく生み出されたであろうDocker解説記事となります。正確には解説動画の解説記事。

というのも、Dockerあるいはコンテナはもはや当たり前、と言えるほど普及してるようにもSNSやブログとかだけ見てると思えますが、実際には話題は知ってるけど良く分かってない/業務で今度使う事を検討したいけどつまり何なの? って人もまだまだ多いです。

なので私が 「Dockerって何?」 と聞かれたとき答えてる内容を動画にしてみました。技術的な詳細を解説というよりは 「そもそも何なの?」 「何で流行ってるの?」 を話しています。

動画で使っているスライドはこちら。
https://slide4vr.nklab.dev/slide/0m3ItnvCMQhbACV9rR5mkdmFOns2/c4c0f543-02c2-433a-9e69-67faecf4c982/

ただ動画の中では長さの都合で話さなかったこともあるので、もう少しだけ詳細を書いておこうと思い解説の解説としてこの記事を書きました。

Dockerとは?

DockerはDocker社によって開発されるOCI系のコンテナです。元々、Docker社はdotCloud というPaaSベンダーで、フルスクラッチでアプリを作る場合のプラットフォームとして当時人気だったのHerokuとは異なり、WordPressとか既存のアプリケーションのホスティングを簡単に出来ることを売りにしていました。その中で使われていた技術がDockerコンテナであり、こちらを公開したところ本業よりも人気になってしまい社名もDocker社に改めて本格的にコミットしてきました。

コンテナという存在はDocker以前にもありましたが、既存のものよりポータビリティに優れ、この段階では後述するVagrantの後継としてちょうど良いポジションだったのでまず普及したかな、という感じがります。もちろん他の文脈で気にしてた人も当時からいると思いますけど。

もう一つ重要な点としてDockerは具体的な実装としてのDockerとは別にOCI系コンテナの総称としても使われます。例えば本番環境でDockerを使っているとは限らず実は別の実装(例えばcontainedとか)を使う事も少なくないのですが便宜上「Dockerを使ってる」と言ったりします。これは後述するOCIと呼ばれる仕組み自体がDockerをオープン化したものであり、その流れから広義にはDockerはOCI系コンテナの総称となります。正確な表現かはさておきとして、実際問題OCI系のコンテナの総称として使われることもあるので 「狭義のDockerと広義のDockerがある」 といったん覚えてもらえれば良いかと思います。

Dockerは本番環境では単体ではなく k8s(Kubernetes) と組み合わせて使われることが多いです。この組み合わせが モダンなインフラを作る基礎技術 になっているので現在メチャクチャ流行っている、という訳です。また**「Dockerって何?」** という話題になった時に、ポータビリティだったりIaCだったり分散システムだと話が発散しがちなのですが、これは元々色々な文脈のプラクティスがDockerに合流しているためです。その点に関しては後半で説明をします。

コンテナとは?

コンテナ概要

コンテナはOS機能による仮想化の一種です。最近よく聞く名前だと思いますが特に新しい技術ではなく何十年も前からある仕組みです。SolarisのZONE、BSDのJail、あるいはLinuxのLXCやOpenVZなど様々なコンテナがあり活用はされてきたのですが、今はコンテナといえばOCI系コンテナを指す と言っても過言ではないと思うので、特別な文脈でなければ「コンテナ == OCI系コンテナ」と思って聞いて大丈夫だと思います。この記事でも以降は単にコンテナと呼びます。

コンテナは OSの仮想化 とも呼ばれますが、VMWareなどのH/W仮想化 とは異なり、OSそのものは共有しているが名前空間の分離やリソースの割り当てを分離しています。そのためオーバーヘッドが非常に小さく ほとんど普通のプロセスと同様の速度で起動/実行されます。

OS(正確には狭義のOSであるカーネル)を共有するのでVMWare等のように自由にゲストOSを選ぶことは出来ません。OS機能を使ってるのでホストOSも通常は限定されます。Dockerの場合はLinuxをベースとした仕組みなので原則Linuxのみで動作します。厳密に言えばWindows ContainerというOCIに準拠したWindowsのコンテナもあります。しかしWindowsサーバを運用する上での主流という感じではないです。とはいえ、コンテナ周りもどんどん発展しており今後Linuxベースでは無いものも普及はしてくるかもしれませんが、現時点ではLinuxベースのものと考えて良いと思います。余談ですがWindowsの内部ではWSL2やDefender Application Guardなどコンテナは結構使われてたりします。内部で使うだけなら必要が無いのでそれらはOCI準拠という分けでも無いでしょうけど。

「いや、うちのMacやWindowsはDocker使えてるよ?」と思われるかもしれませんが、あれはDocker DesktopがVitual Boxや各種OSの仮想化機能を使ってH/W仮想化でLinuxを動かしてその上でDockerを動かして透過的につないでるだけです。Windowsの場合はHyper-vと組み合わせてOCI準拠の形でLinuxを動かすrunhcsという形で仕様としてもまとめられています。非常に便利な仕組みですね。ただ、Linux以外のホストOSでLinuxコンテナを動かしてる場合は大なり小なり仮想環境を挟んでいるので、意識してないと偶に罠にはまりますので注意をしてください。

H/W仮想化とコンテナ

H/W仮想化とコンテナの違いをもう少し追っていきましょう。良くある説明の図はこんな感じ。

H/W仮想化ではまずハイパーバイザーが一番下に置かれます。その上で各種ゲストOSが動く形ですね。ハイパーバイザーとは雑に言えば「仮想マシン専用の実行基盤(=OS)」です。通常のOSよりも仮想マシンの実行に特化しているので無駄なものが無くセキュアで軽く高機能、というわけです。VMWare ESXiが一番有名だと思います。

本当はH/W仮想化もハイパーバイザー方式以外にもType2とも呼ばれるQEMUやVirtualBoxなどOSのアプリケーションとして動く仮想化ソフトウェアもあるのですが、サーバサイドでは通常はハイパーバイザー方式を採用するのでそちらと比較しています。

ハイパーバイザがその上で各マシンをエミュレーションしその上にOSをデプロイしているのに対し、コンテナの場合は同じOSの上にコンテナという箱を置いてそこでアプリ単位での仮想化を実行しています。図を見るだけでもパソコン/サーバを丸ごとエミュレーションしているH/W仮想化よりはアプリの実行のところだけ仮想化しているコンテナ の方がなんとなくオーバーヘッド小さそうですよね?

具体的な仮想化対象の違いは以下の通り。

図の通り、H/W仮想化ではCPUやメモリといったものを仮想化しています。そのため仮想マシンより上は通常のOSになりWindowsとLinuxをそれぞれGuest OSで動かしたりすることも可能です。準仮想化の話とかあるけどここでは割愛。

対してコンテナでの仮想化の基本は名前空間の分離です。これは同じOSの上にあるのにそれぞれのアプリを専用環境で動かしているように見えるという事です。例えば利用するディレクトリ及びインストールされているソフトウェアが異なっていたり、コンテナ間でプロセスが共有されなかったり、NWで同じIPやポートを使っても干渉しなかったり、そういったOS
OSの各種機能が隔離されているという事です。またCPUやメモリ、ストレージといったリソースの割り当ても制御します。

コンテナはあくまでOSの各プロセスにタグのようなものを付けコンテナ間で干渉しないようにフィルタリングしているような挙動になります。実際にDockerなどであればホストOSでPSコマンドを打てばDocker上のプロセスも通常のプロセスのように見えます。H/W仮想化でも仮想マシンの上で動くプロセスを確認は出来ますがこれは仮想マシンの上で動くOSをのぞき込んでるだけでコンテナのケースとはかなり挙動が違います。この違いがパフォーマンスやセキュリティに大きな影響を与えています。

イメージとコンテナ

Dockerの基本となるDockerfile/イメージ/コンテナについて解説します。

まず、Dockerfileですがこれはビルドスクリプトです。Dockerではマニュアル片手にコンテナにログインしてコマンドを手作業で打って環境構築、ということは通常はしません。代わりにDockerfileというBash風のビルドスクリプトを使います。これによって手順書でインフラを作るよりも誰が作っても再現性の高い環境を構築できます。このような考え方をIaC (Infrastructure as a Code) と呼びます。AnsibleとかChefとか使ったことがある人はイメージがしやすいですね。ビルド結果としてimageが出来ます。

次にimageですが、これはLinuxのディレクトリを/からtarで固めたものと考えてみてください。実際にはDockerはLayerd File Systemを採用しているので単一のファイルとして固められてるわけではないのですが/から固めたファイル全部と考えた方が想像しやすいのでまずはそう考えても良いと思います。LinuxといえばRedhatやCentOS、DebianやUbuntuなど様々なディストリビューションがありますがカーネルは同じです。そのためルートからのディレクトリを丸ごと置き換えてやれば異なるディストリビューションとして振舞います。またイメージの最も重要な点は 「配布可能」 という事です。これによりWrite once, Run anywhereをいかなる言語であっても実現する事が出来ます。

最後にContainerですがこれはImageを実行した状態と考えることが出来ます。ImageとContainerは最初はどっちがどっちだったかと混乱しがちですが、ディスクイメージのような塊がImage、実際に動いてるプロセスがContainerと考えると良いと思います。

Dockerが流行っている理由

Dockerで出来ること

簡単に構成の話が出来たので、次にDockerで出来る事を解説します。シンプルに言えば以下の3つです。

  • DockerfileでImageを作成できる
  • Docker Imageを配布できる
  • Docker Imageをコンテナとして隔離された形で実行できる

という3点です。つまるところアプリを必要なライブラリごとパッケージング して、配布して環境に依存せずに実行 できます。さて、ではなぜこの特徴でここまで流行っているのでしょうか?

端的にいえばDockerは流行っているから流行っています

DockerHubやk8sといったエコシステムの力を使いたいから流行っているのです。もちろん、そのエコシステムが出来上がったのには理由があり、それこそが最初に上げたDockerの特徴です。この特徴が有用だったでのDocker以前から存在していた様々なプラクティスがDockerに集約されていきました。

Docker前史

先ほど述べたようにDockerは様々なプラクティスが集約されています。つまり目的が分かりづらいです。なので、Dockerに集約される前の前史を振り返ってみます。

運用/インフラ/あるいはDevOpsという界隈では上記の4つの考え方があり10年くらい色んな製品が群雄割拠していました。

パッケージング/ポータビリティ

これは依存関係を含めて一つに固めてそれを配布すればどこでも動く、ということです。一番成功した例はJavaEEのwarではないでしょうか? あるいはRubyのエンジニアならばbundler, Pythonのエンジニアであればpipenvを思い浮かべても良いと思います。これらは単一ファイルまたはディレクトリに依存を固めることでポータビリティを実現しています。ただし課題もあって多くの場合はOSのグローバル環境にも依存していしまいます。/var/etcあるいはホームディレクトリなどの構成やIPアドレスにポート番号、また自前主義のJavaはともかくスクリプト言語だとOSにインストールされているパッケージも重要です。こういったところで差分が出てしまいポータビリティには課題が残る状態でした。これを解決するために仮想OSに固めてVMイメージを配布するVagrantというソフトも人気を博していましたが、Dockerに比べると起動のオーバーヘッドやイメージが大きかった状態です。

IaC (Infrastructure as a Code)

先ほども説明した通り手作業ではなくスクリプトでインフラを組む考え方です。これは手順書の代わりに構築を自動化させて作業を効率化させるという観点もあるのですが、どちらかというとバージョン管理や簡単なdiffの確認、PullRequest/コードレビューなど開発のベストプラクティスをインフラにも持ち込むための考え方です。AnsibleやChefも有名ですね。Iacにより手順書やパラメータシートを疑って本番で値を確認しなくても良くなります。特にその中でもDockerは一度作った環境を変更しないImmutable Infrastructureと呼ばれる運用を実現できます。実はAnsibleやChef、あるいは特に自前のBashによる環境構築をした場合は手で誰かが後から変更してしまったり、スクリプトに不備があった時に誤った変更をしてしまい環境を壊す場合がありました。Immutable Infrastructureでは変更では無く常に新規構築なので誤った場合に元の内容に戻すのも容易です。

サーバ利用効率化

ハードウェアをより有効活用しよう、という話です。現在のサーバはスペックが高く通常時は空きリソースが出来るのは当然です。そしてクラウド時代と違いHWは貴重なので、アプリケーションを相乗りさせてHWリソースを有効活用しようという話になりました。しかしながら、素朴な相乗りでは同一のライブラリの異なるバージョンを要求して片方のアプリが壊れたり、セキュリティ設定があまいだと別チームの人間が別アプリを触れたり、そして何より片方のアプリが高負荷な時に巻き込まれて死ぬ、という事象が発生していました。これらを解決するためにOSレベルのセキュリティ/リソースの分離をすべくVMwareなどの仮想化が普及していきました。特にVMWareは2つの異なるアプリケーションが同時に高負荷になる可能性は低い、という特性に注目して単にに2で割ったリソース分配ではなく少し多めにリソースを割り当てるオーバーコミットをする事が出来ます。銀行の信用想像みたいなものです。皆が一斉に引き出す(=一斉に高負荷)と取り付け騒ぎになるのも同様ですね。

オーケストレーション

この文脈では大規模分散システムのリソース管理を指します。これはある意味ではH/W仮想化を使ったサーバ利用効率化をより推し進めたものでOSのスケジューラよりもよりたくさんの必要な情報をとれるためミドルウェアとして実装され対応したアプリケーションのスケジューリングを行っていました。有名な実装としてHadoop YARNやMesosがあります。

こういった様々な観点がDockerとK8sに集約されていき、現在は上記の4つのいずれかを実践したい場合は最新の環境がDocker + k8sになるので人気があるわけです。まあ、最新の仕組みが一番自分たちに合うかどうかは別の話だけど。

Dockerの周辺システム

DockerHub

DockerHubはDockerイメージを共有するための仕組みです。DockerにはRegistryというイメージを配布する仕組みがあり、DockerHubはその本家本元公式サイト、というわけです。DockerHubの公開済みイメージを使う事で今まではそれなりに手間がかかったMySQLやMongoDBなどのミドルウェア、あるいはそれらも利用したWordPressのようなアプリケーションが今やdocker runの一発で構築できるようになりました。これはメチャクチャ強力です。Dockerが流行った原動力の一つはこのDockerHubの豊富な充実度だと思っています。

k8s (Kubernetes)

k8sは非常に大きく複雑な仕組みなのであまり触れませんが、オーケストレーションを担当するミドルウェアになります。つまりDockerを使った分散環境です。色々機能はありますが主にスケジューリング/デプロイ/セキュリティを担当します。つまりYARNやMesosのような位置づけですね。Googleが社内で利用していたBorg/Omegaといった大規模コンテナ実行基盤をベースに、Dockerに対応できるように一から書き起こしたものです。元々コンテナの超ヘビーユーザであるGoogleによって作られただけあって拡張性が非常に高くかつスケーラブルです。

分散環境で自由度の高いスケジューリングを行おうとすると配下のどのノードにもデプロイでき依存無く実行される必要があります。これにはDockerの特徴は最適です。

ただ、私の認識ですがk8sはPaaSなどのクラウド環境を作る基盤という特性が強いので自力で運用しようとするとかなりのパワーを使います。そのため素のk8sを直接運用するよりもCloud RunやHerokuのようなPaaS/CaaSとして利用できる別のコンテナ実行基盤や、AWS FargateやGKE Autopilotのようにフルマネージドなk8sか、せめてGKEやAmazon EKSを使うのが良いと個人的には思います。前から順番にお勧め。もちろん、必要なら素のk8sを選べばいいと思います。

Docker以外のOCIコンテナ

OCIは元々Dockerをオープン化した仕様となります。さらにリファレンス実装の多くが元々Docker由来という事もあってOCI系コンテナの総称としてDockerを使うというのはすでに述べた通りです。逆にいえばDocker以外の実装も存在します。

有名どころとしてはcontainerd, cri-o, そしてPodmanです。

containerdは実はDockerの内部にも使われている実装でいわばDockerから本番実行に不要な部分を外したコードです。そのためDockerとの互換性も非常に高くGKE, EKS, AKSなどでもサポートされています。

cri-oはその登場経緯からしてk8sで動かすことを目的として作られました。そのため軽量でk8sで動かすことに特化しているそうです。OpenShiftなどで利用されています。

最後にPodmanですがRedhat社がDockerの代替を狙って開発しているコンテナです。Docker同様に開発ツールなのでビルドなどの機能も充実しています。大きな特徴として不要なデーモンプロセスを無くしたりsystemdとの連携を高めるなどセキュリティやLinuxとの統合をより進めたプロダクトとなっています。

Dockerとセキュリティ

Dockerにおいてセキュリティは重要なキーワードです。それは原理的にOSを共有しているためVMWareなどのH/W仮想化に比べると隔離レベルが低いからです。これは社内などすべてのコンテナが自社のもののケースでは問題になりにくいですが、クラウドベンダーなど複数のユーザのワークロードを混在して実行させる環境では大きな問題になることもあり得ます。

そのためいくつかのセキュリティのための実装があります。特に有名なのがAmazonのFirecrackerとGoogleのgVisorです。これらはAWSやGCPなどで既に利用されています。

Firecrackerは分かりやすくmicro-VMとも呼ばれる非常に小さなVMを起動しその上でコンテナを動かすのに必要最小限のLinuxを動かす方式です。micro-VMは1秒以下の時間で起動する非常に高速な実装なのでVMwareとかでイメージする仮想マシンの起動速度とは一線を画します。WindowsのWSL2とかもそうですね。VMなので隔離レベルは高くシンプルですし、それでいて起動が高速なのは素晴らしいです。なおFirecracker はコンテナランタイムではないので注意をしてください。

gVisorはユーザ空間で動くアプリケーションとして実装されたカーネルです。コンテナ側から見えるカーネルを直接ホストのカーネルではなくコンテナ毎に専用のカーネルで実行します。最終的にはこのgVisorのカーネル自体はホストのカーネルの上で動くことになりますが直接コンテナから見えませんし強力なセキュリティとパフォーマンスを両立できます。一方でmicro-VMと比べると仕組みが複雑になりがちかと思います。

Dockerとセキュリティ、というと脆弱性スキャンの話も話題になりがちですが、今回はコンテナに特化した事情というこでカーネル周りの話をもってきました。

まとめ

なるべく技術的な詳細には踏み込まずにかつ使いたい理由/流行っている理由をまとめてみました。とりあえず一通り読むと以下のイメージが大分つきやすくなったんじゃないでしょうか?

  • Dockerは仮想化であるコンテナの実装の一種
  • ただし、広義のDockerはOCI系コンテナの総称
  • アプリの配布と実行の仕組みと思えばOK
  • コンテナによりIaCや一貫したデプロイ、H/Wの効率的な利用がしやすくなる

OCIとかRunCとかCRIとか技術的な背景が知りたいんだー! って人には物足りないと思いますし、コマンドでの操作とか実務的な内容は別でやる必要がありますけど 「そもそも何?」 って段階だと、このくらいがちょうど良いんじゃないかな、と。

ちなみにこれはかなりジェネラルな説明で相手の知識によってもちろんカスタマイズします。特にJava EEとかに慣れてる人だったら「war=docker, k8s=weblogic/glassfishととりあえず思ってください」という事が多いかな。

それではHappy Hacking!

参考

この記事はあまり細かい所を深堀していないので以下の資料も読むとより詳しく分かるかと思います。

https://docs.docker.com/get-started/overview/
https://opencontainers.org/
https://kubernetes.io/docs/concepts/
https://www.slideshare.net/zembutsu/container-and-cloud-native-overview-distribution
https://blog.inductor.me/entry/2020/12/03/061329
https://blog.inductor.me/entry/2021/03/07/011811
https://cloud.google.com/kubernetes-engine/docs/concepts/sandbox-pods
https://github.com/firecracker-microvm/firecracker
https://systemadminspro.com/google-gvisor-amazon-firecracker-openstack-kata/

Discussion

kayakaya

いつも有用な記事ありがとうございます。
誤字報告です。

  • Write onece, Run anyware → Write once, Run anywhere
  • 2箇所DockerがDokcerになってる

なんでZennは編集リクエスト機能ないのだろうと思ったら、
記事がGit管理だからそっちに訂正投げてくれってシステムなのですね。
私がこの記事のRepository見逃してたらすみません。

kodukikoduki

読んでいただきありがとうございます! & 誤字の指摘ありがとうございます。修正しました。
なるほど、編集リクエストが無いのはそういう。。。私はGithub管理にはしてなかったですがそっちのが良いのかな

inductorinductor

いくつか気になったことがあるので書き残しておきます。

  1. WindowsコンテナはOCI互換ではないかのような記述が見受けられますが、間違っていると思います。こちらのドキュメントrunhcsの箇所を御覧ください。
  2. もう一つ重要な点としてDockerは具体的な実装としてのDockerとは別にOCI系コンテナの総称としても使われます。例えば本番環境でDockerを使う事はそんなに多くなく実は別のコンテナを使ってるのですが便宜上「Dockerを使ってる」と言ったりします。とありますが、私にはあまり分かりませんでした。これって具体的にどういう環境のことでしょうか?
  3. k8sは本質的にPaaSなどのクラウド環境を作る基盤という特性が強いので自力で運用しようとするとかなりのパワーを使います。そのためKNative/Cloud RunやHerokuのようなPaaS/CaaSレベルに仕立てたものかFargateやGKE Autopilotのようにフルマネージドなk8sとありますが、Cloud RunとHerokuはKubernetesベースなんでしょうか?自分は知らなかったので、もし参考文献があったら知りたいです。それからKnativeに関してはSelf hosted clusterにデプロイするのであればクラスター運用は避けられないのでここでの言及は不適切に思いました。
  4. cri-oはその登場経緯からしてk8sで動かすことを目的として作られました。そのため軽量でk8sで動かすことに特化しているのでやはりこちらも本番環境で人気があります。CRI-Oの本番利用例をOpenShift以外の文脈で聞いた覚えがないのですが、どこかで事例発表があったのであれば知りたいです。私の知る限り少なくともGKE, EKS, AKSではContainerd/Dockerがサポートされている認識です。
  5. FirecrackerはランタイムではなくMicroVM技術です。コンテナを動かすための方式、という表現もミスリーディングだなと思いました。ref. Firecracker はコンテナランタイムではありません

全体的に主観で書かれているのか事実に基づいているのかがわからない箇所が多く、参考文献等があると嬉しいなぁと思いました(勘違いだったらすみませんが、私が過去に作成したスライドや文章によく似た箇所がいくつかあるなと思ったので、念のため)

kodukikoduki

コメントありがとうございます。いつも記事拝見させて頂いています。

  1. WindowsコンテナはOCI互換ではないかのような記述が見受けられますが、間違っていると思います。こちらのドキュメントのrunhcsの箇所を御覧ください。

厳密に言えばWindows ContainerというOCIに準拠したWindowsのコンテナもありますが、これは逆にWindowsでしか動かないのでそこまで利用はされていません。(OCI準拠かはさておきWindowsの内部では割とコンテナは使われてます。WSL2とかDefender Application Guardとか)

たぶん、こちらの記述ですよね? WindowsコンテナがOCI互換ではないと書いたつもりはなく、多くの人は(VMのイメージで)Linuxが動くことを期待するだろうから「OCI準拠のWindowsコンテナ」はあまり使われていない、という意図でした。実際、Docker/k8sで「Windowsコンテナ」を積極的に使ってる事例はあまり知らないので。個人的にはちょっと興味もありますが。
その上で括弧の中でOCI準拠かさておき。。と書いてるのはWSL2やDefender Application GuardはWindowsのコンテナ技術を利用していますがそのAPIがOCIに準拠してるかは確認できなかったからです。その必要が無いので違う気がしていますが未確認なので少しあいまいな表現をしていました。いずれにしても「Windowsコンテナ」がOCIに準拠してないまがい物だ、的な意図は無いです。その点は私の表現力の問題ですね。

以上が執筆時点での認識ですが、共有頂いたドキュメント読むとhyperv isolationでLinuxを動かしたときもOCI準拠という扱いになるのですね。この構成があることは認識してましたがコンテナ単独ではないのでそれそのものはOCI準拠ではない(正確にはVMの上のLinuxでOCI準拠のコンテナを動かしている)と認識していました。OCIって別にコンテナに限定しないのですね。これは私の不勉強です。ご指摘ありがとうございます。ちょっと記事をよく読んで本文の表現考えます。

2.もう一つ重要な点としてDockerは具体的な実装としてのDockerとは別にOCI系コンテナの総称としても使われます。例えば本番環境でDockerを使う事はそんなに多くなく実は別のコンテナを使ってるのですが便宜上「Dockerを使ってる」と言ったりします。とありますが、私にはあまり分かりませんでした。これって具体的にどういう環境のことでしょうか?

自分の認識ではGKEでは少なくとも1.19以降はcontainerdですしOpenShiftはcrioですし、それ以外でもcontainerdはk8sでのランタイムとして広く使われている認識です。そうした 「k8sで利用しているランタイムがDockerではない環境」 でも「本番でDockerを使っている」と言う事はしばしばあると思います。これは正しい表現では全くありませんが発言者が認識してなかったり、便宜上よりOCIやcontainerdより浸透している言葉である 「Docker」 という単語を選ぶことはしばしばあります。良し悪しは別として。なので 「OCI系コンテナの総称としても使われます」 と記載しました。

ただ、特に統計とか取ったわけでもなく単純に身近な事例からコメントしたので、現時点ではほとんどのk8s環境はdockerをランタイムとして使っているなら書いてることと違うのでそこは訂正したいと思います。

  1. k8sは本質的にPaaSなどのクラウド環境を作る基盤という特性が強いので自力で運用しようとするとかなりのパワーを使います。そのためKNative/Cloud RunやHerokuのようなPaaS/CaaSレベルに仕立てたものかFargateやGKE Autopilotのようにフルマネージドなk8sとありますが、Cloud RunとHerokuはKubernetesベースなんでしょうか?自分は知らなかったので、もし参考文献があったら知りたいです。それからKnativeに関してはSelf hosted clusterにデプロイするのであればクラスター運用は避けられないのでここでの言及は不適切に思いました。

Cloud RunはKNativeベースなので普通に考えればバックエンドはk8sかと思います。
https://cloud.google.com/blog/products/serverless/knative-based-cloud-run-services-are-ga
Herokuは残念ながら知りませんが恐らくdynoを動かしてる基盤をベースにしてると想像できるので別な気がしますね。

ただ、ここで言いたかったのはk8sをセルフホスティングして運用する以外にも**「コンテナの運用」** をする方法がある、と言いたかっただけでk8sのマネージドサービスであるか否かは問題にしていません。コンテナの活用とk8sの運用を常にセットの組み合わせと考えて欲しくなかったからです。

KNativeがクラスタ運用不可避の観点はおっしゃる通りですね。書きながら「アプリのデプロイが簡単」というアプリの視点と「インフラの運用が簡単」というインフラの視点がちょっと混ざってましたね。筋がぶれるのでこれは消しときます。

  1. cri-oはその登場経緯からしてk8sで動かすことを目的として作られました。そのため軽量でk8sで動かすことに特化しているのでやはりこちらも本番環境で人気があります。 CRI-Oの本番利用例をOpenShift以外の文脈で聞いた覚えがないのですが、どこかで事例発表があったのであれば知りたいです。私の知る限り少なくともGKE, EKS, AKSではContainerd/Dockerがサポートされている認識です。

私もOpenShiftくらいしか言われてみると知らないですね。 OpenShiftという一応メジャーなプロダクトで利用されているからの表現でしたが、OpenShift自体がGKE, EKS, AKSに比べて利用例が少ないので「人気があります」と言う表現は誤解があるという事ですかね? 特段containerdより使われてるとか言う意図もありませんし修正しておきます。

  1. FirecrackerはランタイムではなくMicroVM技術です。コンテナを動かすための方式、という表現もミスリーディングだなと思いました。ref. Firecracker はコンテナランタイムではありません

これに関してはおっしゃる通りランタイムではなくMicroVMだと思ってますし書いてるつもりですね。
> micro-VMとも呼ばれる非常に小さなVMを起動しその上でコンテナを動かすのに必要最小限のLinuxを動かす方式
ミスリーディングを誘いたいわけではないので懸念されてる部分は訂正したいのですが、「コンテナを動かすのに必要最小限のLinux」が正確ではないとかでしょうか?

>全体的に主観で書かれているのか事実に基づいているのかがわからない箇所が多く、参考文献等があると嬉しいなぁと思いました(勘違いだったらすみませんが、私が過去に作成したスライドや文章によく似た箇所がいくつかあるなと思ったので、念のため)
参考文献は確かにあった方が良いですね。後ほど可能な範囲で足しておきます。今回の動画及び記事作成で意識的にinductorさんの記事やスライドを参照したところは多分なかったと思いますが、むしろ普段から読ませて頂いてるので結果として似たところはたくさんある気がします!

以上、修正は後ほどやりますが取り急ぎコメントだけ。

inductorinductor

Cloud RunはKNativeベースなので普通に考えればバックエンドはk8sかと思います。

憶測の域を出ないのでなんとも言えないなというふうには思いました。例えばgVisorはOSSではOCI compliantなランタイムですが、Googleの内部ではOCIではないランタイムとして動くような匂わせをする文献をいくつか見かけたことがあります(ちょっとすぐには思い出せませんが)。また、BorgもLinux containerではあったとしてもOCI互換かどうかまでは少なくとも公開資料には出ていないので、この点においてGoogle内部で使われる技術と外に出ている技術が一致するとも限らず、私は少なくとも断言できないものであると考えています。

kodukikoduki

一応下記を見るとCloud Run on AnthosはKNativeをGKE上で動かしてるようですね。
https://cloud.google.com/anthos/run

とはいえフルマネージド版をどうしてるかは確かに言及がないので、そちらはKNativeのI/FでBorgを動かしてる可能性は確かに否定はできないですね。Anthos向けにCloud RunなどK8s互換のI/Fは推し進めてるようには見えますが、Googleならマネージド側はユーザ向けI/Fだけ互換にして中身はBorgとOmega(今もOmegaが最新かは知らないですが)で動かすとか普通にやりそうな気もしますし。

Hiroshi KoyamaHiroshi Koyama

有用な記事をありがとうございます。拝見して、「Java EEとかに慣れてる人だったら「war=docker, k8s=weblogic/glassfishととりあえず思ってください」という事が多いかな。」に違和感を覚えました。

war=docker の部分が ファイルアーカイブ=ソフトウェアとなっているからだと思います。あと、k8s=weblogic/glassfish は前者の右辺と左辺に対しての対応が違っていないでしょうか。

Java だったら、jar は Docker イメージ、JavaVM が Docker というメタファが使えそうですが、war は難しいですね... たとえば、war(JavaEEだとear?)=Docker イメージ、war を動作させるために必要なもの=Docker、war アプリを管理するために必要なもの=k8s といった対応とかでしょうか。

war を動作させるために必要なものは「JavaVM+アプリケーションサーバの war 実行用機能」、war アプリを管理するために必要なものは「アプリケーションサーバの war 管理用機能」でしょうか。とすると、とりあえずということなら、「ear=Docker イメージ、glassfish=Docker、OpenShift=k8s」あたりでも良いのかもしれません。

kodukikoduki

war(あるいはear)=dockerの部分はDockerイメージで書いていたのでファイルアーカイブという意味では同じですね。ただ普通に文章が分かりづらいですね。力不足です...

war(JavaEEだとear?)=Docker イメージ、war を動作させるために必要なもの=Docker、war アプリを管理するために必要なもの=k8s といった対応とかでしょうか。

なるほどですね。はい、概ねおっしゃるイメージで、もう少しいうとwar/ear=Dockerイメージ、warを動作させるのに必要なもの(JVMやGrizzlyとかWeldとか)=Docker(正確にはcontainerdやrunc)、war アプリを管理するために必要なもの(Glassfish等の管理コンソールやJMXやデプロイ周りやクラスタリング等など)=k8s という感じですね。
おっしゃる通り、OpenShiftは管理のレイヤーなのですが今となってはk8sそのものだし、少しストーリ的には異なるかなー、と。

メタファーとして被せてみましたが、厳密には一致しないところはるかもですねー。