como descobrir o namespace de um processo específico?

25

Eu já fiz uma pergunta sobre como listar todos os namespaces no Linux , mas não havia respostas corretas e exatas, portanto, quero descobrir um método que possa me ajudar a descobrir o namespace do PID de algum processo ou grupo de processos. Como isso pode ser feito no Linux?

zerospiel
fonte

Respostas:

39

Tentarei responder a essa e à sua pergunta anterior , pois estão relacionadas.

As portas dos namespaces são arquivos em /proc/*/ns/*e /proc/*/task/*/ns/*.

Um espaço para nome é criado por um processo que compartilha seu espaço para nome. Um espaço para nome pode ser tornado permanente montando o nsarquivo em outro local.

É o que ip netnsocorre, por exemplo, nos namespaces da rede . Ele unshares seu netnamespace e bind-montagens /proc/self/ns/netpara ./run/netns/netns-name

Em um /procespaço para nome montado pid raiz, você pode listar todos os espaços para nome que possuem um processo, fazendo:

# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]

O número entre colchetes é o número do inode.

Para obter isso para um determinado processo:

# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid

Agora, pode haver namespaces permanentes que não possuem nenhum processo. Encontrá-los pode ser um AFAICT muito mais complicado.

Primeiro, você deve ter em mente que pode haver vários namespaces de montagem .

# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw

Aqueles /mnt/1/a, /run/netns/apodem ser arquivos de namespace.

Podemos obter um número de inode:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a

Mas isso não nos diz muito mais do que não está na lista computada acima.

Podemos tentar inseri-lo como qualquer um dos diferentes tipos:

# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#

OK, esse era um netarquivo de espaço para nome.

Portanto, parece que temos um método para listar os espaços de nomes: liste os nsdiretórios de todas as tarefas, encontre todos os procpontos de montagem em todos os /proc/*/task/*/mountinfoe descubra seu tipo tentando inseri-los.

Stéphane Chazelas
fonte
19

Se você possui o util-linux v2.28 ou superior, pode usar lsns :

# lsns
        NS TYPE  NPROCS   PID USER             COMMAND
4026531836 pid       78     1 root             /sbin/init
4026531837 user      79     1 root             /sbin/init
4026531838 uts       78     1 root             /sbin/init
4026531839 ipc       78     1 root             /sbin/init
4026531840 mnt       75     1 root             /sbin/init
4026531857 mnt        1    12 root             kdevtmpfs
4026531957 net       79     1 root             /sbin/init
4026532393 mnt        1  1214 root             /lib/systemd/systemd-udevd
4026532415 mnt        1  2930 systemd-timesync /lib/systemd/systemd-timesyncd
4026532477 mnt        1 32596 root             -bash
4026532478 uts        1 32596 root             -bash
4026532479 ipc        1 32596 root             -bash
4026532480 pid        1 32596 root             -bash

Correção: lsns não está disponível no util-linux v2.27, como costumava dizer esta resposta. Veja https://www.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes

Rfraile
fonte
Também há um bom script python que encontrei para aqueles que usam Linux mais antigo. opencloudblog.com/?p=251
Neil McGill
lsnsé muito útil, mas mostra apenas o PID mais baixo em cada espaço para nome - ou seja, não pode indicar o espaço para qualquer PID arbitrário. +1 de qualquer maneira, porque ainda é uma resposta útil, mesmo que não responda diretamente à pergunta.
cas
9
$ ip netns identify $PID

onde $PIDestá o ID do processo, que você pode obter de várias maneiras.

http://man7.org/linux/man-pages/man8/ip-netns.8.html

Ken Sharp
fonte
11
Observe que é apenas para namespaces de rede e somente aqueles criados usando ip netns(ou pelo menos criados por algo que monta as portas do namespace em / run / netns, como ip netnsfaz). Basicamente, procura em / run / netns arquivos que são iguais a /proc/$PID/ns/net.
Stéphane Chazelas 22/02
O que? /run/netnsnem existe no meu computador.
Ken afiada
/run/netnsou onde quer que o ipbind-monta os arquivos especiais do espaço para nome. findmnt -t nsfspode dizer onde está no seu sistema. OTOH, se você fizer unshare -n sleep 1000 & ip netns identify "$!", você não receberá nada.
Stéphane Chazelas
findmnt -t nsfs- nada. unshare -n sleep 1000 & ip netns identify "$!"- unshare: unshare falhou: Operação não permitida
Ken afiada
Você precisa de privilégios de superusuário (capacidade CAP_SYS_ADMIN) para criar um novo netns. findmnt -t nsfsdevolver nada sugere que você não possui redes no caixa eletrônico da máquina.
Stéphane Chazelas
9

psagora tem opções de saída para os diferentes tipos de namespaces associados a processos: ipcns, mntns, netns, pidns, userns, e utsns. Para esta pergunta, a relevante é o espaço para nome PID, ou pidns.

portanto, se você deseja descobrir o ID do namespace do PID, por exemplo, pid 459:

# ps -h -o pidns -p 459
4026532661

e para listar todos os processos nesse espaço para nome:

ps -o pidns,pid,cmd | awk '$1==4026532661'

ou com pgrep, você pode ir diretamente de um PID para uma lista de todos os processos que compartilham o mesmo espaço de nome do PID:

pgrep -a --ns 459

Ao contrário ps, pgreppode limitar a saída a um espaço de nome específico (se você conhece o PID de um dos processos nele), mas possui recursos de formatação de saída muito limitados (apenas PIDs ou PIDs e suas linhas de comando)

Você sempre pode canalizar a saída de pgrep --ns 459para xargs ps -fpara recuperar as informações necessárias sobre o processo.

cas
fonte
0

Namespace-Lister :

Você pode usar listns.py

Uso: ./listns.pyou python2 listns.pyPara responder exatamente a essa pergunta, você pode receber o resultado dessa forma python2 listns.py | grep $PID(substituir a variável pid)

Fonte: github-mirror e artigo - todos os créditos a Ralf Trezeciak

Namespaces de rede :

Para o namespace da rede, ip netns identify $PIDpode ser usado.

Nsutils

Forneça pidnslistque retorne o namespace pid de um processo

$ pidnslist -ss 8782
pid:[4026531836] 
intika
fonte