当我创建一个新的docker容器时
docker run -it -m 560m --cpuset-cpus=1,2 ubuntu sleep 120
Run Code Online (Sandbox Code Playgroud)
并检查其命名空间,我可以看到已创建新的命名空间(pid 7047的示例).
root@dude2:~# ls /proc/7047/ns -la
total 0
dr-x--x--x 2 root root 0 Jul 7 12:17 .
dr-xr-xr-x 9 root root 0 Jul 7 12:16 ..
lrwxrwxrwx 1 root root 0 Jul 7 12:17 ipc -> ipc:[4026532465]
lrwxrwxrwx 1 root root 0 Jul 7 12:17 mnt -> mnt:[4026532463]
lrwxrwxrwx 1 root root 0 Jul 7 12:17 net -> net:[4026532299]
lrwxrwxrwx 1 root root 0 Jul 7 12:17 pid -> pid:[4026532466] …Run Code Online (Sandbox Code Playgroud) KVM和Linux容器(LXC)有什么区别?对我来说,如果我们同时使用内核的"命名空间"和"控制组"功能,那么LXC也是在同一内核中创建多个虚拟机的一种方式.
这一系列命令有效:
unshare --fork --pid --mount
umount /proc
mount -t proc proc /proc
umount /dev/pts
mount -t devpts devpts /dev/pts
Run Code Online (Sandbox Code Playgroud)
但是,相应的C程序没有按预期工作(似乎它没有卸载以前的/ proc,并且它还提供了尝试卸载devpts的EBUSY):
unshare(CLONE_NEWPID | CLONE_NEWNS );
int pid = fork();
if (pid != 0) {
int status;
waitpid(-1, &status, 0);
return status;
}
printf("My pid: %i\n", getpid()); // It prints 1 as expected
umount("/proc"); // Returns 0
system("mount"); // Should print error on mtab, but it prints the previous mounted filesystems
mount("proc", "/proc", "proc",
MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV, …Run Code Online (Sandbox Code Playgroud) 我正在使用以下C函数从单个流程实例创建多个网络命名空间:
void create_namespace(const char *ns_name)
{
char ns_path[100];
snprintf(ns_path, 100, "%s/%s", "/var/run/netns", ns_name);
close(open(ns_path, O_RDONLY|O_CREAT|O_EXCL, 0));
unshare(CLONE_NEWNET);
mount("/proc/self/ns/net", ns_path, "none", MS_BIND , NULL);
}
Run Code Online (Sandbox Code Playgroud)
在我的进程创建了所有namspaces之后,我在任何一个网络命名空间(带命令)中添加了一个tap接口ip link set tap1 netns ns1,然后我实际上在所有命名空间中看到了这个接口(可能,这实际上是一个名称不同的命名空间).
但是,如果我通过使用多个进程创建多个名称空间,那么一切正常.
这可能有什么问题?我是否必须将任何其他标志传递unshare()给单个流程实例?是否存在单个流程实例无法创建多个网络命名空间的限制?或者是否存在mount()调用问题,因为/proc/self/ns/net实际上已多次挂载?
更新:
似乎unshare()函数正确创建了多个网络命名空间,但/var/run/netns/实际上所有挂载点都引用了该挂载中安装的第一个网络命名空间.
Update2: 似乎最好的方法是fork()另一个进程并从那里执行create_namespace()函数.无论如何,我很高兴听到一个更好的解决方案,不涉及fork()调用或至少得到一个确认,证明不可能从单个进程创建和管理多个网络命名空间.
Update3: 我可以使用以下代码使用unshare()创建多个名称空间:
int main() {
create_namespace("a");
system("ip tuntap add mode tap tapa");
system("ifconfig -a");//shows lo and tapA interface
create_namespace("b");
system("ip tuntap add mode tap tapb");
system("ifconfig …Run Code Online (Sandbox Code Playgroud) 我正在阅读mount和clone手册页.我想澄清一下CLONE_NEWNS如何影响子进程的文件系统视图.
(文件层次结构) 
让我们将此树视为目录层次结构.让我们说5和6是父进程中的挂载点.我在另一个问题中澄清了挂载点.
所以我的理解是:5和6是挂载点意味着该mount命令以前用于在5和6处"挂载"文件系统(目录层次结构)(这意味着必须有5和6下的目录树).
从mount手册页:
A mount namespace is the set of filesystem mounts that are visible to a process.
Run Code Online (Sandbox Code Playgroud)
从clone手册页:
Every process lives in a mount namespace. The namespace of a process is the data
(the set of mounts) describing the file hierarchy as seen by that process. After
a fork(2) or clone() where the CLONE_NEWNS flag is not set, the child lives in the
same mount …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用linux命名空间.特别是pid命名空间.
我以为我用bash测试了一些东西但遇到了这个问题:
unshare -p /bin/bash
bash: fork: Cannot allocate memory
Run Code Online (Sandbox Code Playgroud)
从那里运行ls给了一个核心转储.退出是唯一可能的事情.
它为什么这样做?
事实:
148020883.10.0-1062.1.2.el7.x86_641.4.4/tmp是xfscapsh两个用户的输出是相同的,但对于 uid / username/etc/sub{u,g}id文件中都有相同的条目$HOME/.config/containers/storage.conf是默认值,除了 uids 之外,两者是相同的。在storage.conf下面参考。我编写了以下 shell 脚本来演示两者运行的环境有多么相似:
#!/bin/sh
for i in 1480 2088; do
sudo chroot --userspec "$i":10 / env -i /bin/sh <<EOF
echo -------------- $i ----------------
/usr/sbin/capsh --print
grep "$i" /etc/subuid /etc/subgid
mkdir /tmp/"$i"
HOME=/tmp/"$i"
export HOME
podman --root=/tmp/"$i" info > /tmp/podman."$i"
podman …Run Code Online (Sandbox Code Playgroud) 我有一个小程序,试图在取消共享后创建一个伪终端.输出是:
uid before unshare:5000
uid after unshare:0
Grant pt Error: : Permission denied
Run Code Online (Sandbox Code Playgroud)
代码:
#define _GNU_SOURCE
#include <sys/mount.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sched.h>
void set_uid_map(pid_t pid, int inside_id, int outside_id, int length) {
char path[256];
sprintf(path, "/proc/%d/uid_map", getpid());
FILE* uid_map = fopen(path, "w");
fprintf(uid_map, "%d %d %d", inside_id, outside_id, length);
fclose(uid_map);
}
void set_gid_map(pid_t pid, int inside_id, int outside_id, int length) {
char path[256];
sprintf(path, "/proc/%d/gid_map", getpid());
FILE* gid_map = fopen(path, "w");
fprintf(gid_map, …Run Code Online (Sandbox Code Playgroud) 我使用命名空间来分隔服务器上的一些物理接口.路由工作完美.另外,我在/ etc/netns /例如/etc/netns/namespaceA/resolv.conf中有每个命名空间的文件夹,这样DNS也能正常工作.
使用DHCP与dhclient时出现问题.我从命名空间内运行dhclient并收到此错误.
(namespaceA)root@tc-vm:~#dhclient
RTNETLINK answers: File exists
mv: cannot move '/etc/resolv.conf.dhclient-new.2740' to '/etc/resolv.conf': Device or resource busy
Run Code Online (Sandbox Code Playgroud)
我发现/etc/resolvconf/update.d/libc中的mv包含一个可能导致问题的mv.
dhclient如何使命名空间感知?
据我所知,在 Linux shell 环境中,我可以使用 列出任何特定命名空间中的网络链接ip,例如:
ip netns exec <namespace> ip link show
我的问题是:
如果我有多个 net 命名空间,如何用一个简单的命令列出所有命名空间中的所有链接?或者我必须编写一个脚本才能这样做?
linux-namespaces ×10
linux ×8
c ×3
cgroups ×2
containers ×2
networking ×2
bash ×1
centos ×1
clone ×1
dhclient ×1
dhcp ×1
dns ×1
docker ×1
ip ×1
kvm ×1
linux-kernel ×1
lxc ×1
mount ×1
podman ×1