Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CEDEC 2020

CEDEC 2020

CEDEC 2020 クラウド時代の組み込みLinuxエンターテインメント製品開発
http://cedec.cesa.or.jp/2020/session/detail/s5e83b4820c017

YAEGASHI Takeshi

September 03, 2020
Tweet

More Decks by YAEGASHI Takeshi

Other Decks in Technology

Transcript

  1. 自己紹介 八重樫 剛史 Takeshi Yaegashi ▪ 株式会社バンダイナムコスタジオ 技術スタジオ ネットワークシステム部 ▪

    Linux・Unix・OSS・Go言語が好きなエンジニア ▪ 組み込みシステム開発、ゲームサーバ開発、CI/CD インフラ開発、 開発環境のクラウドシフトなどの業務に従事 ▪ 主なアウトプット先 GitHub https://github.com/yaegashi GitLab https://gitlab.com/yaegashi Qiita https://qiita.com/yaegashi DEV https://dev.to/yaegashi Twitter https://twitter.com/hogegashi
  2. 今日の話題 ▪ 次のトピックについて話します − 組み込み Linux の製品開発 − 組み込み Linux

    リファレンスプロジェクトの紹介 − 組み込み Linux のアプリ開発 − 組み込み Linux のシステム技術 − 組み込み Linux のビルドと CI/CD ▪ 今回は次の話はしません − ハードウェアの設計・開発 − オープンソースライセンス − セキュリティ、改ざん防止、コンテンツ保護
  3. 組み込みLinuxの普及 ▪ 2000年代以降、携帯電話などのデジタルガジェットを中 心にLinuxが採用される ▪ 2008年、Androidスマートフォンが登場、高性能・安価な SoC (System on Chip)マイコンが多数市場投入される

    ▪ 2013年、教育用の安価なシングルボードコンピュータ Raspberry Piが登場、PC並みの性能を備えLinuxのデスクト ップOSが動作する ▪ メイカームーブメントや IoT の流行に乗って Raspbery Pi は 広く受け入れられ、組み込みLinuxは商用製品からホビー プロジェクトまで開発者の裾野が広がった
  4. Raspberry Piの産業応用・製品採用 ▪ Raspberry Piは普及とともに産業応用・製品採用が進み、 ソニーなどの国内メーカーも生産されるようになった ▪ Raspberry Piの採用事例 −

    業務用アミューズメント機器 − エレメカ製品、プライズ製品のビデオ・オーディオ制御 − 売上計数 IoT システムのクライアント端末 − デジタルサイネージ、キオスク端末 − エッジAI・クラウドAI端末 − Wi-Fi AP、ルータ、サーバ機器
  5. ビデオゲーム玩具製品の例 ▪ 2016年発売の「ニンテンドークラシックミニ ファミ リーコンピュータ」は組み込みLinux製品の一例 ▪ 次のOSSコンポーネントを使用 − ブートローダ u-boot

    − カーネル Linux 3.4 − ユーザーランド glibc, SDL2 ほか − Android ではない GNU/Linux の組み込みシステム 引用:https://www.nintendo.co.jp/support/oss/
  6. GNU/Linux と Android の比較 ▪ 本講演では「GNU/Linux」は「非Android」という意味合いで使っている ▪ 両者でライセンス、得意分野、開発環境、開発者人口、入手性が大きく異なる 項目 GNU/Linux

    Android カーネル Linux (GPL2) Linux (GPL2) ユーザーランドコンポーネント GNU libc, Bash, etc. (copyleft) Bionic libc, Toybox (non-copyleft) ネイティブGUIアプリ △ ◎ Webフロントエンドアプリ ◦ ◦ ゲームエンジンのサポート △ ◎ スクリプト言語によるアプリ ◎ △ ハード制御・システム操作・サーバアプリ ◎ △ アプリ開発者数 △ ◦ システム開発環境の入手性とカスタマイズ ◦ △
  7. 組み込みLinuxの製品を作るには ▪ Raspberry Pi OSなどのLinuxデスクトップ環境で動くソフトウェア はそのままでは組み込みLinux製品にできない ▪ ランタイムの対応 − 電源断対策・ファイルシステム保護

    − コピー・改ざん対策 − アップデートシステム ▪ 開発・テスト・量産の対応 − 開発言語・ライブラリ・SDK対応 − 自動ビルド・CI/CDインフラ構築 − デバッグ・量産・検査設計
  8. embl0w プロジェクトの紹介 ▪ クラウド時代の組み込みLinuxの参考実装を示す目的で作った個人プロジェクト ▪ 現時点で 2 つのマイコンボードに対応 − Raspberry

    Pi 4 Model B https://github.com/embl0w/embl0w-rpi − NVIDIA Jetson Nano https://github.com/embl0w/embl0w-l4t ▪ GitHub ActionsでSDカードイメージのビルドができる − タグを作るとビルドが始まり、リリースにイメージが登録される − 所要時間 15 分程度 (GitHub Actions無料枠2000分/月)
  9. miraikomachi SDカードイメージの説明 ▪ 組み込みLinuxのエンターテインメント製品の構築デモとして作成 ▪ 「ミライ小町Unityプロジェクト」を内蔵 https://github.com/Miraikomachi/MiraikomachiUnity − 簡単なカメラ操作 UI

    を追加して WebGL プレイヤーを出力している − 電源を入れるとChromium Webブラウザが自動的に起動し再生開始する ▪ パフォーマンス − NVIDIA Jetson Nano では十分な性能 フルHD 60fps (動画の内容) − Raspberry Pi 4 Model B では残念ながら性能不足で実用にはならない − OS・アプリ全部入りで300MB〜400MB程度
  10. 組み込みLinuxのエンターテインメント製品開発 ▪ Linuxによるエンタメ製品開発には多大な労力とノウハウが必要 − グラフィックス・GUIや低レベルなシステムプログラミングが難しい ▪ Androidとゲームエンジンの活用 − CG・GUI主体の製品ではAndroidとゲームエンジン (Unity,

    Unreal など) の組み合わせが手堅い − Androidアプリ向けの開発環境が整っており、開発者の数も多い − ただしAndroidが使えるプラットフォームは限られる (Raspberry Pi や Jetson では使えない) ▪ Web技術の活用 − HTML5, WebGL, Web Assembly, Electron など周辺技術の進歩が著しい − オープンソース Chromium ブラウザがキーコンポーネント − 一般的な GNU/Linux システムで使える (Raspberry Pi や Jetson でも実用) − WebGL で Unity Player も動作する (embl0w デモ)
  11. 組み込みLinuxのIoT製品開発 ▪ Go言語の活用 − Google 製の C ライクでシンプルな文法のプログラミング言語 (2009) −

    IoT、ネットクライント、サーバ、システム制御の開発に幅広く対応可能 − 組み込みLinuxシステムの開発に適した特徴 − 並行処理サポート (goroutine, chan)、豊富なライブラリ − クロスビルド対応、シングルバイナリ − 統合開発環境 (Visual Studio Code + Gopls + Remote development) ▪ ハード制御の注意点 − リアルタイム要件のあるハード制御は Linux だけでは苦しい − 外付け回路・マイコンの補助を検討する − Raspberry Pi GPIO 制御では GPU DMA を活用した pigpiod も利用できる
  12. 組み込みLinuxアプリ開発環境の進化 ▪ Visual Studio Code − Windows, macOS, Linuxで動く開発者向けエディタ −

    Remote Development 拡張によりターゲットボードに SSHで接続しリモートファイルを自由に編集できる − 高機能なシェルコンソールを内蔵 ▪ Docker − macOSやWindowsでLinuxの実行環境が構築できる − QEMU ユーザーモード(後述)によりARMのLinuxコン テナも実行できる ▪ Windows Subsystem for Linux (WSL) − Windows PCでLinux開発環境を簡単に構築できる
  13. 組み込みLinuxファイルシステムの保護 ▪ ファイルシステム保護の基本:RO/RWマウントの使い分け − システム、コンテンツのファイルシステム → 常に読み込み専用 (RO) でマウント −

    データ保存のファイルシステム → 必要時だけ書き込み可能 (RW) でマウント (remount) − 重要なデータはファイルシステムを 2 系統用意し交互に RW マウントして書き込む ▪ 特殊な Linux ファイルシステムの活用 − tmpfs RAMにファイルを格納し、電源を切ると消える (/tmp など) − squashfs 個々のファイルを圧縮格納しつつ、直接 RO マウントできる − overlayfs 複数のファイルシステムを重ね、同じマウントポイントにマウントできる − マウントポイントに対する書き込みは、最上層の RW ファイルシステムに反映される − Docker などのコンテナで多用されている
  14. 電源断障害に耐えるパーティション構成例 MicroSD (MBR) 1: System (FAT32) RO - (Boot loader

    files) - kernel7.img - initramfs.gz - appfs.squashfs - rootfs.squashfs overlayfs (RW) 1: Volatile tmpfs (RW) 2: App/content squashfs (RO) 3: System squashfs (RO) Linux filesystem / (overlayfs) |- /bin |- /usr |- /var |- /proc (procfs) |- /sys (sysfs) |- /dev (tmpfs) |- /tmp (tmpfs) ループデバイスROマウント overlayfs への書込はすべて tmpfs に記録 overlayfs 構成のセットアップはカー ネル起動後最初に読み込まれる initramfs.gz の中のシェルスクリプト (busybox) が行う
  15. 安全なデータ更新ができるパーティション構成例 MicroSD (MBR) 1: System (FAT32) RO - (Boot loader

    files) - kernel7.img - initramfs.gz - appfs.squashfs - rootfs.squashfs 2: Data A (ext4) RO↔RW - (User data files) 3: Data B (ext4) RO↔RW - (User data files) Linux filesystem / (overlayfs) |- /bin |- /usr |- /var |- /proc (procfs) |- /sys (sysfs) |- /dev (tmpfs) |- /tmp (tmpfs) |- /data |- /a (ext4) |- /b (ext4) overlayfs (RW) 1: Volatile tmpfs (RW) 2: App/content squashfs (RO) 3: System squashfs (RO) 書き込むときだけ RW マウントする 2つのパーティションを用意して 交互に書き込む
  16. オンラインアップデート対応パーティション構成例 ▪ パーティション構成: Boot×1 System×2 − Bootは実行・更新Systemを選んで再起動 − 実行Systemはファイルシステムにマウント されてOS・アプリを実行する

    − 更新Systemはオンラインアップデートがダ ウンロードされる ▪ アップデート実行手順 − オンラインアップデートのダウンロードが 完了したら、実行・更新Systemの役割を入 れ替えて起動する − 起動に失敗して再起動した場合はBootが自 動的に元の役割に戻す (ロールバック) MicroSD (MBR) 1: Boot (FAT32) RO - (Boot loader files) - kernel7.img - initramfs.gz 2: System A (FAT32) RO - (Boot loader files) - kernel7.img - initramfs.gz - appfs.squashfs - rootfs.squashfs 3: System B (FAT32) RW - (System A と同じ) 4: Data A (ext4) RO↔RW 5: Data B (ext4) RO↔RW Linux filesystem ブート CAS CDN マウント・実行 更新ダウンロード
  17. Content-Addressable Storage (CAS) の活用 ▪ Content-Addressable Storage とは? − 格納するオブジェクトの内容をキーとして参照するストレージ

    − 通常はオブジェクトの内容の適当なハッシュ値をキーとする − ハッシュ値をファイル名とすることで、一般のファイルシステムに簡単に実装できる − 重複排除、転送効率化、変更履歴保全などに有用 ▪ 用途 − 分散バージョン管理システム (Git) − オンラインアップデート配信 (casync)
  18. casync – Content-Addressable Data Synchronizer ▪ casync - https://github.com/systemd/casync −

    Lennart Poettering (systemd の作者) による OSS − ライセンス LGPL-2.1 (glibc と同じ) − Linux ディストリビューションのインターネット での配布に適した CAS の実装 − ブロックデバイスやディレクトリツリーの CAS 格納・インデックス生成・復元の機能を備える − 復元時は HTTP での CAS アクセスが可能 引用: http://0pointer.net/blog/casync-a-tool-for-distributing-file-system-images.html
  19. casync の CAS による効率的なアップデート配信 ▪ 送信側 − ディレクトリツリー内の全ファイルを連結してひとつの配信ファイルを作る − 配信ファイルを一定サイズのブロックに分解し、個別に圧縮したチャンクとする

    − チャンクはそのハッシュ値をキーとする共有 CAS に格納する − 配信ファイル・ディレクトリツリー復元に必要なチャンクのインデックスを生成する ▪ 受信側 − インデックスを取得し、共有 CAS から必要なチャンクを受信して復元する − 一度受信したチャンクは保持しておき、自分が持っていないチャンクのみ受信する ▪ 共有 CAS − AWS S3 などのオブジェクトストレージに配置する − CDN やプロキシなど階層型 Web コンテンツキャッシュインフラが活用できる
  20. ビルドおよびアップデートのシステム CAS CDN Build casync make Upload Duplicate Install 1:

    System (FAT32) RO - (Boot loader files) - kernel7.img - initramfs.gz - appfs.squashfs - rootfs.squashfs CAS chunks System image casync extract Local cache Source repository
  21. 組み込みLinuxのビルドシステム ▪ 各種リポジトリからコンポーネントを集め、ソースコード をコンパイルし、ストレージに格納するファイルやディス クイメージを作る ▪ Raspberry Pi のシステムの例 −

    ブートローダーファイル − Linuxカーネル − initramfsイメージ (cpio+gzip) − ユーザーランド (squashfs イメージ) − システム − アプリケーション MicroSD (MBR) 1: System (FAT32) RO - (Boot loader files) - kernel7.img - initramfs.gz - appfs.squashfs - rootfs.squashfs Build
  22. Raspberry Pi向けコンポーネントの入手先 ▪ 必要なものはほぼすべてインターネットで公開されている URL 説明 https://github.com/raspberrypi/linux Linux カーネルのソースコードの Git

    リポジトリ カスタムカーネルをビルドするのでなければ不要 https://github.com/raspberrypi/firmware Raspberry Pi のブートローダ、Dispmanxライブラリ、 コンパイル済みカーネルイメージを収めた Git リポジトリ https://archive.raspbian.org/raspbian/ Raspberry Pi OS (Raspbian) のパッケージリポジトリ https://archive.raspberrypi.org/debian/ Raspberry Pi 向け追加ソフトウェアの deb パッケージリポジトリ http://ftp.debian.org/debian/ Debian の deb パッケージリポジトリ (armhf/arm64) http://ports.ubuntu.com/ubuntu-ports/ Ubuntu の deb パッケージリポジトリ (armhf/arm64)
  23. embl0w-rpi ビルドワークフロー userland archive kernel modules kernel image firmware bootloader

    20-debootstrap app build app archive 10-firmware 50-boot bootfs archive 60-image disk image 30-root rootfs archive 40-app appfs archive raspberrypi /firmware Raspbian repository your application bootable storage
  24. 組み込みLinuxシステムのビルドの課題 ▪ 実機 (Raspberry Pi) がとても遅いためセルフビルドは時間がかかる − ARM マイコンは CPU

    が遅い、ストレージ (MicroSD) や I/O も絶望的に遅い ▪ もっと高速なマシンでクロスビルドしたい − 強力な x86_64 CPU を搭載しストレージも高速なサーバでビルドしたい − 最近は ARM64 CPU を搭載するサーバもあるので試したい ▪ クラウドサービスで CI/CD を構築したい − クラウドが利用できれば TCO 削減や可用性、コスト伸縮性の点で大きなメリットがある − CI/CD サービスの無料枠を活用すればコストをほぼゼロにできるし、 逆にコストを度外視した高速化も容易に試すことができる
  25. エミュレーション技術の活用 ▪ QEMU: オープンソースのエミュレータソフトウェア − 高速なx86_64サーバでARMマイコンの実行ファイルが動かせる − 2 種類のエミュレーション動作が可能 ▪

    完全システムエミュレーション − ターゲットの CPU と仮想化ハードウェアのエミュレーションを提供し、 ターゲットシステムの OS がホストシステム上でブートできるようにする − ストレージや I/O のオーバーヘッドが大きく、ゲストOSとのファイル交換も不便 ▪ ユーザーモードエミュレーション − ターゲットの CPU と OS システムコールのエミュレーションを提供する − ターゲットシステムの実行ファイルをホストシステム上で透過的に実行可能 (binfmt_misc) − ホストシステムのファイルをターゲットシステムから直接アクセス可能
  26. Build ARM executable with Go ▪ x86_64 ホストで ARM の実行ファイルをクロスビルドする

    (Go言語を使用) $ cat >hello.go package main import "fmt" func main() { fmt.Println("hello, world") } $ sudo apt install golang $ GOARCH=arm go build hello.go $ file hello hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=r25mtH3xAmMqsN82YvTf/76iAXGVuGm9vmj6JX2uK/wp_gTuNYGed7ykVck7Ur/mSyuD7KUTU2imdNgD NtQ, not stripped $ ./hello -bash: ./hello: cannot execute binary file: Exec format error GOARCH=arm 指定で ARMバイナリをビルド x86_64 ホストでは ARM バイナリは実行できない
  27. qemu-user-static & binfmt_misc ▪ x86_64 ホストで ARM の実行ファイルを透過的に実行する $ sudo

    apt install qemu-user-static $ qemu-arm-static hello hello, world $ sudo apt install binfmt-support $ ./hello hello, world $ cat /proc/sys/fs/binfmt_misc/qemu-arm enabled interpreter /usr/bin/qemu-arm-static flags: OCF offset 0 magic 7f454c4601010100000000000000000002002800 mask ffffffffffffff00fffffffffffffffffeffffff qemu-arm-static で ARM バイナリ実行 binfmt_misc により x86_64 ホスト上で ARM バイナリを直接実行 binfmt_misc 特定のビット列 (magic) を 検出したら interpreter を起動するカーネルの機能
  28. qemu-debootstrap ▪ x86_64 ホストで ARM の Debian buster をブートストラップする $

    sudo apt install debootstrap $ sudo qemu-debootstrap --arch=armhf --variant=buildd buster armroot $ sudo chroot armroot # uname -m arm7l # ls bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp u sr var # cat >hello.c #include <stdio.h> int main() { printf("hello, world¥n"); return 0; } # gcc hello.c # ./a.out hello, world x86_64 ホストで chroot で Debian ARM 32-bit 環境に入る qemu-debootstrap qemu-user-static を使って ホストとは異なるアーキテクチャの Debian ファイルシステムを作る armhf = Debian ARM 32-bit
  29. embl0w-rpi ビルド CI/CD ▪ embl0w-rpi の CI/CD には次の条件を満たすビルド環境が前提となる − Debian

    ベースの Linux システム (コンテナでも可) − binfmt_misc が使える (異種アーキテクチャ実行ファイルの透過実行) ▪ 様々な選択肢を実際に試しパフォーマンスやコストを比較してみた − 実機 vs サーバ − オンプレミス vs クラウド − x86_64 vs ARM64 − IaaS (VM) vs SaaS (CI/CD サービス)
  30. embl0w-rpi ビルドベンチマーク ▪ embl0w-rpi の make build の総所要時間 (real) を比較する

    ▪ mksquashfs (圧縮ファイルシステム生成) の所要時間も別途記録する ▪ deb パッケージは同じホストで稼働する apt-cacher-ng 経由で取得する ▪ 何度か実行して総所要時間が最も短いものを代表値とする
  31. ビルド環境調査 (オンプレミス / クラウドVM) オンプレミス Raspberry Pi 3B オンプレミス Raspberry

    Pi 4B オンプレミス 自作PC クラウド Azure F2s_v2 クラウド AWS c6g.large 総所要時間 mksquashfs 27m38.095s 2m50.81s 14m27.295s 1m12.99s 8m55.874s 11.32s 8m34.881s 48.65s 5m24.315s 57.50s OS Raspbian 10 armhf Raspbian 10 armhf Ubuntu 20.04 amd64 Ubuntu 18.04 amd64 Ubuntu 18.04 arm64 CPU Cortex-A53 1.2GHz Cortex-A72 1.5GHz Core i7-6700 3.4GHz Xeon Platinum 8168 2.7GHz Graviton2 論理コア数/メモリ 4 / 1GB 4 / 4GB 8 / 32GB 2 / 4GB 2 / 4GB ストレージ 32GB MicroSD 32GB MicroSD 500GB SATA SSD 30GB Premium SSD 16GB Local SSD 30GB gp2 SSD コスト 約10,000円 約12,000円 約100,000円 9,428円 / mon 7,402円 / mon 2020/07/25 時点の実績
  32. ビルド環境調査 (オンプレミス / クラウドVM) ▪ Raspberry Pi 実機はやはり遅い。特にストレージ (MicroSD) の遅さが大きく影響して

    いると思われる。 ▪ ARM64 アーキテクチャの AWS c6g.large インスタンスが予想以上に速い。 x86_64 の インスタンスに比べてコストが低く ARM システム向けの CI ランナーとして有望。
  33. ビルド環境調査 (CI/CD サービス) GitLab CI GitHub Actions Azure Pipelines AWS

    CodeBuild GCP Cloud Build 総所要時間 mksquashfs 14m2.019s 1m42.63s 9m29.951s 49.04s 11m6.074s 50.65s 10m41.740s 22.56s N/A スペック GCP n1-standard-1 Azure DS2_v2 Azure DS2_v2 AWS a1.2xlarge GCP n1-standard-1 論理コア数/メモリ 1 / 4GB 2 / 7GB 2 / 7GB 8 / 16GB 1 / 4GB コンテナ Y N N Y Y binfmt_misc Y Y Y N N loop device N Y Y Y Y self hosted Y Y Y N N コスト $8 / 1000min $0.008 / min 4480円 / mon $0.02 / min $0.003 / min 無料枠 2000min / mon 2000min / mon 1800min / mon N/A 120min / day 2020/10/01 より 400min/mon 2020/07/25 時点の実績
  34. ビルド環境調査 (CI/CD サービス) ▪ GitLab CI: 無料ランナー GCP n1-standard-1 が非力なため時間がかかる。

    AWS ARM64 イ ンスタンスのランナーと組み合わて使いたい。 ▪ GitHub Actions: いちばん速い。無料 CI サービスの中では第一候補。 ▪ Azure Pipelines: ランナーのスペックは GitHub Actions と同じはずだがなぜか遅い。課 金体系が他サービスと異なる。 ▪ AWS CodeBuild: 唯一の ARM64 ランナーによる CI サービス。第一世代 Graviton のため かあまり速くない。また無料枠対象ではない。 ▪ GCP Cloud Build: binfmt_misc が使えずジョブを完遂できなかった。対処法があるかも しれない。
  35. embl0wプロジェクトのこれから ▪ 完成度の向上 − 売り物になるレベルまで作り込み? ▪ イメージサイズの削減 − せめて半分くらいに減らしたい −

    Buildroot や Yocto Linux のような路線には行かない予定 ▪ Chromiumブラウザの最適化 − Web技術のコアコンポーネントとしてパフォーマンス改善に取り組んでいる − Raspberry Pi 4 で Ozone + GBM で動かす試み (X11やWaylandを使わない) − ChromiumOSの設計や技術を参考にする (Androidアプリも動けば夢が広がる)