コンテンツに移動
デベロッパー

Google がデスクトップ向け Linux リリースのロールアウトに至った経緯

2022年7月22日
https://storage.googleapis.com/gweb-cloudblog-publish/images/rodete-hero.max-800x800.png
Google Cloud Japan Team

※この投稿は米国時間 2022 年 7 月 12 日に、Google Cloud blog に投稿されたものの抄訳です。

Google では、YouTube や Gmail などの Google プロダクトを提供する大規模な本番環境のフリートを管理しています。エンジニアを含む全社員をサポートするために、複数のプラットフォーム、モデル、ロケーションに及ぶ数十万台のデバイスを備えた大型の企業フリートも管理しています。各 Google 社員が生産性の最も高い環境で作業できるようにするために、Linux システムを含む多数の OS プラットフォームを運用しています。社内向け Linux ディストリビューションである Goobuntu は、長い間、Ubuntu 長期サポート(LTS: Long-term support)リリースをベースに構築されていました。2018 年に、Debian をベースにしたローリング リリース モデルへの移行が完了しました。  

アップグレードのトイル

15 年以上前、Ubuntu は、ユーザー フレンドリーで使いやすく、趣向を凝らした追加機能を数多く備えていたため、社内向け Linux ディストリビューションのベースとして選ばれました。Canonical が 2 年以上のセキュリティ アップデートを提供したことが評価されて、長期サポート(LTS)リリースが選ばれました。

しかし、この LTS リリースのリリース サイクルが 2 年ということは、OS のサポート終了前に、10 万台を超えるデバイスのフリートのすべてのマシンをアップグレードする必要があるということでもありました。企業のマシンで実行されるワークロードは本質的に複雑であるため、マシンの再インストールや完全なカスタマイズが困難で時間のかかる操作になる可能性がありました。すべてのエンジニアに 2 年ごとにワークスペースをゼロから構成させることは生産性に打撃を与えるもので、経済的な道理にかなう選択肢ではありませんでした。

OS のサイクルごとに、メジャー パッケージで大幅なバージョン アップがあり、ソフトウェアの構成に著しい変更が必要になる場合がありました。このプロセスを自動化するために、よくあるケースの問題を多く処理する無人化したインプレースのアップグレード ツールを作成しました。この自動化に焦点を当てたアプローチにより、Google 社員の大半にとって、マシンを再インストールしてからすべての構成を再作成するという、手動でのマシンのアップグレードが不要になりました。しかし、これを実現するには、アップグレード プロセスの包括的なテストを実施し、変更されたすべてのメジャー パッケージが動作し続けていることを確認する必要がありました(Ubuntu では、最大で数千ほどのパッケージが、メジャー バージョン間のアップグレードの対象となる場合があります)。非推奨事項が発生し、エンジニアが先に進む方法を決めなくてはならないケースでは、自動化を提供することが困難なこともありました。

Goobuntu のフリートをアップグレードするというこの取り組みは、通常、ほぼ 1 年かかりました。サポート期間が 2 年だと、次期の LTS で同じプロセスをもう一度やり直すまでに 1 年しかありませんでした。このすべてのプロセスが、チームにとって大きなストレスの要因でした。コーナーケースに対するヘルプのリクエストで、何百ものバグを抱えていたからです。1 つのアップグレードが完了すると、チーム全般に「燃え尽き症候群に近い」感じがあり、次の更新時期までにほとんど回復できませんでした。LTS バージョンを実行すると、ディストリビューションのユーザーが遭遇したバグの一部が、アップストリームで修正済みの可能性がある一方で、その修正が LTS バージョンにバックポートされていない可能性がるということもありました。

数年続く可能性のある、ロングテールの特別なケースのアップグレードもありました。このプロセスに対応することは、自動プロセスで機能しなかったマシンをエンジニアにアップグレードさせるチェンジ マネジメントの大きな課題でした。ユーザーにマシンのアップグレードを促す際は、創造性を発揮しました。UI 上のしつこいメッセージ、メール、スケジュール設定された再起動、さらにはマシンのシャットダウンなど、さまざまな手段を講じて、アップグレードが必要なマシンがまだあることを認識させました。これにより、完全に忘れていたマシンの存在に気づくことがありました。たとえば、机の下にある 1 台のマシンが、大事なプロセスの極めて重要なパイプラインを実行していることが判明しました。

ローリング リリース

gLinux Rodete(Rolling Debian Testing)の設計時に、2 年のアップグレード サイクルを取り除き、代わりにチームの負荷を終始分散させることを目指しました。業界での CI / CD への全面的な移行により、小さな増分変更は、管理とロールバックがより簡単であることが示されました。今日の Linux ディストリビューションでのローリング リリースは、より一般的になってきています(Arch Linux、NixOS)。

他の Linux ディストリビューションを使用することを検討しましたが、円滑なインプレースの移行を提供したかったため、Debian を選ぶことになりました。Debian のパッケージの可用性、大規模な Debian コミュニティ、また、Debian 形式を使用していた既存の社内パッケージとツールも考慮事項となっていました。Debian 安定版のトラックは、次期のリリースまでほぼ 2 年の間隔で続きます。一方、Debian テスト版のトラックは、ローリング リリースとして機能します。アップストリームから取り込まれて構築されたすべてのパッケージのプールであるためで、次期の安定版のリリースまで待機します。

アップストリーム リリースからテスト版が利用できるようになるまでの時間は、多くの場合わずか数日です(ただし、Debian 安定版リリース前のフリーズ期間中には、2、3 か月遅れることがあります)。つまり、一般的に、はるかにきめ細かい変更が得られ、長期間待つことなく、Google のエンジニアに最新のソフトウェアを提供できることになります。

この頻度の更新には、多くのシステムやプロセスの再設計が必要でした。当初はより頻繁なリリースを予定していましたが、迅速な移行とリリースの適格性のバランスがとれ、デベロッパーの生産性の低下を抑えられるのは、週次リリースであることがわかりました。

新たなリリースを開始するたびに、Debian から取り込んだすべてのパッケージのスナップショットをこの時点で取ります。いくつかの受け入れテストを経て、新たな密閉型のリリース候補は、専用のテスト版フリートと、フリート全体の 1% がカナリア版に慎重にロールアウトされます。カナリア版は、フリート全体へと進む前に、Debian パッケージ、または Google 社内パッケージの問題を検出するために、数日間意図的に保持されます。

Sieve のご紹介

ソースからすべてのアップストリーム パッケージを構築することから、このような複雑なタスクをすべて管理するために、Sieve と呼ばれるワークフロー システムを構築しました。新しいバージョンの Debian パッケージがあればいつでも、新たに構築を開始します。一緒にアップグレードする必要がある個別のパッケージを考慮して、パッケージ グループでパッケージを構築します。グループ全体が構築されたら、仮想化されたテストスイートを実行して、コア コンポーネントとデベロッパー ワークフローに破損がないか確認します。各グループは、そのバージョンのオペレーティング システム上で、フル システム インストール、起動、ローカル テストスイートを実行して、個別にテストされます。個々のパッケージの構築は、通常数分以内に完了しますが、パッケージ グループの複雑さを考慮すると、このテストには最大 1 時間かかることがあります。

パッケージが構築され、すべてのテストに合格したら、新しいパッケージをすべて最新のパッケージ プールとマージします。新しいリリースをカットする場合は、各パッケージ バージョンをそのリリース用にロックインして、そのプールのスナップショットを作成します。次に、段階的カナリア処理やフリートの状態のモニタリングなどの SRE の原則を活用して、このリリースをフリートへ慎重に誘導していきます。

ただし、最初の試行ですべての構築が成功するわけではありません。パッケージの構築に失敗した場合、通常、Debian バグトラッカーで既知のバグをチェックし、万一、既知でない場合は報告します。場合によっては、リリース エンジニアが創造性を発揮し、ローカルでの回避策やパッチを適用する必要があります。パッケージを取得して、エコシステム内に構築し、アップストリームで修正プログラムがリリースされたら、この回避策を破棄します。

たとえば、私たちが何度か遭遇した問題の一つは、アップストリームの Debian のパッケージは通常、Debian 不安定版で構築されるということです。数日後、構築済みのパッケージは、Debian テスト版に移行されます。ただし、場合によっては、ビルドの依存関係が不安定版で行き詰まり、テスト版内での構築が(まだ)可能でないこともあります。通常、このようなケースでは、まずアップストリームで作業するようにしているため、ローカルパッチを維持する複雑さやメンテナンスの負担を減らすと同時に、コミュニティへの還元も行っています。

いずれかの手順が失敗しても、Sieve には、構築を再試行するための効果的な方法を取れるツールボックスが備わっています。たとえば、1 つのパッケージ グループの初期構築を開始すると、システムは、どの依存関係を一緒に構築する必要があるか知識に基づいて推測します。ただし、Debian ソース パッケージで提供されるバージョン情報が不完全で、この推測が間違っている場合があります。このため、Sieve は失敗したグループの構築を定期的に再試行します。パッケージの最新のスナップショットは動く標的であるため、一見独立しているように見えるパッケージ グループがスナップショットに追加された後、過去に破損したグループが予期せずに構築され、テストに正しく合格するようなことが起こる可能性があります。このようなワークフローのすべては、ほとんど自動化されており、このフィールドで SRE として考えることの重要性を強調しています。障害に直面した場合、通常、失敗したビルドを 1 回修正する方が簡単なようですが、同じ回避策を繰り返し適用する必要がある場合は、コードに回避策を記述することで、エンジニアの負担が全般的に軽減されます。

ソースからすべてのバイナリを構築し、実行中のバイナリの起源を確認する追加のソースコードの来歴を保持することは、セキュリティ上の利点もいくつかあります。たとえば、セキュリティ インシデント中、迅速に再構築でき、一時的なパッチを使用した構築に自信が持てます。ディストリビューションになる、すべてのパッケージを以前に構築していたことがあるからです。さらに、アップストリームの Debian に配置する必要のある信頼エンベロープと、インフラストラクチャによって生成されるバイナリビルドのアーティファクトも削減します。代わりに、ソースコードが取り込まれ、バイナリが検証可能な形で構築されると、実行中のバイナリが、まさにそのソースコードから生成されたことを暗号で証明できます。

Rodete へのアップグレード

前回の Goobuntu リリースは、Ubuntu 14.04 LTS(コードネーム Trusty)ベースでした。Rodete の開発は、2015 年に開始され、Trusty のサポートを打ち切り、エンジニア全員に新しいディストリビューションをインストールさせるわけにはいかないことが、すぐに明らかになりました。LTS バージョン間にインプレースで更新するという過去の経験から、この移行で何が待ち受けているか、すでにある程度感じ取っていました。Ubuntu は、Debian から派生したものであり、同じパッケージ処理のインフラストラクチャやフォーマット(apt)を多数使用しているため、フリートを Goobuntu 14.04 から Debian にインプレースでアップグレードすることは、突拍子もない考えではありませんでした。以前のインプレース アップグレード ツールの一部を再利用し、自動化とテストをさらに追加することで、信頼性の向上に取り組みました。

このようなツールの作成、テスト、および移行期間中の保守を容易にするために、ベースラインと呼んでいる特定の日付の Debian テスト版のスナップショットとして、gLinux Rodete を一時的にフリーズすることに決めました。自身で選んでこのベースラインを進めて、Sieve が取り込むパッケージのバランスを取ることができます。摩擦を減らすために、2016 年に、現行の Debian 安定版リリースで Rodete のベースラインを意図的に設定しました。これは、Ubuntu Trusty の通常の状態にかなり近いものでした。このようにして、Trusty から Debian へのインプレース アップグレードと、後日 Debian で発生したメジャー パッケージのバージョン変更を分けることができました。

2017 年には、マシンを Rodete に移行し、2018 年の年末までに最後のインプレースでの移行を完了しました。しかしその時点では、2 年近く前のパッケージのベースラインがまだありました。Debian テスト版に追いつくために、Sieve の動作を最適化し、パッケージの構築およびテストに必要な時間を短縮することに焦点を当てた、チーム全体での取り組みを開始しました。この増分型のアップグレードを再度行い、ローリング リリースの動く標的を管理することで、Google のエンジニアとチームのワークロードが軽減されました。

2019 年初頭に、Goobuntu マシンの最後の残りをシャットダウンし始めました。また、ベースラインは約 250 日の遅れにとどまるだけで進みました。つまり、そのとき、バスターの一部であるパッケージ バージョンの大半を使用していたということでした。2020 年半ばまでには、ようやく完全に追いつきました。Debian bullseye のリリースと同じ時期でした。ベースラインを前進させ続け、2023 年半ばに次期の Debian 安定版がリリースされるまでには、同様のバージョンをおそらくすでに使用しているでしょう。

禅の精神に至る

現在、gLinux チームメンバーの生活は、大きく異なるようです。リリースに必要なエンジニアリングの時間とエネルギーの量を、当番(チームメンバー間で交代)のリリース エンジニアを 1 名に削減しました。フリート全体をアップグレードするという大変な取り組みは、もうありません。Ubuntu Precise や Lucid をまだ実行している古いマシンを同時に追跡しながら、新しい LTS リリースのマルチステージのアルファ版、ベータ版、GA に対応する必要も、もうありません。

また、フリートをアップストリーム リリースに近づけて運用することで、セキュリティのスタンスも劇的に改善しました。Debian は安定版のトラックと旧安定版のトラックに適したセキュリティ パッチを提供しますが、パッチを取得するすべてのセキュリティ ホールに、必ずしも Debian セキュリティ勧告(DSA: Debian Security Advisor)または CVE 番号があるとは限らないことに気づきました。以前は、セキュリティ エンジニアが各 DSA を慎重に確認し、修正がフリートに行き渡ったことを確実にする必要がありましたが、ローリング リリース スケジュールにより、安定性を損なうことなく、フリート全体にセキュリティ ホールのパッチを迅速に適用できています。

また、改善されたテスト版のスイートと、極めて重要なデベロッパー システムを実行する重要なパートナー チームとの統合テストにより、最新バージョンの Linux カーネルを提供する Linux ディストリビューションを使用した、より安定したエクスペリエンスがもたらされました。パイプラインのすべてを自動化するという強い望みが、チーム内のトイルとストレスを大幅に軽減しました。Linux エコシステム内で Google ツールが最適に動作するようにしながら、バグや他のライブラリ バージョンとの非互換性を報告することも可能になりました。

社内でローリング リリースを行うことに関心がありましたら、会社のニーズとアップグレードのアジリティのバランスを考慮してください。自身の動く標的とベースラインを管理することで、あまりにも多くの問題に遭遇し、チームの SLO のいずれかに反したときでも、速度を低減できるようになりました。このジャーニーで、増分変更はビッグバン リリースよりも対処しやすいということを最終的に確信しました。

新しい作業の流入を管理し、それを予測可能な状態に保てれば、エンジニアの満足感を高め、ストレスを軽減できることを経験しました。これにより、最終的にチームの離脱も減り、複数の燃える炎に同時に対応する代わりに、専門知識を構築できるようになりました。

将来的に、アップストリームの Debian と緊密に連携して、Debian パッケージのエコシステムを管理するために、より多くの社内パッチの提供を計画しています。


- Kordian Bruck、Margarita Manterola
- Sven Mueller

投稿先