kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

SHOKZのOPENCOMM2を買った

リモートミーティング用にSHOKZの骨伝導ヘッドセットであるOPENCOMMを2年半ほど愛用していたが、先日ブームマイクを回転した際に「パキッ」という音とともにブームの根が折れてしまった。

x.com

いちおうまだつながってはいるのだが、そのうち完全に断線することが予想されるので、トラブルになる前にさっさと買い換える。とはいえ、耳への負担と可搬性を考えると骨伝導は必須なので、選択肢としては今のOPENCOMMシリーズが妥当と判断。OPENCOMM2 2025 Upgradedモデルを購入。

前代からは一見見た目や重さは変わらないが、細かいところで違いがある。

旧モデル
新モデル

  • 一番大きな違いは、マイクの位置。前代は左側だったのが、右側に変更された。長さは同じなので大きな違和感はない。隣でパートナーが別のミーティングの会話をしているときの混線にはちょっと変化はあるかもしれない。
  • 壊れる原因になったブームの回転はスムーズになった。前代のはガチガチでそれは持ち方によって折れもするだろうというものだったので、不安がだいぶ減った。
  • 独自のUSB-マグネットからUSB-Cの給電になった。グローバルスタンダードになったという利点はあるものの、マグネットで雑にパチッと充電できたのが、いちいちフタを開けて刺さないといけなくなったのはやや不便。USB-Cのアダプタだらけでタップが混雑しているため、USB-C給電タップがほしくなる。
  • マイクにミュートボタンが付いた。前代は回転でミュートだったので、オフィス移動時以外でも回転させることがたまにあったのだが、物理ボタンで済むのは安心…と思ったけどアプリケーションが対応している必要があるっぽい?
  • 2台接続は前代では宣伝されていなかったけど、今回は明確に打ち出されて、音声アナウンスでも「1つめのデバイスと接続しました」のように流れる。
  • ケースが少し小さくなった。もともとヘッドセット以外入れようのないデザインに対してふた回りくらい大きいなぁと感じていたので、持ち運びにありがたい。

幸い(?)本日に障害対応のミーティングがあって使ってみたのだが、マイク音質の変化は特段ないようだ。ヘッドフォン音声もクリア。今度は2年半より持ってほしいな。

『Fluent Python第2版』の制作でCIを構築していた話

編集制作プロダクションから転職してそろそろ3年になるが、しばらく前にオライリー・ジャパンさまよりRe:VIEW原稿の重厚な書籍『Flluent Python第2版』の制作への協力要請があり、組版と電子版の制作をしていた。

先週この出来本が届いた。圧巻の1.4kg。ヤバい。鈍器。

Pythonの入門を済ませたエンジニアが、「さらにもっと良い書き方、使い方があるのではないか?」というときに読む本。ハードな量ではあるものの、関心のあるところから読み拾っていくことで実力がついていくだろう。

ということで、制作中に構築したCIについて少し書いてみる。

自動ビルドの要件

版元のGitHubリポジトリ上にRe:VIEW原稿は揃っていて、版元のほうではすでに仮スタイルを当てた手元PDFビルドでおおまかな編集とプレビューは済んでいる状態。

ここから本格的に編集作業と本番紙面化を進めるにあたって、CIでのプレビューPDF作成が必須要件だった。

前職では大きめVPSにJenkinsを入れて済ませていたのだが、立場上離れているので自前で構築する必要がある。せっかくなのでクラウドサービスでどのくらいのコストでできるのかを試してみることにした。

CI構成にあたって要件を分解すると以下のとおり。

  • インフラコストを抑える
  • セキュアにする
  • できるだけ速く実行する

リポジトリの更新頻度はそう高くない。人間が編集してリポジトリにpushするというタイミングに依存し、競合の可能性もほぼ無視できるだろう。GitHub Actionsを使ってビルドを呼び出すようにし、仮に何か競合(たとえば前の実行が終わってない間に後からpushが入って一時ファイルや成果物が壊れるなど)があったとしてもActionをリトライすれば十分と割り切った。

成果物であるPDFおよびビルドレポートについての置き場所については少し悩む。

  • GitHubアーティファクト:プライベートリポジトリのメンバーだけが見えるという意味では最適。PDFサイズが大きくコストにつながる懸念があるのと、リリースまでやらないとアーティファクトへのアクセスが面倒。
  • S3での難読URL公開:URLをどうメンバーに伝えるかわかりにくい。何かの拍子に悪意を持った者にわたったときの異常アクセスが怖い。
  • VPSを使ったメンバー公開AWSのインフラとは異なるが、万が一異常アクセスとなってもVPS固定額の範囲になる。メンバー認証を行って成果物フォルダから取得できるようにする。

VPS保有していることもあって今回はVPSを採用した。

ECSで構築してみる

EC2というかIaaSであればなんとでもなることがわかっているので、さして新味がない。そこで、「コスト削減に効く」とよく言われるECS上に構築してみることにした。業務の検証以外ではちゃんとECSを使ったことがなかったので、やってみたかったというだけである。

ECSの設定を手でやっていると後々泣くことになる予感があるので、最初からTerraformを使いながら進めた。

ビルドとしては次のような流れになる。

  1. GitHubリポジトリでpushを受けたら、以下のActionsが実行される。
  2. リポジトリランチアーカイブを作成し、S3にアップロードする。
  3. ECSのタスクをaws ecs run-taskで呼び出す。このタスクではリポジトリのビルドコマンドが呼び出される。S3からブランチアーカイブのダウンロード、展開、Re:VIEW→PDFのビルド、成果物のS3アップロードが行われる。
  4. タスクが終了するまで待機する。終了コードを保存しておく。
  5. S3にアップロードされた成果物をrsyncVPSに送る。
  6. 保存していた終了コードを返す。

動作としてはうまくいった。しかし、しばらく運用してみて課題が見えてきた。

  • 想像していたことではあったが、Re:VIEW→PDFの中核であるTeX環境およびフォントでコンテナイメージサイズが巨大(4GB)で、プロビジョニングにかなりの時間を食ってしまう。このサイズだとLambdaでも同じ問題にぶつかる。更新頻度的には起動しっぱなしにするものでもない。
  • 全体に遅い。プロビジョニングも遅いし、ビルドも時間がかかる。TeXはシングルスレッドで分散処理できず、パワーで押し切るしかないからね……。
  • VPCエンドポイントが予想外に高い。もっと大規模に使っているならともかく、間欠的な利用ではECRとCloudWatch用に作っているインターフェイスの課金が全体の比率として大きくなりすぎる。パケットが流れなくても存在すれば課金、VPCインターフェイスを立てるプロビジョニング時間が長いの2点の性質が厳しい。

EC2で構築してみる

ということで、結局こうなるか…というところではあるがEC2で立てることにする。Jenkinsでもよかったかもしれないけど、せっかくECSでビルドコマンドまで作っていたので、SSMで呼び出す仕組みとしてみた。インスタンスはt4g.medium。再現性のためにTerraformも継続利用している。

ビルドとしてはECSよりもシンプルになり、以下のようになる。

  1. GitHubリポジトリでpushを受けたら、以下のActionsが実行される。
  2. EC2インスタンスの状態を確認し、休止中であれば起動する。
  3. SSMでEC2インスタンスにアクセスし、リポジトリのビルドコマンドを呼び出す。リポジトリブランチのcheckoutとpull、Re:VIEW→PDFのビルド、成果物のS3アップロードが行われる。
  4. ビルドが終了するまで待機する。終了コードを保存しておく。
  5. S3にアップロードされた成果物をrsyncVPSに送る。
  6. 保存していた終了コードを返す。

コスト抑制のためにビルドが終わったあとはEC2インスタンスを休止させたいが、制作作業をしているときは連続して何度もpushを行うのが普通だろう。起動はECSプロビジョニングよりは速いとはいえ時間がそれなりにかかるし、1つのインスタンスを使い回している都合上、起動や休止のプロセスとぶつかって何かまずいことも起きかねない。

マネージドにはEventBridgeなどを使う方法もあるようだが、インターネット老人としてビルドコマンドの冒頭に時限爆弾を仕掛けるようにした。

for job in $(atq | awk "{print \$1}"); do
  atrm $job
done
echo "sudo shutdown -h now" | at now + 30 minutes

まとめ

ビルド時間としてはだいたい以下のとおり。競合起因で再実行をしたのは2回程度だった。

  • ECS(目次索引なし版):9〜10分
  • EC2(目次索引なし版):起動なし 7〜8分、起動済み 4分
  • EC2(目次索引あり版):起動なし 9〜10分、起動済み 5〜6分

「インフラコストを抑える」「セキュアにする」「できるだけ速く実行する」の3点の観点では、手元PCでビルドよりは遅いものの、コスト的にはこのくらいだと嬉しいというところに収まった。EC2化したことでpublic subnetに置く必要は生じたが、ingressは無でSSMアクセスにしているのでセキュアに守れている。

クラウドネイティブからは遠いので、修行はまだ必要だ。

  • 最終的に劣化Jenkinsになったので、普通にCodeBuildを使うのでもよさそうだなと思った。TeX環境が4GBイメージでも、LARGEやXLARGEあたりのタイプで高速めに進められるのではないか。
  • ハッシュ値バージョンのGitHubリリースおよび過去のクリーンアップによるGitHubアーティファクト公開もGHAでやってみないとな。