Невозможно создать вложенное сетевое пространство имен

Кажется, что нельзя создать сетевое пространство имен из сетевого пространства имен. В результате появляется сообщение «Ошибка: ссылка на одноранговую сеть netns недействительна».

Является ли это ошибкой или существует какое-то ограничение, о котором я не знаю?

Ниже мой cmd-след ошибки.

# ip netns add foo1
# ip netns exec foo1 ip netns add foo2
# ip netns
Error: Peer netns reference is invalid.
Error: Peer netns reference is invalid.
foo2
foo1
# ip netns exec foo2 /bin/bash
setting the network namespace "foo2" failed: Invalid argument

1
задан 4 April 2019 в 16:34
1 ответ

TL; DR: Як бы дзіўна гэта ні здавалася, гэта на самой справе не праблема прасторы імёнаў сеткі , а праблема прасторы імёнаў mount . чакаецца.

Вы павінны стварыць усе новыя "прасторы імёнаў ip netns" (сэнс гл. пазней), г.зн. запусціць усе ip netns add ... каманды з пачатковай (хаста) "ip netns прасторы імёнаў", а не знутры "ip netns прасторы імёнаў", уведзенай з ip netns exec ... . Пакуль вы не ствараеце іх, вы можаце пераключаць паміж імі па жаданні, уключаючы ўкладванне каманд з адной на іншую, з ip netns exec .. .

Падрабязнае тлумачэнне з пакрокавымі прыкладамі пасля ...


ip netns спецыялізуецца на сеткавых прасторах імёнаў, але для апрацоўкі ўсіх функцый таксама неабходна змешвацца з прасторамі імёнаў для мантажу на дваіх прычыны (прынамсі, мне вядомыя):

  • прывязаць мантаж / etc / netns / FOO / SOMESERVICE да / etc / SOMESERVICE для кіравання альтэрнатыўнымі канфігурацыямі службы / дэмана

    Функцыя, якая можа быць зручнай для запуску некаторых (звязаных з сеткай) дэманаў у іншай прасторы імёнаў сеткі, але акрамя гэтага яна ўсё яшчэ з'яўляецца часткай "хаста". Вы можаце праверыць мой адказ у UL на пытанне пра гэта там: Кіраванне прасторай імёнаў з ip netns (iproute2) . Яго выкарыстанне патрабуе той жа апрацоўкі, што і наступная функцыя, таму я больш пра гэта казаць не буду.

  • перамантаж / sys , каб выставіць сеткавыя прылады новай сеткавай прасторы імёнаў у яе іерархіі

    Гэта абавязковая асаблівасць. Прыклад выкрыцця праблемы:

    Ад "пачатковага хаста":

     # ip link add dev dummy9 type dummy
     # ip -br спасылка паказаць манекен9
    фіктыўны9 УНІЗ f6: f6: 48: 9c: 12: b9 <ШЫРОКАДАЦЫЯ, NOARP>
     # ls -l / sys / class / net / dummy9
    lrwxrwxrwx.  1 корань кораня 0 красавіка 4 22:09 / sys / class / net / dummy9 -> ../../devices/virtual/net/dummy9
     

    Выкарыстанне інструмента ніжняга ўзроўню для пераходу на іншую (эфемерную) прастору імёнаў сеткі:

     # unshare --net ip -br link show dummy9
    Прылада "dummy9" не існуе.
     # скасаваць доступ --net ls -l / sys / class / net / dummy9
    lrwxrwxrwx.  1 корань кораня 0 красавіка 4 22:13 / sys / class / net / dummy9 -> ../../devices/virtual/net/dummy9
     

    І гэта праблема: / sys па-ранейшаму выстаўляе пачатковыя інтэрфейсы хаста замест інтэрфейсу новай сеткавай прасторы імёнаў. Тут адбываецца ўзаемадзеянне паміж сеткавай прасторай імёнаў і з мантажом / sys : калі / sys усталяваны з новай сеткавай прасторы імёнаў, ён пераключыцца на выстаўленне новых сеткавых інтэрфейсаў у выбраным каталогу. іерархіі (напрыклад, / sys / class / net і / sys / devices / virtual / net ). Гэта робіцца толькі падчас мантажу, а не дынамічна. Некаторыя пашыраныя налады сеткі лёгка даступныя, проста чытаючы ці пішучы там, таму іх трэба прадастаўляць, і наадварот:ізаляваныя працэсы, якія працуюць у новым сеткавым асяроддзі, не павінны бачыць альбо змяняць інтэрфейсы пачатковага хаста.

Такім чынам ip netns exec FOO ... (але не ip netns дадаць FOO ) вырашае гэта, таксама выдаляючы агульны доступ прастору імёнаў змантавання і перамяшчаючы ў яе / sys / , каб не парушыць прастору імёнаў першапачатковага хаста. Але важна тое, што гэтая прастора імёнаў мантажу сама па сабе эфемерная: калі вы запускаеце асобна два ip netns exec FOO ... каманды, яны не трапляюць у адну і тую ж прастору імёнаў. У кожнага з іх ёсць свой уласны, / sys перапісаны там, паказваючы на ​​тую ж прастору імёнаў сеткі.

Дагэтуль без праблем. Калі гэта адбылося, я назаву гэта "прасторай імёнаў ip netns", паколькі зараз уключаны два тыпы прастор імёнаў. Да гэтага часу мы маем:

term1:

# ip netns add FOO
# ls -l /proc/$$/ns/{mnt,net}
lrwxrwxrwx. 1 root root 0 Apr  4 22:28 /proc/1712/ns/mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Apr  4 22:28 /proc/1712/ns/net -> net:[4026531992]
# ip netns exec FOO bash
# ls -l /proc/$$/ns/{mnt,net}
lrwxrwxrwx. 1 root root 0 Apr  4 22:33 /proc/1864/ns/mnt -> mnt:[4026532618]
lrwxrwxrwx. 1 root root 0 Apr  4 22:33 /proc/1864/ns/net -> net:[4026532520]

term2:

# ls -l /proc/$$/ns/{mnt,net}
lrwxrwxrwx. 1 root root 0 Apr  4 22:32 /proc/1761/ns/mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Apr  4 22:32 /proc/1761/ns/net -> net:[4026531992]
# ip netns exec FOO bash
# ls -l /proc/$$/ns/{mnt,net}
lrwxrwxrwx. 1 root root 0 Apr  4 22:33 /proc/1866/ns/mnt -> mnt:[4026532821]
lrwxrwxrwx. 1 root root 0 Apr  4 22:33 /proc/1866/ns/net -> net:[4026532520]

Звярніце ўвагу, як пасля змены прастор імёнаў ip netns, у той час як новая прастора імёнаў сетак аднолькавая для term1 і term2 , новыя прасторы імёнаў мантавання адрозніваюцца адзін ад аднаго (і ад пачатковага хаста).

Цяпер, што адбываецца, калі ў term1 вы ствараеце новую прастору імёнаў ip netns? Давайце паглядзім:

term1:

# ip netns add BAR
# ip netns ls
BAR
FOO

term2:

# ip netns ls
Error: Peer netns reference is invalid.
Error: Peer netns reference is invalid.
BAR
FOO

Гэта таму, што новая прастора імёнаў BAR, якая будзе захоўвацца існай без працэсу, як і іншыя, усталявана на на (нядаўна створаны пусты файл ) / var / run / netns / BAR (яшчэ раз, гл. Прыклады ў папярэдняй спасылцы ). Хоць прасторы імёнаў мантавання розныя, у іх адзін і той жа каранёвы каталог: пачатковы корань хаста. Таму, вядома, гэты нядаўна створаны пусты файл / var / run / netns / BAR можна ўбачыць усюды (пачатковы, term1 мантаванне ns, term2 's мантаваць ns), калі ён быў створаны.

Нажаль, мантаванне над ім, зробленае на прасторы імёнаў мантавання FOO term1 , можна ўбачыць толькі на term1 , а не на term2 , ні дзе-небудзь яшчэ, таму што гэта іншая прастора імёнаў мантавання. Такім чынам, у той час як у term1 (прастора імёнаў FOP ip netns) / var / run / netns / BAR знаходзіцца псеўда-файл, які належыць псеўда-файлавай сістэме nsfs :

term1:

# stat -f -c %T /var/run/netns/BAR
nsfs

Гэта пусты файл на tmpfs (з фактычнага мантажу / run ) дзе заўгодна:

term2:

# stat -f -c %T /var/run/netns/BAR
tmpfs

Любы іншы тэрмінал:

$ stat -f -c %T /var/run/netns/BAR
tmpfs

Ён усё яшчэ можа быць заўважаным у term1, пакуль ніхто не выходзіць з бягучай "прасторы імёнаў ip netns". Калі з term1 усё роўна пераключаецца прастора імёнаў ip netns, гэта ўсё роўна будзе добра, таму што новая непадзеленая эфемерная прастора імёнаў мантажу з'яўляецца копіяй папярэдняй, уключаючы ўсе мантажы.

Пры выхадзе, гэтая кропка мантавання губляецца (і гэта азначае, што калі ўжо няма працэсаў альбо дэскрыптараў файлаў, якія выкарыстоўваюць яго, адпаведная сеткавая прастора імёнаў BAR знікне, таму што ўтрымлівалася толькі гэтай кропкай мантавання) Пасля гэтага любая каманда ip netns ls будзе скардзіцца ў любым месцы. Вы можаце проста выдаліць састарэлы і цяпер бескарысны файл / run / netns / BAR , каб выправіць.

Пасля гэтага пакрокавага тлумачэння трэба памятаць, што вы не павінны стварыць новыя прасторы імёнаў з ip netns дадаць унутр прасторы імёнаў, у цяперашні час уведзенай з ip netns exec . Вы павінны стварыць іх усіх з пачатковай прасторы імёнаў (хаста), пасля чаго вы можаце пераключацца па жаданні паміж імі з любой прасторы імёнаў ip netns.

Вядома, калі / var / run / netns / (г.зн. кропка мантавання / run ) адрознівае прасторы імёнаў (застаючыся размытымі), тады ўзаемадзеяння адсутнічае, і кожны выклік ip netns будзе ізаляваны ад іншых, не бачачы і не ўзаемадзейнічаючы з іншымі. Дзе гэта звычайна адбываецца? У поўных кантэйнерах, дзе і прастора імёнаў, і мантаванне, і сеткавыя прасторы размешчаны асобна і паказваюць на розныя рэсурсы з самага пачатку.


АБНОЎЛЕННЕ : па запыце ў каментарах, я праверыў, як "выправіць" гэтую праблему, але не змог знайсці любое простае рашэнне.

Па-першае, ёсць абавязковая ўмова: як было сказана вышэй, як толькі новая прастора імёнаў "ip netns" BAR створыцца ўнутры FOO, а FOO застанецца, адзіная спасылка на BAR знікне, такім чынам, BAR таксама знікне. Патрэбна нешта большае.

На самай справе ёсць тры спосабы захаваць спасылку на прастору імёнаў :

  • працэс: гэта асноўны метад, і большую частку часу менавіта так выкарыстоўваецца прастора імёнаў
  • кропка мантавання (гэта метад, які выкарыстоўваецца ip netns ): дазваляе захоўваць прастору імёнаў без якіх-небудзь працэсаў, выдатна мець прастору імёнаў з толькі сеткавымі наладамі (інтэрфейсы, масты, правілы tc, правілы брандмаўэра , ...)
  • дэскрыптар адкрытага файла: рэдкі, выкарыстоўваецца пры стварэнні прастор імёнаў, але рэдка захоўваецца, за выключэннем прыкладанняў, якія адначасова працуюць з некалькімі прасторамі імёнаў і пераключаюць некаторыя з іх з дапамогай дэскрыптара файлаў для зручнасці.

Мы можам выкарыстоўваць 1-ы ці 3-і спосаб.Вось розныя няўдалыя спробы перад тым, як знайсці што-небудзь, што працуе ...

Як ужо было сказана, не атрымаецца:

# ip netns add FOO
# ip netns exec FOO ip netns add BAR

Проста пакіньце працэс, які часова працуе ў прасторы імёнаў "ip netns" , для яго эфемерная змантаваць частка прасторы імёнаў, каб захаваць неабходную спасылку на новую "ip netns" прастору імёнаў сеткі прасторы імёнаў і паўторна выкарыстоўваць яе звонку (з пачатковай прасторы імёнаў)

Таксама не атрымаецца:

# ip netns add FOO
# ip netns exec FOO sh -c 'ip netns add BAR; sleep 999 < /var/run/netns/BAR & echo $!'
28344
# strace -e trace=readlink,mount mount --bind /proc/6295/fd/0 /var/run/netns/BAR
readlink("/proc/6295/fd/0", "/run/netns/BAR", 4095) = 14
readlink("/var/run", "/run", 4095)      = 4
mount("/run/netns/BAR", "/run/netns/BAR", 0x55c88c9cccb0, MS_BIND, NULL) = 0
+++ exited with 0 +++
# stat -f -c %T /run/netns/BAR
tmpfs

Як відаць з strace , каманда mount ішла па сімвалічнай спасылцы, калі яна не павінна быць у гэтым выпадку (заўвага: маунт па-ранейшаму звязаны з працэсам сну, які трэба адключыць, каб адключыць яго.

Гэта (уваход у прастору імёнаў mount mount sleep mount для доступу да змантаванага BAR ] сетка прастора імёнаў, схаваная там) працуе, але абапіраецца на далейшае існаванне спячага рэжыму альбо на любы працэс для далейшага выкарыстання:

# ip netns add FOO
# ip netns exec FOO sh -c 'ip netns add BAR; ip -n BAR link add dummy8 type dummy; sleep 999 & echo $!'
12916
# nsenter --target=12916 --mount ip -n -brief BAR link show
lo               DOWN           00:00:00:00:00:00 <LOOPBACK> 
dummy8           DOWN           8e:ce:b3:d1:9c:bb <BROADCAST,NOARP> 

дзіўна, гэта (мы ярлык прасторы імёнаў мантавання / proc / pid / root / ) не працуе (я сапраўды не ведаю, чаму):

# stat -f -c %T /proc/12916/root/var/run/netns/BAR 
tmpfs

Нарэшце, што будзе працаваць:

# ip netns add FOO
# ip netns exec FOO sh -c 'ip netns add BAR; ip -n BAR link add dummy8 type dummy; ip netns exec BAR sh -c '\''sleep 999 & echo $!'\'
14124
# mount --bind /proc/14124/ns/net /var/run/netns/BAR
# ip -n BAR -brief link show
lo               DOWN           00:00:00:00:00:00 <LOOPBACK> 
dummy8           DOWN           3a:48:65:20:68:c1 <BROADCAST,NOARP> 

Такім чынам, можа быць нешта падобнае выкарыстоўваецца ў рэшце рэшт. Могуць быць умовы гонкі, калі вы паспрабуеце выдаліць іх адразу пасля таго, як скончыцца каманда сну.

# ip netns add FOO
# mount --bind /proc/$(ip netns exec FOO sh -c 'ip netns add BAR; ip netns exec BAR bash -c '\''sleep 5 </dev/null >/dev/null 2>&1 & echo $!; disown'\')/ns/net /var/run/netns/BAR

Як можна выкарыстоўваць такую ​​канструкцыю? Я паняцця не маю, таму што першапачатковая праблема перад сутыкненнем з укладзенай праблемай "ip netns" не была дадзена. Магчыма, даступныя больш простыя рашэнні, не спрабуючы стварыць "укладзеную сеткавую прастору імёнаў".

2
ответ дан 3 December 2019 в 20:08

Теги

Похожие вопросы