unshare
自分だけを含む新しいネットワーク名前空間を作成するプロセス呼び出しがあります。 start bashを呼び出すと、execve
ipコマンドはデバイスが1つしかないことを示しますlo
。ユーザーネームスペースも作成し、そのネームスペース内でプロセスをルートとしてスケジュールすると、そのip
コマンドを使用してデバイスを起動して機能します。
このコマンドを使用して、この名前空間にip
デバイスを作成することもできます。ただし、期待どおりにveth
ルートレベルの名前空間には表示されず、ip netns list
新しいデバイスもルートレベルの名前空間には表示されません。ルートレベルの名前空間のデバイスをプロセスの名前空間の新しいデバイスに接続するにはveth
?このコマンドは、名前空間にコマンドによって割り当てられた名前を持つように要求するようです。私のコマンドは名前空間を作成するために使用していなかったので必要ありません。veth
veth
ip
ip
ip netns add
おそらく、netlinkデバイスを使用して設定するプログラムを直接書くことでこれを行うことができます。しかし、私は本当にそうしたくありません。コマンドラインでこれを行う方法はありますか?
Dockerコンテナにも独自のネットワーク名前空間があり、その名前空間にも名前がないため、これを行う方法が必要です。ただし、内部には外部機器veth
に接続する機器があります。veth
私の目標は、理想的には、コンテナの外部でルートになる必要なしにプロセス分離コンテキストを動的に生成することです。これを行うには、PIDネームスペース、UIDネームスペース、ネットワークネームスペース、IPCネームスペース、およびマウントネームスペースを作成します。 cgroup名前空間を作成することもできますが、これは新しいものであり、現在サポートされているSLES、RHEL、およびUbuntu LTSのバージョンで実行できる必要があります。
私はこの名前空間を一度に1つずつ作業してきましたが、現在ユーザー、PID、およびマウント名前空間がうまく機能しています。
必要に応じてマウントできますが、/proc/pid/ns/net
名前空間の外側のルートになる必要がないように、ユーザーの名前空間内でマウントすることをお勧めします。ほとんどの場合、名前空間のすべてのプロセスが消えると、すべてが消えると予想されます。タスクが完了したら、ファイルシステムで複数の状態をクリーンアップするのは理想的ではありません。コンテナが最初に割り当てられたときに一時的に作成し、すぐに削除することは、コンテナが終了したときにクリーンアップするよりもはるかに優れています。
いいえ、使用できません。ドッカー、長沙、ククト、または他の既存のソリューションを使用した湿地標準システムユーティリティ(例:アイピー)、次のシステムライブラリglibc、Linuxシステムコール。
答え1
ip link
ネットワーク名前空間名に加えて使用できる名前空間オプションがあります。PID参照されるプロセスの名前空間です。もしPID名前空間プロセス間で共有されるため、デバイスを任意の方向に移動できます。これがおそらく最も簡単な方法です。~へ、考えるとPID 1存在する「外部」。別にPID名前空間外部(PID)名前空間から内部名前空間に移動する必要があります。
たとえば、ネットワーク名前空間内で次のように作成できます。veth デバイスペア到着PID 1名前空間:
ip link add veth0 type veth peer name veth0 netns 1
Linuxでネームスペースがどのように機能するか
各プロセスには、その名前空間の参照ファイルがあります/proc/<pid>/ns/
。また、このファイルはip netns
次の/run/netns/
ファイルと関連があります。setns
システムコールは、実行中のスレッドの名前空間を、このファイルが指す名前空間に変更します。
シェルでは、次を使用して別の名前空間を入力できます。nsenter
プログラムは引数に名前空間ファイル(パス)を提供します。
Linux 名前空間の良い概要については、以下を参照してください。実行中の名前空間LWN.netの記事シリーズ。
名前空間の設定
複数の名前空間を設定する場合(マウント、pid、ユーザー、など)、変更前にネットワークネームスペースを設定してください。山そしてPID名前空間。共有していない場合山またはPID名前空間の場合、外部ネットワーク名前空間を参照するファイルが表示されないため、外部ネットワーク名前空間を指す方法はありません。
コマンドラインユーティリティが提供するよりも柔軟性が必要な場合は、システムコールを使用してプログラムから直接名前空間を管理する必要があります。ドキュメントについては、関連するマニュアルページを参照してください。man 2 setns
、man 2 unshare
そしてman 7 namespaces
。
答え2
Aはveth
一対のデバイスで構成され、各デバイスを通信するネットワークネームスペース(またはルートネームスペース)に配置します。
これは、新しいネットワークネームスペースを作成し、ルートネームスペースとネットワークネームスペースの間にvetペアを設定するためにルートネームスペースからルートとして呼び出されるスクリプトです。最後の行はその名前空間でxtermを起動します。必要に応じて調整してください。
#!/bin/bash
# Setup network namespace with veth pair, start xterm in it
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
NS=${1:-ns0}
DEV=${2:-veth0}
DEV_A=${DEV}a
DEV_B=${DEV}b
ADDR=${3-:10.0.0}
ADDR_A=${ADDR}.254
ADDR_B=${ADDR}.1
MASK=${5:-24}
COL=${4:-yellow}
# echo ns=$NS dev=$DEV col=$COL mask=$MASK
ip netns add $NS
ip link add $DEV_A type veth peer name $DEV_B netns $NS
ip addr add $ADDR_A/$MASK dev $DEV_A
ip link set ${DEV}a up
ip netns exec $NS ip addr add $ADDR_B/$MASK dev $DEV_B
ip netns exec $NS ip link set ${DEV}b up
ip netns exec $NS ip route add default via $ADDR_A dev $DEV_B
ip netns exec $NS su -c "xterm -bg $COL &" your_user_id
また、使用することができます
ip link set name_of_if netns name_of_ns
ネットワークネームスペース間でネットワークインターフェイス(物理デバイスへのインターフェイスを含む)を移動します。
編集する
今テストしました。ペアを作成することもできます。以内に新しい名前空間を作成し、エンドポイントをルート名前空間に配置します。秘密は、ルートネームスペースには明らかに名前はありませんが、idでアクセスできるということです1
。
sudo ip link add veth1b type veth peer name veth1a netns 1
どのように機能するかはわかりませんが、unshare
新しく作成されたネットワーク名前空間を何らかの形で見つけることができるようです /proc/<pid>/ns/<type>
。名前がない場合は、少なくとも数字IDが必要です。ip netns list
ヘルプも利用可能です。私はこれすべてです。を使用する代わりに、システムコールを介して実行することも、ip
何かを把握するのに役立ちますstrace
。ltrace
編集する
私はman namespaces 7
名前空間を調べるだけで十分だと思います(ファイル記述子が1つしかありません)、名前空間を作成してからプログラムを起動する方が良いと思います/proc
。あなたが仮定ip netns add
ip netns exec
unshare
ただそれ以外の新しいネットワーク名前空間が必要です。