ポストモダン技術 普及と展開 {.unnumbered}

この資料はテスト技法セミナーのスライドに関する補助資料です.目次は右側に表示されます.

1 docker

以下では、Docker の機能・背景(なぜ生まれたか)・仕組み(アーキテクチャ)・動作原理を、組込み/Linux 技術の観点も踏まえて体系的に解説します。 技術ドキュメントや研修資料として使用可能なレベルで包括的にまとめています。


1.1 Docker とは何か(概要)

Docker は コンテナ型仮想化技術を利用して、アプリケーションを 「依存関係ごとパッケージ化し、どこでも同じ動作を保証」するためのプラットフォームです。

特徴としては:

  • 高速起動(数百 ms〜秒)
  • 軽量(OS 全体ではなくプロセス単位で隔離)
  • 移植性が高い(Docker イメージがあれば同一動作を再現)
  • 開発〜テスト〜本番まで環境の一貫性を保持
  • コンテナ間通信やオーケストレーションが容易

Linux の 名前空間(namespaces)cgroups を活用することで実現されています。


1.2 背景:なぜ Docker が必要になったのか

派生背景(課題)

従来の開発環境では以下の課題がありました:

  1. 環境差異の問題(動かない問題) 開発者ごとに OS やライブラリが異なり、 “It works on my machine” が頻発。

  2. 仮想マシン(VM)のコストが大きすぎる

    • VM = OS 全体を仮想化
    • 起動が遅く、メモリ・CPU のオーバーヘッドが大きい
    • 数百 MB〜数 GB のディスクを占有
  3. デプロイの再現性が低い

    • バージョンのずれ
    • 手作業のセットアップ
    • アプリの依存関係が複雑化
  4. クラウド・マイクロサービス化によるスケール問題 軽量・高速で多数のアプリを並列に動かす必要があった。

これらを解決するために、軽量・再現性の高い仕組みが求められた。


1.3 Docker の仕組み(アーキテクチャ)

Docker は大きく以下で構成されます:

  1. Docker Engine(デーモン)
  2. Docker CLI
  3. Docker イメージ
  4. Docker コンテナ
  5. コンテナ runtime(containerd / runc)
  6. Linux カーネル機能:namespaces / cgroups / overlayfs

1.4 1 Docker Engine の構造

Docker の本体は以下のレイヤで構成されています:

+--------------------------------------------------+
| Docker CLI (docker コマンド)                     |
+-------------------------+------------------------+
| Docker REST API         |                        |
+-------------------------+                        |
| Docker daemon (dockerd)                          |
+-------------------------+------------------------+
| containerd (コンテナ管理)                         |
+-------------------------+------------------------+
| runc (実際にコンテナを起動するランタイム)         |
+-------------------------+------------------------+
| Linux kernel (namespaces, cgroups, overlayfs)     |
+--------------------------------------------------+

1.5 Docker を支える 3つのカーネル技術

Docker “そのもの”が OS を仮想化しているわけではなく、 Docker は Linux の分離機能を利用して「隔離されたプロセス」を構築します。


1.6 名前空間 Namespaces — 見える範囲を隔離する

代表的な namespace:

namespace 隔離対象
pid プロセス ID
net ネットワーク(eth0, IP, ルーティングなど)
mount ファイルシステム
user UID/GID
uts ホスト名
ipc 共有メモリ

プロセスごとに世界を分離する技術で、 コンテナからは「別 OS」に見える。


1.7 cgroups — 資源利用を制限

CPU・メモリ・IO などの使用量を制御。

例:

  • CPU を 1 コア分に制限
  • メモリ上限を 512MB に設定
  • IO 帯域を制限

コンテナ単位で資源を分離できる。


1.8 OverlayFS — 軽量で高速な「レイヤ式ファイルシステム」

Docker イメージは複数のレイヤの積み重ねで構成されます:

Base image (Ubuntu)
  + Layer: apt install ...
    + Layer: アプリコード配置

コンテナ起動時は「書き込み用レイヤ」を追加するだけ。

  • 共有部分はイメージを使いまわし
  • 差分だけが保存されるので軽量

1.9 Docker の動作の流れ(内部メカニズム)

例:docker run ubuntu:22.04 bash

① CLI → Docker daemon に API リクエスト

docker run → dockerd に REST API で要求

② イメージを Docker Hub から pull(無ければ)

ubuntu:22.04 のレイヤをダウンロード

③ containerd に「コンテナ作成」を要求

④ runc が namespace / cgroups / rootfs を作成し、プロセスを起動

⑤ bash プロセスが分離された世界で実行される


1.10 Docker イメージとコンテナ

用語 定義
イメージ 実行可能な fs スナップショット(read-only)
コンテナ イメージ + 書き込みレイヤで作られた「実行中のインスタンス」

コンテナを停止してもイメージは残る。 コンテナは何度でも作り直し可能。


1.11 Docker が解決すること

開発環境の標準化

Dockerfile で環境をコード化 → チーム全員が同じ環境。

デプロイの自動化

CI/CD や Kubernetes と組み合わせて高速にスケール。

環境差異の排除

複雑な依存関係も含めて再現性が保証される。

ソフトウェア分離・セキュリティ

互いに独立したサービスとして動作。

VM より軽量で高速

OS を含まない → 数百 ms で起動、数十 MB のイメージ。


1.12 仮想マシンとの違い

項目 Docker(コンテナ) VM(仮想マシン)
起動速度 ms〜秒 数十秒〜分
OS ホストの Linux を共有 ゲスト OS あり
重さ 軽い(MB〜数百 MB) 重い(GB)
性能 ネイティブに近い 若干低下
分離 軽量プロセス分離 強い分離(完全仮想化)

1.13 組込み Linux における Docker の位置づけ

利用が増えている領域

  • Yocto / Buildroot の ビルド環境の再現性確保
  • クロスコンパイルツールチェーンの配布
  • CI/CD 上でのユニットテスト
  • QEMU 上での Linux エミュレーション(仮想実機)
  • 車載 / ロボティクスでのマイクロサービス実験

実機上で動かすことは?

  • 制約デバイスでは難しいが、 Jetson/NVIDIA、Raspberry Pi、ARM64 サーバ、車載ゲートウェイなどでは可能。

1.14 . まとめ

Docker は以下の技術・構造により、 軽量・高速なコンテナ環境を提供します:

  • Linux 名前空間 (隔離)
  • cgroups (資源制限)
  • OverlayFS (レイヤ式ファイルシステム)
  • containerd / runc (実行ランタイム)
  • イメージ / コンテナという構造化デプロイモデル

背景としては、 「環境差異・仮想マシンの重さ・クラウドスケール課題」を解決するために登場しました。


2 docker による開発ワークフロー

以下では、組込み向けの QEMU + Docker を使った CI(Continuous Integration)パイプライン構成を、背景・狙い・アーキテクチャ・具体的パイプライン例の順に体系的に説明します。


2.1 背景:なぜ組込みで QEMU + Docker を併用するのか

Image

Image

組込み向け CI では、以下の課題が頻出します。

  • 組込みボードが高価で台数を増やせない
  • 再現性のあるテスト実行環境の確保が難しい
  • クロスコンパイル環境の依存関係が複雑
  • カーネルやブートローダ(U-Boot)レベルの回帰テストを自動化したい
  • HW 不在時にも自動テスト(夜間バッチ)を回したい

このため、 Docker → 依存関係を統一しビルド環境をコンテナ化 QEMU → SoC/ボードをエミュレーションし実行テストを自動化 という構成が一般化しています。


2.2 Docker と QEMU の役割分担

Image

Image

Docker の役割(Build/Toolchain)

  • クロスコンパイラ(arm-none-eabi、aarch64-linux-gnu)
  • Yocto Build 環境(Poky + Bitbake)
  • カーネルビルド環境
  • Unit Test 実行環境(googletest 等)

Docker によって、 ビルド環境のスナップショット化・再現性確保・スケールアウトが実現。

QEMU の役割(Run/Execution)

  • ARM Cortex-A/M プラットフォームの実行エミュレーション
  • Linux カーネル起動テスト
  • U-Boot のブートテスト
  • FreeRTOS のバイナリ実行確認
  • デバイスドライバの単体/結合テスト
  • Syscall/API レベルの非退行テスト

2.3 アーキテクチャ全体像(CI 上での配置)

[Developer Push]
       |
       v
+------------------------+
|      CI Runner         |
| (GitHub/GitLab/BuildKite)
+------------------------+
       |
       +--> Docker Build Stage
       |        - Cross compile
       |        - Kernel/RTOS build
       |
       +--> Docker Test Stage
                |
                +--> QEMU 起動
                |       - Virt board (ARM/AArch64/RISC-V)
                |       - Kernel/RTOS 実行
                |
                +--> テストスクリプト実行 (pytest 等)

2.4 組込み向け QEMU + Docker CI パイプライン:具体例

1 Stage 1: Build(Docker)

docker build -t my-embedded-build:latest .
docker run --rm -v $PWD:/work my-embedded-build \
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all

成果物(artifacts)

  • u-boot.bin
  • zImage
  • dtb
  • rootfs.ext4
  • FreeRTOS.elf(RTOS の場合)

2 Stage 2: Test(Docker + QEMU)

Docker コンテナ内で QEMU を起動し、自動テストを実行。

Linux カーネル例

qemu-system-arm \
  -M virt \
  -cpu cortex-a15 \
  -kernel zImage \
  -dtb virt.dtb \
  -append "console=ttyAMA0" \
  -drive file=rootfs.ext4,if=none,id=drv \
  -device virtio-blk-device,drive=drv \
  -nographic

FreeRTOS(ARM Cortex-M)例

qemu-system-arm \
  -M mps2-an385 \
  -kernel FreeRTOS.elf \
  -nographic

自動テスト(例:Expect や pytest)

pytest tests/qemu_linux/ --qemu-port=5555

2.5 QEMU + Docker を利用した高度な CI 最適化

(1) 複数バージョンの Linux/RTOS 同時テスト

  • Linux 5.4 / 5.10 / 6.1
  • FreeRTOS 202212 / 202406

→ 回帰保証(Backward Compatibility)

(2) ハードウェア抽象テスト(HAL/API)

  • LED/TIM/GPIO API の自動テスト
  • Driver Stub を QEMU カスタムデバイスとして挿入
  • カーネルモジュールの insmod/rmmod テスト

(3) デバイスドライバの CI

  • 仮想 I2C/SPI/UART の QEMU デバイスを作成し結合テスト
  • Zephyr や RT-Thread でも類似手法が利用可能

(4) Fuzzing の組込み

  • syzkaller + QEMU + Docker
  • kernel syscall fuzzing
  • ドライバの fault injection

2.6 使用される技術スタックまとめ

Docker

  • BuildKit
  • multi-stage build
  • artifact キャッシュ
  • GitHub Actions/GitLab Runner と相性が良い

QEMU

  • qemu-system-arm / aarch64 / riscv32 / riscv64
  • カスタムデバイスモデル
  • GDB Remote Debug(:1234
  • 様々な組込み SoC (virt, stm32, mps2, raspberry-pi)

テストフレームワーク

  • pytest
  • Expect
  • Robot Framework
  • syzkaller(カーネル用)

2.7 典型的なリポジトリ構成例

.
├── docker/
│   ├── Dockerfile.build
│   └── Dockerfile.test
├── src/
├── kernel/
├── rtos/
├── qemu/
│   └── launch_scripts/
├── tests/
│   ├── linux/
│   └── freertos/
├── .gitlab-ci.yml
└── README.md

2.8 まとめ

組込み向け CI では、Docker によるビルド環境の標準化と、QEMU による仮想実行検証を組み合わせることで、高速・再現性・安定性のある開発パイプラインを構築できます。

  • Docker → クロスコンパイル環境・依存関係の固定
  • QEMU → ボード不要の自動実行テスト
  • CI → 回帰テスト・夜間テスト・安定リリース

3 docker compose

以下では、Docker Compose におけるファイル共有(Volume)とネットワーク共有(Network)について、組込み開発視点も含めて体系的に説明します。


3.1 Docker Compose の役割

Image

Image

Docker Compose は、複数コンテナを 1 つのサービス群として定義・起動するための仕組みです。 典型例:

  • ビルド環境 + テスト環境 + QEMU 実行環境
  • Web server + DB
  • CI パイプライン内での複合サービス構築

Compose の yml では、

  • volumes(ファイル共有)
  • networks(ネットワーク共有) がもっとも重要な概念です。

3.2 ファイル共有(Volumes)の仕組み

コンテナ同士/ホストとの共有

Volumes は以下を実現します:

方式 内容 用途
bind mount ホストのディレクトリをコンテナに直結 組込み開発のビルド成果物共有(ELF, dtb, rootfs など)
named volume Docker 管理下の領域をコンテナ間で共有 DB, キャッシュ、永続データ
tmpfs メモリに作られる一時領域 高速テスト、機密一時データ

docker-compose.yml 記述例(bind mount)

version: "3.9"
services:
  builder:
    image: my-cross-build
    volumes:
      - ./src:/work/src
      - ./build:/work/build

  qemu:
    image: my-qemu
    volumes:
      - ./build:/mnt/firmware

この例では:

  • builder が生成した成果物(ELF, Kernel, rootfs)が ./build に出力
  • qemu が同じ ./build を読み取り実行テストを行う

組込み CI で典型的な例

ビルドしたファームウェアを QEMU が即座に拾う構成。


named volume の例

volumes:
  shared-data:

services:
  tool:
    volumes:
      - shared-data:/opt/data
  analyzer:
    volumes:
      - shared-data:/opt/data

複数コンテナで共通データ(テストログなど)を共有できます。


3.3 ネットワーク共有(Networks)の仕組み

Docker Compose におけるネットワークは:

  • 同一ネットワーク内のコンテナは 名前解決(DNS)できる
  • bridge がデフォルト
  • 組込み用テストや QEMU のネットワークエミュレーションに有効

Compose の基本ネットワーク例

services:
  host1:
    image: alpine
    networks:
      - testnet

  host2:
    image: alpine
    networks:
      - testnet

networks:
  testnet:
    driver: bridge

同じネットワークに属するため:

host1 -> ping host2
host2 -> ping host1

が可能。


3.4 QEMU と Docker Compose の組込み用途でのネットワーク利用例

QEMU をネットワークで結合するケース

services:
  qemu:
    image: my-qemu
    networks:
      - emunet
    ports:
      - "2222:22"   # QEMU ゲストへ SSH

  tester:
    image: pytest-runner
    networks:
      - emunet
    depends_on:
      - qemu

networks:
  emunet:

動作イメージ

  • tester → qemu の仮想 Linux に対し SSH/SCP でテスト実行
  • QEMU の -netdev user,hostfwd によりネットワークモデリング
  • 組込み機器の通信テストも CI で自動化可能

Volumes + Networks を組み合わせた Compose 構成(組込み CI 編)

以下は、典型的な ビルド(gcc/clang)+QEMU 実行+テスト構成。

version: "3.9"
services:
  builder:
    image: embedded-build
    volumes:
      - ./src:/app/src
      - build-artifacts:/app/build

  qemu:
    image: embedded-qemu
    depends_on:
      - builder
    volumes:
      - build-artifacts:/mnt/bin
    networks:
      - emunet

  tester:
    image: pytest-runner
    depends_on:
      - qemu
    networks:
      - emunet

volumes:
  build-artifacts:

networks:
  emunet:

この構成が実現するもの

builder でクロスビルド

  • build-artifacts ボリュームに成果物出力

2. qemu がビルド成果物を読み込み実行

  • /mnt/bin にマウントされる

3. tester がネットワークで QEMU と通信しテスト実行

  • SSH / REST API / IPC テストなど

3.5 まとめ

Docker Compose を利用すると、組込み向け CI で次を容易に実現できます。

ファイル共有(Volumes)

  • ホストコードとコンテナを同期
  • ビルド成果物をテストコンテナへ共有
  • 長期・短期データの住み分け
  • named volume による永続化

ネットワーク共有(Networks)

  • コンテナ同士の自動 DNS 解決
  • QEMU とのネットワーク通信テスト
  • 複数サービスの疎結合構成

組込み開発の利点

  • ボードなしでビルド・実行・テストまで完結
  • CI サーバで安定動作
  • 再現性の高い環境構築
  • FreeRTOS/Linux/Android Automotive 含む幅広い運用が可能

4 Yocto(Poky)

以下に、Yocto(Poky)について、見出し後に番号を付けず、階層構造(##、###、####)を維持した解説を再構成しました。内容は技術研修資料として利用できるよう、精度と網羅性を重視しています。


4.1 Yocto Projectとは

Yocto Projectは、組込みLinuxディストリビューションを再現性・移植性・拡張性を伴って構築するためのオープンソース開発基盤。特定のLinuxディストリビューションではなく、「任意のハードウェアに対して任意のLinuxシステムを構築するためのビルドフレームワーク」を提供する点が特徴。 ビルドシステムの中心はBitBakeであり、メタデータ(レシピ・クラス・設定)を利用して、カスタムLinux OSを生成する。


4.2 Pokyとは

PokyはYocto Projectから提供されるリファレンスディストリビューションであり、実態としては以下をまとめたメタディストリビューション。

Pokyの内訳

BitBake

Yoctoのビルドエンジン。MakeやCMakeではなく、タスク指向・依存管理・クロスビルド前提の専用エンジン。

OE-Core(OpenEmbedded-Core)

最小限のLinuxを構築するメタデータセット(レシピ群)。

Poky固有のメタデータ

ビルド設定、テンプレート、skeletonなど。

Pokyは、Yoctoの機能全体をシンプルな形で利用できるようにまとめたもので、開発者は通常「Pokyディストリビューションを基礎に、meta-xxxを追加する」形式で開発を開始する。


4.3 Yoctoのアーキテクチャ

Yoctoでは、メタレイヤを組み合わせることで構造化されたディストリビューションを構築する。

メタレイヤ構造

core層

OE-Coreを含む最小システム構築用のレシピ。

bsp層

特定のハードウェア(ARM, x86, RISC-V, SoCベンダー固有)のサポート。 例:meta-raspberrypi, meta-intel, meta-ti.

distro層

標準のpokyを拡張するディストリビューション(独自ポリシーやPackage管理方式)。 例:poky, openembedded, Ångström。

application層

アプリケーション・ミドルウェア固有の構成。 例:meta-qt5, meta-ros, meta-multimedia。


4.4 ビルドプロセス

Yoctoのビルドステップの基本構造は以下の通り。

ビルドセットアップ

$ git clone git://git.yoctoproject.org/poky
$ cd poky
$ source oe-init-build-env

コンフィギュレーション

conf/local.conf

  • MACHINE
  • DL_DIR
  • SSTATE_DIR
  • パッケージ形式(rpm/ipk/deb)

conf/bblayers.conf

  • 追加メタレイヤの指定

ビルドの実行

bitbake core-image-minimal

生成物

  • rootfs
  • kernel
  • device tree
  • toolchain(SDK)

4.5 Pokyを使うメリット

一貫したビルド環境

再現性が高く、CI/CDなどで完全に同一環境を保証できる。

クロスコンパイル環境の自動生成

SDKやext-sdkを自動生成可能。

高度なカスタマイズ性

ユーザ空間からカーネル、ブートローダまで統合構築。

商用サポートエコシステム

Wind River、Siemensなどが商用Yocto対応を提供。


4.6 Yoctoと他の組込みLinuxとの比較

Buildrootとの比較

Yocto

  • 再現性・拡張性・レイヤ構造が強力
  • ビルドは時間がかかる
  • 企業規模の製品開発向け

Buildroot

  • 単一構成で軽量・高速
  • 再現性やレイヤリングは限定的
  • 小規模プロジェクト向け

Vendor BSPとの比較

Yoctoは複数ベンダーのBSPを統合でき、長期保守にも適する。


4.7 Yocto学習のポイント

レシピ(.bb, .bbappend)

BitBakeでビルドされる単位。 例:パッケージビルド方法、fetch方法、パッチ適用など。

bbclass(クラス)

共通ロジックを抽象化する仕組み。 例:autotools.bbclass、cmake.bbclass。

変数スコープ

BitBakeの変数はPython風だが独自ロジックを持つ。 例:

  • DEPENDS(ビルド依存)
  • RDEPENDS(ランタイム依存)
  • FILESEXTRAPATHS
  • IMAGE_INSTALL

必要であれば、以下も続けて作成できます。

  • 学習ロードマップ(基礎→応用→製品開発)
  • Pokyのディレクトリ構造詳細
  • meta-layerの作成手順
  • core-image-minimalを拡張する実例

ご希望はありますか。