docker rootlessでコンテナ内でファイルを作成するとsubuidで設定しているユーザ所有になってしまう。
% ll hoge.txt
-rw-r--r-- 1 100999 100999 6 2024-01-28 12:41 hoge.txt
一般ユーザのままでchownではエラーになってしまう。
% chown myuser:myuser hoge.txt
chown: changing ownership of 'hoge.txt': Operation not permitted
正しいのか分からないが以下でできた。
% rootlesskit -- chown 0:0 hoge.txt
(2024/04/11追記)
rootlesskitで解決できる理由がわかったのでメモ。
testuserのuidが1000、subuidで100000から65536個分割り当たっているとする。
dockerではsubuidやsubgidでユーザID空間を分け擬似的にrootになった状態にしている。
マッピングの状態は、実際にマッピングされたプロセスに対して以下の処理をすれば確認できるが、docker内のプロセスはプロセス空間も分離されていてホスト上でpsしても見れないので、まず適当にユーザID空間を分けた状態を作る。
% rootlesskit bash
これのpidを確認。
% ps aux|grep 'bash.*testuser'
そのpidについて、uid_mapを確認。
% cat /proc/3371297/uid_map
0 1000 1
1 100000 65536
意味 (分離空間上uid) (ホスト上uid) (いくつ分か)
分離空間上のuid0番がホスト上のuid1000(ホスト上のtestuser)になっている。
分離空間上のuid1以降は飛んで、1が100000(subuidで割りあたっている最初のもの)、2が100001…とマッピングされている。
そのためdocker内でrootで作ったファイルはホスト上ではtestuser所有になっており、1以降のファイルは100000以降(ホスト上では特に名前は割りあたっていないのでls -lしてもuidのまま表示される)になっている。
100000以降のファイルはホスト上でtestuserのままで消そうと思っても消せない。rm等がuidのマッピングを気にしてくれないから。
rootlesskit -- chown root:rootしてから消せばOK。
参考資料。
https://gihyo.jp/admin/serial/01/linux_containers/0016
https://github.com/rootless-containers/rootlesskit?tab=readme-ov-file#usage