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。

  1. 「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
    
  2. 「ip netns list」
    列出/var/run/netns下的所有network namespace

    # 带有id的,表示正在运行(即有进程尚未退出)的network namespace以及它的ID号
    # ID会自动分配,从0开始,后面通过ip netns命令也可以自己设置ID号
    $ ip netns list
    ns2
    ns1 (id: 0)
    
  3. 「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
    
  4. 「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
    
  5. 「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)
    
  6. 「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
    
  7. 「ip netns pids NAME」
    输出networ namespace中当前正在运行的所有进程PID

    $ sudo ip netns pids ns1
    5298
    
  8. 「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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/535443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes 的原理

kubernetes 已经成为容器编排领域的王者&#xff0c;它是基于容器的集群编排引擎&#xff0c;具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。 本文将带着大家快速了解 kubernetes &#xff0c;了解我们谈论 kubernetes 都是在谈论什么。 kuberne…

Zookeeper:实现“分布式锁”的 Demo

Zookeeper 能保证数据的强一致性&#xff0c;用户任何时候都可以相信集群中每个节点的数据都是相同的。一个用户创建一个节点作为锁&#xff0c;另一个用户检测该节点&#xff0c;如果存在&#xff0c;代表别的用户已经锁住&#xff0c;如果不存在&#xff0c;则可以创建一个节…

JavaIO流:案例

java.io 包下需要掌握的流有 16 个&#xff0c;本篇内容包括&#xff1a;java.io包下需要掌握的流、Java IO 案例。 文章目录一、java.io包下需要掌握的流二、Java IO 案例1、Demo 1&#xff08;FileInputStream&#xff09;2、Demo 2&#xff08;FileInputStream&#xff09;3…

比对excel数据

#!/usr/bin/env pythonimport openpyxl from openpyxl.styles import PatternFill from openpyxl.styles import colors from openpyxl.styles import Font, Color aD:/测算单位设置/比对/吉林/tmp001.xlsx bD:/测算单位设置/比对/吉林/国网吉林电力.xlsx cD:/测算单位设置/比对…

CPU 是如何执行任务的

前言 你清楚下面这几个问题吗&#xff1f; 有了内存&#xff0c;为什么还需要 CPU Cache&#xff1f; CPU 是怎么读写数据的&#xff1f; 如何让 CPU 能读取数据更快一些&#xff1f; CPU 伪共享是如何发生的&#xff1f;又该如何避免&#xff1f; CPU 是如何调度任务的&a…

Ansible 的自动化运维

1、Ansible 特点 Ansible 自 2012 年发布以来&#xff0c;很快在全球流行&#xff0c;其特点如下&#xff1a; Ansible 基于 Python 开发&#xff0c;运维工程师对其二次开发相对比较容易&#xff1b; Ansible 丰富的内置模块&#xff0c;几乎可以满足一切要求&#xff1b; …

Shell 信号发送与捕捉

1、Linux信号类型 信号&#xff08;Signal&#xff09;&#xff1a;信号是在软件层次上对中断机制的一种模拟&#xff0c;通过给一个进程发送信号&#xff0c;执行相应的处理函数。 进程可以通过三种方式来响应一个信号&#xff1a; 1&#xff09;忽略信号&#xff0c;即对信…

运维面试题总结

集群相关 简述 ETCD 及其特点&#xff1f; etcd 是 CoreOS 团队发起的开源项目&#xff0c;是一个管理配置信息和服务发现&#xff08;service discovery&#xff09;的项目&#xff0c;它的目标是构建一个高可用的分布式键值&#xff08;key-value&#xff09;数据库&#x…

详解设计模式:建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;也叫做生成器模式&#xff0c;是 GoF 的 23 种设计模式的一种&#xff0c;它将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 当我们需要实列化一个复杂的类&#xff0c;以得到不同结…

图文并茂 VLAN 详解,让你看一遍就理解 VLAN

一、为什么需要VLAN 1.1、什么是VLAN? VLAN(Virtual LAN)&#xff0c;翻译成中文是“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络&#xff0c;也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。 在此让我们先复习…

认识VLAN,并学会VLAN的划分和网络配置实例

VLAN的划分和网络的配置实例 1、VLAN基础知识 VLAN&#xff08;Virtual Local Area Network&#xff09;的中文名为&#xff1a;“虚拟局域网”&#xff0c;注意和VPN&#xff08;虚拟专用网&#xff09;进行区分。 VLAN是一种将局域网设备从逻辑上划分&#xff08;不是从物…

VLAN划分及配置注意事项

VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。VLAN内的主机间可以直接通信&#xff0c;而VLAN间不能直接通信&#xff0c;从而将广播报文限制在一个VLAN内。VLAN之间的通信是通过第3…

Docker原理剖析

一、简介 1、了解Docker的前生LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化&#xff0c;以便隔离进程和资源&#xff0c;而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中&#…

获取Linux内存、cpu、磁盘IO等信息

#!/bin/bash # 获取要监控的本地服务器IP地址 IPifconfig | grep inet | grep -vE inet6|127.0.0.1 | awk {print $2} echo "IP地址&#xff1a;"$IP# 获取cpu总核数 cpu_numgrep -c "model name" /proc/cpuinfo echo "cpu总核数&#xff1a;"$c…

Docker容器网络解析

Docker 容器网络的发展历史 在 Dokcer 发布之初&#xff0c;Docker 是将网络、管理、安全等集成在一起的&#xff0c;其中网络模块可以为容器提供桥接网络、主机网络等简单的网络功能。 从 1.7 版本开始&#xff0c;Docker正是把网络和存储这两部分的功能都以插件化形式剥离出来…

将指定excel的一列数据提取到另一个excel的指定列

#!/usr/bin/env python import openpyxl bjD:/地市县公司/西藏台账数据分析-设备台帐分析.xlsx wb openpyxl.load_workbook (bj) get_sheets wb.sheetnames #print(get_sheets) TA01TA01 TA02TA02 TA03TA03 TE01TE01 YG201YG201 YG202YG202 YG203YG203 YG204YG204 YG205YG205…

Docker 数据管理介绍

默认容器的数据是保存在容器的可读写层&#xff0c;当容器被删除时其上的数据也会丢失&#xff0c;所以为了实现数据的持久性则需要选择一种数据持久技术来保存数据。官方提供了三种存储方式&#xff1a;Volumes、Bind mounts和tmpfs。前面还介绍了&#xff1a;Docker 服务终端…

Docker 数据持久化的三种方案

容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题&#xff1a; 数据不是持久化。意思是如果容器删除了&#xff0c;这些数据也就没了 主机上的其它进程不方便访问这些数据 对这些数据的I/O会经过存储驱动&#xff0c;然后到达主机&#xff0c;引入了一层间…

Git 存储原理及相关实现

Git 是目前最流行的版本控制系统&#xff0c;从本地开发到生产部署&#xff0c;我们每天都在使用 Git 进行我们的版本控制&#xff0c;除了日常使用的命令之外&#xff0c;如果想要对 Git 有更深一步的了解&#xff0c;那么研究下 Git 的底层存储原理将会对理解 Git 及其使用非…

Git内部原理

Git有什么特点&#xff1f; fast&#xff0c;scalable&#xff0c;distributed revision control system&#xff08;快速&#xff0c;可扩展的分布式版本控制系统&#xff09; 几乎所有操作都是本地执行 每一个clone都是整个生命周期的完整副本 the stupid content tracker&a…