Ubuntu

Ubuntu20.04 ローカルにアーカイブミラーを立ててみる

パッケージのインストールやアンインストールを繰り返して、最適なLive環境を作りたい。
サーバーに迷惑を掛けるのもイマイチなので、ローカルにアーカイブミラーを立ててみようと思った。



広告


やること。

考えていたより少し大変だったけれど、どうにかミラーが立てられた。

環境

VMware Workstation Playerで、CPUx1、メモリ4GB、ディスク20GBという最低限の環境を構築。
他のホストから参照できるように、ネットワークはブリッジを選択。

パッケージを保存するディレクトリには数TBの容量が必要になる場合もあるようだけれど、とりあえず1TBの仮想ディスクを別に作って、それをマウントすることで自由に使えるようにする。

仮想ゲストを作成後、さらにUEFIでセキュアブート対応にするなど、直接関係ないところも設定だけはしておこう。

Mirror.vmx

firmware = "efi"
efi.legacyBoot.enabled = "FALSE"
uefi.secureBoot.enabled = "TRUE"
ulm.disableMitigations="TRUE"
disk.EnableUUID = "TRUE"

設定後、仮想マシンを立ち上げて、Ubuntu 20.04 LTS Serverをインストールした。

アーカイブミラー構築

必要なのは、apache2とapt-mirrorらしい。
LinuxConfig.org / How to create a Ubuntu repository server
LinuxTechi / How to Setup Local APT Repository Server on Ubuntu 20.04

apt-mirrorは、サーバーから複数スレッドで設定ファイルやパッケージをダウンロードしてきてため込む仕組み。
ため込んだファイルをHTTPでクライアントに見せるということの模様。

ほぼ、この2つのサイトで教えてくれていることをやっている。
一部、公開ディレクトリとか、実行者とかにこだわってみている。

初期設定

仮想ゲストをDNSに登録。
FQDNはmirror.hogeserver.hogeddns.jpとし、IPアドレスは192.168.0.90とした。

これに合わせたネットワーク設定をしておく。
/etc/netplan/00-installer-config.yaml

# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 192.168.0.90/24
      gateway4: 192.168.0.1
      nameservers:
        addresses:
        - 192.168.0.1
        search:
        - hogeserver.hogeddns.jp
  version: 2

反映。

$ sudo netplan apply

これで、他のホストから、この名前でアクセスができるようになった。

外からsshで接続したかったので、許可してから、ファイアウォールを有効にした。

$ sudo ufw allow ssh
$ sudo ufw enable

ついでに、時間をJSTに変えておこう。

$ sudo timedatectl set-timezone Asia/Tokyo

初期設定はこんなもので良いだろう。

Apacheのインストール

Apacheをインストールして、ファイアウォールを設定する。

$ sudo apt install apache2
$ sudo ufw allow http

ブラウザでアクセスして、デフォルトページが表示されることを確認する。
今回の設定でいくと、こんなURLになる。
http://mirror.hogeserver.hogeddns.jp/

アクセスできることが確認できたら、公開するディレクトリを設定しておく。
この時点では存在しないディレクトリだが、apt-mirrorで同期するとできあがる。

/etc/apache2/sites-enabled/

<VirtualHost *:80>

…
        Alias /ubuntu /var/spool/apt-mirror/mirror/archive.ubuntu.com/ubuntu
        <Location /ubuntu>
                Options FollowSymLinks Indexes
                Require all granted
        </Location>

</VirtualHost>

設定を反映。

$ sudo systemctl reload apache2

apt-mirrorのインストール

apt-mirrorをインストールする。

$ sudo apt install apt-mirror

インストールはしたものの、どうやら、20.04に同梱されているapt-mirrorには問題があって、一部必要なファイルをダウンロードできない。
修正パッケージを提供してくれている方がいたので、使わせていただくことにする。
https://github.com/Stifler6996/apt-mirror

作業ディレクトリを作り、ファイルをダウンロードしてくる。

$ wget https://github.com/Stifler6996/apt-mirror/archive/refs/heads/master.zip
$ unzip master.zip

元々のスクリプトを待避して、ダウンロードしたスクリプトに置き換える。

$ sudo cp -ar /usr/bin/apt-mirror /usr/bin/apt-mirror.original
$ sudo cp -ar apt-mirror-master/apt-mirror /usr/bin/
$ sudo chown root:root /usr/bin/apt-mirror

パッケージ保管場所の設定

追加した1TBのディスクを確認。/dev/sdbになっていた。

$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0    7:0    0 55.5M  1 loop /snap/core18/2253
loop1    7:1    0 55.4M  1 loop /snap/core18/2128
loop2    7:2    0 61.9M  1 loop /snap/core20/1270
loop3    7:3    0 70.3M  1 loop /snap/lxd/21029
loop4    7:4    0 67.2M  1 loop /snap/lxd/21835
loop5    7:5    0 43.3M  1 loop /snap/snapd/14295
loop6    7:6    0 32.3M  1 loop /snap/snapd/12704
sda      8:0    0   20G  0 disk
tqsda1   8:1    0  512M  0 part /boot/efi
mqsda2   8:2    0 19.5G  0 part /
sdb      8:16   0    1T  0 disk
sr0     11:0    1 1024M  0 rom

パーティションを作る。

$ sudo gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries in memory.

Command (? for help): n[Enter]
Partition number (1-128, default 1): [Enter]
First sector (34-2147483614, default = 2048) or {+-}size{KMGTP}: [Enter]
Last sector (2048-2147483614, default = 2147483614) or {+-}size{KMGTP}: [Enter]
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): [Enter]
Changed type of partition to 'Linux filesystem'

Command (? for help): w[Enter]

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y[Enter]
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

パーティションをフォーマットする。
この操作は普通なら時間が掛かりそうだけれども、仮想ディスクだからか、あっという間に終了する。

$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 268435195 4k blocks and 67108864 inodes
Filesystem UUID: 810d3ca6-cffb-42c6-81d5-5c8440ff8bd6
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done

/etc/fstab

/dev/disk/by-uuid/810d3ca6-cffb-42c6-81d5-5c8440ff8bd6 /var/www/html/ubuntu ext4 defaults 0 1

※この指定を追加。UUIDはフォーマットしたときに表示されたものを書いた。

再起動してマウントされていることを確認する。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           391M  1.5M  390M   1% /run
/dev/sda2        20G  6.6G   12G  37% /
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/loop1       44M   44M     0 100% /snap/snapd/14295
/dev/loop2       56M   56M     0 100% /snap/core18/2253
/dev/loop3       71M   71M     0 100% /snap/lxd/21029
/dev/loop0       33M   33M     0 100% /snap/snapd/12704
/dev/loop4       68M   68M     0 100% /snap/lxd/21835
/dev/loop5       56M   56M     0 100% /snap/core18/2128
/dev/loop6       62M   62M     0 100% /snap/core20/1270
/dev/sda1       511M  5.3M  506M   2% /boot/efi
/dev/sdb1      1007G   77M  956G   1% /var/spool/apt-mirror
tmpfs           391M     0  391M   0% /run/user/1000

マウントできていることが確認できたら、持ち主を元々のapp-mirrorに変えておく。

$ sudo chown apt-mirror:apt-mirror /var/spool/apt-mirror/

これ以降、apt-mirrorさんの持ち物としてマウントされる。

apt-mirrorの設定

設定ファイルを編集。パッケージの元々の設定は、17.10のリポジトリを参照しているので、20.04に書き換える。
Wikipedia / Ubuntuのバージョン履歴

今回はデバッグを行わず、ソースコードを使うこともないと思ったので、コメント化している。
また、普通にインストールしたつもりのUbuntu 20.04から要求されたので、i386のパッケージも一部取り込んでいる。

/etc/apt/mirror.list

############# config ##################
#
# set base_path    /var/spool/apt-mirror
#
# set mirror_path  $base_path/mirror
# set skel_path    $base_path/skel
# set var_path     $base_path/var
# set cleanscript $var_path/clean.sh
# set defaultarch  <running host architecture>
# set postmirror_script $var_path/postmirror.sh
# set run_postmirror 0
#set nthreads     20
set nthreads     6
set _tilde 0
#
############# end config ##############

deb http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu focal-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse
#deb http://archive.ubuntu.com/ubuntu focal-proposed main restricted universe multiverse
#deb http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse
deb-i386 http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse
deb-i386 http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse

#deb-src http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse
#deb-src http://archive.ubuntu.com/ubuntu focal-security main restricted universe multiverse
#deb-src http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse
#deb-src http://archive.ubuntu.com/ubuntu focal-proposed main restricted universe multiverse
#deb-src http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse

clean http://archive.ubuntu.com/ubuntu

base_pathを変更しているので、パッケージが用意してくれたbase_pathの内容をコピーする。

$ sudo cp -ar /var/spool/apt-mirror/* /var/www/html/ubuntu/

ミラー処理の終了後に実行されるスクリプト(postmirror.sh)では、特にやることもないと思われたので、GitHubにあったソースをそのままファイルにする。

$ sudo -u apt-mirror tee /var/spool/apt-mirror/var/postmirror.sh > /dev/null <<EOF
#!/bin/sh -e

## Anything in this file gets run AFTER the mirror has been run.
## Put your custom post mirror operations in here (like rsyncing the installer
## files and running clean.sh automatically)!

## Example of grabbing the extra installer files from Ubuntu (Note: rsync needs
## to be installed and in the path for this example to work correctly)

#rsync --recursive --times --links --hard-links --delete --delete-after rsync://mirror.anl.gov/ubuntu/dists/trusty/main/debian-installer /var/spool/apt-mirror/mirror/archive.ubuntu.com/ubuntu/dists/trusty/main/
#rsync --recursive --times --links --hard-links --delete --delete-after rsync://mirror.anl.gov/ubuntu/dists/trusty/main/dist-upgrader-all/ /var/spool/apt-mirror/mirror/archive.ubuntu.com/ubuntu/dists/trusty/main/
#rsync --recursive --times --links --hard-links --delete --delete-after rsync://mirror.anl.gov/ubuntu/dists/trusty/main/installer-amd64/ /var/spool/apt-mirror/mirror/archive.ubuntu.com/ubuntu/dists/trusty/main/
#rsync --recursive --times --links --hard-links --delete --delete-after rsync://mirror.anl.gov/ubuntu/dists/trusty/main/installer-i386/ /var/spool/apt-mirror/mirror/archive.ubuntu.com/ubuntu/dists/trusty/main/
EOF

$ sudo chmod 775 /var/spool/apt-mirror/var/postmirror.sh

※teeでEOFまでの入力内容をファイルに出力し、標準出力への出力は破棄。単純に > で出力すると、パーミッションエラーが発生するので、こうした。

これで準備OK。

同期

パッケージのダウンロードには、当たり前といえば当たり前だけど、相当に時間が掛かる。ウチの環境で、今回の設定だと6時間30分程。

$ sudo -u apt-mirror apt-mirror
Downloading 196 index files using 6 threads...
Begin time: Sat Dec 25 22:58:47 2021
[6]... [5]... [4]... [3]... [2]... [1]... [0]...
End time: Sat Dec 25 22:59:33 2021

Processing translation indexes: [TTTTT]

Downloading 555 translation files using 6 threads...
…

iftopコマンドで確認したところ、50Mb前後の値が表示されているが、ホストのWindowsでタスクマネージャーを表示させたところ、90Mbpsを超えたりしていて、これはウチの環境の限界を超えており、他の調べごとなどが滞ることになった。
そのため、スレッド数を6に設定するなどして使用帯域を調整したところ、50Mbps程度、調子がいいときで85Mbps程度、少し余裕ができた。

ダウンロードした結果の状態を確認すると、185GB程であった。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           391M  1.5M  390M   1% /run
/dev/sda2        20G  6.6G   12G  37% /
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/loop2       56M   56M     0 100% /snap/core18/2128
/dev/loop0       56M   56M     0 100% /snap/core18/2253
/dev/loop4       68M   68M     0 100% /snap/lxd/21835
/dev/loop5       33M   33M     0 100% /snap/snapd/12704
/dev/loop3       71M   71M     0 100% /snap/lxd/21029
/dev/loop1       62M   62M     0 100% /snap/core20/1270
/dev/loop6       44M   44M     0 100% /snap/snapd/14295
/dev/sda1       511M  5.3M  506M   2% /boot/efi
/dev/sdb1      1007G  186G  771G  20% /var/www/html/ubuntu
tmpfs           391M     0  391M   0% /run/user/1000

ファイルを見てみる

今回の設定でいくと、以下のURLでアクセスし、ディレクトリをたどっていけばファイルが見られる。
http://mirror.hogeserver.hogeddns.jp/ubuntu

上手く構築できたようだ。

定期実行

パッケージを適切に最適化して、最新に保っておこう。

/etc/crontab

41 23   * * *   apt-mirror /usr/bin/apt-mirror

※毎日23:41にコマンドを実行する例。

アーカイブミラー参照

作ったミラーを参照する。
特に設定を変えていないUbuntuデスクトップの設定(/etc/apt/sources.list)をみたところ、
 http://jp.archive.ubuntu.com/ubuntu/
 http://security.ubuntu.com/ubuntu
という2つのサーバーを参照していた。

securityという文字が気になって探してみたところ、これは変えてはいけないもののようだった。
純規の暇人趣味ブログ / security.ubuntu.comはそのままで

ということで、sources.listのバックアップを取りつつ編集。

/etc/apt/sources.list

deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal main restricted
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-updates main restricted
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal universe
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-updates universe
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal multiverse
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-updates multiverse
#deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu focal-security main restricted
deb http://security.ubuntu.com/ubuntu focal-security universe
deb http://security.ubuntu.com/ubuntu focal-security multiverse

※コメントアウトされているところを除くとこんな感じ。

ポケットbackportsは、新しいメジャーリリースの一部を旧バージョン用に移植したものが入っているそうなのだが、ミラーしていなかったので外した。
必要ならば、ミラーの対象に入れておけば良さそう。

これで、updateすれば使える。

$ sudo apt update

当然だけど、速度は速い。

起きたこと

apt updateでエラー

日頃見慣れないエラーが発生。なんじゃこりゃ?

$ sudo apt update
Get:1 http://mirror.hogeserver.hogeddns.jp/ubuntu/mirror/archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Get:2 http://mirror.hogeserver.hogeddns.jp/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
…
Reading package lists... Done
E: Failed to fetch http://mirror.hogeserver.hogeddns.jp/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/focal/main/dep11/icons-64x64@2.tar  404  Not Found [IP: 192.168.0.90]
E: Failed to fetch http://mirror.hogeserver.hogeddns.jp/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/focal-updates/main/dep11/icons-64x64@2.tar  404  Not Found [IP: 192.168.0.90]
E: Some index files failed to download. They have been ignored, or old ones used instead.

調べてみると、同梱されているapt-mirrorに問題があって、@を含むファイルが取り出せないみたい。
ask ubuntu / 20.04 local repository not working for updates/installs

そこで、有志が作成してるらしい修正版を使わせていただいた。
本編にその手順を記載している。

実行時にスクリプトが見つからない

実行時に以下のエラーが発生していることに気が付いた。2021/12/30追記。

$ sudo -u apt-mirror apt-mirror
Downloading 196 index files using 6 threads...
Begin time: Thu Dec 30 10:04:19 2021
…
Running the Post Mirror script ...
(/var/spool/apt-mirror/var/postmirror.sh)

/bin/sh: 0: Can't open /var/spool/apt-mirror/var/postmirror.sh

Post Mirror script has completed. See above output for any possible errors.

postmirror.shはミラー処理が終わった後(clean.shよりも後)に呼び出されるスクリプト。
amd64でも必要となるi386の一部をスクリプトで取りに行くようなことを書いたりするらしい。
GitHub / apt-mirror / apt-mirror / postmirror.sh
hamakichitaro’s blog / オフライン環境でapt-getを普通に使うapt-mirror 、セットアップしてみた。

今回の手順で進めている場合、このタイミングでやることはないので、空っぽのスクリプトでも作っておけば問題はない。
本編にその手順を記載している。

仮想ゲストが突然死

必要なディスクの容量がどの程度なのか全く分からなかったので、できる限り効率的に仮想ホストのディスクを使えないかと考えた。
そうだ、VMwareには共有フォルダがあるじゃん!

しかし…結論からすると、Windows DefenderとVMwareの共有フォルダの相性が悪いらしく、ディスクアクセスが爆増し、VMwareのプロセスが停止、通常の操作では仮想ゲストを落とすことができなくなる、という事態に発展。2時間くらいは動いていたから…20GBくらいをダウンロードしたところで問題が発生したのだろう。

とはいえ、やったことを書くと以下の通り。

VMwareの共有フォルダをここにマウントする。
VMware CUSTMER CONNECT / How to configure VMware Tools Shared Folders Linux mounts (60262)

まずはお試し。

$ sudo vmhgfs-fuse .host:/Share /var/spool/apt-mirror/ -o subtype=vmhgfs-fuse,allow_other

起動するたびに共有フォルダをマウントするように設定。

/etc/fstab

.host:/Share /var/spool/apt-mirror fuse.vmhgfs-fuse defaults,allow_other 0 0

※この指定を追加。

再起動。

$ reboot

この後、ファイルのダウンロードが始まったところで、ディスクアクセスが100%に。

リアルタイム検索をオフにすると、いくらかマシになるものの、それでもかなり高い使用率になる。
また、リアルタイム検索はある程度時間がたつと、オンに戻ると画面上に書かれている。

リアルタイム検索をオンにしたまま、ディレクトリShareの除外ができないかと思い、フォルダを指定して除外してみたものの、あれはなんだろう…フルスキャンするときの除外なの?なんだか分からないけれども、効果がなかった。

共有フォルダは便利な機能だけれども、この場合には使えないと諦めて、シン・プロビジョニングの1TBディスクを作って使うことにした。

さいごに

これで、気兼ねなくパッケージのインストールを試すことができる環境ができあがった。
同じ仮想ホスト上に、ミラーとLive構築用の仮想ゲストを立てることで、超高速なパッケージダウンロードができるだろう。

でも、ウチの中に配線済みのLANケーブルは古くて、100Mbpsしか出ない。
どこかにサーバーを常設して、みんなそこを参照するような仕組みにするとなると…帯域制限が必要。
多分この方法でいけると思うから、やってみるかー。

コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他