DUICUO

Docker だけではなく、他にも選択できるコンテナ化ツールは多数あります...

この記事はWeChat公式アカウント「AI Discovery」(ID: AI_Discovery)から転載したものです。

かつてのコンテナ時代(正確には4年前)には、Dockerがコンテナ競争の唯一のプレイヤーでした。しかし状況は変わりました。Dockerはもはや唯一の存在ではなく、業界に存在する数多くのコンテナエンジンの1つに過ぎません。

Dockerはコンテナイメージのビルド、実行、プル、プッシュ、検査などを可能にしますが、それぞれのタスクにおいて、Dockerよりも優れた代替手段が利用できる可能性があります。そのため、現状を検証する必要があります。そうでないと、Dockerをアンインストールし、完全に忘れ去ってしまうかもしれません。

[[352235]]

Docker を使わないのはなぜですか?

長い間 Docker を使用してきた人にとって、別のツールへの切り替えを検討するよう自分自身を説得するには、ある程度の努力が必要になるかもしれません。

Dockerは、あらゆる機能を実行しようとする巨大なモノリシックツールですが、必ずしも最適な方法で実行できるとは限りません。1つの機能だけを非常にうまく実行できる、特化型のツールを選ぶ方が賢明です。異なるツールセット間の切り替えに不安を感じたり、異なるコマンドラインインターフェース(CLI)、異なるAPI、あるいは一般的に異なる概念を習得しなければならないのではないかと心配しているのであれば、もう心配する必要はありません。

この記事で紹介したツールはどれも(Dockerも含め)Open Container Initiative(OCI)の仕様に準拠しているため、完全にシームレスに選択できます。OCIには、コンテナランタイム、コンテナディストリビューション、コンテナイメージの仕様が含まれており、コンテナの使用に必要なすべての機能が網羅されています。OCIでは、Dockerと同じAPIとCLIコマンドを使用しながら、ニーズに最適なツールセットを選択できます。

したがって、新しいツールを試してみたい場合は、Docker とその競合製品の長所、短所、機能を比較して、Docker を放棄して代わりに新しいツールを試すことを検討する必要があるかどうかを確認してください。

コンテナエンジン

Docker を他のツールと比較する場合は、コンポーネント別に分類する必要がありますが、まず最初にコンテナ エンジンについて説明します。

コンテナエンジンは、イメージやコンテナを操作するためのユーザーインターフェースを提供するツールです。そのため、SECOMPルールやSELinuxポリシーの混乱を心配する必要はありません。コンテナエンジンの役割には、リモートリポジトリからイメージをプルしてディスクに展開することも含まれます。一見するとコンテナを実行しているように見えますが、実際にはコンテナマニフェストとイメージレイヤーを含むディレクトリを作成し、それらをruncやcrunなどのコンテナランタイムに渡すことです。

利用可能なコンテナエンジンは数多くありますが、Dockerの主な競合相手はRed Hatが開発したPodmanです。Dockerとは異なり、Podmanはデーモンプロセスの実行やルート権限を必要としません。これはDockerが長年懸念してきた問題です。

その名前が示すように、Podmanはコンテナだけでなくポッドも実行できます。ポッドはKubernetesにおける計算の最小単位です。ポッドは、補助的なタスクを実行する1つ以上のコンテナで構成されます。これにより、Podmanユーザーは後からワークロードをKubernetesに移行しやすくなります。1つのポッドで2つのコンテナを実行する方法は次のとおりです。

  1. ~ $ podman podcreate --name mypod
  2. ~ $ podman ポッドリスト
  3. POD ID 名前 ステータス 作成済み コンテナ数 インフラ ID
  4. 211eaecd307b mypod 2分前 1 a901868616a5 実行中
  5. ~ $ podman run -d--pod mypod nginx # 最初のコンテナ
  6. ~ $ podman run -d--pod mypod nginx # 2番目のコンテナ
  7. ~ $ podman ps -a--pod
  8. コンテナID イメージ コマンド 作成 ステータス ポート名 ポッド ポッド名
  9. 3b27d9eaa35c docker.io/library/nginx:latest nginx -g daemon o... 2秒前 1秒前 brave_ritchie 211eaecd307b mypod
  10. d638ac011412 docker.io/library/nginx:latest nginx -g daemon o... 5 分前 5 分前 cool_albattani 211eaecd307b mypod
  11. a901868616a5 k8s.gcr.io/pause:3.2

最後に、Podman は Docker とまったく同じ CLI コマンドを提供します。単に `alias Docker=Podman` を実行し、変更が加えられていないものとして扱います。

DockerとPodman以外にもコンテナエンジンは存在しますが、どれも将来性に欠けるか、ローカルでの開発や利用には適していないと考えています。具体的な理由は以下の通りです。

  • LXD — LXDはLXC(Linuxコンテナ)用のコンテナマネージャー(デーモン)です。このツールは、VMに近いコンテナ環境を提供するシステムコンテナの実行機能を提供します。LXDは非常に狭い範囲で利用されており、ユーザー数も少ないため、非常に特殊なユースケースがない限り、DockerまたはPodmanを使用する方がよいでしょう。
  • CRI-O — CRI-O について検索すると、コンテナエンジンと説明されているのを目にするかもしれません。しかし、実際にはコンテナランタイムです。さらに、「通常の」用途には適していません。つまり、CRI-O は Kubernetes ランタイム (CRI) 専用に構築されており、エンドユーザー向けではないということです。
  • rkt — rkt(「Rocket」)は、CoreOSによって開発されたコンテナエンジンです。このプロジェクトは終了し開発も停止しているため、ここでは完全性を保つために言及しています。そのため、使用は避けるのが最善です。

ビルドイメージ

コンテナ エンジンでは Docker の選択肢は 1 つしかありませんが、イメージの構築に関してはより多くの選択肢があります。

まずはBuildahから始めましょう。BuildahはRed Hatが開発した、Podmanと連携するツールです。Podmanをインストールしている場合は、Podmanのbuildサブコマンドに気づいたかもしれません。これは実際にはBuildahを偽装したもので、そのバイナリはPodmanに含まれています。

Buildah の機能は Podman と同じアプローチ、つまりデーモンフリーかつルート権限なしで実行できるという点です。OCI 準拠のイメージを生成できるため、Docker でビルドされたイメージと同じように動作します。さらに、Buildah はイメージレイヤーをより細かく制御できるため、単一のレイヤーに多くの変更をコミットできます。Docker と比較すると、Buildah はユーザー固有のイメージをビルドするため、ユーザーがビルドしたイメージのみを一覧表示できます。

Buildah は既に podman CLI に含まれているのに、なぜ別途 Buildah CLI を使用するのでしょうか?その理由は、buildah CLI が podman build に含まれるコマンドのスーパーセットだからです。buildah CLI を必ずしも使用する必要はないかもしれませんが、使用することで、いくつかの便利な追加機能を発見できるかもしれません。

以下に簡単なプロセスデモンストレーションを示します。

  1. ~ $ buildah bud-f Dockerfile 。
  2. ~ $ buildah from alpine:latest # 開始コンテナを作成 - "FROM alpine:latest" と同等
  3. 画像ソース署名の取得
  4. blobdf20fa9351a1 のコピーが完了しました
  5. configa24bb40132のコピーが完了しました
  6. マニフェストをイメージの保存先に書き込む
  7. 署名の保存
  8. alpine-working-container # 一時コンテナの名前
  9. ~ $ buildah runalpine-working-container --apk add --update --no-cache python3 # 「RUN apk add--update --no-cache python3」と同等
  10. http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz を取得します
  11. http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz を取得します
  12. ...
  13. ~ $ buildahcommit alpine-working-container my-final-image # 最終イメージを作成する
  14. 画像ソース署名の取得
  15. blob50644c29ef5a のコピーはスキップされました: 既に存在します
  16. blob362b9ae56246のコピーが完了しました
  17. config1ff90ec2e2のコピーが完了しました
  18. マニフェストをイメージの保存先に書き込む
  19. 署名の保存
  20. 1ff90ec2e26e7c0a6b45b2c62901956d0eda138fa6093d8cbb29a88f6b95124c
  21. ~# ビルド画像
  22. リポジトリタグイメージID作成サイズ
  23. localhost/my-final-imagelatest 1ff90ec2e26e 22秒前 51.4 MB

上記のスクリプトからわかるように、イメージはBuildah budのみでビルドできます。budはDockerfileを使用したビルドを表します。ただし、Buildahのfrom、run、copyコマンドを使用することで、より多くのスクリプトメソッドを使用できます。これらのコマンドはDockerfile内のコマンドと同等です。

次はGoogleのKanikoです。KanikoもBuildahと同様にDockerfileを使ってコンテナイメージを構築しますが、デーモンは必要ありません。Buildahとの主な違いは、KanikoがKubernetes内でのイメージ構築に重点を置いている点です。

Kanik は実行するイメージとして gcr.io/kaniko-project/executor を使用します。これは Kubernetes にとっては理にかなっています。ただし、新しいイメージをビルドするには Docker を使用して Kaniko イメージを実行する必要があるため、ローカル ビルドには不便で不十分です。

とはいえ、Kubernetes クラスター (CI/CD パイプラインなど) でデーモンフリーかつ (おそらく) より安全なイメージを構築するためのツールを探している場合は、Kaniko が適切な選択肢になるかもしれません。

しかし、私の個人的な経験から言うと、Kubernetes/OpenShiftクラスターでKanikoとBuildahの両方を使用してイメージをビルドする場合、どちらも問題なく機能すると考えています。ただし、Kanikoを使用すると、レジストリにイメージをプッシュする際に、ランダムなビルドクラッシュや失敗が発生することがあります。

Dockerの3つ目の競合は、次世代Dockerビルドとも呼ばれるbuildkitです。これはDockerと同様にMobyプロジェクトの一部であり、DOCKER_BUILDKIT=1 dockerbuildとすることでDockerの実験的な機能として有効化できます。

並列ビルドステップ、未使用ステージのスキップ、より優れた増分ビルド、ルートレスビルドなど、多くの改善と機能が導入されています。ただし、デーモン(buildkitd)の実行は依然として必要です。したがって、Dockerを廃止したくないが、いくつかの新機能と適切な改善を望む場合は、buildkitの使用が理想的な選択肢となるかもしれません。

さらに、言及する価値のある他の点がいくつかありますが、それらは私の好みの選択ではありません。

  • Source-To-Image (S2I) は、Dockerfile を必要とせずにソースコードから直接イメージをビルドできるツールキットです。このツールは、シンプルで予測可能なシナリオやワークフローに適していますが、カスタマイズがほとんど必要ない、またはプロジェクトのレイアウトが理想的でない場合には、すぐに煩雑になります。Docker や OpenShift クラスターでのイメージビルドに自信がない場合は、S2I の使用を検討してください。S2I を使ったビルドは OpenShift クラスターに組み込み機能として含まれています。
  • Jibは、Javaイメージのビルド用に特別に設計されたGoogleのツールです。MavenおよびGradleプラグインが含まれているため、Dockerfileに影響を与えることなく簡単にイメージをビルドできます。
  • 最後に、Bazel があります。これはコンテナイメージの作成だけでなく、完全なビルドシステムも備えた Google ツールです。イメージの作成だけをしたいのであれば、Bazel を深く掘り下げるのは少し難しすぎるかもしれませんが、間違いなく学習する価値のある体験です。

[[352236]]

画像出典: unsplash

コンテナランタイム

最後の課題は、コンテナの実行を担うコンテナランタイムです。コンテナランタイムはコンテナのライフサイクル/スタック全体の一部であり、速度やセキュリティなどに関して非常に厳格な要件がない限り、簡単に中断されることはありません。以下のツールが利用可能です。

runcは、OCIコンテナランタイム仕様に基づいて構築された最も人気のあるコンテナランタイムです。Docker(コンテナ経由)、Podman、CRI-Oがruncを使用しているため、ほぼすべてのコンテナはLXCを使用するLXDを使用する傾向があります。ほぼすべてがデフォルトで設定されており、この記事を読んだ後にDockerを放棄したとしても、runcを使い続ける可能性が高いでしょう。

runc に似た機能を持つものの、紛らわしい代替手段として crun があります。これは Red Hat が開発したツールで、すべて C 言語で書かれています(runc は Go 言語で書かれています)。そのため、runc よりも高速で効率的です。また、OCI 互換のランタイムであるため、ご自身で試してみたい場合は簡単に切り替えることができます。現時点ではあまり普及していませんが、RHEL 8.3 では OCI ランタイムの代替としてテクニカルプレビューに登場し、最終的には Podman や CRI-O によって Red Hat のデフォルト製品として採用される可能性があります。

CRI-Oについてですが、先ほども申し上げたように、CRI-Oはコンテナエンジンではなく、コンテナランタイムです。これは、イメージのプッシュといったコンテナエンジンに期待される機能を備えていないためです。

CRI-O はランタイムとして、コンテナの実行に内部的に runc を使用します。このランタイムは Kubernetes ノード上のランタイムとして構築されており、「Kubernetes に必要なすべてのランタイムのみ」と説明されているため、マシン上で使用することはお勧めしません。

したがって、Kubernetes クラスター (または OpenShift クラスター - CRI-O がすでにデフォルト) をセットアップしていない限り、このクラスターには触れないでください。

最後に、Cloud Native Computing Foundation(CNCF)が卒業間近のプロジェクトであるコンテナ化についてお話ししましょう。コンテナ化は、様々なコンテナランタイムやオペレーティングシステムのAPIファサードとして機能するデーモンです。バックグラウンドでは、Dockerエンジンのデフォルトランタイムであるruncに依存しています。

Google Kubernetes Engine (GKE) と IBM Kubernetes Service (IKS) もこれを使用しています。これは Kubernetes コンテナランタイムインターフェース(CRI-O と同じ)の実装であり、Kubernetes クラスタランタイムに最適です。

ミラーの検査と配布

コンテナスタックの最後の部分は、イメージの検査と配布です。これは実質的に「docker inspect」の代わりとなり、(オプションで)リモートレジストリ間でイメージのコピー/配布を行う機能も追加します。

これらのタスクを実行できる唯一のツールはSkopeoです。Red Hatが開発し、Buildah、Podman、CRI-Oにバンドルされています。Dockerで知られている基本的なskopeo inspectに加え、Skopeoはskopeo copyを使用してイメージを複製できるため、ローカルレジストリにプルすることなく、リモートレジストリ間でイメージを作成できます。この機能は、ローカルレジストリを使用している場合のプル/プッシュにも使用できます。

さらに、画像の検査、閲覧、分析のためのよりユーザーフレンドリーなツールであるDiveについても触れておきたいと思います。Diveはより読みやすい出力を提供し、画像をより深く(あるいは、より深く掘り下げて)分析・測定し、効率性を測定できます。CIパイプラインにも適しており、画像が「十分に効率的」かどうかを測定できます。

[[352237]]

画像出典: unsplash

この記事は、Dockerを完全に放棄するよう説得するものではなく、コンテナとそのイメージを構築、実行、管理、配布するためのあらゆるツールとオプションを包括的に概説することを目的としています。Dockerを含む各ツールにはそれぞれ長所と短所があり、どのツールがワークフローとユースケースに最適かを見極めることが重要です。