読者です 読者をやめる 読者になる 読者になる

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 なので、今後のバージョンアップでいい感じに解決できるようになるかもしれません。

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

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/