设为首页 收藏本站
查看: 768|回复: 0

[经验分享] Docker从入门到实战(一)

[复制链接]

尚未签到

发表于 2018-5-26 10:55:43 | 显示全部楼层 |阅读模式
  一步一步走,写小白都能看懂的文章,将持续更新中,敬请期待!
Docker从入门到实战(一)
一:容器技术与Docker概念
1 什么是容器
  容器技术并不是一个全新的概念,它又称为容器虚拟化。虚拟化技术目前主要有硬件虚拟化、半虚拟化、操作系统虚拟化等。
1.1关于虚拟化
虚拟化技术的分类与定义在不同领域有不同的理解。对于计算机领域,虚拟化技术主要分为两大类:一类基于硬件虚拟化,另一类基于软件虚拟化。硬件虚拟化并不多见,大都是半虚拟化与软件结合,应用较为广泛的则是基于软件的虚拟化技术。
基于软件虚拟化又可分为应用虚拟化(如Wine)和平台虚拟化(如虚拟机),容器技术属于操作系统虚拟化,属于平台虚拟化的一种。
DSC0000.jpg
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項基本隔离。
DSC0001.jpg
对namespace的操作主要通过clone(),setns(),unshare()这三个系统调用来完成的。
3.1.1查看当前的namespance
root用户:ls -l /proc/$$/ns
DSC0002.jpg
这里$$指的是当前进程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启动的时候做了。
DSC0003.jpg
在主流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 (&quot;path_of_rootfs/&quot;, path);
exec (&quot;/bin/bash&quot;);
}
通过上面的操作,成功的在一个容器中运行了/bin/bash。
3.4 容器云
虽然Docker提供了较为便捷的操作方式,但是在开发、生产环境中网路、存储、集群和高可用等问题层出不穷。仅凭Docker是无法做到面面俱到,于是就从容器到容器云就成了容器技术的 必然发展途径。
完整来说,容器云是以容器为资源分割和调度的基本单位,通过容器封装软件运行环境,为用户提供一个集构建,发布和运行于一体的分布式应用平台。它与IaaS(Platform as a Service,也就是平台即服务)、PaaS等不同,容器云可以共享与隔离资源、编排与部署容器。在这点上容器云与IaaS相似。但是容器云也可以渗透到应用支撑与运行时环境,在这一点上与PaaS 类似。
  文中所有内容皆为手动敲出来的,难免有疏忽之处,欢迎评论指正!
后续文档Docker从入门到实战(二)链接 http://blog.51cto.com/12943999/2072592

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-481281-1-1.html 上篇帖子: Docker安装快速入门 下篇帖子: Docker镜像篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表