命名空间详解,命名空间是什么意思
老铁们,大家好,相信还有很多朋友对于命名空间详解和命名空间是什么意思的相关问题不太懂,没关系,今天就由我来为大家分享分享命名空间详解以及命名空间是什么意思的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
详解Linux中的命名空间
背景
从Linux 2.6.24版的内核开始,Linux就支持6种不同类型的命名空间。它们的出现,使用户创建的进程能够与系统分离得更加彻底,从而不需要使用更多的底层虚拟化技术。
CLONE_NEWIPC:进程间通信(IPC)的命名空间,可以将 SystemV的 IPC和 POSIX的消息队列独立出来。
CLONE_NEWPID:进程命名空间。空间内的PID是独立分配的,意思就是命名空间内的虚拟 PID可能会与命名空间外的 PID相冲突,于是命名空间内的 PID映射到命名空间外时会使用另外一个 PID。比如说,命名空间内第一个 PID为1,而在命名空间外就是该 PID已被 init进程所使用。
CLONE_NEWNET:网络命名空间,用于隔离网络资源(/proc/net、IP地址、网卡、路由等)。后台进程可以运行在不同命名空间内的相同端口上,用户还可以虚拟出一块网卡。
CLONE_NEWNS:挂载命名空间,进程运行时可以将挂载点与系统分离,使用这个功能时,我们可以达到 chroot的功能,而在安全性方面比 chroot更高。
CLONE_NEWUTS: UTS命名空间,主要目的是独立出主机名和网络信息服务(NIS)。
CLONE_NEWUSER:用户命名空间,同进程 ID一样,用户 ID和组 ID在命名空间内外是不一样的,并且在不同命名空间内可以存在相同的 ID。下面我们介绍一下进程命名空间和网络命名空间。
进程命名空间
本文用 C语言介绍上述概念,因为演示进程命名空间的时候需要用到 C语言。下面的测试过程在 Debian 6和 Debian 7上执行。首先,在栈内分配一页内存空间,并将指针指向内存页的末尾。这里我们使用 alloca()函数来分配内存,不要用 malloc()函数,它会把内存分配在堆上。
复制代码代码如下:void*mem= alloca(sysconf(_SC_PAGESIZE))+ sysconf(_SC_PAGESIZE);然后使用 clone()函数创建子进程,传入我们的子栈空间地址"mem",并指定命名空间的标记。同时我们还指定“callee”作为子进程运行的函数。
复制代码代码如下:mypid= clone(callee, mem, SIGCHLD| CLONE_NEWIPC| CLONE_NEWPID| CLONE_NEWNS| CLONE_FILES, NULL);clone之后我们要在父进程中等待子进程先退出,否则的话,父进程会继续运行下去,并马上进程结束,留下子进程变成孤儿进程:
复制代码代码如下:while(waitpid(mypid,&r, 0)< 0&& errno== EINTR)
{
continue;
}最后当子进程退出后,我们会回到 shell界面,并返回子进程的退出码。
复制代码代码如下:if(WIFEXITED(r))
{
return WEXITSTATUS(r);
}
return EXIT_FAILURE;上文介绍的 callee函数功能如下:
复制代码代码如下:static int callee()
{
int ret;
mount("proc","/proc","proc", 0,"");
setgid(u);
setgroups(0, NULL);
setuid(u);
ret= execl("/bin/bash","/bin/bash", NULL);
return ret;
}程序挂载了/proc文件系统,设置用户 ID和组 ID,值都为“u”,然后运行/bin/bash程序,LXC是一个操作系统级的虚拟化工具,使用 cgroups和命名空间来完成资源的分离。现在我们把所有代码放在一起,变量“u”的值设为65534,在 Debian系统中,这是“nobody”和“nogroup”:
复制代码代码如下:#define _GNU_SOURCE
#include
#include
#include
#include types.h>
#include wait.h>
#include mount.h>
#include
#include
#include
#include
static int callee();
const int u= 65534;
int main(int argc, char*argv[])
{
int r;
pid_t mypid;
void*mem= alloca(sysconf(_SC_PAGESIZE))+ sysconf(_SC_PAGESIZE);
mypid= clone(callee, mem, SIGCHLD| CLONE_NEWIPC| CLONE_NEWPID| CLONE_NEWNS| CLONE_FILES, NULL);
while(waitpid(mypid,&r, 0)< 0&& errno== EINTR)
{
continue;
}
if(WIFEXITED(r))
{
return WEXITSTATUS(r);
}
return EXIT_FAILURE;
}
static int callee()
{
int ret;
mount("proc","/proc","proc", 0,"");
setgid(u);
setgroups(0, NULL);
setuid(u);
ret= execl("/bin/bash","/bin/bash", NULL);
return ret;
}执行以下命令来运行上面的代码:
复制代码代码如下:root@w:~/pen/tmp# gcc-O-o ns.c-Wall-Werror-ansi-c89 ns.c
root@w:~/pen/tmp#./ns
nobody@w:~/pen/tmp$ id
uid=65534(nobody) gid=65534(nogroup)
nobody@w:~/pen/tmp$ ps auxw
USER PID%CPU%MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 0.0 0.0 4620 1816 pts/1 S 21:21 0:00/bin/bash
nobody 5 0.0 0.0 2784 1064 pts/1 R+ 21:21 0:00 ps auxw
nobody@w:~/pen/tmp$注意上面的结果,UID和 GID被设置成 nobody和 nogroup了,特别是 ps工具只输出两个进程,它们的 ID分别是1和5(LCTT注:这就是上文介绍 CLONE_NEWPID时提到的功能,在线程所在的命名空间内,进程 ID可以为1,映射到命名空间外是另外一个 PID;而命名空间外的 ID为1的进程一直是 init)。
网络命名空间
接下来轮到使用 ip netns来设置网络的命名空间。第一步先确定当前系统没有命名空间:
复制代码代码如下:root@w:~# ip netns list
Object"netns" is unknown, try"ip help".如果报了上述错误,你需要更新你的系统内核,以及 ip工具程序。这里假设你的内核版高于2.6.24,ip工具版本也差不多,高于2.6.24(LCTT注:ip工具由 iproute安装包提供,此安装包版本与内核版本相近)。更新好后,ip netns list在没有命名空间存在的情况下不会输出任务信息。加个名为“ns1”的命名空间看看:
复制代码代码如下:root@w:~# ip netns add ns1
root@w:~# ip netns list
ns1列出网卡:
复制代码代码如下:root@w:~# ip link list
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000
link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff创建新的虚拟网卡,并加到命名空间。虚拟网卡需要成对创建,互相关联——就像交叉电缆一样:
复制代码代码如下:root@w:~# ip link add veth0 type veth peer name veth1
root@w:~# ip link list
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 1000
link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
3: veth1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether d2:e9:52:18:19:ab brd ff:ff:ff:ff:ff:ff
4: veth0: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether f2:f7:5e:e2:22:ac brd ff:ff:ff:ff:ff:ff这个时候 ifconfig-a命令也能显示新添加的 veth0和 veth1两块网卡。
很好,现在将这两份块网卡加到命名空间中去。注意一下,下面的 ip netns exec命令用于将后面的命令在命名空间中执行(LCTT注:下面的结果显示了在 ns1这个网络命名空间中,只存在 lo和 veth1两块网卡):
复制代码代码如下:root@w:~# ip link set veth1 netns ns1
root@w:~# ip netns exec ns1 ip link list
1: lo: mtu 65536 qdisc noop state DOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: veth1: mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether d2:e9:52:18:19:ab brd ff:ff:ff:ff:ff:ff这个时候 ifconfig-a命令只能显示 veth0,不能显示 veth1,因为后者现在在 ns1命名空间中。
如果想删除 veth0/veth1,可以执行下面的命令:
复制代码代码如下:ip netns exec ns1 ip link del veth1我们可以为 veth0分配 IP地址:
复制代码代码如下:ifconfig veth0 192.168.5.5/24在命名空间内为 veth1分配 IP地址:
复制代码代码如下:ip netns exec ns1 ifconfig veth1 192.168.5.10/24 up在命名空间内外执行 ip addr list命令:
复制代码代码如下:root@w:~# ip addr list
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
inet 192.168.3.122/24 brd 192.168.3.255 scope global eth0
inet6 fe80::20c:29ff:fe65:259e/64 scope link
valid_lft forever preferred_lft forever
6: veth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 86:b2:c7:bd:c9:11 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.5/24 brd 192.168.5.255 scope global veth0
inet6 fe80::84b2:c7ff:febd:c911/64 scope link
valid_lft forever preferred_lft forever
root@w:~# ip netns exec ns1 ip addr list
1: lo: mtu 65536 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: veth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 12:bd:b6:76:a6:eb brd ff:ff:ff:ff:ff:ff
inet 192.168.5.10/24 brd 192.168.5.255 scope global veth1
inet6 fe80::10bd:b6ff:fe76:a6eb/64 scope link
valid_lft forever preferred_lft forever在命名空间内外查看路由表:
复制代码代码如下:root@w:~# ip route list
default via 192.168.3.1 dev eth0 proto static
192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.3.122
192.168.5.0/24 dev veth0 proto kernel scope link src 192.168.5.5
root@w:~# ip netns exec ns1 ip route list
192.168.5.0/24 dev veth1 proto kernel scope link src 192.168.5.10最后,将虚拟网卡连到物理网卡上,我们需要用到桥接。这里做的是将 veth0桥接到 eth0,而 ns1命名空间内则使用 DHCP自动获取 IP地址:
复制代码代码如下:root@w:~# brctl addbr br0
root@w:~# brctl addif br0 eth0
root@w:~# brctl addif br0 veth0
root@w:~# ifconfig eth0 0.0.0.0
root@w:~# ifconfig veth0 0.0.0.0
root@w:~# dhclient br0
root@w:~# ip addr list br0
7: br0: mtu 1500 qdisc noqueue state UP
link/ether 00:0c:29:65:25:9e brd ff:ff:ff:ff:ff:ff
inet 192.168.3.122/24 brd 192.168.3.255 scope global br0
inet6 fe80::20c:29ff:fe65:259e/64 scope link
valid_lft forever preferred_lft forever为网桥 br0分配的 IP地址为192.168.3.122/24。接下来为命名空间分配地址:
复制代码代码如下:root@w:~# ip netns exec ns1 dhclient veth1
root@w:~# ip netns exec ns1 ip addr list
1: lo: mtu 65536 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: veth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 12:bd:b6:76:a6:eb brd ff:ff:ff:ff:ff:ff
inet 192.168.3.248/24 brd 192.168.3.255 scope global veth1
inet6 fe80::10bd:b6ff:fe76:a6eb/64 scope link
valid_lft forever preferred_lft forever现在, veth1的 IP被设置成 192.168.3.248/24了。
C#深入详解的目录
第1章.NET基础体系结构
1.1什么是.NET
1.2我们为什么需要.NET技术
1.3什么是.NET Framework
1.4.NET和J2EE的相同点和不同点
1.5.NET和C#之间的关系
1.6 C#语言的特点
1.7 C#程序的编译运行
1.7.1什么是CLI
1.7.2什么是CLR
1.7.3什么是IL
1.7.4 C#程序是如何编译运行的
第2章 C#开发环境
2.1 C#语言需要的开发工具
2.2软件的安装、卸载
2.2.1安装Visual Studio 2005需要的软、硬件配置
2.2.2安装Visual Studio 2005需要的权限设置
2.2.3并行安装Visual Studio版本
2.2.4进行.NET Framework版本的并行安装
2.2.5安装IIS
2.2.6安装Visual Studio 2005
2.2.7卸载
2.3 Visual Studio 2005开发环境实际应用
2.3.1管理解决方案、项目和文件
2.3.1.1创建解决方案
2.3.1.2创建解决方案的目录
2.3.1.3更改或添加默认编辑器
2.3.1.4升级使用Visual Studio.NET2002或Visual Studio.NET2003创建的项目
2.3.1.5设置启动项目
2.3.1.6修改项目属性和配置设置
2.3.1.7添加新项目项
2.3.1.8复制项目
2.3.1.9删除或移除项目
2.3.1.10卸载和重新加载项目
2.3.1.11移动项
2.3.1.12刷新解决方案资源管理器中的项
2.3.1.13如何重命名解决方案、项目和项
2.3.2项目属性
2.3.2.1指定程序集信息
2.3.2.2更改程序集名称
2.3.2.3更改应用程序的命名空间
2.3.2.4启用或禁用编译器警告
2.3.2.5更改应用程序的生成位置
2.3.2.6为项目生成XML文档
2.3.2.7设置编译常量
2.3.2.8针对特定的CPU类型优化应用程序
2.3.2.9在Visual Studio中添加或移除引用
2.3.2.10设置引用的Copy Local属性
2.3.2.11添加或移除字符串资源
2.3.2.12访问设置事件
2.3.2.13对应用程序和部署清单进行签名
2.3.2.14对程序集进行签名
2.3.2.15设置引用路径
2.3.2.16设置生成属性
2.3.2.17指定生成事件
2.3.3编辑代码和资源文件
2.3.3.1选择和更改文本
2.3.3.2显示代码大纲和隐藏代码
2.3.3.3在编辑器中管理自动换行
2.3.3.4在编辑器中显示行号
2.3.3.5在编辑器中将URL显示为链接
2.3.3.6以递增方式搜索文档
2.3.3.7交互式搜索
2.3.4生成、调试和测试
2.3.4.1启用/禁用实时调试
2.3.4.2设置简单断点
2.3.4.3启用SQL Server 2005调试
2.3.4.4更改应用程序调试的启动操作
2.3.4.5设置应用程序调试的启动选项
2.3.4.6启用远程调试
第3章编写第一个C#程序
3.1 C#程序的常规结构
3.2 Main()和命令行参数
3.2.1运用命令行参数
3.2.2使用foreach访问命令行参数
3.2.3 Main()返回值标识
3.3学习第一个C#程序
3.3.1编写第一个C#代码
3.3.2程序添加注释
3.3.3编译程序
第4章 C#程序设计之基础知识
4.1数据类型
4.1.1 C#的数据类型
4.1.2 C#值类型
4.1.2.1 C#值类型介绍——bool类型
4.1.2.2值类型介绍——byte类型
4.1.2.3值类型介绍——char类型
4.1.2.4值类型介绍——decimal类型
4.1.2.5值类型介绍——double类型
4.1.2.6值类型介绍——enum类型
4.1.2.7值类型介绍——float类型
4.1.2.8值类型介绍——int类型
4.1.2.9值类型介绍——long类型
4.1.2.10值类型介绍——sbyte类型
4.1.2.11值类型介绍——short类型
4.1.2.12值类型介绍——struct类型
4.1.2.13值类型介绍——uint类型
4.1.2.14值类型介绍——ulong类型
4.1.2.15值类型介绍——ushort类型
4.1.3引用类型包括的内容
4.2语句
4.2.1 C#语言的语句类型
4.2.1.1选择语句——if-else定义及使用
4.2.1.2选择语句——switch定义及使用
4.2.1.3迭代语句——do定义及使用
4.2.1.4迭代语句——for定义及使用
4.2.1.5迭代语句——foreach定义及使用
4.2.1.6迭代语句——while定义及使用
4.2.1.7跳转语句——break定义及使用
4.2.1.8跳转语句——continue定义及使用
4.2.1.9跳转语句——goto定义及使用
4.2.1.10跳转语句——return定义及使用
4.2.1.11异常处理语句——throw定义及使用
4.2.1.12异常处理语句——try-catch定义及使用
4.2.1.13异常处理语句——try-finally定义及使用
4.2.1.14异常处理语句——try-catch-finally定义及使用
4.2.1.15检查处理语句——Checked定义及使用
4.2.1.16检查处理语句——unchecked定义及使用
4.2.1.17 Fixed语句定义及使用
4.2.1.18 lock语句定义及使用
4.3运算符
4.3.1 C#运算符定义
4.3.1.1 [ ]运算符定义和应用
4.3.1.2()运算符定义和应用
4.3.1.3(.)运算符定义和应用
4.3.1.4(::)运算符定义和应用
4.3.1.5+运算符定义和应用
4.3.1.6运算符定义和应用
4.3.1.7*运算符定义和应用
4.3.1.8/运算符定义和应用
4.3.1.9%运算符定义和应用
4.3.1.10&运算符定义和应用
4.3.1.11|运算符定义和应用
4.3.1.12 ^运算符定义和应用
4.3.1.13!运算符定义和应用
4.3.1.14~运算符定义和应用
4.3.1.15=运算符定义和应用
4.3.1.16<运算符定义和应用
4.3.1.17>运算符定义和应用
4.3.1.18?:运算符定义和应用
4.3.1.19++运算符定义和应用
4.3.1.20运算符定义和应用
4.3.1.21&&运算符定义和应用
4.3.1.22||运算符定义和应用
4.3.1.23<<运算符定义和应用
4.3.1.24>>运算符定义和应用
4.3.1.25==运算符定义和应用
4.3.1.26!=运算符定义和应用
4.3.1.27<=运算符定义和应用
4.3.1.28>=运算符定义和应用
4.3.1.29+=运算符定义和应用
4.3.1.30=运算符定义和应用
4.3.1.31*=运算符定义和应用
4.3.1.32/=运算符定义和应用
4.3.1.33%=运算符定义和应用
4.3.1.34&=运算符定义和应用
4.3.1.35|=运算符定义和应用
4.3.1.36 ^=运算符定义和应用
4.3.1.37<<=运算符定义和应用
4.3.1.38>>=运算符定义和应用
4.3.1.39->运算符定义和应用
4.3.1.40??运算符定义和应用
4.4数组
4.4.1数组的定义和标识
4.4.2一维数组的定义标识
4.4.3一维数组初始化
4.4.4多维数组的定义和标识
4.4.5多维数组的初始化
4.4.6交叉数组的定义和标识
4.4.7在数组使用foreach
4.4.8将一维数组作为参数传递
4.4.9将多维数组作为参数传递
4.4.10使用ref和out传递数组
4.5字符串
4.5.1字符串的定义和标识
4.5.2访问字符串的字符
4.5.3连接字符串
4.5.4字符串进行比较
4.5.5使用Split方法分析字符串
4.5.6使用字符串方法搜索字符串
4.5.7修改字符串内容
4.6命名空间
4.6.1命名空间的定义和标识
4.6.2访问命名空间
4.6.3使用命名空间别名
4.6.4使用命名空间来控制范围
4.7 C#预处理器指令
4.7.1 C#预处理的指令种类
4.7.2预定义指令——#if的定义和应用
4.7.3预定义指令——#else的定义和应用
4.7.4预定义指令——#elif的定义和应用
4.7.5预定义指令——#endif的定义和应用
4.7.6预定义指令——#define的定义和应用
4.7.7预定义指令——#undef的定义和应用
4.7.8预定义指令——#warning的定义和应用
4.7.9预定义指令——#error的定义和应用
4.7.10预定义指令——#line的定义和应用
4.7.11预定义指令——#region的定义和应用
4.7.12预定义指令——#endregion的定义和应用
4.7.13预定义指令——#pragme的定义和应用
4.7.14预定义指令——#pragmewarning的定义和应用
4.7.15预定义指令——#pragme checksum的定义和应用
第5章面向对象的程序设计思想
5.1面向对象的基本概念
5.1.1对象的概念
5.1.2面向对象技术的由来
5.2面向对象的模型技术
5.2.1对象模型技术
5.3面向对象的分析
5.3.1面向对象分析的概念
5.3.2面向对象分析的任务
5.3.3面向对象分析的层次
5.3.4面向对象分析的步骤
5.4面向对象的设计
5.4.1面向对象设计的概念
5.4.2面向对象设计阶段
5.4.3面向对象设计的几个步骤
第6章面向对象的C#语言
6.1类(class)
6.1.1类的概念
6.1.2类的标识
6.1.3类的特点
6.1.4使用类创建对象
6.1.5类的继承
6.1.6类的修饰符
6.1.7静态类
6.1.7.1静态类的概念
6.1.7.2静态类的特点
6.1.7.3使用静态类
6.1.8类的成员
6.1.8.1类成员的概念
6.1.8.2类的成员——this保留字的运用
6.1.8.3类的成员——静态成员的标识
6.1.8.4类的成员——静态成员和非静态成员的区分
6.1.8.5类的成员——成员常量
6.1.9构造函数
6.1.9.1构造函数的使用
6.1.9.2实例构造函数
6.1.9.3私有构造函数
6.1.9.4静态构造函数
6.1.9.5复制构造函数
6.1.10析构函数
6.2方法
6.2.1方法的标识
6.2.2方法返回值
6.2.3方法中的参数类型
6.2.4静态和非静态的方法
6.3结构
6.3.1结构的标识
6.3.2结构的特点
6.3.3使用结构
6.3.4传递结构与传递类实例
6.4继承
6.4.1继承的概念
6.4.2继承的标识
6.4.3 base保留字的使用
6.4.4抽象类和密封类
6.4.5多态
6.5属性
6.5.1属性的概念
6.5.2接口属性的使用
6.5.3非对称访问器的使用
6.6事件
6.6.1事件的概念
6.6.2使用事件
6.6.3创建响应事件的控件
6.6.4接口中声明一个事件并类中实现该事件
6.6.5在Visual C#代码编辑器中创建事件处理程序
第7章深入了解C#
7.1接口
7.1.1接口的概念
7.1.2接口的标识
7.1.3显式接口的实现
7.1.4显式实现接口成员
7.2委托
7.2.1委托的概念
7.2.2委托的应用
7.2.3委托中命名方法的应用
7.2.4委托中匿名方法的应用
7.2.5使用委托而不使用接口
7.2.6合并委托
7.3索引器
7.3.1索引器的概念
7.3.2索引器的应用
7.3.3接口中使用索引器
7.3.4属性和索引器之间的不同点和相同点
7.4迭代器
7.4.1迭代器的概念
7.4.2迭代器的标识
7.4.3为整数列表创建迭代器块
7.4.4为泛型列表创建迭代器块
7.5线程
7.5.1线程的概念
7.5.2线程的应用
7.5.3应用线程进行同步
7.5.4创建和终止线程
7.5.5针对制造者线程和使用者线程进行同步
7.5.6使用线程池
7.6反射
7.6.1反射的概念
7.6.2反射的应用
……
关于命名空间详解和命名空间是什么意思的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。