ラズパイでゼロから作るDocker

-- Views

October 10, 25

スライド概要

ラズパイでゼロから作るDocker ―― コンテナの仕組みを根本から理解し,現場で役立つスキルを習得したい方に,CQ出版エレクトロニクス・セミナで使用されたテキストの一部を公開します.
 今注目のコンテナ技術を基礎から実践まで深く掘り下げます.まずは「コンテナとは何か?」といった概要から,デファクトスタンダードである「Docker」の機能,イメージ管理,実行,ストレージ,ネットワークを実際に操作し体験しながら解説します.次に,コンテナを支える「名前空間」「cgroup」「OverlayFS」「仮想ネットワーク」といった基盤技術について深く理解します.そして,習得した知識を活かし,自作のコンテナ管理ツールを実際に構築します! 
 プログラム実行環境の分離,ストレージ・ネットワーク管理,ホストとのファイル共有,外部へのネットワークアクセス,リソース制限ツールの作成まで,手を動かしながら実践的に学びます.OS標準のコマンドを利用して作成するためC言語やGo言語などでの難しいシステムプログライミングなしに管理ツールを作成します.コンテナの仕組みを根本から理解し,現場で役立つスキルを習得したい方におすすめです.

●本セミナのURL
https://seminar.cqpub.co.jp/ccm/ES25-0078

profile-image

1950年代からエレクトロニクス専門誌を発行してきたCQ出版の公式アカウントです。ハードウェア設計、ソフトウェア、無線、AI、IoTまで、電子技術の最先端を深掘りする情報をお届けします。 弊社の「エレクトロニクス・セミナ」で実際に使用されたスライド資料の一部や、技術解説記事の補足資料などを公開しています。専門的な知識を深めたい方は、ぜひ資料をご覧ください。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

ラズパイで ゼロから作るDocker 1.コンテナ概要 2.Dockerコンテナ解析 3.コンテナを実現する技術 4.コンテナ管理ツールを作る 2025/10/15 1

2.

1.コンテナ概要 2025/10/15 2

3.

ここで知ること ⚫コンテナとは何か? ⚫コンテナがなぜ利用されているのか? ⚫コンテナ管理ツール(Docke)とは? を中心にコンテナを概観します 2025/10/15 3

4.

コンテナとは? コンテナとは、アプリケーションの動作環境を分離する仮想化方式の一 種です。 なんで仮想化するのか? 1. コンピュータ利用を効率化し管理を省力化する 2. セキュリティーを確保する 3. ソフトウェアのライフサイクルとハードウェアのライフサイクルの ギャップを埋める(環境の安定化) 2025/10/15 4

5.

効率利用 一般的なプログラムはIO処理を 伴い、その場合CPUは全く使われ ないなんてことはざらです 昨今のコンピュータは非常に高性能で、マルチコア化が進み並列処理が得意となっています。 そのため、ハードウェア性能を1人や1つのプログラムでは使いきれない状態になってきています。 そこで1台のコンピュータを複数の人やアプリケーションでシェアするのはよくあることです。 その場合、アカウントを分けるのはあたりまえですが、 ⚫リソースの競合も避けたい ⚫可能ならバージョンの異なるライブラリなどを使いたい という要望も出てきます。 このような要望を満たし、お互いが干渉しない隔離環境を実現するのが仮想環境です。 それぞれの環境は仮想化ソフトウェアが隔離してくれるので、あたかも一人で占有するつもりで使用し ても問題ありません。 これはアプリケーションや利用者が仮想環境であることを意識する必要がないので、アプリ使用環境と しての導入も容易です。 2025/10/15 5

6.

管理の省力化 コンピュータに故障はつきものです。 ハードウェア故障などで環境を再構築する場合でも仮想化された環境 であれば、仮想環境をそのまま別のハードウェアにコピーすれば元の 環境が再構築できます。 仮想化されていない場合には、OSのインストールからアプリケーション のインストールおよび設定など1から設定し直さなければなりません。 このような便利さはクラウド環境を実現する上でも重要な特徴となって います。 2025/10/15 6

7.

セキュリティーを確保する 仮想環境でそれぞれの環境が分離されていると、お互いの機密情報を 盗み見られるリスクが減ります。 また、アプリケーションのバグなどによりシステムが乗っ取られたりする こともありますが、その場合でも1つの環境だけが影響を受けるのでリ スクを最小化できます。 そのため、一般的には、外部(インターネットなど)と接触する環境と重 要情報などを管理する環境を分離しそれぞれの環境を疎結合すること で、情報漏洩しにくい構成とすることが多いです。 2025/10/15 7

8.

ライフサイクルのギャップを埋める 個人用のアプリケーションとは異なり業務システムやアプリケーションの 更新サイクルは長く、10年以上使うこともまれではありません。 そういった場合、ハードウェアやOSのライフサイクルの方がはやく終了 してしまうことがあります。 特に、ハードウェアは更新が早く故障しても新たに入手出来ないことは あります。 その際には新しいハードウェアを使うしかありませんが、そのハードウェ アでこれまでのOSが動作するとは限りません。 OSまで置き換えるとアプリケーションにも手を加える必要があります。 そういったケースでは仮想環境を導入しハードウェアとOSの間を疎結合 にするといった対策が可能です。 2025/10/15 8

9.

環境の安定化 新しいアプリケーションの導入や開発時のテストを行う場合に、既存の ものへの影響がないことを確認するのは大変です。 共通のシステムファイルなどの更新を行わなければならない場合はより 慎重にならざるを得ません。 そこで、アプリケーションを動作させう環境を仮想化により分離できれば それぞれ影響する異なくアプリケーションの更新が行えます。 逆に、自身が動作する環境は周りに影響されず常に同じ状態を維持す ることが可能です。 環境が変わらない(安定している)ということはアプリケーションにとって 重要なことです。 2025/10/15 9

10.

さまざまな仮想化方式 汎用性は高いがオーバーヘッドが大きい(特にIO) 仮想化レベル 方式 例 ハードウェア PCなどのハードウェアすべてをエミュレーションする。 仮想マシンと呼ばれる方式。 PCとして扱えOSをインストールしてからアプリケーショ ンを使用する。 PC用OSであればたいてい利用可能。 ホストとは異なるCPUアーキテクチャ、OSが利用可能 VMWare QEMU OS OS環境を提供する。 仮想化された環境上でそれぞれのOS向けのアプリ ケーションが利用可能。 一般的には、ホストOSと同じ環境同じCPUアーキテク チャ向けのアプリケーションが利用可能。 Linuxコンテナ BSD Jail WSL2 Dos窓 アプリケーション実行環境 特定のハードウェアやOSではなく、独自のアプリケー ション実行環境を提供。 アプリケーション実行環境があれば、基本的には同じ ものがどこでも動作可能(Write once, run anywhere) JVM スクリプト言語 (Python,Ruby,etc…) Linuxコンテナが昨今の主流 お手軽だがオーバーヘッドが大きい 性能改善のためにネイティブモジュールがあるが汎 用性を阻害する要因でもある それぞれ一長一短あり、適材適所で利用している 2025/10/15 10

11.

仮想化のデメリット 仮想環境自体に処理が必要なためその分がオーバーヘッドとなり動作 に影響を与えます。 ・性能劣化 ・ハードウェア利用の制限 =>コンテナはこれが小さい 2025/10/15 11

12.

コンテナとVMの比較 仮想マシン上の OS向け アプリケーション RaspberryPi OS 向け アプリケーション Raspberry Pi OS 向け アプリケーション OS、ハードウェア に近いほど高速 OS 仮想マシン コンテナ環境 Raspberry Pi OS Raspberry Pi 4B 2025/10/15 12

13.

コンテナの仮想化方式 コンテナではカーネルは共有し、カーネルの上に隔離されたアプリケー ション実行環境を用意します。 カーネルは変更できませんが、OSとは異なるライブラリやアプリケー ションをコンテナ環境に閉じ込めて実行することが可能です。 コンテナ型は、仮想マシンを用意する方式ではなく、あくまで隔離され たOS/アプリケーション実行環境を用意するので、仮想化によるオー バーヘッド少ない。 2025/10/15 13

14.

コンテナの構造 アプリケーションの利用する ユーザランタイム(ライブラリ やコマンドなど)はコンテナ ごとに独自に異なる環境を 用意できる Raspberry Pi OS 向け アプリケーション Debian向け アプリケーション Ubuntu向け アプリケーション Raspberry Pi OS コンテナ環境 Debian コンテナ環境 Ubuntu コンテナ環境 Raspberry Pi OS カーネルは同じものを共有 システムコールの互換がないアプリ ケーションは動かない 2025/10/15 14

15.

コンテナの実現 コンテナは、名前空間という仕組みを使って実現しています。 名前空間はシステムのリーソースを分離し各環境間を隔離するもので す。 その他、 ⚫cgroup(Control Group)というリソース制限機能 ⚫OverlayFSによるデータ領域管理機能 ⚫仮想Ethernetデバイス、仮想ブリッジといった機能を使った仮想ネット ワーク機能 といった、技術もコンテナを実用的に利用するためには必要なものとな ります。 2025/10/15 15

16.

コンテナを実現する技術 要素技術 名前空間(namespace) 機能 主な用途 名前空間は、グローバルシステムリソース を抽象化 コンテナ毎に利用するリソースを分離する して、干渉しない隔離された環境にを実現するため の仕組み Cgroup (コントロールグループ) 実行プロセスをグルーピングして、そのグループに プロセスに割り当てるCPUやメモリといった物理リ 対してリソース利用制限などの制御を行う仕組み ソースの利用調停 OverlayFS (Overlay Filesystem) 複数のディレクトリを重ねて1つのディレクトリに コンテナイメージが保存されたディレクトリの上に 見えるマウント機能 コンテナ用のディレクトリを重ねて、コンテナデー タとして使える様にする 仮想ブリッジ ホスト上に仮想的なL2スイッチを用意する 仮想Ethernetデバイス 互いに接続された仮想的なネットワークIFのペアを コンテナとホスト上の仮想ブリッジを接続し、コン 用意する テナをネットワークに接続する nftables パケットフィルタリング ホスト外からコンテナにネットワークアクセスでき るようにポートフォワード行う BPF (Berkley Packet Filter) カーネルイベント発生時に処理を実行する仕組み cgroupと組み合わせ、cgroupに属するプロセスがデ バイスへアクセスしようとした場合に、イベント起 動されたBPDプログラムでデバイスへのアクセス許 可を制御する capability 操作やファイルアクセスなどの細かな権限制御を提 コンテナで動作するプロセスへの特権操作などの権 供する仕組み 限付与 Seccomp (Secure Computing Mode) アプリケーションの利用できるシステムコールを制 コンテナで利用できるシステムコールを制限しセ 御する仕組み キュリティーを高める 2025/10/15 ホスト上に分離されたネットワークを作り、コンテ ナからみて別々の物理ネットワークを用意する 16

17.

コンテナのメリット/デメリット メリット ⚫オーバーヘッドが小さい、必要リソースが少ない ⚫簡単・高速に環境を準備・起動できる ⚫比較的どこでも起動可能 デメリット ⚫Linuxに依存 ⚫セキュリティー分離が弱い そういったデメリットについても日々改善されていますし、コンテナは実運用システ ムでも普通に使われているものなのでそれが問題になることはないと思います。 2025/10/15 17

18.

コンテナの使いどころ 1. 処理量が変動するようなサービスの運用基盤 処理負荷に応じて起動するサービスの数を動的に変更するのが簡単 2. サービス稼働率を高めたいシステム アプリケーションのデプロイが簡単なの素早い復旧が可能 3. 開発環境 開発環境の準備や共通化などが簡単 運用でもコンテナを利用すればテスト環境と開発環境を同じにできる 2025/10/15 18

19.

Docker コンテナを実現するための仕組みそのものもはLinuxカーネルに組み込まれており、 それ使ってコンテナ環境の作成および管理を行うのがDockerです。 コンテナ環境を作成するためには、動作させるための名前空間の準備、コンテナ用 のネットワーク環境やストレージの準備、CPUやメモリリソースの割り当てなど多くの 仕事があります。 また、コンテナに含まれるライブラリやアプリケーションなどをイメージ化したものの 管理も必要で、それらをトータルで面倒みてくれます。 それがコンテナ管理の仕組みとしてDockerが広まりデファクトスタンダードとなった理 由です。 コンテナを実現する要素技術自体は昔からあるものですが、それを使いやすくしてく れたおかげて、コンテナが身近なものとなったのです。 また、Docker向けのコンテナイメージを提供するdockerhub(https://hub.docker.com) も用意されており、そこで公開されているイメージを利用することも可能で、自分でイ メージを用意しなくても簡単にDockerコンテナ環境を準備し利用できます。 2025/10/15 19

20.

Dockerの構成 イメージを管理するDocker HUBとの連携が普及のカギ 2025/10/15 20

21.

Dockerの主要機能 対象リソース 機能 主なコマンド コンテナ コンテナの構成および実行管理 docker run docker exec docker create docker start イメージ コンテナイメージの管理 docker pull docker commit docker save docker load ストレージ コンテナの利用するストレージ docker run -v 構成の管理 docker volumes create docker volumes mount ネットワーク コンテナの利用するネットワー docker run -p ク構成の管理 docker network create docker network connect docker network disconnect docker network rm コンテナを作成し起動する コンテナ内でコマンドを実行する コンテナを作成する コンテナを開始する Docker HUB からコンテナイメージを取得する コンテナをイメージ化する コンテナイメージをファイルとして取り出す ファイルからコンテナイメージを登録する ホストとコンテナでディレクトリを共有する。 もしくは、ボリュームをコンテナに接続する。 データを永続化するためのボリュームを作成する ボリュームを削除する ポートフォワードの設定を行う コンテナ向けのネットワーク作成する コンテナをネットワークに接続する コンテナをんっとワークから切断する ネットワーク削除する 同じ処理でも複数の呼び出し方があります。 また、ここに挙げた物以外にも多数の機能がありますので、詳細はdockerコマンドのマニュアルやインターネットの情報を参照してください。 2025/10/15 21

22.

標準化 コンテナが普及すると、個別に実装されていたコンテナの標準化が必要とされ、OCIが策 定された。 OCI(Open Container Initiative)とは、コンテナ環境の定義と操作を標準化した仕様で以下 の2つの仕様からなる(https://www.opencontainers.org/ )。 1. コンテナイメージの形式 OCI Image Format Specification (https://github.com/opencontainers/image-spec) 2. コンテナ環境を操作するためのIF Open Container Initiative Runtime Specification (https://github.com/opencontainers/runtime-spec) このOCIに準拠したランタイムモジュールは、作成者を問わずコンテナの作成、起動など の操作に互換性がもたされ、(基本的には)ランタイムを切り替えて運用することが可能 となる。 2025/10/15 22

23.

いろいろなコンテナランタイム コンテナランタイムの標準化により様々なランタイムを切り替えて利用 できるようになった。 コンテナランタイム runC gVisor kata-container nabla-container 概要 機能制限 コンテナ間の分離方式 URL https://github.com/opencontai コンテナ環境のデファクト 基準 namespace ners/runc コンテナの話をする場合の基準 cgroup https://gvisor.dev/ カーネルをエミュレーションするレイ gVisorエミュエーションしてい namespace ヤーを通して環境を分離 ないカーネル機能が利用でき サンドボックスレイヤとIOプロ ない セス https://katacontainers.io/ VM環境の上でアプリを動作させ アプリケーションからみたら制 namespace る構造 限というものはなさそう。 仮想マシンでの分離 ただし、コンテナからホストデバ イスへのアクセスはできないの で、デバイスアクセスを行いた いケースには対応できない 通常実行環境(カーネル、ライブ 専用アプリケーションしか動作 専用のカーネル実行環境を https://nablaラリとも)ではない機能制限された しないので、それが最大の制 用意し、専用のアプリケー containers.github.io/ 特別な環境(Solo5)の上でアプ 限 ションをどうさせることで、分離 リケーションを動作させる構造。 を実現 ※nabla-containerはここ数年更新がないので止まっているプロジェクトかも 2025/10/15 23

24.

オーケストレーションツール コンテナは、アプリケーションをパッケージ化してどこにでも高速に、配 備・起動できる、隔離されたアプリケーション実行環境です。 この特性により、物理環境はもとより他の仮想化方式に比べて多数の 環境が使われ、さらにそれらの起動停止も頻繁に行われる傾向があり ます。 要するに環境が動的であるということです。 この様に、構成が動的で大量の管理対象が ある場合に人手で運用 を行うのは無理があります。 そこで、オーケストレーションツールが必要となります。 2025/10/15 24

25.

オーケストレーションツールの主な機能 機能 内容 コンテナ管理機能 ・コンテナの作成や起動・停止 ・コンテナの動作の監視と自動復旧 ・物理サーバーの負荷に応じでコンテナの配置を最適化 ネットワーク管理 ・コンテナ間の通信経路の管理 ・物理サーバーをまたがったコンテナ間の通信経路の管理 ・コンテナと外部システムとの通信経路の管理 ・コンテナ上のアプリケーションの外部管理 ストレージ管理 ・コンテナの使用するストレージ領域の管理 ・データが永続化されるストレージ領域の管理 ・コンテナへのストレージの提供管理 ・コンテナ間でのストレージの共有管理 特に、ネットワークの管理とコンテナの自動復旧といったところが運用 面では重要であると考えます。 2025/10/15 25

26.

Kubernetes(クーバネティス) コンテナの世界でオーケストレーションツールのデファクトスタンダードとなって いるのが、Kubernetes(https://kubernetes.io/) です。 Kubernetesは商用クラウドサービス含め広く使われているものとなります。 今ではコンテナだけでなく、仮想マシンや物理マシン(ベアメタル)の管理も行 えるようになり、コンピューティングリースの管理ツールとなってきました。 2025/10/15 26

27.

Kubernetesを試す クラウドサービスを使って試して見ても良いでしょう。 手元でてっとりばやくKubernetesを体験して見るのは、minikubeを試し てみるのが簡単です。 https://minikube.sigs.k8s.io/docs/start/ 2025/10/15 27

28.

2.Dockerコンテナ解析 2025/10/15 28

29.

ここで知ること コンテナ管理のデファクトスタンダードであるDockerの機能を見てコンテナ 管理ツールがどのようなことをしているのかを見ていきます。 ⚫コンテナ管理ツール ⚫Dockerの機能 ⚫Dockerの裏で起きていること ⚫コンテナ環境は隔離されている について実習します。 ※Linux、ラズベリーパイの操作に慣れてもらう ※コンテナとはどんな感じのものか体験してもらう 2025/10/15 29

30.

コンテナ管理ツール Dockerはコンテナ管理を行うツールで、コンテナを起動する元となる情報の管理や、 コンテナ環境の構築とコンテナ内でのプログラムの実行を制御するものです。 コンテナを実現するための仕組みそのものもはLinuxカーネルに組み込まれており、 それらの機能を使ってコンテナ環境の作成および管理を行うのがDockerです。 元々はLinuxから始まりましたが、今ではWindowsやmacOSなどどこでもDockerコン テナが利用できる様になっています。 また、ホストOSとは異なるCPUアーキテクチャのアプリケーションの実行も可能と なっている。 ➢Linux以外の環境では、LinuxをどうさせるためにWSL2(Windows)やHypervisorフレームワーク (macOS)などを利用している ➢ホストCPUと異なるアーキテクチャのアプリケーションを動作させるためには、QEMUの助けを借りて いる QEMU - オープンソースの仮想マシンソフトウェアでシステム全体のエミュレーションを行える (https://www.qemu.org/) 2025/10/15 30

31.

Dockerの構成 イメージを管理するDocker HUBとの連携が普及のカギ 2025/10/15 31

32.

Dockerの主要機能 対象リソース 機能 主なコマンド コンテナ コンテナの構成および実行管理 docker run docker exec docker create docker start イメージ コンテナイメージの管理 docker pull docker commit docker save docker load ストレージ コンテナの利用するストレージ docker run -v 構成の管理 docker volumes create docker volumes mount ネットワーク コンテナの利用するネットワー docker run -p ク構成の管理 docker network create docker network connect docker network disconnect docker network rm コンテナを作成し起動する コンテナ内でコマンドを実行する コンテナを作成する コンテナを開始する Docker HUB からコンテナイメージを取得する コンテナをイメージ化する コンテナイメージをファイルとして取り出す ファイルからコンテナイメージを登録する ホストとコンテナでディレクトリを共有する。 もしくは、ボリュームをコンテナに接続する。 データを永続化するためのボリュームを作成する ボリュームを削除する ポートフォワードの設定を行う コンテナ向けのネットワーク作成する コンテナをネットワークに接続する コンテナをんっとワークから切断する ネットワーク削除する 同じ処理でも複数の呼び出し方があります。 また、ここに挙げた物以外にも多数の機能がありますので、詳細はdockerコマンドのマニュアルやインターネットの情報を参照してください。 2025/10/15 32

33.

Dockerの裏側 Dockerを使ってコンテナを利用する場合、Dockerでの操作の結果とし てどのような状態でコンテナ環境が作られるのか、以下の主要機能に ついて実際に操作してDockerの裏側について見ていきます。 ① コンテナイメージ管理 ② コンテナの実行管理 ③ コンテナストレージ管理 ④ コンテナネットワーク管理 2025/10/15 33

34.

ラズベリーパイへの接続確認 1. ラズベリーパイのIPアドレスを確認します デスクトップの右上のWiFiマークの上にマウスカーソルを合わせるとIPアドレスが確認できます。 2. Tera Termを起動し、HostにIPアドレスを入力しssh接続します 1、で求めたIPドレスを指定 22番ポートを指定 sshを選択 2025/10/15 34

35.

Dokcerの起動確認 ラズベリーパイにログインして以下のコマンドを実行します。 Dockerが起動している場合は以下のような表示となります。 1)docker ps 2)docker info 2025/10/15 35

36.

イメージ管理の仕組み Dockerのイメージ管理の主な機能として以下のものがあります。 ⚫Docke HUBからコンテナイメージを取得しコンテナ起動に使用できるよ うにする ⚫独自に変更を加えたコンテナイメージを登録し、そのイメージからコン テナを起動できるようにする ⚫コンテナイメージの取り出し/登録機能で他ホストのDockerにコンテ ナイメージをコピーし、そのイメージからコンテナを起動できるようにす る 2025/10/15 36

37.

実習(イメージ管理) ① イメージがない状態からコンテナ起動 Docker HUBからイメージがダウンロードされ、コンテナが起動することを確認 ② イメージが存在する状態からコンテナ起動 すでに存在するのでダウンロードせずにコンテナが起動することを確認 ③ コンテナからイメージを作成 コンテナを編集してイメージ登録しそのイメージから起動すると自分で編集したコンテナが起 動することを確認 ④ イメージを保存して別のDockerに登録 イメージをアーカイブとして取り出せること、および、イメージを登録できることを確認 ここで使用するコマンド docker images docker run docker ps docker inspect docker pull docker rmi docker save docker load 2025/10/15 37

38.

コンテナ実行の仕組み コンテナでは環境分離に名前空間を分けることは説明しました。 Dockerでは各種名前空間の制御を行い、指定された条件の隔離環境 を用意します。 docker run –help の抜粋 以下のように、名前空間を切り替えられるオプションがある --cgroupns string Cgroup namespace to use (host|private) 'host': Run the container in the Docker host's cgroup namespace 'private': Run the container in its own private cgroup namespace '': Use the cgroup namespace as configured by the --pid string PID namespace to use --userns string User namespace to use --uts string UTS namespace to use 2025/10/15 38

39.

実習(コンテナ実行) Dockerでコンテナ環境を作成・起動した場合の環境の分離について名 前空間の状態を中心に見てきます。 作成される名前空間の様子、名前空間によって環境が隔離される様 子を見ます。 ① コンテナを起動して名前空間が分離されていることを確認 ② コンテナ環境とホスト側でのプロセスなどの見え方を確認 ここで使用するコマンド docker run docker exec 2025/10/15 39

40.

ストレージ管理の仕組み Dockerではコンテナの使用するデータ領域を管理します。 ⚫コンテナイメージから作成されるコンテナ環境のrootとなる領域管理 ◦ イメージ管理 ⚫ホストのディレクトリをコンテナからアクセスできるようにする制御(bind) ◦ ホストのディレクトリをコンテナのディレクトリにマウントする ◦ ホスト-コンテナ間でファイルを共有できる ⚫永続的にデータを保持可能なボリューム管理(volume) ◦ ホストの特定の領域にデータを保持 ◦ 他のコンテナと共有可能 ⚫メモリを利用するディスクには書き込までないデータ領域(tmpfs) ◦ 高速でデータをディスクに残さないので安全 ◦ 他のコンテナと共有はできない 2025/10/15 40

41.

コンテナで使えるストレージ コンテナ /sharedData / bind コンテナ レイヤ コンテナイメージ / +- home +- cq /work/tmp tmpfs mount メモリ +-- sharedData 2025/10/15 41

42.

コンテナイメージの構成管理 コンテナの元となるイメージについては、スペース効率を考慮した管理が必要となります。 同じイメージから起動したコンテナごとに、全データを保持するとすぐに領域を食いつぶし ます。 コンテナイメージについてはoverlayfsを使ったレイヤー構造で管理されていて、省スペー ス化を実現しています。 Debianコンテナ1 Debianコンテナ2 Debianコンテナ3 Debianコンテナ イメージ Debianコンテナ イメージ Debianコンテナ イメージ 起動 起動 起動 Debianコンテナ1 起動 Debianコンテナ2 起動 Debianコンテナ3 起動 共通部分はイメージを参照 Debianコンテナ イメージ 2025/10/15 起動ごとにコンテナイメージをコ ピーしたら、領域が3倍以上に膨 れ上がるのでNG Debianコンテナ イメージ 42

43.

コンテナ2起動時に用 意される、debianイ メージ、python3イメー ジ、コンテナ2の3つの レイヤーを重ねてコン テナ2に見せるデータ 領域 イメージの構造 イメージ管 理機能で、 コンテナイ メージの内 容を階層管 理する範囲 Debianコンテナ コンテナ2 コンテナ1 レイヤ コンテナ2 レイヤ debian コンテナイメージ debian_with_py コンテナイメージ python3イメージレイヤ debianイメージレイヤ 2025/10/15 コンテナ2起動時に用 意されコンテナ2で行 われた変更内容を保 持 Debianイメージと python3イメージを重ね てpython3インストール 済みdebian点てなイ メージとして見せる Debinaコンテナに python3をインストール した際に差分となった データを保持 Docker HUBより取得し たdebianコンテナイ メージの内容 43

44.

実習(ストレージ管理) Dockerコンテナの使うデータ領域がどのように用意されるのか見てい きます。 また、イメージ管理の様子も簡単に見ます。 ※overlayfsの詳細は後で見るので、ここでは概観する程度とします。 ① ホスト側のディレクトリをコンテナと共用できることを確認 ② コンテナが見ているストレージ領域はどう作られているか確認 ③ コンテナイメージの構成管理を確認 ここで使用するコマンド docker run docker ps docker inspect docker commit 2025/10/15 44

45.

ネットワーク管理の仕組み Dockerでは一般的なネットワーク構成を準備し、コンテナがネットワー クに接続できるようにしてくれます。 ⚫コンテナ間の通信 ⚫外部との通信 などネットワークを使う上で必要となる構成は簡単に構築可能です。 2025/10/15 45

46.

Dockerでサポートされるネットワーク デフォルトで3つのネットワークが存在する。 bridge ホストとは異なるコンテナ用のネットワークで、仮想ブリッジを介してホストのネットワークと接続しているので外部との通信も可能 host ホストとNIC共有する(IPアドレスも)コンテナ用 None ネットワークなしコンテナ用 これ以外にもユーザ定義ネットワークを追加でき、コンテナ作成時にいずれかのネットワークに所属させるこ とで目的に応じたネットワーク接続を実現できる。 2025/10/15 46

47.

bridgeネットワーク コンテナ独自のネットワークを持 ち、仮想ブリッジを介してホストの ネットワークとつながり外界と繋 がる 2025/10/15 47

48.

hostネットワーク ホストのEthernetデバイスお よびIPアドレスを使ってホスト と同じネットワークに所属する 2025/10/15 48

49.

noneネットワーク ネットワークには繋がらない、 孤立したコンテナ 2025/10/15 49

50.

実習(ネットワーク管理) ここからは、dockerを使ってコンテナ を作りながらネットワークの構成 についてみます。 ① コンテナ起動した場合のネットワーク状態を確認 ② hostネットワークに接続したコンテナを起動してネットワーク状態を 確認 ③ noneネットワークに接続したコンテナを起動してネットワーク状態を 確認 ここで使用するコマンド docker images docker run docker ps docker inspect docker pull docker rmi docker save docker load 2025/10/15 50

51.
[beta]
補足:dockerで作ったコンテナのNET名
前空間がip netns lsで表示されない
ip netnsは/var/run/netns配下から一覧を取得している。

docker の場合/var/run/netnsに情報を置かないのでここにシンボリック
リンクを貼ってアクセスできるようにする。

$ sudo ip netns ls
$ docker ps
CONTAINER ID IMAGE COMMAND
CREATED
STATUS
PORTS
NAMES
5cc9eff45b97 ubuntu "/bin/bash" 2 hours ago Up 2 hours 0.0.0.0:8080->80/tcp gifted_galileo
$ docker inspect 5cc9eff45b97 --format '{{.State.Pid}}'
2478
$ sudo ln -s /proc/2478/ns/net /var/run/netns/gifted_galileo_net
$ sudo ip netns ls
gifted_galileo_net (id: 0)
$

2025/10/15

51

52.

おまけ:異なるアーキテクチャのアプリ実行 DockerではQEMUの助けを借りてホストとは異なるCPUアーキテクチャ 向けのコンテナ環境も簡単に準備できます。 ここでは、x86のコンテナイメージを起動してみます。 2025/10/15 52

53.

3.コンテナを実現する技術 2025/10/15 53

54.

ここで知ること コンテナを実現する以下の基礎技術について、説明と実習を通して機能と操作方法 を理解します。 ① 名前空間(namespace)による環境分離 ② cgroupによるシステムリソースの利用制限 ③ OverlayFSを使ったコンテナストレージの仕組み ④ 仮想Ethernet デバイスと仮想ブリッジで 仮想ネットワークを作る 詳細を掘り下げる時間は足りないので、機能概要と用途、コマンドでの操作方法を 見ていきます。 ※実現方法の詳細を知るにはカーネルソースを読みます。 2025/10/15 54

55.

準備 Dockerをインストールすると、nftablesにDokcer向けの設定が行われるので、まずはその 設定を消します。 方法は2つあります。 ① Dockerをアンインストールする ② nftablesの設定を一時的に消す ここでは2番目の方法で設定を消します。以下のコマンドを実行すると設定が消せます。 $ sudo nft flush ruleset この場合、ラズベリーパイを再起動するとnftablesの設定が戻るのでこれ以降の実験を 行う場合は再度消す必要があります。 再起動すれば再度Dockerが利用可能になるので、Dokcerを使い続けたい場合はこの方 法がよいと思います。 2025/10/15 55

56.

コンテナを実現する技術 要素技術 名前空間(namespace) 機能 主な用途 名前空間は、グローバルシステムリソース を抽象化 コンテナ毎に利用するリソースを分離する して、干渉しない隔離された環境にを実現するため の仕組み Cgroup (コントロールグループ) 実行プロセスをグルーピングして、そのグループに プロセスに割り当てるCPUやメモリといった物理リ 対してリソース利用制限などの制御を行う仕組み ソースの利用調停 OverlayFS (Overlay Filesystem) 複数のディレクトリを重ねて1つのディレクトリに コンテナイメージが保存されたディレクトリの上に 見えるマウント機能 コンテナ用のディレクトリを重ねて、コンテナデー タとして使える様にする 仮想ブリッジ ホスト上に仮想的なL2スイッチを用意する 仮想Ethernetデバイス 互いに接続された仮想的なネットワークIFのペアを コンテナとホスト上の仮想ブリッジを接続し、コン 用意する テナをネットワークに接続する nftables パケットフィルタリング ホスト外からコンテナにネットワークアクセスでき るようにポートフォワード行う BPF (Berkley Packet Filter) カーネルイベント発生時に処理を実行する仕組み cgroupと組み合わせ、cgroupに属するプロセスがデ バイスへアクセスしようとした場合に、イベント起 動されたBPDプログラムでデバイスへのアクセス許 可を制御する capability 操作やファイルアクセスなどの細かな権限制御を提 コンテナで動作するプロセスへの特権操作などの権 供する仕組み 限付与 Seccomp (Secure Computing Mode) アプリケーションの利用できるシステムコールを制 コンテナで利用できるシステムコールを制限しセ 御する仕組み キュリティーを高める 2025/10/15 ホスト上に分離されたネットワークを作り、コンテ ナからみて別々の物理ネットワークを用意する 56

57.

準備 Raspberry Pi には2つのターミナルからアクセスします。 TeraTermを2つ起動して、それぞれRaspberry Piにssh接続してください。 2025/10/15 57

58.

名前空間(namespace)による環境分離 名前空間は、リソースをグルーピングするもので、OS(RapberryPi OSな ど)の上にリソースが直接存在するのではなく、グループ分けした環境 の中にリソースが存在するという形をとります。 そのグループを名前空間と呼び、複数の名前空間を同一OS上に用意 することができます。 そしてプロセスはいずれかの名前空間に所属し、所属した名前空間に あるリソースは利用することができますが、他の名前空間のあるリソー スを使うことはもちろん、存在を認識することもできません。 存在を認識することができないため名前空間が異なれば同じ名前やID のリソースが競合することなく存在できるということです。 2025/10/15 58

59.

サーバのリソース サーバのリソースには、以下のものがあります。 ⚫CPU ⚫メモリ ⚫ファイル ⚫ネットワーク ⚫プロセス情報 ⚫ユーザ情報 これらはグローバルなリソースで全てのプロセスで共通です。 2025/10/15 59

60.

リソース分離 LinuxではCPUやメモリは標準的に分離・仮想化されているため、隔離では なく使用量を制限するだけ(cgroup)ですみます。 その他リソースについては、それぞれのリソースを箱(名前空間)に詰めリ ソースの隔離を行い、プロセスから参照する箱を変えることで見えるリソー ス範囲を制限します。 プロセ ス1 PID (PID名前空間a) MOUNT プロセ ス2 PID (MOUNT名前空間c) (PID名前空間b) プロセ ス3 MOUNT (MOUNT名前空間d) 2025/10/15 60

61.

名前空間で分離できるリソース 名前空間 隔離対象リソース PID PID、プロセスツリー情報 USER UID/GID、権限などの管理情報 MOUNT ファイルシステムのマウント情報 UTS ホスト名、ドメイン名 NET NICやネットワークスタック IPC System V IPC オブジェクト、POSIXメッセージキュー CGROUP cgroup TIME モノトニック、ブートタイムクロック 2025/10/15 61

62.

名前空間の操作 名前空間を操作するシステムコール システムコール clone 説明 新規プロセスを作成する。 プロセス作成時に名前空間を分離するか共有するか指定可能。 プロセスが生まれた時から名前空間が変わっている unshare 親プロセスと共有している実行コンテキストを分離する。 名前空間を変更可能。 PID名前空間は子プロセスから有効になる。子プロセスが新しい名前空間のPID 1と なる。 setns 名前空間を関連付けしなおす。 PID名前空間は子プロセスから有効になる。子プロセスが新しい名前空間のPID 1と なる。 呼び出し元自体のPID名前空間は変わらない。 名前空間を操作するコマンド 今日は、こっちのコマンドを使っていきます コマンド 説明 unshare プログラムを親プログラムとは名前空間を分離した状態で起動する。 PIDを分離したい場合は-fオプションでforkさせる。 nsenter lsns 2025/10/15 他の名前空間を使ってプログラムを起動する。 既存名前空間を指定する。 名前空間の一覧取得 62

63.

参考:カーネルの名前空間管理 少し前のカーネルな ので今は変わってい るかもしれないが基本 的な構造は同じだと思 います。 各名前空間はUSER名前空間を参照する。 これは権限制御のため。 nsproxyがプロセ スの属する名前 空間を持つ nsproxy struct uts_namespace 1:/usr/sbin/apache2 struct ipc_namespace /: /var/lib/docker/overlay2/790a8905〜〜 struct mnt_namespace struct pid_namespace /usr/sbin/apache2 (task_struct) init (task_struct) struct net cred struct user_namespace 共有メモリ セマフォ etc.. eth0 172.17.0.2 www-data/www-data USER名前空間は credで管理される struct uts_namespace /bin/bash (task_struct) この2プロセスは名 前空間が同じ struct ipc_namespace nsproxy struct mnt_namespace struct pid_namespace /usr/sbin/mysqld (task_struct) struct net cred 2025/10/15 1:/bin/bash 2: /usr/sbin/mysqld struct user_namespace / : /var/lib/docker/overlay2/8774d2b8 〜〜 共有メモリ セマフォ etc.. eth0 172.17.0.3 tsuyo/tsuyo 63

64.

名前空間の実際 コンテナ環境構築時に重要な以下の名前空間を操作し、名前空間が 分離されると環境はどのように見えるのか確認します。 他の名前空間も基本的には環境毎に分離されて見えるものなので、 以下のものを知ればだいたい理解できると思います。 ① PID名前空間 ② MOUNT名前空間 ③ NET名前空間 2025/10/15 64

65.

PID名前空間 名前空間を分離すると、それぞれの空間に属するプロセスで見えるプロセスツリー が異なったものになります。 PID名前空間が別であればプロセスに同じPIDが付与されることがあります。 PID:1 PID空間の分離の例 ⚫黒文字のPIDはホストで見えているプロセスID 名前空間を分離 PID:2 ⚫赤文字のPIDがコンテナ内で見えているID PID:1 PID:1 PID:3 ⚫コンテナAとコンテナBには同じPIDが存在するが 実態は別のプロセス PID:4 PID:2 2025/10/15 PID:2 PID:5 名前空間:A 名前空間:B コンテナ:A コンテナ:B 65

66.

実習(PID名前空間) PID名前空間を分離した場合の様子を確認します。 ① 元の名前空間と分離した名前空間ではPIDが別になっていること ② PID名前空間を分離すると分離したプロセスとその子プロセス以外 が見えないこと 2025/10/15 66

67.

MOUNT名前空間 MOUNT名前空間を分離すると、それぞれの空間に属するプロセスで見え るファイルシステムツリー(マウント)が異なったものになります。 分離する前の状態は維持され、その後の変更がそれぞれの名前空間に 閉じたものとなり異なった状態となっていきます。 bash bash / ファイルシステムを/dir2にマウント / /dir2 /dir4は見えない MOUNT名前空間を分離 してbashを起動 unshare –mount bash MOUNT名前空間が分離された環境 bash bash / ファイルシステムを/dir4にマウント / /dir4 /dir2は見えない 名前空間分離後にそれぞれの環境で マウントされたファイルシステム情報は お互いに見えない 2025/10/15 67

68.

実習(MOUNT名前空間) ① MOUNT名前空間を分離した後に行ったmount操作が元の名前空 間には影響しないことを確認 2025/10/15 68

69.

NET名前空間 NET名前空間ではネットワークに関するリソースを隔離することができ ます。 ⚫ネットワークデバイス ⚫アドレス ⚫ルーティング など、ネットワークに関するものが対象となります。 コンテナのネットワークというとさまざまな要素がからみ複雑なもので す。 ここでは、単純にNET名前空間を分離するとネットワークリソースの競 合がなくなることのみ示します。 2025/10/15 69

70.

実習(NET名前空間) ① 単純にNET名前空間を分離するとネットワークリソースの競合がな くなることを確認 2025/10/15 70

71.

cgroupによるシステムリソース制限 cgroup(control group)は、Linuxカーネルの持つプロセスグループに対 する制御機能を提供する仕組みです。 主な機能として以下があります。 ⚫リソース制限:リソースの上限制限、デバイスへのアクセスをブロック など ⚫優先度制御:リソースを共有するプロセス間での割り当て順序制御 ⚫チェックポイント・リスタート:プロセスを停止させ状態を固定化と再開 2025/10/15 71

72.

cgroup cgroupは統一的なIFの提供と設定の管理をするもので、実際の制御はスケジュー ラ、メモリ管理、デバイスドライバなどがそれぞれ行います。 cgroupの特徴 ⚫制御値指定は、リソースを意味するサブシステムとそれぞれのパラメータがあり、 サブシステムに対してパラメータ設定することで行う ⚫cgroupは階層構造を持ち親の属性を継承する ⚫属性の上書きもできるが、親の制限を広げるようなことはできない ⚫プロセスはcgroupに属することでそこに設定された制限が適用される なおcgroupには古いv1とさまざまな構造を整理したv2があり、v2にシフトしています。 ですので、ここでは、v2を扱います。 2025/10/15 72

73.

cgroupリソース制御構造 /sys/fs/cgroup bash プロセス mycgroup cgroup.procs bashプロセスをcgroupに所属 cpu.max memory.max CPU利用時間の制限値を設定 ・ ・ メモリ使用制限値を設定 BPFプログラムをcgroupにアタッチ BPFプログラム (my_devctl.o) /dev/random other_cgroup cgroup.procs cpu.max memory.max 2025/10/15 ・ ・ デバイスアクセス制限を設 定 /de/zero 73

74.

プロセスへの制限設定 cgroupでの制限の設定および解除方法は ⚫プロセスをcgroupツリーに入れる(制限する)または出す(制限しない) →cgroup.procsにPIDを追加または削除 ⚫リソースパラメータを変更する ことで行います。 2025/10/15 74

75.

cgroupv2で制御可能な主なリソース コントローラ 機能 制御方法 CPU CPU処理時間の割り当て制御 /sys/fs/cgroup/<cgroup名>/cpu.maxに期間とその期間に使えるCPU時 間を設定することで利用制限がかかる。 メモリ メモリ使用量の制御 /sys/fs/cgroup/<cgroup名>/memory.max またはmemory.highに制限値 を設定すると制御がかかる。 memory.maxの場合は制限値を超えるとプロセスがKILLされるが、 memory.highの場合はプロセスはKILLされずメモリを解放する様な制御が かかる。 IO IO帯域の制御 /sys/fs/cgroup/<cgroup名>/io.maxにデバイス番号と制限値を設定する ことで対象デバイスへのアクセスが制御される。 PID プロセス起動数の制御 /sys/fs/cgroup/<cgroup名>/pids.max に値を設定するとプロセス生成数 の上限を制御できる。 DEVICE デバイスへのアクセス制御 デバイスへのアクセスを制御するBPF(Berkeley Packet Filter)プログラム を登録し、cgroupと紐付けると制御がかかる。 ネットワーク ネットワークフィルタリング制御 iptables/nftablesでパケットの遮断、接続数制限、帯域制限などのフィル タリング設定を行い、それをcgroupに紐付けると制御がかかる。 2025/10/15 75

76.

cgroupの実際 それぞれもう少し細かく見ていきますが、全てを見ていけないので、こ こではコンテナ環境構築時に意識するケースの多い以下の物理リソー スに関する制御について説明します。 ① CPU利用制限 ② メモリ使用制限 ③ デバイスアクセス制限 を見ていきます。 2025/10/15 76

77.

CPU利用制限 cgroupでのCPU利用制限は、指定期間中に使用できるCPU時間の制限 値を指定して行います。 例えば、"100 100000" と指定した場合は、100000μsごとに100μsのCPU 時間を割り当てることとなります。 なお、システムデフォルトは ”max 100000”です。なお、システムデフォ ルトは ”max 100000”です。 この値を cgroup の cpu.max(CPUリソースのmaxパラメータ) で指定し て制御します。 その他にも、多くのパラメータがりますが、詳細はgroupのCPUリソース のドキュメントを参照して下さい。 2025/10/15 77

78.

実習(CPU制限) ここでは、以下の内容を確認します。 ① CPUの利用制限の設定時の操作方法とプロセスの挙動 ② CPUの利用制限の解除時の操作方法とプロセスの挙動 なお、操作のために3つめのターミナルが必要なので、もう1つTeraTerm を起動してRaspberry Piにssh接続してください。 2025/10/15 78

79.

メモリ使用制限 cgroupでのメモリ使用量制限は、メモリリソースのパラメータである、 ⚫memory.max → メモリ使用制限を超過するとプロセスがkill または ⚫memory.high → 制限値に収まるようにメモリ回収を進める を使う2つの制御方法があります。 メモリ使用量制限値はバイト単位で指定します。 2025/10/15 79

80.

実習(メモリ利用制限) メモリ利用制限について確認します。 ① memory.maxでのメモリ利用制限設定時のプロセスの挙動 ② memory.highでのメモリ利用制限設定時のプロセスの挙動 実験のために、swapは無効化しておきます。 sudo swapoff -a でスワップを無効化できます。 ラズベリーパイを再起動するか sudo swapon /var/swap すれば再度 有効化できます。 2025/10/15 80

81.

デバイスアクセス制限 デバイスコントローラでは、プロセスからのデバイスへのアクセス許可/ 不許可の制御が可能です。 これを使ってコンテナから不用意にデバイスを操作されない様に制御 して安全な環境を提供しています。 cgroupでのデバイスアクセス制御の仕様がv1とv2で大きく変わりました。 cgroup v1ではデバイスコントローラーへのインターフェース (devices.allow,devices.deny)でデバイスへのアクセスを制御できました が、v2ではデバイスコントローラへの直接インターフェースはなくなり、 制限にBPF(Berkeley Packet Filter)を使うようになりました。 2025/10/15 81

82.

補足:v1とv2 BPFプログラムをcgroupにアタッチし、そのcgroupに属するプロセスが デバイスへのアクセスを行おうとすると、そのアタッチしたプログラムへ 制御が移り、プログラムが成功もしくは失敗を返すことで制御を行いま す。 2025/10/15 82

83.

補足:v1とv2ネットワーク ネットワークコントローラに関しても仕様が変わり具体的な制御は iptablesやnftablesといったパケットフィルタリングの仕組みを使うことに なります。 iptables/nftablesではパケットの遮断や接続数制限、帯域制限が設定 できるのでその設定を cgroupと紐づけてそれに属するプロセスの通信 の場合に制限をかける動きとなる様です。 2025/10/15 83

84.
[beta]
補足:BPF(Berkeley Packet Filter)
Linuxカーネルがもつフィルタリング機能を組み込むための仕組み。
決まった形式でC言語でプログラ
ムを書き、ビルドしてツールで組み
込み利用する。
右のプログラムは、0を返すとデバ
イスへアクセスは不可能、1を返す
とデバイスへのアクセスを許可す
るという振る舞いをするフィルタプ
ログラムでデバイスへアクセスしよ
うとするとその直前に呼び出され
てアクセス制御します。

2025/10/15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("cgroup/dev")
int my_dev_cntl(struct bpf_cgroup_dev_ctx *ctx)
{
/*
bpf_cgroup_dev_ctx にアクセスタイプと対象デバイスが入っている
タイプやデバイスを見て制御する処理を実装する
ここでは、
/dev/random はアクセ不可
/dev/zero はアクセ可能
その他はアクセス可能
という制御を実装する
*/
if (ctx->major == 1 && ctx->minor == 8) {
bpf_printk("my_dev_cntl:NOT allowed");
return 0; // アクセス不可能
}
else if (ctx->major == 1 && ctx->minor == 5) {
bpf_printk("my_dev_cntl:allowed");
return 1; // アクセス可能
}
else {
return 1; // アクセス可能
}
}
char _license[] SEC("license") = "GPL";

84

85.

実習(デバイスアクセス制限) cgroupとBPFプログラムを使用したデバイスアクセス制限について確認 する。 ① デバイスアクセス制限の設定方法と挙動の確認 ② 制限デバイス以外のアクセスは可能であることの確認 を行います。 2025/10/15 85

86.

OverlayFSを使ったコンテナストレージ コンテナ環境で使用するストレージは、 ⚫コンテナイメージとイメージを展開してシステム(コンテナストレージ)と して使用する非永続化領域 ⚫永続性を持つデータ保存領域 があり、それぞれ求められる要件が異なります。 コンテナは、起動して処理して捨てるというのが基本的なライフサイク ルであり、コンテナが使うストレージはコンテナが終了すると消えます。 残しておきたいデータはコンテナストレージとは別の領域に保存してお く必要があります。 2025/10/15 86

87.

コンテナストレージの要件 コンテナストレージは、ベースとなるコンテナイメージとそのデータへの 変更差分を保持して、コンテナ独自の領域を提供しています。 また、コンテナイメージ自体も効率化のため同じような構造となってい ます。 この様に、元データとその差分を保持することでストレージの利用量を 最小化し、差分管理することで、変更前後のデータに簡単にアクセス できる様になる柔軟性を提供で着ます。 ここでは、コンテナイメージやコンテナストレージを構成する仕組みとし て利用されている、OverlayFSについて詳細を見たいと思います。 このあたりに使われる技術は様々なものが使われてきました。 overlay、aufs、btrfs、devicemapper、などが利用可能で以前は devicemapperが利用されることが多かったです。 今はOverlayFSがデフォルトとなっていますが、別のテクノロジー が出てきたらそちらに変わっていくかもしれません。 2025/10/15 87

88.

OverlayFSとは Linuxの持つファイルシステムの1つで、複数のディレクトリを重ねて1 つのファイルシステムに見せる機能を持ちます。 それぞれのディレクトリをレイヤーと見立てて、元となるベースレイヤー とベースレイヤーに対する変更内容を保持する差分レイヤーを重ね合 わせて1つのファイルシステムとして扱うものです。 利用する側はデータがどこに入っているのか意識せずに単一のものと して、他のファイルシステム同様に、データを見ることができます。 ベースとその差分情報で管理することで、同じベースから派生するコン テナのような環境では、共有する部分と個別の分を分けて管理でき ディスク消費量を抑えられるメリットがあります。 2025/10/15 88

89.

OverlayFSの構造 ファイルシステムのView ビュー FILE1 差分 レイヤー FILE1 ベース レイヤー FILE2 FILE3 最初は空 更新されるとここに溜 まる FILE3 更新を保持するレイヤー 元となるデータ FILE1 FILE2 ベースとなるデータの入っているレイヤー OverlayFSは以下の3層で構成される。 最下層のベースレイヤー自体は複数のレイヤーで構成されることもある。 2025/10/15 89

90.

OverlayFSのデータアクセス 種別 処理 ファイル参照 ファイルを参照する場合、まずは差分レイヤー内でファイルを探しファイル があればその内容を読み込みます。 差分レイヤーにファイルがない場合はベースレイヤーを探します ファイル新規作成 ファイル新規作成時は、差分レイヤーにファイルを作成します。 ファイル更新 既存ファイルを更新する場合は、ベースレイヤーからファイルを差分レイ ヤーにコピーして、そのコピーしたファイルを更新します。 ファイル削除 ファイル削除は、差分レイヤーにあるファイルは削除され、ベースレイヤー にファイルが存在する場合は、ベースレイヤーと同じ名前のキャラクタデ バイスを差分レイヤーに作成することで、ベースレイヤーのファイルを見え なくして削除された様に振る舞います。 作成されるキャラクタデバイスは、メジャー、マイナー共に0のもの となりま す。 2025/10/15 90

91.

OverlayFSを使ったコンテナイメージの構成例 コンテナ1 コンテナ2 コンテナ3 コンテナ4 コンテナ1 レイヤ コンテナ2 レイヤ コンテナ3 レイヤ コンテナ4 レイヤ CentOS+Apache コンテナイメージ CentOS+ Apache+redmine コンテナイメージ CentOS コンテナイメージ redmineイメージレイヤ Apacheイメージレイヤ CentOSイメージレイヤ 2025/10/15 91

92.

実習(OverlayFS) OverlayFSの仕組みを確認。 ① OverlayFSの構成方法 ② OverlayFSに対する各種操作時の挙動 2025/10/15 92

93.

仮想ネットワークを作る コンテナ環境ではネットワークは非常に重要なものです。 というのも、通常コンテナへは直接コンソールで操作することはなく、 ネットワーク経由でサービスへアクセスするのが一般的だからです。 そんなネットワークへの要望には、 ・コンテナ毎に隔離されたネットワーク ・コンテナ間、コンテナと外部サーバとの通信 ・ホストをまたがったコンテナ間の通信 ・一般的なネットワークセキュリティー があります。 2025/10/15 93

94.

利用するネットワーク技術 このような要求を満たすために以下の技術を使ってコンテナネットワー クを実現しています。 機能 用途 NET名前空間 ネットワークリソースの分離 仮想Ethernetデバイス ホストとコンテナ間での通信 仮想ブリッジ ホストとコンテナ間での通信 パケットフィルタリング(nftables) ホストとコンテナ間での通信 オーバーレイネットワーク ホストをまたがったコンテナ間の通信 これらはLinuxで標準的に用意されているネットワーク機能です。 2025/10/15 94

95.

仮想Ethernetデバイス veth(Virtual Ethernet device)と呼ばれるペアで構成されるデバイスで 両端が内部で繋がったパイプのようなものです。 それぞれの端点を異なる名前空間に入れて名前空間をまたがった通 信経路を作れます。 通常は、一方をコンテナ他方を仮想ブリッジに接続し、コンテナをある ネットワークに所属させるために使用します。 sudo ip link add name my-ns-veth type veth peer name my-host-veth my-ns-veth 2025/10/15 my-host-veth 95

96.

仮想ブリッジ ホストLinux上に作る仮想的なL2スイッチで、コンテナネットワークとホス トネットワークをつなぐために使用します。 sudo ip link add name mybr type bridge sudo ip link set dev my-host-veth master mybr コンテナネットワーク my-ns-veth my-host-veth mybr ホストネットワーク 2025/10/15 96

97.

パケットフィルタリング (nftables) ファイアウォール、NAT、ポートフォワードなどをnftablesで実現します。 NAT、ポートフォワードなどでコンテナを他のコンテナやホストおよび外 部サーバと通信できるように制御するために使用します。 prerouting foreward postrouting パケット パケット dnat masquerade パケット nftablesルール パケット 2025/10/15 97

98.

オーバーレイネットワーク 一般的にはVXLAN(Virtual eXtentible Local Area Network)を使って実現 します。 L3ネットワーク上に論理的なL2ネットワークを作ることで複数ホストにま たがった仮想ネットワークを構成するものです。 コンテナネットワーク コンテナネットワーク my-ns-veth my-ns-veth my-host-veth my-host-veth mybr mybr 論理的なL2ネットワーク ホストネットワーク 2025/10/15 98

99.

仮想ネットワークの実際 これまで見てきたネットワーク機能を使ってコンテナ環境のネットワー クを構築します。 一般的には、以下の3パターンの構成となります。 ⚫仮想Ethernetを使った構成 ⚫仮想ブリッジと仮想Ethernetを使った構成 ⚫仮想ブリッジと仮想Ethernetとポートフォワードを使った構成 2025/10/15 99

100.

仮想Ethernetを使った構成 この構成では、ホスト-コンテナ、および、コンテナ-コンテナ間の通信が 可能となる構成です。 仮想Ethernetの接続しているネットワークからのみアクセスできます。 2025/10/15 100

101.

仮想ブリッジと仮想Ethernetを使った構成 この構成では、ホスト-コンテナ、および、コンテナ-コンテナ間の通信が 可能となる構成です。 仮想ブリッジを通してホストの属しているネットワークからアクセスが可能で すが、ホストの外部との通信はできません。 2025/10/15 101

102.

ポートフォワードで外部からコンテナにアクセス この構成では、ホスト-コンテナ、および、コンテナ-コンテナ間の通信が 可能で、ホスト外部との通信も可能となる構成です。 2025/10/15 102

103.

ネットワーク実験の前にnftablesの設定 ネットワークの実験を始める前に、nftablesの設定を行います。 以下のコマンドを実行して、からのnatテーブルを用意しておきます。 これからの操作でこのnatテーブルの中に設定を行います。 nftablesの設定をクリアする $ sudo nft flush ruleset $ sudo nft add table nat $ sudo nft -a list ruleset 2025/10/15 空のnatテーブルを用意する 現在の状態を表示する 103

104.

実習(仮想ネットワーク) 名前空間を超えた通信(コンテナーホスト通信相当)を行うための構成 と動作を確認します。 ① 仮想Ethernetデバイスを用いたNET名前空間をまたがった通信(コ ンテナーホスト、コンテナーコンテナに相当) ② 仮想ブリッジを使って分離されたNET名前空間からホストネットワー クへの通信 ③ nftablesによるポートフォワードを使ってホスト外部から分離された NET名前空間に通信 2025/10/15 104

105.

4.コンテナ管理ツールを作る 2025/10/15 105

106.

こんなものを作る Dockerと同じようなコンテナ管理ツールを作ってみます。 ⚫名前空間を分離してコンテナ環境を作りそのなかで指定プログラムを 実行するツール ⚫C言語などでシステムコールを使うプログラムではなく、コマンド+スク リプトで実装 標準のLinuxの機能・コマンドでコンテナ環境が作成できることをわかっ てもらいたい 2025/10/15 106

107.

用意するコマンド コマンド 機能 処理内容 create_mycont.sh コンテナ環境作成 実行ディレクトリを作成し、システムファイルおよ びットワーク環境を準備 start_mycont.sh コンテナ環境起動 コンテナモニタプロセスの起動とIPアドレスポート フォワード設定などを行いコンテナ環境でプログラ ムの起動 stop_mycont.sh コンテナ環境停止 実行プログラムおよびコンテナモニタプロセスの停 止し、ポートフォワード、IPアドレスの設定解除 remove_mycont.sh コンテナ環境削除 システムファイル、ネットワークを破棄し、実行ディレ クトリ削除 必ずしも4コマンドを用意する必要はありません。 ⚫ コンテナ環境作成+起動 を1コマンド ⚫ コンテナ停止+コンテナ環境削除 を1コマンド の2コマンド構成でもOK。 2025/10/15 107

108.

使用する主なコマンド コマンド 機能 unshare プログラムを親プログラムとは名前空間を分離した状態で起動する。 nsenter 他の名前空間を使ってプログラムを起動する。 kill プロセスを終了させる sudo 管理者権限でコマンドを実行する mkdir ディレクトリを作成する。データ配置場所などを作るために使用する。 rm ディレクトリ、ファイルを削除する。後片付けで使用する。 mount ファイルシステムをマウントする。コンテナ向けのデータ領域の準備に使用する。 umount ファイルシステムをアンマウントする。データ領域の後片づけに使用する。 ip ネットワークの設定を行う。仮想Ethernetの作成/削除、仮想ブリッジの作成/削 除、アドレス設定などに使用する。 nft nftableの操作を行う。ポートフォワードなどのパケットフィルタ設定に使用する。 2025/10/15 108

109.

コンテナ仕様 ⚫CGROUP名前空間以外全ての名前空間を分離した環境を用意 リソース管理についてはシステムグローバルにしておくためCGROUP名前空間は 分離しない ⚫指定されたプログラムをコンテナ環境で実行する ⚫RaspberryPi OSのベースとしてコンテナ用のシステム領域を用意 コンテナ環境ではRaspberryPi OSのコマンドを使用可能 ⚫コンテナ環境でのファイル変更はコンテナ環境でのみ有効となる ホストや他のコンテナへは影響しない ⚫任意のアドレスを指定してコンテナネットワークを追加可能 ⚫ポートフォワードの設定が可能 外部からコンテナ内のネットワークサービスへアクセス可能、コンテナからインター ネットへアクセス可能 ⚫ホストとコンテナ間で共有フォルダを持てる(1箇所のみ) 2025/10/15 109

110.

補足:Linuxのプロセス プロセスは親子関係を持ったツリー管理されている 環境情報は親から子へと受け継がれる 環境情報は以下のものなど動作を制御する情報 ・ユーザ ・各種アクセス権限と範囲 コンテナ環境を作るためにはこの環境情報をいろいろな方法で 変更していく Linuxのプロセス PID:1 環境1 PID:2 PID:3 環境3 PID:4 PID:5 環境2 環境4 名前空間A 2025/10/15 名前空間B 110

111.

補足:bind mount ホスト側のあるディレクトリをコンテナに見せるために利用。 今回は、RaspberryPi OSである / と procfs をマウントするために使用。 コンテナ /sharedData mount --bind /home/cq/sharedData /sharedData / +- home +- cq +-- sharedData 2025/10/15 111

112.

補足:chroot/unshare -R chroot /home/cq/work/cntRoot /bin/bash プロセス1 root=/ / プロセス1の見える範囲 home プロセス2 cq root= /home/cq/cntRoot cntRoot work 2025/10/15 プロセス2の見える範囲 112

113.

サンプル実装について microSDにサンプル実装が置いてあるので参考としてください。 ~/CQ_ContainerSeminar/4_ContManager/Sample/PROG 実習に入る前に、サンプル実装について簡単に説明します。 ここでは、処理についてではなく、 ⚫どういう考え方 ⚫どうコマンドを使っているか について参考となる部分を中心に聞いてもらえればよいです。 2025/10/15 113

114.

ファイル構成 PROG/ create_mycont.sh start_mycont.sh stop_mycont.sh remove_mycont.s env.sh MYENV コンテナ環境を作成するコマンド コンテナを起動するコマンド コンテナを停止するコマンド コンテナ環境を削除するコマンド 環境設定ファイルの生成コマンド 環境設定ファイル res/ CGROUPリソース制御関連 cpu_limit.sh CPU利用制限の設定コマンド cpu_unlimit.sh CPU利用制限の解除コマンド memory_limit.sh メモリ利用制限の設定コマンド memory_unlimit.sh メモリ利用制限の解除コマンド device_limit.sh デバイス利用制限の設定コマンド device_unlimit.sh デバイス利用制限の解除コマンド mem.c メモリ獲得テストプログラム my_devctl.c デバイス制限BPFプログラム conf/ 設定ファイルを配置するディレクトリ ここに、コンテナ名をファイル名にして設定ファイルを置く env/ コンテナ環境/名前空間管理関連 my_contmon_pid コンテナのモニタプロセスのPID取得処理 my_cont_pid コンテナで動作しているプログラムのPID取得処理 net/ ネットワーク管理関連 bridge_create.sh 仮想ブリッジの作成処理 bridge_remove.sh 仮想ブリッジの削除処理 veth_create.sh 仮想Ethernetデバイスの作成処理 veth_remove.sh 仮想Ethernetデバイスの削除処理 net_attach.sh コンテナにネットワークの接続処理 net_detach.sh コンテナからネットワークの切断処理 portfwd_create.sh ポートフォワードの設定処理 portfwd_remove.sh ポートフォワードの解除処理 work/ 2025/10/15 コンテナ環境動作ディレクトリ ここに、コンテナ名のディレクトリが作成され動作環境が作られる 114

115.

create_mycont.sh(1) #!/bin/bash # # コンテナ環境を作成するコマンド if [ "$#" -lt 1 ]; then echo "Usage: $0 コンテナ名" exit 1 fi MY_CONT=$1 echo "Create Container: $MY_CONT" # 環境情報読み込み . $MYCON_TOP/MYENV # コンテナ情報読み込み . $MYCON_TOP/conf/$MY_CONT CONT_DIR=$MYCON_TOP/work/$MY_CONT ROOT_DIR=$CONT_DIR/root # コンテナ環境のデータ保存用のディレクトリ作成 mkdir -p $CONT_DIR/root mkdir -p $CONT_DIR/upper mkdir -p $CONT_DIR/work 2025/10/15 115

116.
[beta]
create_mycont.sh(2)
# overlay FSCONT_DIR
# システムの/をベースとして利用する -> Raspberry Pi OSのアプリを使える
sudo -E mount -t overlay $MY_CONT -o lowerdir=/,upperdir=$CONT_DIR/upper,workdir=$CONT_DIR/work $CONT_DIR/root
# procファイルシステムは共有する(bind)
mkdir -p $ROOT_DIR/proc
sudo -E mount --bind /proc $ROOT_DIR/proc
# コンテナ用のcgroupを作成
sudo mkdir -p /sys/fs/cgroup/$MY_CONT
# ホストとの共有ストレージをバインドマウントで用意
if [ $HOST_DIR"x" != "x" ]; then
mkdir -p $CONT_DIR/root$DIR
sudo -E mount --bind $HOST_DIR $CONT_DIR/root$DIR
fi
# 仮想ブリッジを作成
if [ $BRIDGE_NAME"x" != "x" ]; then
$MYCON_TOP/net/bridge_create.sh $BRIDGE_NAME
fi
# 仮想Ethernetデバイスを作成
if [ $NET_NAME"x" != "x" ]; then
$MYCON_TOP/net/veth_create.sh $NET_NAME
fi

2025/10/15

116

117.
[beta]
create_mycont.sh(3)
# モニタ処理プロセス用のコマンドファイル生成
cat <<EOF > $ROOT_DIR/${MY_CONT}.mon
#!/bin/bash
echo "start ${MY_CONT}.mon ..."
while [ -e /${MY_CONT}.run ]
do
ip addr
sleep 10
done
echo ".... finish"
EOF
# モニタ処理コマンドの実行権を設定
chmod a+x $ROOT_DIR/${MY_CONT}.mon

2025/10/15

117

118.
[beta]
start_mycont.sh(1)
#!/bin/bash
#
# コンテナを起動するコマンド
#
# unshareで名前空間を分離してコンテナ環境上で指定プログラムを実行する
# 1)まずは、バックグラウンドで動作するモニタスクリプトを動作させる
# モニタスクリプトは、コンテナのルートディレクトリにchrootする
# バックグラウンドでモニタ的なものをコンテナ環境で分離して動作させ、
# 2)起動したモニタスクリプトのPIDを求め、そのプロセスのNET名前空間にネットワーク設定を行う
# 3)モニタプロセスと同じ名前空間で指定されたプログラムを実行
if [ "$#" -lt 1 ]; then
echo "Usage: $0 コンテナ名 <background>"
exit 1
fi
MY_CONT=$1
BACKGROUND=$2
echo "Start Container: $MY_CONT $BACKGROUND"
# 環境情報読み込み
. $MYCON_TOP/MYENV

2025/10/15

118

119.

start_mycont.sh(2) # コンテナ情報読み込み . $MYCON_TOP/conf/$MY_CONT CONT_DIR=$MYCON_TOP/work/$MY_CONT ROOT_DIR=$CONT_DIR/root # コンテナ環境のディレクトリへ移動 cd $MYCON_TOP/work/$MY_CONT # モニタスクリプトの実行制御を行うファイルを作成する(このファイルがある間モニタが動作する) touch $ROOT_DIR/${MY_CONT}.run # 名前空間を分けてモニタスクリプトを起動する # リソース制御のためCGROUP名前空間は分離しない nohup unshare -i -m -n -p -u -U -T -R `pwd`/root -f /${MY_CONT}.mon & sleep 1 # モニタプロセスのPIDを取得する MON_PID=`$MYCON_TOP/env/my_contmon_pid $MY_CONT` echo "MON_PID = $MON_PID" 2025/10/15 119

120.

start_mycont.sh(3) # ネットワーク設定 if [ $NET_NAME"x" != "x" ]; then $MYCON_TOP/net/net_attach.sh $MON_PID $NET_NAME $IP $BRIDGE_NAME $BRIDGE_IP $NETWORK_BITS $BROADCAST fi # ポートフォワードを設定する if [ $HOST_PORT"x" != "x" ]; then $MYCON_TOP/net/portfwd_create.sh $HOST_PORT $IP $PORT fi # 指定コマンドをモニタプロセスと同じ名前空間で実行する if [ $BACKGROUND"x" = "background""x" ]; then echo "BACKGROUND exec $PROG" nohup nsenter -t $MON_PID -m -u -i -n -p -U -T --preserve-credentials -r -w "$PROG" & else echo "FOREGROUND exec $PROG" nsenter -t $MON_PID -m -u -i -n -p -U -T --preserve-credentials -r -w $PROG fi 2025/10/15 120

121.

stop_mycont.sh(1) #!/bin/bash # # コンテナを停止するコマンド if [ "$#" -lt 1 ]; then echo "Usage: $0 コンテナ名" exit 1 fi MY_CONT=$1 echo "Stop Container: $MY_CONT" # 環境情報読み込み . $MYCON_TOP/MYENV # コンテナ情報読み込み . $MYCON_TOP/conf/$MY_CONT CONT_DIR=$MYCON_TOP/work/$MY_CONT ROOT_DIR=$CONT_DIR/root echo "Remove MyCont -- $MY_CONT" 2025/10/15 121

122.
[beta]
stop_mycont.sh(2)
# コンテナで実行しているコマンドのPIDを求める
PID=`$MYCON_TOP/env/my_cont_pid $MY_CONT`
echo "PROG PID = $PID"
# コマンドを終了させる
sudo kill -9 $PID
# ポートフォワードの設定を解除する
if [ $HOST_PORT"x" != "x" ]; then
$MYCON_TOP/net/portfwd_remove.sh $HOST_PORT $PORT
fi
# NET名前空間のリンク削除する
if [ $NET_NAME"x" != "x" ]; then
$MYCON_TOP/net/net_detach.sh $PID $NET_NAME $IP $BRIDGE_NAME $BRIDGE_IP $NETWORK_BITS $BROADCAST
fi
# モニタスクリプトの実行制御を行うファイルを削除する
#rm -f $ROOT_DIR/${MY_CONT}.run

2025/10/15

122

123.
[beta]
remove_mycont.sh(1)
#!/bin/bash
#
# コンテナ環境を削除するコマンド
if [ "$#" -lt 1 ]; then
echo "Usage: $0 コンテナ名"
exit 1
fi
MY_CONT=$1
echo "Remove Container: $MY_CONT"

# 環境情報読み込み
. $MYCON_TOP/MYENV
# コンテナ情報読み込み
. $MYCON_TOP/conf/$MY_CONT
CONT_DIR=$MYCON_TOP/work/$MY_CONT
ROOT_DIR=$CONT_DIR/root
# モニタスクリプトの実行制御を行うファイルを削除する
rm -f $ROOT_DIR/${MY_CONT}.run

2025/10/15

123

124.

remove_mycont.sh(2) # 仮想Ethernetデバイスを削除 if [ $NET_NAME"x" != "x" ]; then $MYCON_TOP/net/veth_remove.sh $NET_NAME fi # 仮想ブリッジ削除 if [ $BRIDGE_NAME"x" != "x" ]; then $MYCON_TOP/net/bridge_remove.sh $BRIDGE_NAME fi # ホストとの共有ストレージをアンマウント if [ $HOST_DIR"x" != "x" ]; then sudo -E umount $CONT_DIR/root$DIR fi # コンテナ用cgroupを削除 ★エラーになるので無効化 #sudo rm -rf /sys/fs/cgroup/$MY_CONT # procファイルシステムの共有を止める sudo -E umount $ROOT_DIR/proc # overlay FS sudo -E umount $MY_CONT # コンテナ環境用ディレクトリ削除 sudo -E rm -rf $MYCON_TOP/work/$MY_CONT 2025/10/15 124

125.

設定ファイルなど 【動作場所の定義を行う環境変数を設定】 export MYCON_TOP=/home/cq/CQ_ContainerSeminar/4_ContManager/Sample/PROG 【コンテナの定義ファイル】 # webコンテナの定義ファイル # pythonでWEBサーバを起動する PROG='python -m http.server 8000 --directory /myweb' # ネットワークの設定 NET_NAME=c_web_net BRIDGE_NAME=c_web_br BRIDGE_IP=10.1.1.1 IP=10.1.1.100 NETWORK_BITS=24 BROADCAST=10.1.1.255 # ホストのディレクトリを/mywebにマウントして共有 HOST_DIR=/home/cq/CQ_ContainerSeminar/4_ContManager/Sample/PROG/work/sharedVol/web DIR=/myweb # ポートフォワード設定(8888->8000) HOST_PORT=8888 PORT=8000 2025/10/15 125

126.

END 2025/10/15 126