Linux namespace之:network namespace
理解network namespace
network namespace用来隔离网络环境,「在network namespace中,网络设备、端口、套接字、网络协议栈、路由表、防火墙规则等都是独立的」。
因network namespace中具有独立的网络协议栈,因此每个network namespace中都有一个lo接口,但lo接口默认未启动,需要手动启动起来。
# -n或--net选项用于创建network namespace
$ sudo unshare -n /bin/bash# 默认未启动lo
root@longshuai-vm:/home/longshuai# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00# 将之启动
root@longshuai-vm:/home/longshuai# ip link set lo up
root@longshuai-vm:/home/longshuai# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
让某个network namespace和root network namespace或其他network namespace之间保持通信是一个非常常见的需求,这一般通过veth虚拟设备实现。veth类型的虚拟设备由一对虚拟的eth网卡设备组成,像管道一样,一端写入的数据总会从另一端流出,从一端读取的数据一定来自另一端。
用户可以将veth的其中一端放在某个network namespace中,另一端保留在root network namespace中。这样就可以让用户创建的network namespace和宿主机通信。
例如:
##### 在第一个shell窗口
# 创建network namespace ns1
$ sudo unshare -n /bin/bash# 查看该network namespace的进程号
root@longshuai-vm:/home/longshuai# echo $$
53091##### 在第二个shell窗口
# 创建veth设备
$ sudo ip link add veth0 type veth peer name veth1# 创建之后,就有了一对虚拟的eth设备
$ ip a | grep veth
3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000# veth0准备留在root network namespace中
# 为veth0设置IP地址并启动
$ sudo ip a add dev veth0 192.168.10.10/24
$ sudo ip link set veth0 up
$ ip a s veth0
4: veth0@veth1: <NO-CARRIER,BROADCAST,MULTICAST,UP,M-DOWN> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000link/ether 36:30:54:ba:d3:aa brd ff:ff:ff:ff:ff:ffinet 192.168.10.10/24 scope global veth0valid_lft forever preferred_lft forever# 最后,将veth1移动到刚才新建的network namespace ns1中
# ip link set xxx netns [ PID|NETNS_NAME ]
$ sudo ip link set veth1 netns 53091# 注:
# 并不是所有的网络设备都能在network namespace之间移动,
# ethtool -k <interface>输出的结果中,netns-local为on的表示不能移动
$ ethtool -k lo | grep netns
netns-local: on [fixed]
$ ethtool -k ens32 | grep netns
netns-local: off [fixed]
$ ethtool -k veth1 | grep netns
netns-local: off [fixed]##### 在ns1中启动veth1并设置IP地址
root@longshuai-vm:/home/longshuai# ip link set dev veth1 uproot@longshuai-vm:/home/longshuai# ip a add dev veth1 192.168.10.20/24root@longshuai-vm:/home/longshuai# ip a s veth1
3: veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 22:a8:4b:5b:55:4d brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 192.168.10.20/24 scope global veth1valid_lft forever preferred_lft foreverinet6 fe80::20a8:4bff:fe5b:554d/64 scope link valid_lft forever preferred_lft forever # 互ping,测试两端是否能通信,例如在ns1测试
root@longshuai-vm:/home/longshuai# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.076 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.189 ms
但现在ns1还不能和公网通信。解决这个问题也很简单,在root network namespace中开启转发并设置SNAT,在ns1中添加默认路由即可。
##### 在root network namespace中执行
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -t nat -A POSTROUTING -o ens32 -j MASQUERADE##### 在network namespace ns1中执行
$ route add default gw 192.168.10.10
$ ping www.baidu.com
PING www.baidu.com (36.152.44.95) 56(84) bytes of data.
64 bytes from 36.152.44.95: icmp_seq=1 ttl=127 time=53.4 ms
64 bytes from 36.152.44.95: icmp_seq=2 ttl=127 time=51.0 ms
持久化的network namespace
正常情况下,当namespace中的所有进程都退出后,namespace也会随之销毁。但有时候需要让namespace即使没有进程在其中运行也依然有效,即namespace的持久化。例如,创建了network namespace后,想要让network namespace中的网络配置一直生效。
实际上,无论是network namespace还是其他类型的namespace,「当通过mount bind为某个namespace的namespace文件(/proc/$$/ns/xxx
)进行了bind挂载,这个namespace将成为持久化的namespace,即使namespace中的第一个进程或所有进程都退出了,namespace也不会立即销毁,之后还可以通过nsenter重新进入该namespace」。
其实方式很简单,直接在unshare创建namespace时的对应长选项上指定一个已存在的文件即可(注:不允许在短选项上指定文件名)。
unshare: -m, --mount[=<file>] unshare mounts namespace-u, --uts[=<file>] unshare UTS namespace (hostname etc)-i, --ipc[=<file>] unshare System V IPC namespace-n, --net[=<file>] unshare network namespace-p, --pid[=<file>] unshare pid namespace-U, --user[=<file>] unshare user namespace-C, --cgroup[=<file>] unshare cgroup namespace
例如,想要让network namespace持久化:
# 对于network namespace持久化,通常指定/var/run/netns/NAME作为持久化文件
$ sudo mkdir -p /var/run/netns
$ sudo touch /var/run/netns/ns1# 也可以不在选项--net上指定文件,而是在network namespace内部
# 将/var/run/netns/ns1通过mount bind挂载到/proc/$$/ns/net上
$ sudo unshare --net=/var/run/netns/ns1 /bin/bash# 现在/var/run/netns/ns1和/proc/$$/ns/net是同一个network namespace
root@longshuai-vm:/home/longshuai# ls -i /var/run/netns/ns1
4026532587 /var/run/netns/ns1root@longshuai-vm:/home/longshuai# readlink /proc/$$/ns/net
net:[4026532587]# 退出ns1
root@longshuai-vm:/home/longshuai# exit
exit# /var/run/netns/ns1仍然指向net inode
$ ls -i /var/run/netns/ns1
4026532587 /var/run/netns/ns1# nsenter重新进入ns1
$ sudo nsenter --net=/var/run/netns/ns1 /bin/bash
root@longshuai-vm:/home/longshuai# hostname -I
192.168.10.20
ip netns
ip netns
命令用于管理network namespace。
ip netns将network namespace与/var/run/netns/NAME相关联,将/var/run/netns下的每一个NAME作为其所管理的每一个network namespace的名称。
ip netns将/etc/netns/NAME/作为对应network namespace的全局网络配置文件的目录,查找它之后才会查找/etc/目录。
例如,如果想要为netns名为ns1的network namespace单独设置DNS,可创建/etc/netns/ns1/resolv.conf,并将DNS相关配置写入该文件,当该文件不存在时才查找/etc/resolv.conf。
ip netns创建network namespace时,同时会创建mount namespace,以便将网络相关配置文件/etc/netns/NAME/xxx挂载到对应的/etc/xxx。
「ip netns add NAME」
创建名为NAME的network namespace,同时会关联/var/run/netns/NAME文件,如果文件不存在,则会自动创建$ sudo ip netns add ns2 $ ls -i /var/run/netns/ns2 4026532759 /var/run/netns/ns2
「ip netns list」
列出/var/run/netns下的所有network namespace# 带有id的,表示正在运行(即有进程尚未退出)的network namespace以及它的ID号 # ID会自动分配,从0开始,后面通过ip netns命令也可以自己设置ID号 $ ip netns list ns2 ns1 (id: 0)
「ip netns attach NAME PID」
将PID对应的network namespace关联到/var/run/netns/NAME(不存在时会自动创建),使得该network namespace就像是被ip netns创建一样,之后它将受ip netns管理# 在第一个窗口中执行 # 使用unshare而非ip netns创建一个network namespace $ sudo unshare -n /bin/bash root@longshuai-vm:/home/longshuai# echo $$ 5094# 在第二个窗口中执行 # 现在这个network namespace就像是由ip netns创建一样 $ sudo ip netns attach ns3 5094
「ip [-all] netns delete [ NAME ]」
删除/vaer/run/netns/下指定的network namespace,如果指定了--all,则删除/var/run/netns下所有的network namespace。注意,它同时会卸载mount bind的挂载点/var/run/netns/NAME并删除该文件。$ ip netns list ns3 ns2 ns1 (id: 0)$ sudo ip netns del ns3 $ ls /var/run/netns ns1 ns2$ sudo ip --all netns del $ ls /var/run/netns
「ip netns set NAME NETNSID」
为/var/run/netns/NAME对应的network namespace设置ID号。$ sudo ip netns add ns1 $ ip netns list ns1$ sudo ip netns set ns1 11 $ ip netns list ns1 (id: 11)
「ip netns identify [PID]」
根据PID,输出该PID所在的network namespace的netns name。$ ip netns list ns1 (id: 11) $ sudo nsenter --net=/var/run/netns/ns1 /bin/bash root@longshuai-vm:/home/longshuai# echo $$ 5298# 在另一个窗口中查询进程PID=5298在哪一个network namespace中 $ sudo ip netns identify 5298 ns1
「ip netns pids NAME」
输出networ namespace中当前正在运行的所有进程PID$ sudo ip netns pids ns1 5298
「ip [-all] netns exec [ NAME ] cmd ...」
在指定的network namespace中执行命令CMD。如果指定了--all选项,则CMD命令将在/var/run/netns/下的所有network namespace中都执行。$ sudo ip netns exec ns1 ip link set lo up $ sudo ip netns exec ns1 ping www.baidu.com
注:如果/etc/netns/NAME下有配置文件,执行ip netns exec命令时会自动将其bind到/etc/下对应的配置文件上。此时还需注意,systemd管理的/etc/resolv.conf是一个软链接,ip netns直接bind时会失败,将其移除后再创建普通文件类型的/etc/resolv.conf才可bind成功。
$ sudo mkdir -p /etc/netns/ns1
$ echo 'nameserver 8.8.8.8' | sudo tee /etc/netns/ns1/resolv.conf$ sudo ip netns exec ns1 ping www.baidu.com
Bind /etc/netns/ns1/resolv.conf -> /etc/resolv.conf failed: No such file or directory
PING www.baidu.com (36.152.44.96) 56(84) bytes of data.
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=1 ttl=127 time=36.2 ms
64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=2 ttl=127 time=37.5 ms# 创建普通文件类型的/etc/resolv.conf
$ readlink /etc/resolv.conf
../run/systemd/resolve/stub-resolv.conf
$ sudo mv /etc/resolv.conf{,.bak}
$ sudo touch /etc/resolv.conf
$ sudo ip netns exec ns1 dig -t A www.baidu.com
......
;www.baidu.com. IN A;; ANSWER SECTION:
www.baidu.com. 581 IN CNAME www.a.shifen.com.
www.a.shifen.com. 51 IN CNAME www.wshifen.com.
www.wshifen.com. 70 IN A 104.193.88.77
www.wshifen.com. 70 IN A 104.193.88.123;; Query time: 215 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) # 已经成功使用8.8.8.8作为nameserver
;; WHEN: Sun Oct 11 16:58:51 CST 2020
;; MSG SIZE rcvd: 127m
Linux namespace之:network namespace相关推荐
- Linux网络虚拟化基石 network namespace
1 网络虚拟化基石 network namespace Linux的namespace的作用就是"隔离内核资源". 在Linux的世界里,文件系统挂载点.主机名.POSIX进程间通 ...
- linux网络命名空间详解,Linux Network Namespace (netns) 详解
Linux Network Namespace (netns) 详解 Network Namespace (以下简称netns)是Linux内核提供的一项实现网络隔离的功能,它能隔离多个不同的网络空间 ...
- linux 的ip 设置lo_linux网络虚拟化: network namespace 简介及实验
namespace(命名空间)和cgroup是软件容器化(想想Docker)趋势中的两个主要内核技术.简单来说,cgroup是一种对进程进行统一的资源监控和限制,它控制着你可以使用多少系统资源(CPU ...
- Linux Namespace系列(06):network namespace (CLONE_NEWNET)
network namespace用来隔离网络设备, IP地址, 端口等. 每个namespace将会有自己独立的网络栈,路由表,防火墙规则,socket等. 每个新的network namespac ...
- Linux network namespace源码分析
一.network namespace的创建 在对iproute2的源码进行分析后,我们可以知道,当我们调用命令`ip netns add ns1`时,本质上就是调用`unshare(CLONE_NE ...
- Network Namespace
在linux上,网络的隔离是通过network namespace来管理的,不同的network namespace是互相隔离的 ip netns list:查看当前机器上的network names ...
- 使用openvswitch网桥连接不同的network namespace
Namespace是Linux提供的一种内核级别环境隔离的方法,在Linux中Namespace实际上有6中,这里只是单纯的说明一下网络命名空间(Network Namespace).在实际应用中,N ...
- ip netns的使用及network namespace 简介
network namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息.不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中.这篇文章介绍 networ ...
- Kubernetes network namespace位置在哪里?
linux network namespace 通常情况下/var/run/netns存放network namespace,但是docker没有将数据同步到linux runtime. 因此ip n ...
最新文章
- 一文读懂MySQL事务锁、事务级别
- 使PropertyGrid控件的属性值可以显示多行的方法
- cmd下的一些小技巧
- mybatis-plus代码生成器简易使用
- debian 下修改boot停留时间
- 第4章 Python 数字图像处理(DIP) - 频率域滤波10 - 使用低通频率域滤波器平滑图像 - 理想、高斯、巴特沃斯低通滤波器
- 用计算机进行服装设计,电脑服装设计(10制版1班)
- python画图入门
- fgets,cin. getline被跳过
- MATLAB rolcus函数,自动控制原理实验报告 .doc
- linux vim 粘贴 没有保持原来的格式,linux中的剪贴板用法,实现vim中原格式粘贴...
- python怎么解微分方程组_python能解微分方程吗
- excel-按条件向下填充
- 计算机实验室安全知识心得体会,浅谈高校计算机实验室的安全管理
- 老男孩python全栈s21day21作业(面向对象)
- 51单片机c语言定义寄存器r,在MCS51单片机中对特殊功能寄存器的C51定义
- Java对象的GC内存分配和回收策略
- 为什么我的电脑只能上qq不能打开网页
- 显示 wordpress 文章摘要函数the_excerpt
- 浏览器网页 自动转格式化显示json数据
热门文章
- python特征工程插件_python特征工程
- qt获取当前场景中的所有图形项的层次
- oracle表空间如何压缩,Oracle里表空间的压缩
- php 断点续传 暂停,PHP 断点续传实例详解
- 智能卡门禁管理系统_出入口门禁控制系统与消防火灾报警系统怎么联动?
- rust队友开挂_腐蚀RUST开挂玩家识别方法 如何识别玩家开挂
- 湖南女子学院 计算机,2019湖南女子学院专业排名
- oracle ora-16003,ORA-31600错误分析
- php hmac sha256签名,HMAC-SHA256签名错误?
- 嵌入式linux中的锁机制,跟涛哥一起学嵌入式第11集:一个实现锁机制非常有意思的宏...