在指定网络名字空间执行命令

对于容器来说,可以与host共享网络名字空间,也可以用单独的网络名字空间。这个可以通过container的配置文件来指定。

如果需要用单独的网络名字空间,可以指定容器的网络类型为veth:

lxc.network.type = veth

如果要跟host共享网络名字空间,那么可以指定容器的网络类型为none

lxc.network.type = none

  

在host上面,作为root用户,是有权限访问所有网络名字空间的数据的,但是大部分程序默认只是访问host所在的网络名字空间。如果我们想访问容器的网络名字空间的数据,那该怎么做呢?

下面讲一下ip netns的用法。

[router] / # ip netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
[router] / #

  

如果我们在host上面创建运行了多个容器,那么就应该会创建多个网络名字空间,用ip netns list应该可以列出来,但是在linux 4.4的host系统上面,我们发现这个命令显示不出任何信息。

实际上ip netns只能看到/var/run/netns里面的内容,但是对于lxc container来说,创建容器时,不会将网络名字空间加到这个目录。如果要使用ip netns,需要我们手动加入。

举例来说,比方说我们现在有个进程(pid=16674)运行在某个容器中,可以通过该进程的proc目录获取该进程所在的网络名字空间:

[router] /proc/16674/ns # ls -la
dr-x--x--x    2 root     root             0 Mar 30 20:37 .
dr-xr-xr-x    8 root     root             0 Mar 30 04:11 ..
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 ipc -> ipc:[4026532966]
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 mnt -> mnt:[4026532964]
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 net -> net:[4026532969]
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 pid -> pid:[4026532967]
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 user -> user:[4026531837]
lrwxrwxrwx    1 root     root             0 Mar 30 20:37 uts -> uts:[4026532965]

  

我们可以创建一个软链接如下:

[router] /proc/16674/ns # ln -s /proc/16674/ns/net /var/run/netns/ns1

  

再执行ip netns list就可以看到这个网络名字空间了:

[router] /proc/16674/ns # ip netns list
ns1 (id: 2)

  

那么下面我们就可以用ip netns访问某个网络名字空间的数据。下面我们在容器的网络名字空间里执行iptables可以显示该网络名字空间里面的规则:

[router] /proc/16674/ns # ip netns exec ns1 iptables -nvL
Chain INPUT (policy ACCEPT 96591 packets, 7177K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 95210 packets, 7046K bytes)
 pkts bytes target     prot opt in     out     source               destination

  

可以看到里面的chain都是空的,跟host里面的规则完全不同。

至于这种机制是如何实现的,我们可以简单了解下。我们先看看下面的系统接口:

  • clone():创建新的进程
  • setns():允许指定进程加入特定的namespace
  • unshare():将指定进程移除指定的namespace

可以看看setns这个API,他可以将某个进程加入到特定的namespace。那么我们知道linux支持如下几种namespace:

Namespace  变量 隔离资源
IPC
CLONE_NEWIPC
System V IPC, POSIX 消息队列等
Network
CLONE_NEWNET
网络设备,协议栈、端口等
Mount 
CLONE_NEWNS 
挂载点
PID
CLONE_NEWPID
进程ID
User
CLONE_NEWUSER 
用户和group ID
UTS  
CLONE_NEWUTS
Hostname和NIS域名
     

如果我们想让一个进程在某个网络名字空间里运行,我们可以创建一个空的父进程,通过setns来指定这个进程的网络名字空间,然后在父进程里fork出子进程来运行所要执行的程序,默认情况下,子进程会继承父进程的名字空间。那么这样就能让程序在指定的名字空间里面执行了。

原文地址:https://www.cnblogs.com/utopia007/p/12603352.html

时间: 2024-10-03 07:31:14

在指定网络名字空间执行命令的相关文章

python 网络编程(远程执行命令与粘包)

远程执行命令 先来学习一个新模块 , 一会用到的.. 新模块: subprocess 执行系统命令 r = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.Popen(a,b,c,d) a: 要执行的系统命令(str) b: shell = True 表示确定我当前执行的命令为系统命令 c: 表示正确信息的输出管道 d: 表示错误信息的输出管道 下边直接上代码,

linux 下使用指定的用户来执行命令

有时间,我们需要在开机的时候执行一些特定的程序或都脚本,因为涉及到安全主面的问题,所以又不想用root来执行,那怎样办呢. 经过查看 su 的帮助提示,发现: [[email protected] ~]# su --help Usage: su [OPTION]... [-] [USER [ARG]...] Change the effective user id and group id to that of USER.   -, -l, --login               make 

查看 Docker 容器的名字空间

转载请注明 http://blog.csdn.net/yeasy/article/details/41694797 熟悉 Linux 技术的人都知道,容器只是利用名字空间进行隔离的进程而已,Docker 在容器实现上也是利用了 Linux 自身的技术. 有时候,我们需要在宿主机上对容器内进行一些操作,当然,这种绕过 Docker 的操作方式并不推荐. 如果你使用的是比较新的 Docker 版本,会尴尬的发现,直接使用系统命令,会无法访问到容器名字空间. 这里,首先介绍下 ip netns 系列命

expect批量同步或执行命令工具

expect脚本同步文件 我们知道主机间传输一个文件受网络.文件大小和磁盘读写速率的影响,在传输一个文件时不可能一下子马上传输到对方,但是使用expect脚本的过程中,值得注意的是在脚本结尾以expect eof结束整个脚本,它的作用是当脚本内涉及到有文件传输时,会让文件传输完成后再彻底结束掉脚本进程,这样会让文件能够成功传输到对方主机上.expect若使用exit或者没有eof这个选项,那么在执行脚本时,expect不管你是否有文件正在传输,当脚本内容执行完成后直接结束掉自己的进程,这样就会造

docker网络名称空间---模拟网桥

#添加网络名称空间ip netns add r1ip netns add r2 #添加一对虚拟网卡ip link add name veth1.1 type veth peer name veth1.2 #把设备和网络名称空间关联起来ip link set dev veth1.1 netns r1 #把其中一端挪到网络名字空间里, 一个设备只能属于一个名称空间 #改个网卡名字ip netns exec r1 ip link set dev veth1.1 name eth0 #激活宿主机这一端i

awk -F选项同时指定多个符号做为分割符时遇到空格坑,题目:请执行命令取出 linux 中 eth0 的 IP 地址

第三关课前考试题:3.请执行命令取出 linux 中 eth0 的 IP 地址(请用 cut,有能力者也可分别用 awk,sed 命令答) 因为以前有个题讲过awk -F选项可以指定输入分割符,也可以同时使用多个符号作为分割符对文件进行切割,所以我决定先使用awk -F 以前awk -F同时指定多个分割符的例子: [[email protected] ~]# cat oldboy.txt I am oldboy,myqq is 31333741 [[email protected] ~]# aw

expect脚本同步文件、指定host和要同步的文件、构建文件分发系统、批量远程执行命令

expect脚本同步文件 1.自动同步文件 [[email protected] shell]# vi 4.expect 增加如下脚本内容: #!/usr/bin/expect set passwd "123456" spawn rsync -av [email protected]:/tmp/12.txt /tmp/ expect { "yes/no" { send "yes\r"} "password:" { send &

expect脚本同步文件expect脚本指定host和要同步的文件 构建文件分发系统批量远程执行命令

20.31 expect脚本同步文件#!/usr/bin/expectset passwd "liang.123"spawn rsync -av [email protected]:/tmp/12.txt /tmp/ 将远程的/tmp/12.txt同步到本地的机器上 expect {"yes/no" { send "yes\r"} 第一次会提示yes或no"password:" { send "$passwd\r&q

expect 脚本同步文件,指定host和要同步的文件,构建文件分发系统,批量远程执行命令

expect脚本自动同步文件 #!/usr/bin/expectset passwd "1q2w3e"spawn rsync -av [email protected]:/tmp/12.txt /tmp/expect {"yes/no" { send "yes\r"}"password:" { send "$passwd\r" }}expect eof 如果尝试取消最后一行,expect eof 会出现,还