关于docker容器是怎样建立新的namespace的。
最近博客收到了一封交流的私信,感谢您的关注;现在就我理解的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的。的更多相关文章
- 使用 Device Mapper来改变Docker容器的大小
作者:Jérôme Petazzoni ( Docker 布道师) 译者:Mark Shao ( EMC 中国高级工程师) 如果在 CentOS . REHL . Fedor 或者其他默认没有 AUF ...
- Docker容器技术的核心原理
目录 1 前言 2 docker容器技术 2.1 隔离:Namespace 2.2 限制:Cgroup 2.3 rootfs 2.4 镜像分层 3 docker容器与虚拟机的对比 1 前言 上图是百度 ...
- 【转】理解Docker容器网络之Linux Network Namespace
原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...
- 理解Docker(4):Docker 容器使用 cgroups 限制资源使用
本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...
- 如何在Docker容器之间拷贝数据
[编者的话]在容器之间拷贝数据是Docker一个重要而且基本的功能.拷贝数据到其他容器是一个经常使用到的场景,如当服务器遇到不可预见的“灾难”(注:断电,宕机)时,起到备份数据的作用.本文作者详细介绍 ...
- Java程序运行在Docker等容器环境有哪些新问题
基本回答 一. 对于Java来说,Docker毕竟是一个较新的环境,其内存.CPU等资源限制是通过ControlGroup实现的.早期的JDK版本并不能识别这些限制,进而会导致一些基础问题. 1.如 ...
- docker 源码分析 五(基于1.8.2版本),Docker容器的创建
前面讲到了docker容器得镜像,镜像其实是docker容器的静态部分,而docker容器则是docker镜像的动态部分,即启动了一个进程来运行,本篇最要来分析一下怎样创建并运行一个容器. 创建一个容 ...
- Docker容器概念讲解
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源. Docker是通过内核虚 ...
- Docker 容器测试全探索
导读 当我们构建好Docker镜像并利用多套容器共同组合成应用程序,建立起持续交付通道,了解了如何将新创建的镜像纳入到生产或者测试环境当中之后,新的问题来了——我们该如何测试自己的Docker容器?测 ...
随机推荐
- simpson法求积分 专题练习
[xsy1775]数值积分 题意 多组询问,求\(\int_l^r\sqrt{a(1-{x^2\over b})}dx\) 分析 double f(double x) { return sqrt(a* ...
- 第二章 NIO入门
传统的同步阻塞式I/O编程 基于NIO的非阻塞编程 基于NIO2.0的异步非阻塞(AIO)编程 为什么要使用NIO编程 为什么选择Netty 第二章 NIO 入门 2.1 传统的BIO编程 2.1.1 ...
- 添加as源码
http://blog.csdn.net/zhang31jian/article/details/23258065
- PIL中的Image和numpy中的数组array相互转换
1. PIL image转换成array img = np.asarray(image) 需要注意的是,如果出现read-only错误,并不是转换的错误,一般是你读取的图片的时候,默认选择的是&quo ...
- ajax 异步插入图片到数据库(多图上传)
额 大概就这么个样子...截个图 点浏览 选择几张图片 选择完了 确定一下 然后插入数据库 同时在页面中显示插入的图片,代码 也没啥.看下 index.php <html><hea ...
- HTML <div> 标签
定义和用法: <div> 可定义文档中的分区或节(division/section). <div> 标签可以把文档分割为独立的.不同的部分.它可以用作严格的组织工具,并且不使用 ...
- C语言模块化编译介绍
C语言模块化编译介绍 模块化编程的概念 所谓模块化变成(多文件开发),就是多文件(.c文件)编程,一个.c文件和一个.h文件可以被称为一个模块. 头文件开发的注意事项: 1)头文件中可以和C程序一样引 ...
- C#精髓 第四讲 GridView 72般绝技
http://blog.csdn.net/21aspnet/article/details/1540301
- C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取
一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...
- Linux x64 下 Matlab R2013a 300 kb 脚本文件调试的 CPU 占用过高问题的解决办法
(1) 系统+软件版本 CentOS 6.5 (Final), 64 位,内核initramfs-2.6.32-431.5.1.el6.x86_64, MATLAB Version: 8.1.0.60 ...