Docker从入门到实战(一)

一:容器技术与Docker概念

1 什么是容器

容器技术并不是一个全新的概念,它又称为容器虚拟化。虚拟化技术目前主要有硬件虚拟化、半虚拟化、操作系统虚拟化等。
1.1关于虚拟化
虚拟化技术的分类与定义在不同领域有不同的理解。对于计算机领域,虚拟化技术主要分为两大类:一类基于硬件虚拟化,另一类基于软件虚拟化。硬件虚拟化并不多见,大都是半虚拟化与软件结合,应用较为广泛的则是基于软件的虚拟化技术。
基于软件虚拟化又可分为应用虚拟化(如Wine)和平台虚拟化(如虚拟机),容器技术属于操作系统虚拟化,属于平台虚拟化的一种。

1.2容器的定义
所谓容器,顾名思义就是来放东西的道具。在刚进入国内时,还有一段时间在讨论Container这个单词翻译为“容器合适”,还是翻译为“集装箱”合适。大可把容器理解为一个沙盒,每个容器是独立的,容器间可以相互通信。

2 容器的前世今生

如果说工业上的集装箱是从一个箱子开始的,那么软件行业的容器则是从文件系统隔离开始的。
2015年微软公司也在Windows Server上为其基于Windows的应用添加了容器支持,称之为Windows Containers,与Windows Server 2016一同发布,通过该实现,Docker可以原生的在Windows上运行Docker容器,而不需要再启动一个虚拟机来运行Docker(Windows上早期运行Docker需要使用Linux虚拟机)。同年,MacOS也原生支持运行Docker容器。

3 容器的原理

容器本质上是宿主机上的进程。容器技术通过namespace实现资源隔离,通过Cgroups(Google公司的Control Groups技术,2007年被合并到Linux2.6.24内核中)实现资源控制,通过rootfs实现文件系统隔离,再加上容器搜索引擎自身的特性来管理容器的生命周期。
3.1认识namespace
在分布式的环境下,容器必须要有独立的IP、端口和路由等,自然就有了网络隔离。同时,进程通信隔离、权限隔离等也要考虑到,因此基本上一个容器需要做到6項基本隔离。

对namespace的操作主要通过clone(),setns(),unshare()这三个系统调用来完成的。
3.1.1查看当前的namespance
root用户:ls -l /proc/$$/ns

这里$$指的是当前进程ID号,可以看到4026531839这样的数字,表示当前进程指向的namespace.当两个进程指向同一串数字时,表示他们处于同一个namespace下。
3.1.2使用clone()创建新的namespace
创建一个namespace的方法是使用clone()系统调用,它会创建一个新的进程。为了说明创建的过程,给出clone()的原型如下:
int clone (int(child_func) (void ) , void child_stack, int flags , voidarg) ;
如果调用clone()时设置了一个CLONE_NEW的标志,一个与之对应的新的命名空间将被创建,新的进程属于该命名空间,可以使用多个CLONE_NEW标志的组合。
3.1.3使用一个sents()关联一个已经存在namespace
当一个namespace没有进程时还保持打开,这么做是为了后续添加进程到该namesapce.而添加这个功能就是使用sents()系统调用来完成,这使得调用的进程能够和namespace关联,docker exec 就需要用到这个方法:
int setns (int fd, int nstyps);
fd参数指明了关联的namespace,其指向了\proc\PID\ns目录系一个符号连接的文件描述符。可以通过发开这些符号链接指向的文件或者打开一个绑定到符号链接的文件来获得文件描述符。
nstype参数运行调用者检查fd指向的命名空间的类型,如果这个参数等于数,将不会检查,当调用者已经知道namespace的类型时这会很有用。当nstype被赋值为CLONE_NEW*的常量时,内核会检查fd指向的namespace的类型。
要把namespace利用起来,还要使用execve()函数(或者其他的exec()函数),使得我们能够构建一个简单但是有用的工具,该函数可以执行用户命令。
3.1.4使用unshare()在已有进程上进行namespace隔离
unshare()和clone()有些像,不同的地方是前者运行在原有进程上,相当于跳出原来namespace操作,Linux自带的unshare()就是通过调用unshare()这个API来实现。
[root@VM_110_98_centos ~]# unshare --help
Usage:
unshare [options] <program> [<argument>...]

Run a program with some namespaces unshared from the parent.

Options:
-m, --mount unshare mounts namespace
-u, --uts unshare UTS namespace (hostname etc)
-i, --ipc unshare System V IPC namespace
-n, --net unshare network namespace
-p, --pid unshare pid namespace
-U, --user unshare user namespace
-f, --fork fork before launching <program>
--mount-proc[=<dir>] mount proc filesystem first (implies --mount)
-r, --map-root-user map current user to root (implies --user)
--propagation <slave|shared|private|unchanged>
modify mount propagation in mount namespace
-s, --setgroups allow|deny control the setgroups syscall in user namespaces

-h, --help display this help and exit
-V, --version output version information and exit

For more details see unshare(1).
由于docker没有使用这个系统调用,所以不展开。
3.2 认识Cgroups
Cgroups是linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如CPU,内存,I/O等)的机制。最初由Google公司的工程师提出看,后来被整合经linux内核。
这么说理解起来有点吃力,我们通过命令来挂载cgroupfs
提示已经挂载,这个动作一般情况下已经在linux启动的时候做了。

在主流linux发行版下,都可以通过/etc/cgconfig.conf或者cgroup-bin的相关指令来配置Cgroups。
mount {
cpuset = /sys/fs/cgroup/cpuset;
momory = /sys/fs/cgroup/momory;
}
group cnsworder/test {
perm {
task {
uid = root;
gid = root;
}
admin {
uid = root;
gid = root;
}
}
cpu {
cpu.shares = 1000;
}
}
然后通过命令行把一个进程移动到这个Cgroups之中。
#mount -t group -o cpu cpu /sys/fs/cgroup/cpuset
#cgcreate -g cpu,momory:/cnsworder
#chown root:root /sys/fs/cgroup/cpuset/cnsworder/test/*
#chown root:root /sys/fs/cgroup/cpuset/cnsworder/test/task
#cgrun -g cpu,momory:/cnsworder/test bash
3.3容器的创建
3.3.1系统调用clone()创建新进程,拥有自己的namespace
该进程拥有自己的pid,mount,user,net,ipc和uts namespace。
#pid =clone(fun,stack,flags,clone_arg);
3.3.2将pid写入Cgroup子系统这样就受到Cgroups子系统控制
#echo$pid >/sys/fs/cgroup/cpu/tasks
#echo$pid >/sys/fs/cgroup/cpuset/tasks
#echo$pid >/sys/fs/cgroup/bikio/tasks
#echo$pid >/sys/fs/cgroup/memory/tasks
#echo$pid >/sys/fs/cgroup/devices/tasks
#echo$pid >/sys/fs/cgroup/feezer/tasks
3.3.3通过pivot_root系统调用,使进程进入一个新的rootfs,之后通过exec()系统调用,在新的namespace,Cgroups,rootfs中执行/bin/bash.
fun () {
pivot_root ("path_of_rootfs/", path);
exec ("/bin/bash");
}
通过上面的操作,成功的在一个容器中运行了/bin/bash。
3.4 容器云
虽然Docker提供了较为便捷的操作方式,但是在开发、生产环境中网路、存储、集群和高可用等问题层出不穷。仅凭Docker是无法做到面面俱到,于是就从容器到容器云就成了容器技术的 必然发展途径。
完整来说,容器云是以容器为资源分割和调度的基本单位,通过容器封装软件运行环境,为用户提供一个集构建,发布和运行于一体的分布式应用平台。它与IaaS(Platform as a Service,也就是平台即服务)、PaaS等不同,容器云可以共享与隔离资源、编排与部署容器。在这点上容器云与IaaS相似。但是容器云也可以***到应用支撑与运行时环境,在这一点上与PaaS 类似。

文中所有内容皆为手动敲出来的,难免有疏忽之处,欢迎评论指正!
后续文档Docker从入门到实战(二)链接 http://blog.51cto.com/12943999/2072592 

Docker从入门到实战(一)的更多相关文章

  1. 赞一个 kindle电子书有最新的计算机图书可买了【Docker技术入门与实战】

    最近对docker这个比较感兴趣,找一个比较完整的书籍看看,在z.cn上找到了电子书,jd dangdang看来要加油啊 Docker技术入门与实战 [Kindle电子书] ~ 杨保华 戴王剑 曹亚仑 ...

  2. docker-9 supervisord 参考docker从入门到实战

    参考docker从入门到实战 使用 Supervisor 来管理进程 Docker 容器在启动的时候开启单个进程,比如,一个 ssh 或者 apache 的 daemon 服务.但我们经常需要在一个机 ...

  3. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  4. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  5. Docker从入门到实战(三)

    Docker从入门到实战(三) 一:安装Docker 1. linux系统脚本安装 Docker基于linux容器技术,面向服务器端,Docker只能安装运行在64位计算机上(社区有对32位的支持), ...

  6. Docker从入门到实战(二)

    Docker从入门到实战(二) 一:什么是docker Docker是一个开源的应用容器引擎,开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到主流的Linux.MacOS.Windo ...

  7. Docker技术入门与实战第2版-高清文字版

      Docker技术入门与实战第2版-高清文字版 下载地址https://pan.baidu.com/s/1bAoRQQlvBa-PXy5lgIlxUg 扫码下面二维码关注公众号回复100011 获取 ...

  8. Docker技术入门与实战

      Docker技术入门与实战 下载地址https://pan.baidu.com/s/1bAoRQQlvBa-PXy5lgIlxUg 扫码下面二维码关注公众号回复100011 获取分享码 本书目录结 ...

  9. Docker技术入门与实战(文摘)

    第一部分 基础入门 第1章 初识容器与Docker 第2章 核心概念与安装配置 第二部分 实战案例 第三部分 进阶技能 第四部分 开源项目

随机推荐

  1. ACM学习历程—HDU5490 Simple Matrix (数学 && 逆元 && 快速幂) (2015合肥网赛07)

    Problem Description As we know, sequence in the form of an=a1+(n−1)d is called arithmetic progressio ...

  2. 如何自动生成和安装requirements.txt依赖

    在查看别人的Python项目时,经常会看到一个requirements.txt文件,里面记录了当前程序的所有依赖包及其精确版本号.这个文件有点类似与Rails的Gemfile.其作用是用来在另一台PC ...

  3. Puppet master nginx 扩展提升性能(puppet自动化系列4)

    puppet使用SSL(https)协议来进行通讯,默认情况下,puppet server端使用基于Ruby的WEBRick HTTP服务器.由于WEBRick HTTP服务器在处理agent端的性能 ...

  4. java对象在内存中的结构(HotSpot虚拟机)

    一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以 ...

  5. openstackM版本安装

    部署期间常见问题:http://www.cnblogs.com/bfmq/p/6001233.html,问题跟对架构的理解永远比部署重要!你玩技术是绝对是要基于理论的 一.基本情况:物理设备:4台惠普 ...

  6. javascript基础之回调函数

    简单来说,回调函数:也就是将要执行的函数. 回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A.我们就说函数A叫做回调函数.如果没有名称(函数表达式),就叫 ...

  7. C笔试题(一)

    a和b两个整数,不用if, while, switch, for,>, <, >=, <=, ?:,求出两者的较大值. 答案: int func(int a, int b) { ...

  8. RN控件之TextInput

    /** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; import Rea ...

  9. xdu2017校赛F

    Problem F Dogs of Qwordance Senior Backend R&D Engineers 问题描述 那年夏天,锘爷和杰师傅漫步在知春公园的小道上.他们的妻子.孩子牵 着 ...

  10. eclipse中使用Maven插件报错:-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable and mvn script match.

    步骤: 1.添加M2_HOME的环境变量 2.Preference->Java->Installed JREs->Edit 选择一个jdk 3.添加 -Dmaven.multiMod ...