aptly による apt リポジトリ管理

インフラストラクチャー部の宮下(@gosukenator)です。

クックパッドでは一部のサーバで Ubuntu を使い始めており、 apt リポジトリをどのように管理するのが良いのか、試行錯誤しています。aptリポジトリ管理で実現したいことは、主に次の2点です。

  • 自前でビルドしたパッケージの管理
  • リモートリポジトリから削除された旧バージョンパッケージの保全

このあたりをいい感じにできるツールはないかな、と社内で話していたところ、カルビ生焼け王 に教えてもらったのが aptly です。

aptly とは

公式サイトに「aptly is a swiss army knife for Debian repository management」とあるように、aptly は多機能な apt リポジトリ管理用ツールです。外部リポジトリのミラー作成、ローカルリポジトリの作成、リポジトリのスナップショット作成、スナップショット同士のマージ、S3 への publish 等の機能があります。「swiss army knife」と謳ってるのは伊達ではなく、かなり多機能でツールの全体像がつかみにくいのですが、オフィシャルサイトの Overview にわかりやすい図などがあるので、そちらを参照してください。

詳しい使い方等はここでは解説しませんが、興味のある方は Tutorial からトライしてみると良いでしょう。

aptly でやろうとしていること

現在 aptly を利用して、以下のことを実現しようとしています。

  • 自前パッケージ管理用のローカルリポジトリの運用
  • リモートリポジトリのミラー作成と、スナップショットを毎日保存してリモートから削除されたパッケージを保全
  • ローカルリポジトリとリモートミラーのスナップショットをマージして S3 へ publish

図にすると以下のようなイメージです。

f:id:MIZZY:20141106143626p:plain

ローカルリポジトリの運用

ローカルリポジトリは次のように作成します。

$ aptly repo create cookpad-repo

ローカルリポジトリにパッケージを追加するには次のように実行します。

$ aptly repo add cookpad-repo package.deb

リモートリミラー作成とスナップショット作成

リモートリポジトリのミラーは次のように作成します。

$ aptly mirror create -architectures=amd64 ubuntu-mirror \
  http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu/ trusty

リモートリポジトリとミラーを同期するには、次のように実行します。

$ aptly mirror update ubuntu-mirror

aptly mirror update を実行すると、リモートリポジトリと完全に同期されるため、リモートで削除されたパッケージはミラーでも削除されてしまいます。リモートで削除されても手元に残るよう、スナップショットを作成します。

$ aptly snapshot create ubuntu-mirror-20141106 from mirror ubuntu-mirror

毎日スナップショットを取得することで、リモートで削除されたパッケージの保全を行います。

ローカルリポジトリとリモートミラーのマージ

ローカルリポジトリとリモートミラーをマージするために、ローカルリポジトリのスナップショットを取得します。

$ aptly snapshot create cookpad-repo-20141106 from repo cookpad-repo

ローカルリポジトリのスナップショットと、リモートミラーのスナップショットをマージしたスナップショットを作成します。リモートで削除されたパッケージをすべて含めるため、リモートミラーから取得したスナップショットすべてをマージ対象に含めます。ローカルリポジトリのパッケージは基本的に削除しないので、最新のスナップショットのみマージ対象に含めます。

aptly snapshot merge --no-remove merged-snapshot-20141106 cookpad-repo-20141106 \
  ubuntu-mirror-20141106 ubuntu-mirror-20141105 ubuntu-mirror-20141104

マージしたスナップショットを S3 へ publish

マージしたスナップショットを publish します。初めて publish する場合はaptly publish snapshotを実行します。

$ aptly publish snapshot merged-snapshot-20141106 s3:cookpad:

2度目以降は aptly publish switch を実行します。

$ aptly publish switch trusty s3:cookpad: merged-snapshot-20141106

問題点

この方法の問題点は、publish switch 実行時に、差分ではなくすべてのパッケージをアップロードするため、非常に時間がかかる、ということです。特に、Ubuntu のパッケージアーカイブをすべてミラーしていると、4万個以上のパッケージをアップロードすることになり、EC2インスタンスからS3への転送に2時間以上時間がかかります。しかも、途中でネットワークエラー等で中断されると、最初からやり直しになってしまいます。

したがって、この方法は現実的でないため、他の方法を模索中です。私が aptly の機能をすべて把握できておらず、他にいい方法があるのに見つけられていない可能性もあるため、現在ドキュメントを読み漁っています。aptly がまだバージョン 0.8 なので、今後のバージョンアップでいい感じに解決できるようになるかもしれません。

もし他にいい方法やいいツールなどありましたら、ぜひ教えてください。