您的位置:首页 > 运维架构 > Docker

Docker(一)Docker基础原理

2017-07-11 15:20 190 查看
一、虚拟化技术分类
二、容器基础概念
三、Docker入门
四、docker层级概念
一、虚拟化技术分类
1.传统虚拟化Xen或者Kvm
[vm.user]
[vm.kern]....//这种虚拟化技术隔离效果最好,但是性能消耗也高
===========
VMM
======
硬件

vm的user进程需要发起system call的时候,需要调用vm.kernel但是真正执行的是host.kernel
使用BT,或者HVM,加速转换。
内存虚拟化:shadow MMU
CPU虚拟化:tagged TLB
2.容器技术:
lxc:linux container
openvz:

[us1][us2].... //userspace,用户空间进行隔离,这就是一个容器
===========
kernel
===========
硬件

xen或者kvm隔离效果比较好,
容器技术:隔离的是user space

3.库虚拟化:
wine
cywin
4.应用级别虚拟化:
jvm
...
二、容器基础概念:
CGroup + NameSpace + AUFS
1.容器虚拟化依赖到的NS:name space
pstree:
PID 1:用户和内核交互的进程
假如us1中的进程,需要使用root权限和内核交互,它是否能够看到id号为1的进程,并且各us又是隔离的?
yum -y install psmisc //安装该包
内核级别,环境隔离;类似chroot机制
PID NameSpace: kernel 2.6.24虚拟出各种pid,每一个用户空间都可以虚拟一个pid为1的进程
PID隔离
Network NameSpace: kernel 2.6.29 实现网络隔离
网路设备,网络栈,端口号等网络资源隔离
User NameSpace:用户隔离,每一个userspace可有同样的用户名的用户
用户和yoghurt组资源隔离,kernel 3.8 +
IPC NameSpace:进程间通信 kernel 2.6.79
信号量,消息队列和共享内存等隔离
UTS NameSpace: kernel 2.6.19
主机名和域名的隔离
Mount NameSpace: us1能看到的fs一定是自己能够看到的fs,us2挂载的专有设备,fs是us1不能看到的
挂载点隔离(FS)隔离;kernel 2.4.19

为了对不同namespace访问
API:clone(),setns(),unshare();

clone:实现线程的系统调用,来实现新线程的。
setns:设定namespace的属性,假如某个进程到某个NS
unshare:非共享机制,进程脱离一个NS,关联到另一个NS

查看:
mount //可以查看挂载情况
lssubsys -m //查看各个名称空间的挂载情况

2.各容器的资源限制:CGroup
一个NS一个占用整个 userspace 的100%,其他NS就没资源用了
因此CGroup
CGroup: linux control group:控制组
内核级别:限制,控制与一个进程组群的资源;
可以限制:内存,cpu等
kernel 2.6.24 收入内核

资源:CPU,内存,IO

CGroup的功能:
Resource limitation:资源限制
Prioritization:优先级控制;哪一个NS更优先获得CPU和资源
Account:统计和审计,主要为了计费
Control:挂起和恢复 进程

/sys/fs/cgroup
进程启用在哪里,代表只能使用多少资源
倒置的树状结构。
每一资源都是一棵树,cpu是一个,内存是一个,io也是一个,..也可以内存和cpu一棵树
还有其他很多的资源等。有的是重合的,有的是独立的。

术语集:
task(任务):cgroups的术语中,task就表示系统的一个进程。
cgroup(控制组):cgroups 中的资源控制都以cgroup为单位实现。cgroup表示按某种资源控制标准划分而成的任务组,包含一个或多个子系统。
一个任务可以加入某个cgroup,也可以从某个cgroup迁移到另外一个cgroup。
subsystem(子系统):cgroups中的subsystem就是一个资源调度控制器(Resource Controller)。比如CPU子系统可以控制CPU时间分配,内存子系统可以限制cgroup内存使用量。
hierarchy(层级树):hierarchy由一系列cgroup以一个树状结构排列而成,
每个hierarchy通过绑定对应的subsystem进行资源调度。
hierarchy中的cgroup节点可以包含零或多个子节点,子节点继承父节点的属性。
整个系统可以有多个hierarchy。

[C,C,C,C] //CPU
[16G] //内存
[io....] //io等其他资源

[c] [c] [c,c]
[2G] [2G] [12G] //上级可以使用所属的所有资源
/ \
[c] [c]
[4G] [8G]

CGroup的子系统(subsystem):
blkio// 块设备的io资源分配,disk
cpu //设定cpu的限制 ,仅能使用40%
cpuacct //报告cgroup中所使用的cpu资源
cpuset //为cgroup中的任务分配cpu和内存资源,
分配你使用哪一个cpu 和memory,分配可以分配整个
memory //设定内存的使用限制
限制内存使用的空间,例如分配的是1个核心,但是仅运行使用40%
devices //控制cgroup中的任务对设备的访问;
freezer //挂起和回复cgroup中的任务;
net_cls(classid),使用等级级别标识符来标记网络数据包,以实现基于tc完成对不同的cgroup中产生的流量的控制;
perf_event:使用后使cgroup中的任务可以进行统一的性能测试
hugetlb;大的tlb,大内存页,hugetlb让大内存页提高命中率,对HugeTLB系统进行限制;

Cgroup的通俗术语:
task:任务,进程或线程
cgroup:一个独立的资源控制单位,可以包含一个或多个子系统
subsystem:子系统,
hierarchy: 层级,可以再次划分。
一个子系统可以附加到多个层级//例如一个cpu可以在多个层级上附加

3.AUFS: union FS
Union FS:它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一 个虚拟文件系统下
Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率

UnionFS:把不同的物理位置的目录,合并到同一个目录中
假如有两个文件或者目录名一样?
叠加:先后顺序,最前面的才是可写的
AUFS:Another UnionFS 、Alternative UFS、Advanced UFS
但是AUFS不是内核的版本,但是ubuntu是没有的,
Docker 依赖于AUFS,用于提高性能

Docker目前支持的 Union 文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper

原因:
之前复制bin,sbin等程序到一个目录中,chroot后可以执行
ns1和ns2一个需要ls,一个需要cat命令,但是ls和cat命令有重复使用的库,可以把该库做成一个联合库(只读)
可以把公共部分做成一个目录,ns1只放ls独有的,ns2只放cat独有的,用ls或者cat独有的联合底 层公共的库即可
目的:减少disk占用

centos 不支持AUFS但是支持UNIONFS //UNIONFS没有AUFS强悍
还有另外一种方案:Device mapper

4.Device Mapper:
多系统机制
md:multi disks http://www.tldp.org/HOWTO/Multi-Disk-HOWTO-1.html dm:device mapper
Kernel 2.6 引入的最重要的技术之一,用于在内核中支持逻辑卷管理的通用设备的映射机制;
从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略,
当前比较流行的 Linux 下的逻辑卷管理器如
LVM2(Linux Volume Manager 2 version)
EVMS(Enterprise Volume Management System)
dmraid(Device Mapper Raid Tool)等都是基于该机制实现的。
它包含三个重要的对象概念,mapped device、映射表、target device
mapped device:可以理解成为内核向外提供的逻辑设备,它通过映射表描述的映射关系和 target device 建立映射

target device:逻辑设备映射到的一个物理设备
https://www.ibm.com/developerworks/cn/linux/l-devmapper/ 为底层块设备提供抽象设备,

Mapped Device:映射的设备
Mapping table:虚拟设备到物理设备的映射
Target Device:被映射的设备

lVM就依赖于device mapper机制。但是不建议device mapper在docker技术中使用,因为有诸多不稳定性。

三、Docker入门:
程序的发布,需要依赖各种环境
一个docker中应该运行几个程序?只能运行一个应用程序?
docker容器是为单一目的而实现的,为一个应用程序而实现的
LAMP:基于docker,要启用是三个容器,http,php,mysql 三者之间进行通信即可
//其实是可以把LAMP坐在一个容器内部的

[]
=====================
[kernel]
[hardware]

运行了三个Nginx容器
第一个cn(conainer) 使用80port,第二个cn也是用80 port,但是内核之有一个80端口
方法:映射,
kernel: 8080 -> cn2.80
kernle: 888 -> cn1.80
...

容器启动:创建,关闭:删除 //基于某个cn创建的文件没有了怎么办?让数据持久化
按需创建,运行在容器云环境,n个物理节点

[cn1] //cn1第一次启动在host1上,第二次可能启动在host2上
======================== //资源抽象层
host1,host2,........... //物理主机

//容器的路径映射
\ \ \
=======================
云存储//数据持久化
//容器使用的路径,关联到容器云的某个路径,保存数据。容器关联到该路径即可访问原有的数据
volume 技术:实现数据持久化,可以进行实时迁移

Docker的核心概念:2013,Go,apache 2.0协议
C/S架构
Docker client:发起请求的node
docker server:容器运行的node,
docCloud公司研发 https://www.docker.com/
=========================

dockerfiles [dockerHUB]
\ /
[images]
\
\[backup]
【containers】
=============
linux OS
==============================
启动docker容器,需要加载images,server从dockerHUB上下载images
把所依赖到的多个images,叠加为一个UnionFS,然后在该容器中运行
可以从公共dockerhub下载,也可以自制
可以共享让别人访问。
可以创建私有hub

dockerfile:创建dockerfile 创建docker映像文件。

四、docker层级概念
Linux内核是第0层-->Docker镜像,是一个只读的镜像,位于第1层,它不能被修改或不能保存状态。
一个Docker镜像可以构建于另一个Docker镜像之上,这种层叠关系可以是多层的。
第1层的镜像层我们称之为基础镜像(Base Image),其他层的镜像(除了最顶层)我们称之为父层镜像(Parent Image)。
这些镜像继承了他们的父层镜像的所有属性和设置,并在Dockerfile中添加了自己的配置。

Docker镜像通过镜像ID进行识别。镜像ID是一个64字符的十六进制的字符串。
但是当我们运行镜像时,通常我们不会使用镜像ID来引用镜像,而是使用镜像名来引用。

可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。对其中一个容器所做的变更只会局限于那个容器本身。

附件1:进程间通信常用的方式:
C方法包括管道(PIPE)、消息排队、旗语、共用内存以及套接字(Socket)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dm md Cgroup Docker AUFS