次の手順でインターフェイスを表示できることがわかりますip a show
。これにはホストが表示できるインターフェイスのみが表示され、コンテナで構成された仮想インターフェイスはこのリストには表示されません。また、試してみましたが、ip netns
どちらも表示されません。別のバージョンを再コンパイルする必要がありますかiproute2
?/proc/net/fb_trie
ローカル/ブロードキャストアドレスが転送データベースとして使用されていることがわかります。
この情報またはすべてのインターフェイス(コンテナを含む)を一覧表示するコマンドはどこにありますか?
これをテストするには、コンテナを起動してください。私の場合は、スナップのlxcコンテナでした。ip a
またはを作成してくださいip l
。ホストビューは表示されますが、コンテナ構成へのインターフェイスは表示されません。コンテナは単にcgroupedプロセスなので、grepingしていますが、procfs
arpエントリ以外には何も得られません。fib_trie
私はこれがnetns名前空間の混乱のためかもしれないと思いましたが、ip netns
それも何も表示されません。
conntrack -L
lxdはパケット転送のための接続追跡を必要とするので、確立されたすべての着信および発信接続を表示するために使用できますが、またはを使用してわかるnetstat
方法など、システムに設定されているすべてのIPアドレスを一覧表示したいと思いますlsof
。
答え1
与えられた時間のインタフェースは次のとおりです。ネットワークネームスペースそしてただ一つだけです。 init(初期)ネットワークネームスペースには、破壊されたネットワークネームスペースの物理インターフェイスを継承する以外に、他のネットワークネームスペースの特別な機能はありません。インターフェイスを直接表示できません。 initのpidおよびmountネームスペースにある限り、利用可能な他の情報を使用してネットワークネームスペースを見つけることができ、/proc
最終的にそのネットワークネームスペースを入力してそのインターフェースを表示できます。
シェルで例を提供します。
ネットワークネームスペースの列挙
これを行うには、リソースが名前空間を維持できる限り、これらの名前空間がどのように存在するかを知る必要があります。ここで、リソースはプロセス(実際にはプロセスのスレッド)、マウントポイント、またはオープンファイル記述子(fd)です。これらのリソースは、すべての名前空間を列挙し、
/proc/
抽象擬似ファイルを指す擬似ファイルシステムで参照されます。nsfs
ファイルに関する唯一の意味のある情報は、ネットワーク名前空間を表す対応するinodeです。ただし、inodeはそれ自体では機能できず、ファイルでなければなりません。そのため、後でinode値(で提供)のみを維持することはできませんstat -c %i /proc/some/file
。重複エントリを削除できるように inode を維持します。そしてまだ利用可能な参照を持つファイル名nsenter
後。プロセス(実際にはスレッド)
最も一般的な場合:一般的なコンテナの場合。各スレッドのネットワーク名前空間は参照として知られています
/proc/pid/ns/net
。これをインポートして、stat
固有の名前空間をすべて列挙するだけです。一時プロセスが見つからない場合は非2>/dev/null
表示にします。stat
find /proc/ -mindepth 1 -maxdepth 1 -name '[1-9]*' | while read -r procpid; do stat -L -c '%20i %n' $procpid/ns/net done 2>/dev/null
特化したスキルでより速くできます。
lsns
このコマンドは名前空間を処理しますが、プロセスのみを処理するようです(以下に示すように、マウントポイントやオープンfdではありません)。lsns -n -u -t net -o NS,PATH
(後で再フォーマットする必要があります
lsns -n -u -t net -o NS,PATH | while read inode path; do printf '%20u %s\n' $inode "$path"; done
)マウントポイント
これは、マウントを介して永続ネットワーク名前空間を生成するコマンドに主に使用されます。
ip netns add
これにより、それを保持するプロセスやfdリソースがない場合に消えるのを防ぎ、たとえばネットワーク上でルーター、ファイアウォール、またはブリッジを実行することもできます。関連付けられたプロセスがない名前空間です。マウントされた名前空間(マウント処理とpid名前空間処理はより複雑になるかもしれませんが、とにかくネットワーク名前空間にのみ興味がある)は、ファイルシステム
/proc/mounts
タイプの他のマウントポイントと似ていますnsfs
。シェルでは、ネットワーク名前空間と異なる種類の名前空間を区別する簡単な方法はありませんが、nsfs
同じファイルシステム(ここ)の両方の擬似ファイルは同じinodeを共有しないため、両方を選択して後で無視するだけです。ネットワーク以外の名前空間参照をネットワーク名前空間ステップとして使用しようとしたときのインタフェース。申し訳ありません。以下は、特殊文字(スペースを含む)を含むマウントポイントを正しく処理しません。これはすでに/proc/mounts
出力からエスケープされているためです(他の言語では簡単になります)。したがって、null 出口を使用しません。ワイヤー。awk '$3 == "nsfs" { print $2 }' /proc/mounts | while read -r mount; do stat -c '%20i %n' "$mount" done
オープンファイル記述子
名前空間の作成時に一時的に除外される場合を除き、マウントポイントよりもまれですが、複数の名前空間を処理する一部の特殊アプリケーション(一部のコンテナ化技術を含む)で保持して使用できます。
/proc/pid/fd/
すべてで利用可能なすべてのfdを検索し、statを使用してそれがネームスペースを指していることを確認しnsfs
、それが実際にネットワークネームスペースであるかどうかをもう気にしないよりも良い方法を考案することはできません。より最適化されたループがあると確信していますが、少なくとも前後に移動したり、最大プロセス制限を想定していないループです。find /proc/ -mindepth 1 -maxdepth 1 -name '[1-9]*' | while read -r procpid; do find $procpid/fd -mindepth 1 | while read -r procfd; do if [ "$(stat -f -c %T $procfd)" = nsfs ]; then stat -L -c '%20i %n' $procfd fi done done 2>/dev/null
これで、前の結果から重複したネットワーク名前空間参照をすべて削除します。たとえば、最初の3つの結果の結合出力(特に開かれたファイル記述子セクション)にこのフィルタを使用すると、次のようになります。
sort -k 1n | uniq -w 20
各名前空間のインタフェースを列挙する
すべての既存のネットワーク名前空間(および無視するネットワークではなく一部の名前空間)への参照があるので、参照を使用して各名前空間を入力してインターフェイスを表示するだけです。
前のコマンドの出力をこのループへの入力として使用し、前述のようにビネットワークの名前空間に起因するエラーを無視しながらインターフェイスを列挙します(OPの質問に従ってそのアドレスを表示するように選択します)。
while read -r inode reference; do if nsenter --net="$reference" ip -br address show 2>/dev/null; then printf 'end of network %d\n\n' $inode fi done
pid 1を参照として使用して、initネットワークのinodeを印刷できます。
echo -n 'INIT NETWORK: ' ; stat -L -c %i /proc/1/ns/net
実行中のLXCコンテナの出力例(実際の編集済み)、ip netns add ...
接続されていないブリッジインターフェイスを持つ空の「マウントされた」ネットワークネームスペース、プロセスdummy0
によってアクティブに保たれる他のインターフェイスを持つネットワークネームスペースいいえこれはネットワークネームスペースにありますが、次のように作成されたオープンfdを残します。
unshare --net sh -c 'ip link add dummy0 type dummy; ip address add dev dummy0 10.11.12.13/24; sleep 3' & sleep 1; sleep 999 < /proc/$!/ns/net &
そしてlo
Firefoxは、接続されていないネットワークネームスペース(すべてのダウンストリームインターフェイス)に分離された各「Webコンテンツ」スレッドを使用して実行されます。
不明127.0.0.1/8::1/128 eth0 の 192.0.2.2/24 2001:db8:0:1:bc5c:95c7:4ea6:f94f/64 fe80::b4f0:7aff:fe76:76a8/64 無線LAN0オフ dummy0 不明 198.51.100.2/24 fe80::108a:83ff:fe05:e0da/64 lxcbr0 10.0.3.1/24 2001:db8:0:4::1/64 fe80::216:3eff:fe00:0/64 virbr0 ダウン 192.168.122.1/24 virbr0-nic ダウン vethSOEPSH@if9 UP fe80::fc8e:ff:fe85:476f/64 ネットワークエンド 4026531992 低い ネットワークエンド 4026532418 低い ネットワークエンド 4026532518 低い ネットワークエンド 4026532618 低い ネットワークエンド 4026532718 不明127.0.0.1/8::1/128 eth0@if10 最大 10.0.3.66/24 fe80::216:3eff:fe6a:c1e9/64 ネットワークエンド 4026532822 低い ブリッジ0 不明 fe80::b884:44ff:feaf:dca3/64 ネットワークエンド 4026532923 低い 仮想0が10.11.12.13/24削除されました ネットワークエンド 4026533021 ネットワーク初期化: 4026531992
答え2
ip netns list
ユーティリティで設定されたネットワーク名前空間のみが一覧表示されますip-netns(8)
。
lsns(1)
パッケージに含まれるutil-linux
プログラム真剣に足りない/proc/<pid>/ns/*
:すべてのスレッド固有の名前空間と、バインドマウントまたは開かれたファイル記述子を介して保持される名前空間を無視し、ファイルを介してアクセスできる名前空間のみを一覧表示します。
次のデモスクリプトは、1つのより良い操作を試みます。ファイルを介してバインドマウントを探し、ファイルを介して/proc/<pid>/task/<tid>/mountinfo
開いたfdを見つけます。/proc/<pid>/task/<tid>/fd
各名前空間に対して、その名前空間にアクセスできるパスを印刷します。
# perl ./lsnsx.pl
...
mnt 3
4026531840 /proc/1/ns/mnt
4026531860 /proc/30/ns/mnt
4026532374 /proc/3119/ns/mnt
net 6
4026531992 /proc/1/ns/net
4026532376 /proc/25781/fd/9
4026532465 /proc/28373/fd/7
...
その後、そのパスを使用できますnsenter(1)
。
nsenter --net=/proc/28373/fd/7 ip link
これを直接実行したり、名前空間を使用したプロセス全体のリストなどの追加情報を表示するようにスクリプトを簡単に変更したりできます。
/proc/<pid>/mountinfo
パスにアクセスできない場合は、親/マウントIDとパスを見つけたファイルが続きます。エスケープされた改行、タブ、スペースはそのまま残ります。
net 9
...
4026532732 /v/net\040ns /proc/3119/mountinfo 60 41
これらすべてのファイルを読み取る必要があるため、/proc/*/task/*
マルチスレッドプログラムを使用するすべてのシステムで速度が遅くなる可能性があります。残念ながら、両方のスレッド/タスクが同じ名前空間を共有していることを確認する簡単な方法が見つかりませんkcmp(2)
。それらは同じアドレス空間、ファイル記述子テーブルなどを共有し、名前空間とは関係ありません。
lsnsx.pl
:
#! /usr/bin/perl
use strict;
my %t2n = (
# the CLONE_NEW* from sched.h
0x02000000 => "cgroup", 0x04000000 => "uts", 0x08000000 => "ipc",
0x10000000 => "user", 0x20000000 => "pid", 0x40000000 => "net",
0x00020000 => "mnt" # CLONE_NEWNS
);
my (%ns);
my $nsfs_dev = (stat "/proc/self/ns/mnt")[0];
my $type = shift || qr/\w+/;
sub unescape { $_[0] =~ s/\\([0-7]{3})/chr oct $1/ger }
# NS_GET_NSTYPE = 0xb7 << 8 | 3
sub nstype { my $h; open $h, $_[0] and ioctl $h, 0xb7 << 8 | 3, 0 }
for(</proc/[0-9]*/task/[0-9]*/{ns/*,fd/*,mountinfo}>){
s{/([0-9]*)/task/\1/}{/$1/};
if(my ($procpid) = m{(.*)/mountinfo$}){
open my $h, $_ or next;
LOOP: while(<$h>){
next unless (my @s = split)[2] eq "0:$nsfs_dev";
if(my($t, $i) = $s[3] =~ /^($type):\[(\d+)\]$/){
next if exists $ns{$t}{$i};
for ("", "$procpid/root"){
my ($d, $i1) =
(stat $_.unescape $s[4])[0, 1];
$ns{$t}{$i} = $_.$s[4], next LOOP
if $d == $nsfs_dev && $i == $i1;
}
$ns{$t}{$i} = "@s[4, 0, 1] $procpid/mountinfo"
}
}
}elsif(m{/ns/}){
$ns{$1}{$2} //= $_ if readlink =~ /^($type):\[(\d+)\]$/;
}else{
next unless my ($dev, $ino) = stat $_;
next unless $dev == $nsfs_dev;
next unless my $t = nstype $_;
next if ($t = $t2n{$t}) and $t !~ $type;
$ns{$t // '???'}{$ino} //= $_;
}
}
for my $type (sort keys %ns){
my $h = $ns{$type}; my @i = sort {$a<=>$b} keys %$h;
printf "%-8s %d\n", $type, scalar @i;
printf " %-11d %s\n", $_, $$h{$_} for @i;
}