ArkEdge Space Blog

株式会社アークエッジ・スペースの技術要素多めのブログ

GitHub ActionsでRaspberry Piのイメージを焼けるようにした

こんにちは。アークエッジ・スペースでソフトウェアエンジニアをしている岩佐です。

私は主に人工衛星の試験システム開発を担当しています。ここでは、そこで使うRaspberry Pi(以下、ラズパイ)の設定をGitHub Actionsをつかって効率化した話をご紹介します!

衛星試験システムって何するの??

衛星試験システムは試験計画に従ったコマンドの送信・テレメトリの確認といった一連の試験手順、および試験の後解析作業を効率的に行うために開発されました。

そもそも、人工衛星の試験はハードウェアの耐久性を測るような試験からソフトウェアの挙動試験まで実に多岐にわたります。衛星試験の中で,衛星試験システムは衛星から流れてくるデータ(テレメトリ)、衛星に送るデータ(コマンド)をハンドリングする機能を提供しています。また、試験後に検証と改善を行えるようにログを提供する役割も果たします。

実際の試験は、試験担当者が衛星試験システムを介してコマンドを衛星に送信し、送信前と後のテレメトリを比較して衛星が所望の動作をしているか確認するという流れで行います。その後、必要があればログを参照し次回以降の試験にフィードバックをしていくことになります。

衛星試験システムにおけるラズパイの使い所

衛星試験システムの大部分はAWS上に構築されており、衛星へのコマンドの送信とテレメトリの受信などの操作はWebUIから行います。ラズパイの用途としては主に2つあります。1つ目はAWS上の試験システムと人工衛星を接続するためにラズパイをUSBで接続し使用しています。2つ目は衛星搭載ソフトウェアをラズパイ上で動かすことで、試験システムの動作検証のための衛星模擬実機としてもラズパイを使用します。 それぞれのラズパイにはVPNソフトとしてwireguardがインストールしてあるので、手元のPCからsshが可能です。こうしてラズパイのトラブルシュートしたりメンテナンスをしていきます。

衛星試験システムにおけるラズパイの使い所の概略図

ラズパイの設定がめんどくさい!!!

ラズパイを愚直に設定しようとすると結構手間がかかります。一歩ずつ列挙すると以下のようになります。

  1. ベースイメージをダウンロードし、SDカードに焼きこむ
  2. 起動後、HDMI経由でモニタにラズパイのターミナルを表示して、IPアドレスを調べる
  3. 手元のPCから取得したIP向けにsshする
  4. vimやwireguardエージェントなど各種パッケージのインストール
  5. wireguardの設定を手元のPCからコピペして適用 & 永続化
  6. ラズパイの用途に合わせてソフトウェアの起動など

上記のような設定も一台だけなら特に問題ありませんが、複数台となってくると色々不都合が発生します。パッケージインストールの漏れが発生してその後の作業の手戻りの原因になったり、wireguardの設定など各ラズパイごとのパラメータセットを間違えたりなどです。また、設定の内容と手順が正確に記録として残らないのでスケーラビリティにも欠け、故障した場合の復旧も難しくなります。

たとえ作業内容を正確に手順書にしたとしても毎回ほぼ同じ操作を人間が行うのは効率という観点からも正確性という観点からもできるだけ避けたいです。実際、私は手順をメモしてそれをもとに久々に設定をしてみましたが、かなり神経を使う上に操作ミスも発生して1時間以上かかってしまいました。

衛星開発の活発化に伴って複数台のラズパイが必要になっていたにも関わらず、すでに管理が不可能になってました。この記事を書いている時点で、衛星模擬用のラズパイが2台 + 仲介用ラズパイ2台の計4台が必要になっています。新しいラズパイが必要になる頻度は衛星試験体制の変更などに依存するため不確定です。設定方法を忘れた頃に作業を依頼されることもあります。また、SDカードが論理障害を起こすこともありその時はラズパイ固有のパラメータを頑張ってメモなどから発掘して再設定しなければなりません。

加えて、詳細な映像試験記録の保存などさまざまな用途でさらに試験システムに使うラズパイが増えることが今後予想されています。

このような背景から、手順②~⑤を自動化しつつパラメータセットも各ラズパイごとに保存できるような仕組みを考える必要がありました。それができればさらに衛星開発が活発化しても必要なラズパイを迅速に準備できますし、故障が発生してもすぐに復旧することが可能になります。

自動化できないかしら??

この手の定形作業は自動化したくなります。cloud-init(OSの初期設定をカスタマイズできる機能)の設定が完了したイメージをCIをつかって作成し、ddコマンドでSDカードに焼くだけにできたらとても楽そうです。ラズパイの初回起動時に勝手にwireguardにも繋がって必要なパッケージインストールも自動で終わったらとってもいいですよね。作業者に依存することなく設定が完了するのもとても大切です。

アークエッジ・スペースの社内ではタスクの自動化にGitHub Actionsが広く使われているためGitHub Actionsでの自動化を考えます。今回はworkflow_dispatchをCIの実行トリガーとして使います。

ここで、GitHub Actionsで自動化するにあたり考えなければいけないことは、ラズパイごとに異なるパラメータをどうイメージへ注入するかです。イメージをカスタマイズする際には性質のことなる複数種類のパラメータが必要なので、それぞれについて扱い方を変えなければなりません。例えば、オフィスのWiFi情報など滅多に変更されないが秘匿すべき情報はRepository Secretsから取得すればいいでしょう。hostnameといったラズパイごとに変更されるが秘匿する必要のない情報はworkflowinputを使用すれば良さそうです。

一方、秘匿情報である上ラズパイごとに異なるパラメータはGitHub ActionsのinputSecretsを使うことができません。今回のケースで言うと、wireguardの設定がこれに該当します。どうにかしてこのパラメータを外部から注入する必要があるので工夫します。

CIでイメージ作成の大方針

GitHub Actionsでイメージを作成する際の全体方針は以下図のようになります。

GitHub Actions で実現するラズパイイメージ作成のワークフロー概要図

ラズパイ毎のwireguardの設定はAWSParameter Storeに保存しておけばGitHub Actions上から安全に取得して使用することができます。このとき、内容をecho "::add-mask::"を使ってマスクしないと取得内容がログに残る可能性があるので注意が必要です。

また、cloud-initに必要な設定ファイルの生成はerbを使用しました。

workflow全体像

全体の流れはできたので、あとはworkflowを書いていくだけです。結果は以下のようになります

name: Configure Raspberry Pi Image

on:
  workflow_dispatch:
    inputs:
      hostname:
        description: 'hostname of Raspberry Pi'
        required: true

~~~
jobs:
  setup_cloud_init:
    runs-on: ubuntu-latest
    env:
      HOSTNAME: ${{ github.event.inputs.hostname }}
      WIFI_SSID: ${{ secrets.WIFI_SSID }}
      WIFI_PASSWORD: ${{ secrets.WIFI_PASSWORD }}
    steps:
      - name: Fetch base image
        run: |
          aws s3 cp s3://base-image/ubuntu.img.xz ./ubuntu.img.xz

      - name: unxz base image
        run: |
          unxz ubuntu.img.xz

      - name: Mount base image
        run: |
          sudo mkdir -p /mnt/boot
          sudo mount -o loop,offset=1048576 ubuntu.img /mnt/boot/

      - name: Get wireguard content
        id: get-wg-content
        # HOSTNAMEをキーにしてwireguard設定を取得
        run: |
          WG_CONTENT=$(aws ssm get-parameter --name "/rp/$HOSTNAME/WG_CONTENT" --with-decryption --query 'Parameter.Value' --output text)

        # ~~~ user-dataやnetwork-configなどの設定ファイル生成&設置 ~~~

      - name: Unmount base image
        run: |
          sudo umount /mnt/boot

      - name: Compress image
        run: |
          xz -9 ubuntu.img

      - name: Push rp image to S3
        run: |
          aws s3 cp ubuntu.img.xz "s3://custom-images/$HOSTNAME.img.xz"

成果

このworkflowを使用して新たなラズパイのキッティングを行ったところ、人間の作業時間はSDカードへの書き込みのみで10分程度になりました。これまで一台の設定に1時間以上かかっていたことを考えると大幅な時間の節約です。これで今後衛星の開発体制が活性化し、数十機ほどの開発規模になってもラズパイの用意がボトルネックになることがなくなりました。また、万が一ラズパイが故障してもイメージがS3上に保存されているのですぐに次のラズパイを用意することが可能です。

おわりに

このようにアークエッジスペースではソフトウェアの力で衛星開発の効率化に取り組んでおります!まだまだ効率化の余地が沢山あり、やりがいに満ちている現場です!少しでも興味を持っていただければ下記のリンクから是非仲間になってください!!

株式会社アークエッジ・スペースは積極的な採用活動を行っています - ArkEdge Space