Docker背后的内核知识Linux namespace

Docker引擎的基础是Linux容器技术(Linux Containers,LXC)容器有效地将由单个操作系统管理的资源划分到孤立的组中,以便更好地在孤立的组之间平衡有冲突的资源使用需求。具体体现在6个方面:

namespaces
MountCLONE_NEWNS挂载点(文件系统)
UTSCLONE_NEWUTS主机名与域名
IPCCLONE_NEWIPC信号量、消息队列和共享内存
PIDCLONE_NEWPID进程号
NetCLONE_NEWNET网络设备、网络栈、端口等等
UserCLONE_NEWUSER用户和用户组

模拟Docker引擎如何使用linux namespace实现容器隔离

/* 定义一个给 clone 用的栈,栈大小1M */
\#define STACK_SIZE (1024 * 1024)
static char container_stack[STACK_SIZE];
char* const container_args[] = {
    "/bin/bash",
    NULL
};

int container_main(void* arg)
{
    /* 直接执行一个shell,以便我们观察这个进程空间里的资源是否被隔离了 */
    execv(container_args[0], container_args); 
    return 1;
}

int main()
{
    /* 调用clone函数,其中传出一个函数,还有一个栈空间的(为什么传尾指针,因为栈是反着的) */
    int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_* | SIGCHLD, NULL);
    /* 等待子进程结束 */
    waitpid(container_pid, NULL, 0);
    return 0;
}

我们可以理解为,linux启动的时候会内核默认创建一个父命名空间,每一个docker都是父命名空间创建的子命名空间,子命名空间中的所有资源(以下6个资源)在子命名空间中都有自己的标识,同时会在父命名空间映射一个标识。该父命名空间是所有docker子命名空间的祖先,所以所有docker子命名空间对linux父命名空间来说都是可见的,但是docker子命名空间对于这些资源来收是它们独立的空间,不同命名空间的资源是不能共享的,保证了隔离。
1.每个docker都有自己的文件目录。
2.每个docker都有自己的主机名与域名。
3.每个docker都有自己的信号量、消息队列和共享内存。虽然进程间通信被隔离,但是大多数情况下docker之间的通信都是用socket来实现,例如本机上的不同docker之间使用unix socket,不同主机上的docker就可以理解为tcp/udp通信了。
4.每个docker都有自己的进程号。例如linux系统进程号为1的进程是init进程,在子命名空间中创建的第一个进程pid也是1,它映射到父命名空间中还有自己的一个pid,相互隔离。
5.每个docker都有自己的网络设备、网络栈、端口等等。
6.每个docker都有自己的用户和用户组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值