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

Alpine Linux入門 -内部構造とapkでパッケージインストール編-

さて、前回のエントリはAlpine Linuxの環境を作ってみる話でした。 stormcat.hatenablog.com

今回は実際にAlpine Linuxの中身を探索していったり、apkでのパッケージインストール等をやってみます。

前回使った仮想環境をそのまま利用します。前回の環境構築プロセスはもういいよって人は、Vagrant Cloudに公開されているboxを使うでもOKです。

各自のAlpine環境にsshでログインしている前提で話を進めます。

Alpineを探索する

まずは素の状態のAlpineがどうのような状態になっているかを確認しておきましょう。Alpineは非常に軽量とされていますが、実際どの程度機能が絞られているかをある程度理解しておく必要があります。

/bin

とりあえず基本的なプログラムが配置されている/binでも見てみましょう。ls -lh /binしてみるとこんな感じになりました。

localhost:~# ls -lh /bin
total 940
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 ash -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 base64 -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 bbconfig -> /bin/busybox
---s--x--x    1 root     root        9.7K Dec 16 08:00 bbsuid
-rwxr-xr-x    1 root     root      790.2K Dec 16 08:00 busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 cat -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 catv -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 chgrp -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 chmod -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 chown -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 conspy -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 cp -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 cpio -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 date -> /bin/busybox
lrwxrwxrwx    1 root     root          12 Feb 28 14:01 dd -> /bin/busybox
------------------(以下省略)----------------------

見た感じ基本的なプログラムは用意されているように見えます。が、やはり気になるのはほとんどのプログラムが/bin/busyboxへのシンボリックリンクになっているということでしょうか。

busyboxとは何かというと、Alpine LinuxのベースとなっているLinuxディストリビューションであり、元々組み込み用途で利用されていました。

/bin/busyboxは単一バイナリでその中には複数のアプリケーションが含まれています。これに適切な引数を渡すことで任意のプログラムを実行できます。

例えば、ls -lh /bin は実質のところ以下のコマンドと同じことをやっていることになります。

$ /bin/busybox ls -lh /bin

busybox(およびAlpine)は、サイズを最適化した単一バイナリを利用することで軽量さを実現しています。

/sbin

/sbin の多くも/bin/busyboxへのシンボリックリンクです。基本的なシステム制御系のアプリケーションはサポートされていて、initserviceもあるので既存のLinux同様のデーモンプログラムの運用も可能です(Docker用途であれば基本的にプロセスをフォアグラウンドで実行するので必要ではありませんが)。

bashじゃなく、ash

Alpineにはbashがサポートされていません。サポートされているのは、ash(Almquist Shell)です(組み込み系Linuxではashがポピュラー)。bashに依存しているものをそのままalpineで動かすことはできません(bashのインストールが必要)

パッケージマネージャ apk

この軽量なLinuxに様々なパッケージやアプリケーションをインストールするにはどうすればよいでしょうか。yumapt-getといったお馴染みのパッケージマネージャはありませんが、Alpineではapkというパッケージマネージャを備えています。

とりあえずhelpでも見てみましょう。

localhost:~# apk --help
apk-tools 2.6.5, compiled for x86_64.

usage: apk COMMAND [-h|--help] [-p|--root DIR] [-X|--repository REPO] [-q|--quiet] [-v|--verbose] [-i|--interactive] [-V|--version] [-f|--force] [-U|--update-cache] [--progress] [--progress-fd FD] [--no-progress] [--purge]
           [--allow-untrusted] [--wait TIME] [--keys-dir KEYSDIR] [--repositories-file REPOFILE] [--no-network] [--no-cache] [--arch ARCH] [--print-arch] [ARGS]...

The following commands are available:
  add       Add PACKAGEs to 'world' and install (or upgrade) them, while ensuring that all dependencies are met
  del       Remove PACKAGEs from 'world' and uninstall them
  fix       Repair package or upgrade it without modifying main dependencies
  update    Update repository indexes from all remote repositories
  info      Give detailed information about PACKAGEs or repositores
  search    Search package by PATTERNs or by indexed dependencies
  upgrade   Upgrade currently installed packages to match repositories
  cache     Download missing PACKAGEs to cache and/or delete unneeded files from cache
  version   Compare package versions (in installed database vs. available) or do tests on literal version strings
  index     Create repository index file from FILEs
  fetch     Download PACKAGEs from global repositories to a local directory
  audit     Audit the directories for changes
  verify    Verify package integrity and signature
  dot       Generate graphviz graphs
  policy    Show repository policy for packages
  stats     Show statistics about repositories and installations

こんな感じのサブコマンドです。とりあえずaddでインストール、delでアンインストール、searchでパッケージを探したりできそうでパッケージマネージャとして一通りの機能を備えていそうな雰囲気はわかります。

update

apk updateすることで、Alpineのパッケージリポジトリから最新のインデックスを取得できます。新たにAlpine環境を構築した場合、必ずやっておくと良いでしょう。

localhost:~# apk update
fetch http://nl.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
v3.3.1-100-g8abdd0b [http://nl.alpinelinux.org/alpine/v3.3/main]
OK: 5313 distinct packages available

search

どんなパッケージがあるかを調べるにはapk searchを利用します。渡した引数の内容で絞込ができるので、vimで絞り込んでみましょう。

localhost:~# apk search vim
tmux-vim-2.1-r2
vim-doc-7.4.943-r2
vimdiff-7.4.943-r2
asciidoc-vim-8.6.9-r1
vim-7.4.943-r2
nginx-vim-1.8.1-r0
msmtp-vim-1.6.3-r0
protobuf-vim-2.6.1-r4
gst-plugins-base1-1.6.1-r0

addでインストール

apk addでは、パッケージをインストールできます。

$ apk add bash

のようにも書けますし、

$ apk add bash vim openssl
(1/8) Installing ncurses-terminfo-base (6.0-r6)
(2/8) Installing ncurses-terminfo (6.0-r6)
(3/8) Installing ncurses-libs (6.0-r6)
(4/8) Installing readline (6.3.008-r4)
(5/8) Installing bash (4.3.42-r3)
Executing bash-4.3.42-r3.post-install
(6/8) Installing openssl (1.0.2f-r0)
(7/8) Installing lua5.2-libs (5.2.4-r2)
 26% [#############################################################       

のように、1回で複数のパッケージをインストールすることもできます。

addでバージョン指定インストール

apk addではバージョン指定でのインストールも可能です。

これはバージョン指定。

$ apk add ruby=2.2.4-r0

Rangeでの指定もできますね。

$ apk add 'nginx<1.8.2'

リポジトリはそれほど新鮮ではない

Alpineのリポジトリはそこまで新鮮さがあるわけではありません。最新版を求めるようなアーリーアダプターはソースコンパイルからのインストールを迫られることになります。

開発用パッケージ

ソースコンパイルからアプリケーションをインストールするためには、様々な開発用パッケージが必要になります。RPMで言うところのperl-develだったりでしょうか。

Alpineでの開発パッケージ名は-develではなく、-devになっているので注意が必要ですね。

--virtual オプション

apk add--virtualというオプションを設定することができます。具体的な用法は以下のようになります。

$ apk add --virtual=build-dependencies build-base perl-dev pcre-dev zlib-dev openssl-dev

一言で言うと、「build-base perl-dev pcre-dev zlib-dev openssl-devを一括でインストールし、これらをbuild-dependenciesという名前でグルーピングする」ということになります。

--virtualオプションのオイシイところは、これらのパッケージを一括りにすることでapk delで指定したグループに属するパッケージを一括削除したりすることができることにあります。後で消したい産業廃棄物を定義するのに便利で、こうすることできれいに書けます。

localhost:~# apk del build-dependencies
(1/27) Purging build-dependencies (0)
(2/27) Purging build-base (0.4-r1)
(3/27) Purging make (4.1-r0)
(4/27) Purging fortify-headers (0.7-r0)
(5/27) Purging g++ (5.3.0-r0)
(6/27) Purging gcc (5.3.0-r0)
(7/27) Purging binutils (2.25.1-r0)
(8/27) Purging isl (0.14.1-r0)
(9/27) Purging libatomic (5.3.0-r0)
(10/27) Purging libc-dev (0.7-r0)
(11/27) Purging musl-dev (1.1.12-r2)
(12/27) Purging perl-dev (5.22.1-r0)
---------------(以下省略)----------------

といった感じ。要点さえつかめば簡単ですね?

まとめ

apkを利用すれば簡単にパッケージを手に入れることもできるし、ソースコンパイルからビルドしてインストールすることもできます。apkさえ操れれば、あとは普通のLinuxの操作です。

さて、ここまでできればAlpineでどうにかやっていけそうですよね。というわけで、次回はAlpineの軽量さを活かしたDockerイメージの作り方について書きまする。