最近博客收到了一封交流的私信,感谢您的关注;现在就我理解的docker建立容器时namespace的建立问题做一个 个人的回答:

一,从原理角度来讲:

docker创建container,说白了就是linux系统中的一次fork的调用,在fork调用的时候,会传入一些flag参数,这些参数可以控制对linux内核的调用使用新的namespace;具体的做法是docker daemon封装好一个Command类,在这个Command类中,有关于namespace的配置;接着docker daemon将这个Command类发给execdriver,execdriver从中提取出关于namespace配置,然后最终将这些配置赋给golang 的exec.Cmd类,这个类就是docker 容器跑起来以后的第一个进程;这个进程在创立的时候就会创建新的namespace;

二,从代码角度来讲:

http://www.cnblogs.com/yuhan-TB/p/5118122.html 这篇文章讲了docker run的启动过程,其中docker daemon 与execdriver之间的交互是通过Command类,这是个重要的类,类的定义在daemon/execdriver/driver.go中;其中主要有:Network、Ipc、Pid、UTS等几种命名空间,uid namespace 现在还不支持创建独立的,也就是docker 容器里面的root和 宿主机的root应该是一样的;而这几个命名空间是怎么放到Command里面来的呢,具体代码在daemon/container_unix.go的populateCommand()函数中,这里面主要的作用就是通过container的config和hostconfig来生成Command中的关于这几个namespace的配置。

现在对于docker daemon来说,它已经生成好了发给execdriver的Command类,那么在execdriver中是怎么使用的呢。

在 daemon/execdriver/native/create.go中

func (d *Driver) createContainer(c *execdriver.Command) (*configs.Config, error)

这个函数的作用是接收Command类,根据里面的配置返回一个libcontainer/configs.Config类, 这个类就是execdriver去实际调用去执行关于生成容器的系统调用的时候的配置;

里面有四个这样的函数,就是来从execdriver.Command类中来提取出namespace的相关配置;

if err := d.createIpc(container, c); err != nil {
    return nil, err
}

if err := d.createPid(container, c); err != nil {
    return nil, err
}

if err := d.createUTS(container, c); err != nil {
    return nil, err
}

if err := d.createNetwork(container, c); err != nil {
    return nil, err
}

生成的这个libcontainer/configs.Config类会在vendor/src/github.com/opencontainers/runc/libcontainer/factory_linux.go的函数

func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, error)  中被复制到linuxContainer类里面:

return &linuxContainer{

id:            id,

root:          containerRoot,

config:        config,   //对,就是这个config

initPath:      l.InitPath,

initArgs:      l.InitArgs,

criuPath:      l.CriuPath,

cgroupManager: l.NewCgroupsManager(config.Cgroups, nil),

},nil

接着这个config的配置 在 /vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go

func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, parentPipe, childPipe *os.File) (*initProcess, error) {     t := "_LIBCONTAINER_INITTYPE=standard"

cloneFlags := c.config.Namespaces.CloneFlags()

if cloneFlags&syscall.CLONE_NEWUSER != 0 {

if err := c.addUidGidMappings(cmd.SysProcAttr); err != nil {

// user mappings are not supported

return nil, err

}

enableSetgroups(cmd.SysProcAttr)

// Default to root user when user namespaces are enabled.

if cmd.SysProcAttr.Credential == nil {

cmd.SysProcAttr.Credential = &syscall.Credential{}

}

}

cmd.Env = append(cmd.Env, t)

cmd.SysProcAttr.Cloneflags = cloneFlags

return &initProcess{

cmd:        cmd,

childPipe:  childPipe,

parentPipe: parentPipe,

manager:    c.cgroupManager,

config:     c.newInitConfig(p),

}, nil

}

在飘红的这两个部分,将这些关于namespace的配置交给exec.Cmd类;

关于docker容器是怎样建立新的namespace的。的更多相关文章

  1. 使用 Device Mapper来改变Docker容器的大小

    作者:Jérôme Petazzoni ( Docker 布道师) 译者:Mark Shao ( EMC 中国高级工程师) 如果在 CentOS . REHL . Fedor 或者其他默认没有 AUF ...

  2. Docker容器技术的核心原理

    目录 1 前言 2 docker容器技术 2.1 隔离:Namespace 2.2 限制:Cgroup 2.3 rootfs 2.4 镜像分层 3 docker容器与虚拟机的对比 1 前言 上图是百度 ...

  3. 【转】理解Docker容器网络之Linux Network Namespace

    原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...

  4. 理解Docker(4):Docker 容器使用 cgroups 限制资源使用

    本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  5. 如何在Docker容器之间拷贝数据

    [编者的话]在容器之间拷贝数据是Docker一个重要而且基本的功能.拷贝数据到其他容器是一个经常使用到的场景,如当服务器遇到不可预见的“灾难”(注:断电,宕机)时,起到备份数据的作用.本文作者详细介绍 ...

  6. Java程序运行在Docker等容器环境有哪些新问题

    基本回答 一.  对于Java来说,Docker毕竟是一个较新的环境,其内存.CPU等资源限制是通过ControlGroup实现的.早期的JDK版本并不能识别这些限制,进而会导致一些基础问题. 1.如 ...

  7. docker 源码分析 五(基于1.8.2版本),Docker容器的创建

    前面讲到了docker容器得镜像,镜像其实是docker容器的静态部分,而docker容器则是docker镜像的动态部分,即启动了一个进程来运行,本篇最要来分析一下怎样创建并运行一个容器. 创建一个容 ...

  8. Docker容器概念讲解

    Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源. Docker是通过内核虚 ...

  9. Docker 容器测试全探索

    导读 当我们构建好Docker镜像并利用多套容器共同组合成应用程序,建立起持续交付通道,了解了如何将新创建的镜像纳入到生产或者测试环境当中之后,新的问题来了——我们该如何测试自己的Docker容器?测 ...

随机推荐

  1. 解决首次访问jenkins,输入默认密码之后,一直卡住问题

    简介   安装系统:centos6.5 安装方式:在官网中下载jenkins.war,放到tomcat根目录下的webapps中,启动tomcat(还有一种yum在线安装的方式) 1.首次访问,出现如 ...

  2. 关于启用 HTTPS 的一些经验分享(一)

    转载: 关于启用 HTTPS 的一些经验分享(一) 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS.就在今天,免费提供证书服务的 Let's Encrypt ...

  3. 使用ajaxfileupload插件进行Ajax Post 异步提交多个文件

    前台代码: <div> <div> <img src="images/pro_upload.png" onclick="javascript ...

  4. 结合个人经历总结的前端入门方法 (转自https://github.com/qiu-deqing/FE-learning)

    结合个人经历总结的前端入门方法 (https://github.com/qiu-deqing/FE-learning),里面有很详细的介绍. 之前一直想学习前端的,都不知道怎么下手都一年了啥也没学到, ...

  5. 简述linux的发行版,并描述不同发行版之间的联系与区别

    bash命令行返回值和展开 标签(空格分隔): bash,命令,状态,展开 1.命令状态结果和执行结果 (1)命令执行的状态返回值,命令执行完成之后,其执行状态结果值保存于bash的特殊状态变量$?中 ...

  6. 封装properties从配置文件读取测试用例输入数据

    当每个测试用例都有输入数据,而且数据量比较大的情况,可以采取从文件读取 如果想让同一套测试用例能够适应相似的输入数据,如果直接代码里面来回切换回可能会漏,而且还需要debug检错 可以把一些公用的输入 ...

  7. [转]CSS hack大全&详解

    转自:CSS hack大全&详解 1.什么是CSS hack? CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的, ...

  8. 10.6 CCPC northeast

    1001 Minimum's Revenge 点的编号从 1 到 n ,u  v 的边权是 LCM(u,v) ,求这个图的最下生成树 搞成一颗以 1 为 根 的菊花树 ---------------- ...

  9. 基于任务的异步模式(TAP)

    Task .net 4.0为我们带来了Task的异步,我们有以下三种方法创建Task. 1,Task.Factory.StartNew,比较常用. 2,Task.Run,是.net 4.5中增加的. ...

  10. javascript快速排序

    function quickSort(arr){ if(arr.length <= 1) return arr;//判断是否有效数组 var cut = Math.floor(arr.lengt ...