Slide 1

Slide 1 text

© DeNA Co., Ltd. 1 DeNA 全社向けに Beta 提供開始 した macOS GitHub Actions セルフホストランナー Tomoya Kawaguchi IT本部品質管理部SWET第一グループ 株式会社ディー・エヌ・エー

Slide 2

Slide 2 text

© DeNA Co., Ltd. 2 Tomoya Kawaguchi ・2024 年新卒 ・CI/CD 基盤(GHA, CircleCI, Bitrise)のお守り ・事業部の CI/CD 周りお手伝い ・最近は AI 系の dev tool 開発も IT本部品質管理部 SWET 第一グループ © DeNA Co., Ltd. 自己紹介 @yamoyamoto @yamoyamoto

Slide 3

Slide 3 text

© DeNA Co., Ltd. 3 目次 背景 全社向けの macOS ランナーに求められる要件と考慮事項 システム構成 1 2 3 しばらく運用してみて / 今後の展望 4

Slide 4

Slide 4 text

© DeNA Co., Ltd. 4 1. 背景

Slide 5

Slide 5 text

© DeNA Co., Ltd. 5 ● DeNA では現在、GitHub Enterprise Server (GHES) 環境がメイン ● GHES では GitHub-hosted runner が利用できない ○ runs-on: ubuntu-latest が使えない 1 DeNAのGitHub環境 自前のインフラ上で Job を実行するための仕組み Self-hosted runner を整備 → 全社的に GitHub Actions を利用できるようになっている

Slide 6

Slide 6 text

© DeNA Co., Ltd. 6 ● 自前のインフラ上で Job を実行するための仕組み ● GitHub の WebUI からコマンドを取得して 簡単に走らせてみることができる ● ランナーの実装は actions/runner で公開されている 1 Self-hosted runnerとは

Slide 7

Slide 7 text

© DeNA Co., Ltd. 7 ● これまで: Linux 上で稼働する Self-hosted runner を運用 ○ システム構成等はこちらのスライドで分かりやすく解説されている 1 DeNA の Self-hosted runner のこれまで

Slide 8

Slide 8 text

© DeNA Co., Ltd. 8 ● CI/CD Job では macOS を必要とするケースもある ○ 主に iOS/Mac アプリのビルド/テスト/署名など ● DeNA で macOS Job を利用するには ○ Bitrise が全社利用可能 ■ 多くの事業部はこちらを利用 ○ 各事業部にて独自に macOS の GitHub Actions self-hosted runner を用意 ■ プロジェクト性質的に気軽にクラウドサービスにデータを置くことが難し い、ランナーのパフォーマンス/カスタマイズ性といった理由で選択される 1 CI/CD Job で macOS を必要とするケース

Slide 9

Slide 9 text

© DeNA Co., Ltd. 9 ● Bitrise ○ 独自にビルドマシンを調達するよりは高額になることが多い ○ 専用の workflow 構文やエコシステムを利用するため独自に学習が必要 ● 各事業部での GitHub Actions self-hosted runner 運用 ○ 各事業部にランナーのメンテコストがかかる ○ それぞれ独自にマシン調達することによってコスト効率が悪化する可能性 ○ ランナー運用の知見も分散する 1 現状の課題

Slide 10

Slide 10 text

© DeNA Co., Ltd. 10 ● Bitrise ○ 独自にビルドマシンを調達するよりは高額になることが多い ○ 専用の workflow 構文やエコシステムを利用するため独自に学習が必要 ● 各事業部での GitHub Actions self-hosted runner 運用 ○ 各事業部にランナーのメンテコストがかかる ○ それぞれ独自にマシン調達することによってコスト効率が悪化する可能性 ○ ランナー運用の知見も分散する 1 現状の課題 macOSのGitHub Actions self-hosted runner を全社的に提供できればいいのでは??

Slide 11

Slide 11 text

© DeNA Co., Ltd. 11 ● 実際に動く前に、社内全体に向けてアンケートを取った ○ 10 近いプロダクト部門から回答あり ● もらった回答ピックアップ ○ 事業部門でのランナー運用 ■ メンテナンスコストが重い ■ 台数が限られていてキューが詰まりがち ○ Bitrise ■ GHESとの連携で躓きがち ■ workflow のyaml 構文が複雑 / yaml 分割もできない 1 アンケート結果

Slide 12

Slide 12 text

© DeNA Co., Ltd. 12 2. 求められる要件と考慮事項

Slide 13

Slide 13 text

© DeNA Co., Ltd. 13 ● Job が都度クリーンな環境で実行される ○ Job のアーティファクトなどが別の Job で見えてはいけない ○ macOS VM を想定 ● パフォーマンスが Bitrise と比較して著しく劣化しない ○ Bitrise も VM 環境で実行されている ● 料金が Bitrise よりも抑えられる見通しがある ○ → Bitrise からの移行量次第だが、将来的な見通しを立てた 2 全社向けの macOS ランナーに求められる要件と考慮事項

Slide 14

Slide 14 text

© DeNA Co., Ltd. 14 ● macOS 仮想化ツールに求めた要件 ○ VM イメージはできるかぎりコード化したい ○ プログラマブルに VM を取り扱える ■ VM の起動 / 停止 / 削除 / クローン / VM 内でのコマンド実行 ○ OSS の場合はライセンス懸念がないこと 2 macOS 仮想化について

Slide 15

Slide 15 text

© DeNA Co., Ltd. 15 ● Apple Silicon 上での macOS 仮想化 ○ Apple 標準の Virtualization Framework から利用可能 ● 世の中の macOS 仮想化ツールの多くは Virtualization Framework をラップしている ○ まずは手早く始めたかったため、ラップしたものを使うことに ● 選択肢 ○ OSS ■ UTM ■ Tart ○ 商用(SWET にて利用実績あり) ■ Parallels Desktop 2 macOS 仮想化について

Slide 16

Slide 16 text

© DeNA Co., Ltd. 16 ● macOS上で動くOSSの仮想化ツール ○ Linux / Windows / macOSのVMが動かせる ● utmctlというCLIでVMに対する一通りの操作が可能 2 UTM

Slide 17

Slide 17 text

© DeNA Co., Ltd. 17 ● Apple Silicon上のCI/CD用途に特化したOSSの仮想化ツール ○ Virtualization Frameworkを使用 ● tartというCLIでVMに対する一通りの操作が可能 ○ ビルドしたVMイメージはOCIイメージとして管理可能 ● cirruslabs/packer-builder-tartにてPacker pluginが提供されている ● ライセンスは Fair Source License(2025/10現在) ○ 組織で利用する場合、「組織全体の合計CPU数<100」の範囲では無料で利用可能 2 Tart

Slide 18

Slide 18 text

© DeNA Co., Ltd. 18 ● macOS上で動く商用の仮想化ツール ● prlctlというCLIでVMに対する一通りの操作が可能 ● Parallels/packer-plugin-parallelsにてPacker pluginが提供されている ○ → VMイメージのビルドをPackerで自動化可能(後述) ○ Parallels/packer-examples にて各OSバージョンごとの Boot Command例が提供されている ○ OCR機能も付属(後述) 2 Parallels

Slide 19

Slide 19 text

© DeNA Co., Ltd. 19 ● 結果: Parallels を使用することに ● 理由 ○ SWET にて利用実績あり ○ Packer Plugin を使ってVMイメージのビルド自動化が可能 ○ prlctl の機能で想定していたシステム構成を実現可能 2 macOS VMについて

Slide 20

Slide 20 text

© DeNA Co., Ltd. 20 ● Tart でも CLI / Packer Plugin が提供されている ● しかし Fair Source License はリスクがあったため見送り ○ DeNA は子会社も多数存在するため 「組織全体」を正しく追跡することは困難と判断 2 macOS VMについて

Slide 21

Slide 21 text

© DeNA Co., Ltd. 21 3. システム構成

Slide 22

Slide 22 text

© DeNA Co., Ltd. 22 1 システム構成

Slide 23

Slide 23 text

© DeNA Co., Ltd. 23 1 システム構成 DeNA の社内システムは AWS メインのため AWS で構成

Slide 24

Slide 24 text

© DeNA Co., Ltd. 24 1 システム構成 Mac マシンは社内で強く推 奨されている EC2 Mac を 採用 Mac インスタンス上の VM でランナーが稼働する ※ M2 Mac は ap-northeast-1 では利用不 可のため us-west-2 で利用

Slide 25

Slide 25 text

© DeNA Co., Ltd. 25 1 システム構成 Mac インスタンス上の VM を 管理する ECS Service EC2 Mac へ SSH し、VMの起動 や停止を行う ※ VM managerと呼んでいるが 詳細は後述

Slide 26

Slide 26 text

© DeNA Co., Ltd. 26 1 システム構成 DeNA の社内ネットワークへの ルートを集中管理している Transit Gateway への接続 ランナー<->社内システムとの通 信で考えると GHES が支配的 → VPC Peering で接続すること で TGW の料金を抑える

Slide 27

Slide 27 text

© DeNA Co., Ltd. 27 1 システム構成 ランナーは polling 型である ため inbound アクセス許可は 不要 → private subnet でも実現可 能だが、NAT Gateway の転送 料金が懸念 → public subnet に Mac イン スタンスを配置し、Internet Gateway 経由で通信させる

Slide 28

Slide 28 text

© DeNA Co., Ltd. 28 1 VM manager ● VM 操作は Mac マシン上で prlctl コマンドを実行することで行う ● ひとつの Mac マシン上で起動できる VM 数は「2」がハードリミット ○ それぞれの VM に割り当てる spec (CPU, Memory) にバリエーションを持たせる ○ → ビルドは強い VM で実行し、resign 等は低スペックの VM で実行して  リソース効率を高める

Slide 29

Slide 29 text

© DeNA Co., Ltd. 29 1 VM manager ● 仕組み a. GHES からランナーを登録するための token(JIT config) を払い出す b. Mac マシンに ssh し、VM 起動 c. VM 内でスクリプトを実行し、ランナーを起動 d. Job が終了したら VM を停止→削除し、また新しい VM を起動

Slide 30

Slide 30 text

© DeNA Co., Ltd. 30 1 VM manager

Slide 31

Slide 31 text

© DeNA Co., Ltd. 31 1 VM manager GHES からランナーを登録する ための token(JIT Config) を払い出しておく

Slide 32

Slide 32 text

© DeNA Co., Ltd. 32 1 VM manager VM manager から Mac マシンに SSH

Slide 33

Slide 33 text

© DeNA Co., Ltd. 33 1 VM manager Mac マシンに Base VM をstop 状態で用意 Base VM には ・actions/runner ・XCode など Job を動作させるために 必要な一式をインストール

Slide 34

Slide 34 text

© DeNA Co., Ltd. 34 1 VM manager 【prlctl clone】 Base VM を clone し、 実際にランナーが稼働する VM を作成 【prlctl set】 それぞれの runner VM に割り 当てる spec (CPU / Memory) を設定

Slide 35

Slide 35 text

© DeNA Co., Ltd. 35 1 VM manager 【prlctl start】 runner VM を起動

Slide 36

Slide 36 text

© DeNA Co., Ltd. 36 1 VM manager 【prlctl exec】 runner VM 内でランナーの起 動スクリプトを実行 この時点で GitHub Actions Job を実行可能な状態になる #!/bin/bash if [ -z "$exit_code" ]; then # 引数で JIT Config を流し込む ./run.sh "$@" fi sudo shutdown -h now スクリプトのイメージ

Slide 37

Slide 37 text

© DeNA Co., Ltd. 37 1 VM manager Job が終了すると、スクリプト 内で macOS シャットダウンを トリガー(VM 停止)

Slide 38

Slide 38 text

© DeNA Co., Ltd. 38 1 VM manager 【prlctl delete】 停止した runner VM を削除

Slide 39

Slide 39 text

© DeNA Co., Ltd. 39 1 VM manager 【prlctl clone】 Base VM から clone して runner VM を作成 〜以降繰り返し〜

Slide 40

Slide 40 text

© DeNA Co., Ltd. 40 1 VMイメージ ● Packer を利用してビルドの大部分をコード化 ○ Parallels Plugin(Parallels/packer-plugin-parallels)を利用 ○ VM にキーイベント(prlctl send-key-event)を送信し、画面操作を自動化 ● 自動化できていない部分 ○ XCode のインストール ■ Apple ID による認証が必要なため ○ XCode の初回 XProtectServiceトリガー ■ これをやらないと、Job で xcodebuild を実行するたびに 重たいスキャンが走ってしまう

Slide 41

Slide 41 text

© DeNA Co., Ltd. 41 1 VMイメージ ● Packer のコード例(Parallels/packer-examplesより抜粋) source "parallels-ipsw" "sequoia_15_3_plus" { # ...略... boot_screen_config { boot_command = [""] screen_name = "Empty" matching_strings = [] } boot_screen_config { boot_command = [""] screen_name = "Language" matching_strings = ["English", "Language", "Australia", "India"] } # ...略... }

Slide 42

Slide 42 text

© DeNA Co., Ltd. 42 1 VMイメージ

Slide 43

Slide 43 text

© DeNA Co., Ltd. 43 1 VMイメージ ● Packer のコード例(Parallels/packer-examplesより抜粋) source "parallels-ipsw" "sequoia_15_3_plus" { boot_screen_config { boot_command = [""] screen_name = "Empty" matching_strings = [] } boot_screen_config { boot_command = [""] screen_name = "Language" matching_strings = ["English", "Language", "Australia", "India"] } # 続く.... } 打ち込むキーを記述 ☆フルキーボードアクセスモード (Control + F7)も適宜活用

Slide 44

Slide 44 text

© DeNA Co., Ltd. 44 1 VMイメージ ● Packer のコード例(Parallels/packer-examplesより抜粋) source "parallels-ipsw" "sequoia_15_3_plus" { boot_screen_config { boot_command = [""] screen_name = "Empty" matching_strings = [] } boot_screen_config { boot_command = [""] screen_name = "Language" matching_strings = ["English", "Language", "Australia", "India"] } # 続く.... } 【OCR 機能】 →画面に表示されたテキストを 条件にして打ち込むキーを指定 できる

Slide 45

Slide 45 text

© DeNA Co., Ltd. 45 1 VMイメージ

Slide 46

Slide 46 text

© DeNA Co., Ltd. 46 4. しばらく運用してみて / 今後の展望

Slide 47

Slide 47 text

© DeNA Co., Ltd. 47 ● Bitrise より若干パフォーマンスが悪い ○ 事前に簡易的な Flutter アプリを用意してビルドしたが有意な差は見られなかった ○ だが、とある事業部の iOS アプリのビルド/テストにてパフォーマンス差が発覚 ● ビルド/テストの実行時間 ○ Bitrise: 約9m ○ GitHub Actions: 約10m30s 4 パフォーマンス

Slide 48

Slide 48 text

© DeNA Co., Ltd. 48 ● パフォーマンス調査 ○ アクティビティモニタを眺めた所、Disk IO の throughput 実効値に差分あり ■ それ以外に有意な差分は見当たらなかった ○ EC2 Mac にアタッチしている EBS のメトリクスを確認したが、Disk IO operation 関連のスロットリングは起こっていない ● → 原因: 物理 Mac 内臓の SSD(μ secオーダー) vs EBS(m secオーダー)のレイテンシ差? ○ Bitrise は「恐らく物理 Mac で稼働している」かつ「Virtualization Framefork を使っ ていると仮定」すると、VM のオーバーヘッドに大きな差分はないはず ○ 詳細はまだ調べられていない 4 パフォーマンス

Slide 49

Slide 49 text

© DeNA Co., Ltd. 49 ● actions/cache によるキャッシュ復元が遅い ○ ダウンロード速度が20MB/s程度しか出なかった ● 考えられる原因 ○ オハイオ(macOS ランナー) <-> 東京(GHES キャッシュストレージ)間の通信 ○ キャッシュストレージが Azure Blob Storage 以外で構成されている場合 マルチパートダウンロードが無効になる(該当箇所) ● 代替として runs-on/cache を試した所、ダウンロード速度が200MB/sまで改善 ○ runs-on/cache: 自前で用意した S3 Bucket をキャッシュストレージとする仕組み 4 パフォーマンス

Slide 50

Slide 50 text

© DeNA Co., Ltd. 50 ● Job内でキーチェーンを作成すると一部が権限不足で動作しない ○ GitHub公式の方法だとApple Rootへの信頼チェーンがうまく確立できない ● VMにVNCで接続し、ターミナルで同様の作業をするとうまくいく ○ → 原因は恐らくsshセッション経由でランナープロセスを起動していること ○ → Launch Agent経由でランナープロセスを実行しlaunchd配下にすればGUIセッ ションを持つようになるはず(未検証) 4 キーチェーン

Slide 51

Slide 51 text

© DeNA Co., Ltd. 51 ● 母艦 Mac マシンの再検討 ○ 現在は Beta 版としての提供なので社内推奨&メンテナンス性から EC2 Mac を採用 ○ しかし前述の通りパフォーマンス差がありそうなため検証から進めたい ● Unity サポート ○ ライセンスサーバーや Unity のプリインストールを整備 4 今後の展望

Slide 52

Slide 52 text

© DeNA Co., Ltd. 52 ● 大容量のキャッシュを高速に使える仕組みの検討 ○ 特に iOS アプリや Unity のビルドは大容量のキャッシュを必要とする 4 今後の展望

Slide 53

Slide 53 text

© DeNA Co., Ltd. 53 ● アイデア ○ VM manager で都度VMを破棄するのではなく、残す ■ 管理主体が同事業部に収まる org ごとに VM を保存し、そこから VM を都度 立ち上げる等、、? ● macOS は CoW な APFS を使っているため Disk 容量はある程度抑えら れそう ■ VM &ランナー起動するまでの待ち時間が増える(長くて 30s 程度)が、大容量 キャッシュ復元よりはマシと思われる ■ VM が大量に残ることによる Disk 圧迫は懸念 4 今後の展望

Slide 54

Slide 54 text

© DeNA Co., Ltd. 54