首页技术linux命名空间 linux软件仓库

linux命名空间 linux软件仓库

编程之家2026-06-06630次浏览

其实linux命名空间的问题并不复杂,但是又很多的朋友都不太了解linux软件仓库,因此呢,今天小编就来为大家分享linux命名空间的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

linux命名空间 linux软件仓库

详解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更高。

linux命名空间 linux软件仓库

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之后我们要在父进程中等待子进程先退出,否则的话,父进程会继续运行下去,并马上进程结束,留下子进程变成孤儿进程:

linux命名空间 linux软件仓库

复制代码代码如下: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了。

linux的命名空间到底是什么,一直搞不懂

抽象的概念。看了一下别人的解析,写一下:

从Linux 2.6.24版的内核开始,Linux就支持6种不同类型的命名空间。(具体也没记住)

命名空间是一种轻量级的虚拟化手段;

传统的虚拟化软件,是虚拟化多个不同的操作系统,对共享资源的限制很大;

通过提供命名空间,可以让进程与进程之间,用户与用户之间彼此看不到对方。

命名空间,相当于容器。

命名空间,本质上建立了系统的不同视图。

Linux根文件系统基本包括哪些内容

通常情况下,Linux内核启动后期,会寻找并挂载根文件系统。根文件系统可以存在于磁盘上,也可以是存在于内存中的映像,其中包含了Linux系统正常运行所必须的库和程序等等,按照一定的目录结构存放。Linux根文件系统基本包括如下内容:

基本的目录结构:/bin、/sbin、/dev、/etc、/lib、/var、/proc、/sys、/tmp等;整个根文件系统都是挂在根目录(/)下,FHS对顶层目录的要求和说明如下表所列。

基本程序运行所需的库文件,如glibc等;

基本的系统配置文件,如inittab、rc等;

必要的设备文件,如/dev/ttyS0、/dev/console等;

基本应用程序,如sh、ls、cd、mv等。

你可以去【周立功】那边了解一下的,蛮多信息的。

OK,本文到此结束,希望对大家有所帮助。

countif函数图解,sumif函数三个条件怎么填下载java教程,java编程