unshare
자신만 포함하는 새 네트워크 네임스페이스를 생성하는 프로세스 호출이 있습니다 . start bash를 호출하면 execve
ip 명령은 장치가 하나만 있다고 표시합니다 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 버전에서 실행할 수 있어야 합니다.
저는 이 네임스페이스를 한 번에 하나씩 작업해 왔으며 현재 사용자, 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
한 쌍의 장치로 구성되며 각 장치를 통신하려는 네트워크 네임스페이스(또는 루트 네임스페이스)에 넣습니다.
이것은 새로운 네트워크 네임스페이스를 생성하고 루트 네임스페이스와 네트워크 네임스페이스 사이에 veth 쌍을 설정하기 위해 루트 네임스페이스에서 루트로 호출하는 스크립트입니다. 마지막 줄은 해당 네임스페이스에서 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
네임스페이스를 알아내는 것만으로도 충분할 것 같아서(파일 설명자가 하나만 있음) 네임스페이스를 만든 다음 그 안에서 프로그램을 시작하는 /proc
것이 더 나을 것 같습니다 . 당신이 가정ip netns add
ip netns exec
unshare
오직다른 것이 아닌 새로운 네트워크 네임스페이스가 필요합니다.