archlinuxコンテナをターミナル開発環境として使う
dockerコンテナをいろいろと開発用ツールを詰め込んだ作業用環境として使ってます。
パッケージを入れたり外したりする関係で、簡単にゼロクリアできる開発環境が必要なので重宝しているのですが、、結構とらぶります。
そもそもコンテナは軽量化のために対話で使う際の機能なんかはかなりごっそりと切り落としていますし、セキュリティの観点で権限管理も固く作られているので、通常利用するときのようにホイホイ一般ユーザを作ってそのユーザで作業しようとするきにけっつまづくとか。
これまではubuntuコンテナこの役割を担わせていたのですが、最近ホスト自体をarchlinuxに差し替えてみたこともあり、このターミナル開発環境コンテナもarchlinux化してみました。
案の定、色々トラブったので、そこら辺のtipsをまとめます。
前提条件
archlinux:latestに対して、一般ユーザを作成し、sudoを導入して、通常時は一般ユーザで色々作業するようにしてます。
トラブル色々
manが使えない
man-dbをインストールしても、manが通りません。
結論からいうと、/etc/pacman.confが原因です。
% man ls
No manual entry for ls
archlinuxコンテナの設定では、pacmanでパッケージを導入した際、manなどのドキュメント系のファイルは導入しないようにする設定が入っています。
% cat /etc/pacman.con
...
[options]
NoExtract = usr/share/help/* !usr/share/help/en*
NoExtract = usr/share/gtk-doc/html/* usr/share/doc/*
NoExtract = usr/share/locale/* usr/share/X11/locale/* usr/share/i18n/*
NoExtract = !*locale*/en*/* !usr/share/i18n/charmaps/UTF-8.gz !usr/share/*locale*/locale.*
NoExtract = !usr/share/*locales/en_?? !usr/share/*locales/i18n* !usr/share/*locales/iso*
NoExtract = !usr/share/*locales/trans*
NoExtract = usr/share/man/* usr/share/info/*
NoExtract = usr/share/vim/vim*/lang/*
下から2行目ですね。
ただし、これだけ直してもだめです。
この設定した「後」にインストールするパッケージ分はいいのですが、最初から入っているパッケージの分はすでにmanなしでインストールされてしまっているので、改めてインストールし直さないといけないわけですね。
対策としては以下みたいに再インストールする方法もありますが、、
# pacman -S coreutils
$ man ls
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
...
まぁきりないので、man-pagesをインストールするのが無難でしょうか。
これで、解決。多分。
Dockerfileに仕込むならこんなでしょうか。
RUN sed -i -e 's|^\(NoExtract *= *usr/share/man/\)|#\1|' /etc/pacman.conf$
pingができない
sudoすれば大丈夫なのですが、一般ユーザ権限だとpingが打てません。。
原因は権限管理でした。
% ping localhost
% echo $?
2
pingはもともとrootじゃないと実施でいないものを、色々設定で一般ユーザでも実施できるようにしているようで。
以下で勉強させていただきまして。
https://blog.ssrf.in/post/ping-does-not-require-cap-net-raw-capability/
https://tenforward.hatenablog.com/entry/2019/11/27/022547
で。
% sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 1 0
man icmpによると、上記は which means no group is allowed to create ICMP Echo socketsの意味とのこと。
一方、ホストにインストールしているarchlinuxを見ると、"net.ipv4.ping_group_range = 0 2147483647"となっていて、これはどのユーザグループもpingを打たせてもらえる、ということだそうで。
ではどこでその設定の差分が出ているかというと、、ちょっとややこしい。
まず、この設定は/usr/lib/sysctl.d/50-default.confに入っています。
このファイルの中身は、ホストにインストールしたものもコンテナも一緒。
一緒なのになぜ動きが違うかというと、、、
# sysctl -p /usr/lib/sysctl.d/50-default.conf
sysctl: permission denied on key "kernel.sysrq"
sysctl: permission denied on key "kernel.core_uses_pid"
sysctl: permission denied on key "net.ipv4.conf.default.rp_filter"
sysctl: cannot stat /proc/sys/net/ipv4/conf/*/rp_filter: No such file or directory
sysctl: permission denied on key "net.ipv4.conf.all.rp_filter", ignoring
sysctl: permission denied on key "net.ipv4.conf.default.accept_source_route"
sysctl: cannot stat /proc/sys/net/ipv4/conf/*/accept_source_route: No such file or directory
sysctl: permission denied on key "net.ipv4.conf.all.accept_source_route", ignoring
sysctl: permission denied on key "net.ipv4.conf.default.promote_secondaries"
sysctl: cannot stat /proc/sys/net/ipv4/conf/*/promote_secondaries: No such file or directory
sysctl: permission denied on key "net.ipv4.conf.all.promote_secondaries", ignoring
sysctl: permission denied on key "net.ipv4.ping_group_range", ignoring
sysctl: cannot stat /proc/sys/net/core/default_qdisc: No such file or directory
sysctl: permission denied on key "fs.protected_hardlinks"
sysctl: permission denied on key "fs.protected_symlinks"
sysctl: permission denied on key "fs.protected_regular"
sysctl: permission denied on key "fs.protected_fifos"
はい。
コンテナではカーネルパラメータがいじれない、、?
残念ながら裏付けは追いきれてませんが。
ちなみにubuntuコンテナでこういうケースってなかったので調べてみたのですが、ubuntu(20.4)は上記のping_group_rangeを使わず、"cap_net_raw+ep"というCapabilityをpingの実行ファイルに付与する方法をとっているようです。
Dockerfileでpingの実行ファイルに上記のCapablilityを付与する処理を追加してもいいのですが、、まぁ、、実害はないので、現状はおいておきます。
とりあえず
今回はこんなところで。
また知見溜まってたら別途書くとして。