
コンテナ内の TCP ネットワークの問題を調査しているときに、ss
コンテナ ネットワーク TCP スタックを覗き見るために使用してみました。
AWS で Amazon Linux を実行しています。
# uname -a
Linux 4.14.173-137.229.amzn2.x86_64 #1 SMP Wed Apr 1 18:06:08 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
ss
これには次の CLI スイッチがあります。
-N NSNAME, --net=NSNAME
Switch to the specified network namespace name.
lsns
次のような出力が得られます。
# lsns | grep net
4026531993 net 225 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 21
4026532284 net 2 26244 root /pause
これはpause
各ポッドに対して作成されるコンテナでありKubernetes
、ネットワーク名前空間を作成するコンテナです。
次のコマンドを実行して、ポッド ネットワークの名前空間を覗いてみますss
:
# ss -tp -N 4026532284
Cannot open network namespace "4026532284": No such file or directory
興味深いのは、 ip netns list
ネットワーク名前空間を返さないことです。
# ip netns list
#
ルート ネットワーク名前空間、つまり netns 1 から K8s ポッド ネットワーク名前空間を調べる方法はありますか?
# ss --version
ss utility, iproute2-ss180129
# lsns --version
lsns from util-linux 2.30.2
# rpm -qi iproute
Name : iproute
Version : 4.15.0
Release : 1.amzn2.0.4
Architecture: x86_64
Install Date: Sat 07 Mar 2020 03:42:24 AM UTC
Group : Applications/System
Size : 1321292
License : GPLv2+ and Public Domain
Signature : RSA/SHA256, Fri 21 Feb 2020 09:00:29 PM UTC, Key ID 11cf1f95c87f5b1a
Source RPM : iproute-4.15.0-1.amzn2.0.4.src.rpm
Build Date : Fri 21 Feb 2020 07:56:50 PM UTC
Build Host : build.amazon.com
Relocations : (not relocatable)
Packager : Amazon Linux
Vendor : Amazon Linux
URL : http://kernel.org/pub/linux/utils/net/iproute2/
Summary : Advanced IP routing and network device configuration tools
更新: 2020年12月1日火曜日 11:35:39 UTC
苦労の末、ついにstrace
これに決めました。
これは素晴らしいツールであることがわかりましたss
が、コンテナで使用するとなると少し物足りないところがあります。しかし、そこには複数の「犯人」が関与していると感じています。
ss
ネットワーク名前空間を作成するプロセスの実際の PID を検索するのではなく、直接チェックします/var/run/netns
。
openat(AT_FDCWD, "/var/run/netns/4026532284", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(2, "Cannot open network namespace \"4"..., 70Cannot open network namespace "4026532284": No such file or directory
) = 70
iproute
さて、これはパッケージの作成方法によるものではないかと考えています。つまり、パッケージに同梱されていることをnetwork namespaces
考えると、ネットワーク名前空間に関する想定は、「すべてのネットワーク ns はディレクトリ内にあるはずです。なぜなら、そうしない理由がないからです。また、これにより開発者の生活が楽になります」などとなります。ss
iproute
ip
/var/run/netns
iproute
ss
これは/側の誤った仮定iproute
、または最新のコンテナツールとiproute
相互運用性に関する「合意」の欠如であることが判明しましたが、これは次のような空の出力をある程度説明しています。
ip netns list
したがって、ネットワーク名前空間を作成する方法ip
( によって検査できるようにするためss
)は、Kubernetes などがネットワーク名前空間を作成する方法とは明らかに一致せず、iproute
全体的な計画ではパッケージ ユーティリティがほとんど役に立たないものになります。
答え1
より一般的な方法は、nsenter(1)
。
nsenter -t ${PID_FOO} -muni ss -tpi
次のようなアプローチが一般的です。アドホックなものを実行する必要があるときに、必ずしもサポートされていないものを使用する。unshare(2)
/setns(2)
内蔵。
docker run -it --rm --security-opt=seccomp:unconfined \
--security-opt=apparmor:unconfined \
--privileged --pid=host --userns=host \
debian:jessie@sha256:51cd80bb935b76fbbf49640750736abc63ab7084d5331e198326b20063e7f13c \
nsenter -t ${PID_FOO} -m -u -n -i -F ss -tpi
答え2
特定のコンテナ名前空間を覗き見るために使用したい場合は、ss
次のようにします。
コンテナプロセスのPIDを調べる
ps aux
か、ps -ef
答えを出す必要があります次のシンボリックリンクを作成します
ln -s /proc/PID/ns/net /var/run/netns/mycontainer
- 利益
ss -tpi -N mycontainer
答え3
最新バージョンをお持ちの場合はlsnsオプションを使用することができます-n -o NSFS名前空間の inode をネットワーク サブシステムで使用される ID に変換します。
たとえば、net NS 4026536974 があるとします。次のように実行できます。
sh-4.4# lsns --version
lsns from util-linux 2.32.1
sh-4.4# lsns -n -o NSFS 4026536974 | sort -u
/run/netns/d0912eba-0fae-425c-94ba-cf270aa23c93
sh-4.4# basename /run/netns/d0912eba-0fae-425c-94ba-cf270aa23c93
d0912eba-0fae-425c-94ba-cf270aa23c93
sh-4.4# ss -nltp -N d0912eba-0fae-425c-94ba-cf270aa23c93 | head -2
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* users:(("nginx",pid=874035,fd=5),("nginx",pid=874028,fd=5))
sh-4.4#
またはオールインワン:
sh-4.4# lsns -n -o NSFS 4026536974 | sort -u | xargs -rn1 basename | xargs -rn1 ss -nltp -N | head -2
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:5000 0.0.0.0:* users:(("nginx",pid=874035,fd=5),("nginx",pid=874028,fd=5))
sh-4.4#