dockerでsedレポートDeviceor resource busyエラーを実行する処理原因と方式


原文出典:https://www.cnblogs.com/xuxinkun/p/7116737.html


エラー現象


dockerコンテナで/etc/resolv.confのnameseverを変更したい場合、sedコマンドを使用して実行中にエラーが発生しました.
/ # sed -i 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf
sed: can't move '/etc/resolv.conf73UqmG' to '/etc/resolv.conf': Device or resource busy

しかし、vi/vimによってこのファイル/etc/resolv.confというファイルの内容を直接修正することができます.

問題の原因


sedコマンドの本質は、ファイルを修正することではなく、既存のファイルを置き換える新しいファイルを生成します.ここで私たちは実験をしました.
まずtest.txtのファイルを作成しました.ファイルの内容は123です.その後、sedコマンドを使用してファイルの内容を置き換えました.test.txtを再度確認します.
/ # stat test.txt   File: test.txt  Size: 4           Blocks: 8          IO Block: 4096   regular fileDevice: fd28h/64808d    Inode: 265         Links: 1Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)Access: 2017-07-04 06:28:35.000000000Modify: 2017-07-04 06:28:17.000000000Change: 2017-07-04 06:29:03.000000000/ # cat test.txt 123/ # sed -i 's/123/321/g' test.txt/ # stat test.txt   File: test.txt  Size: 4           Blocks: 8          IO Block: 4096   regular fileDevice: fd28h/64808d    Inode: 266         Links: 1Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)Access: 2017-07-04 06:29:31.000000000Modify: 2017-07-04 06:29:31.000000000Change: 2017-07-04 06:29:31.000000000/ # cat test.txt321

ファイルの内容が正しく修正されているのがわかりますが、同時にファイルのinodeも修正されています.実質的に新しく生成されたファイルが既存のファイルに置き換えられていることを説明した.しかしvim/viは元のファイルに基づいて修正されているのでinodeは変わりません.
dockerでは、/etc/resolv.confは容器に装着される.したがって、このマウントファイル、すなわちマウントポイントを削除したい場合は、Device or resource busyに通報します.
これは特権privilegeかどうかとは関係ありません.privilegeの容器でも、この問題があります.
/ # rm /etc/resolv.conf 
rm: can't remove '/etc/resolv.conf': Device or resource busy

実は/etc/resolv.confだけでなく、/etc/hostname/etc/hostsなどの書類も容器にマウントすることでマウントされています.だからsedで彼らを修正しようとすると、このような問題に直面します.df -hで容器内の積載状況を確認できます.
/ # df -h
Filesystem                Size      Used Available Use% Mounted on/dev/mapper/docker-253:2-807144231-37acfcd86387ddcbc52ef8dac69d919283fc5d9d8ab5f55fd23d1c782e3b1c70                         10.0G     33.8M     10.0G   0% /tmpfs                    15.4G         0     15.4G   0% /devtmpfs                    15.4G         0     15.4G   0% /sys/fs/cgroup/dev/mapper/centos-home                        212.1G    181.8G     30.3G  86% /run/secrets/dev/mapper/centos-home                        212.1G    181.8G     30.3G  86% /dev/termination-log/dev/mapper/centos-home                        212.1G    181.8G     30.3G  86% /etc/resolv.conf/dev/mapper/centos-home                        212.1G    181.8G     30.3G  86% /etc/hostname/dev/mapper/centos-home                        212.1G    181.8G     30.3G  86% /etc/hostsshm                      64.0M         0     64.0M   0% /dev/shmtmpfs                    15.4G         0     15.4G   0% /proc/kcoretmpfs                    15.4G         0     15.4G   0% /proc/timer_stats

解決方法


viを使うのはもちろんですが、一括操作には向いていません.置換は、sedとechoの組合せコマンドecho "$(sed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf)" > /etc/resolv.confによって実現することができる.
/ # cat /etc/resolv.conf 
search default.svc.games.local svc.games.local games.localnameserver 192.168.1.1options ndots:5/ # echo "$(sed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf)" >  /etc/resolv.conf
/ # cat /etc/resolv.conf 
search default.svc.games.local svc.games.local games.localnameserver 192.168.1.254options ndots:5

ここではsed 's/192.168.1.1/192.168.1.254/g' /etc/resolv.conf > /etc/resolv.confを使用すると無効です.最終的には、/etc/resolv.confのコンテンツが空になります.