Namespaces系列3:network namespace

Time: 一月 18, 2016
Category: namespaces

As the name would imply, network namespaces partition the use of the network—devices, addresses, ports, routes, firewall rules, etc.—into separate boxes, essentially virtualizing the network within a single running kernel instance. Network namespaces entered the kernel in 2.6.24

1. 简介

简单点来说,network namespace主要实现了一套独立的协议栈,为不同的应用程序实现完整的网络隔离

由于有了独立的网络协议栈,应用程序可以灵活自主的组建适合自己的网络架构。network namespace技术本身其实不复杂,复杂的是有了network namespace之后网络的构建,就像给你一堆服务器,交换机,路由器,你需要用网线把这些设备连接起来,并设置路由规则,防火墙规则,网络地址等等,才能实现网络访问

network namespace能解决很多问题,常见的如端口

在多个业务混部在同一个机器上的时候,端口协调是一件非常困难的事情,kubernetes在介绍自身的网络模型中也提到了这一点:

Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Dynamic port allocation brings a lot of complications to the system - every application has to take ports as flags, the API servers have to know how to insert dynamic port numbers into configuration blocks, services have to know how to find each other, etc.

https://kubernetes.io/docs/admin/networking/

但是,如果有了network namespace,用户就不需要关心这个问题,不同的network namespace有各自的网络地址,端口不再受限制

另外,还有虚拟化,安全性,自定义网络等等

2. 基本用法

2.1. 创建

创建network namespace有两种方式:

  1. clone系统调用并指定CLONE_NEWNET,子进程会在一个全新的network namespace里,这种方法适合老系统老内核
  2. 新的操作系统,用户可以简单的通过 ip netns add ns1 来创建一个名为ns1的network namespace

第一种方法,clone的用法是:

 child_pid = clone(childFunc, child_stack + STACK_SIZE, /* Points to start of
          downwardly growing stack */ CLONE_NEWNET | SIGCHLD, argv[1]);

network namespace创建完之后,默认情况下,除了一个lo回环设备,是没有任何其他网络设备的,通过/sbin/ifconfig和ip link我们可以看得出来

2.2. 加入

加入一个network namespace,通过setns系统调用,具体可参考: http://man7.org/linux/man-pages/man2/setns.2.html

2.3. 销毁

和其他namespace一样,当network namespace中的最后一个进程退出时,内核会自动销毁它所引用的network namespace

Leave a Comment