1.docker容器技术基础入门

1.容器

​  容器时一种基础工具;泛指任何可以用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳、存储、运输物品;物体可以被放置在容器中,而容器则可以保护内容物

2.LXC(Linux Container)

  • 关键词

    • chroot:根切换
    • namespaces:名称空间
    • CGroups:控制组
  • docker说明

​ docker时LXC的增强版,docker本身不是容器,而是容器的易用工具/前端工具,容器是linux内核的一种技术,而docker仅是把这种技术进行简化、普及、与使用

2.1 主机级虚拟

1)定义

​  为每一个封闭的实例,提供的是一个从底层硬件开始一直到高层的基础环境。也就意味着说我们每一个对应的虚拟机实例就拥有自己可视的,而且是隔离于其它实例的基础硬件,包括CPU,内存等等,所以它在硬件完成资源划分以后,提供给了我们每一个实例一个基础环境,使得我们每一个实例都得安装操作系统,从而就拥有自己的内核空间和用户空间,所以这么一来,做为当前实例的使用者,就得安装操作系统,提供环境,安装程序并提供配置文件,最终才可用服务。

​  主机级虚拟化,由于做了两级内核,虚拟机自己有一级,hypervisor会有性能损耗,但是隔离性是非常好的。但过于重量级。

2)常见类型

  • Type-Ⅰ
    • 这种虚拟化,Hypervisor绕过我们熟知的OS内核,直接接管硬件,然后自己再虚拟出对应所需要的OS内核
    • 主要产品有:VMware ESXI
  • Type-Ⅱ
    • 宿主机虚拟化,hypervisor层运行于宿主机OS之上,通过主机OS内核来进行硬件的内核调试
    • 主要产品有:VMware workstation

3)主机级虚拟化架构图

1.docker容器技术基础入门_第1张图片

1.docker容器技术基础入门_第2张图片

  • Hypervisor说明

    ​  Hypervisor,又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的软件、固件或硬件。
    ​  被Hypervisor用来执行一个或多个虚拟机器的电脑称为主体机器(host machine),这些虚拟机器则称为客体机器(guest machine)。hypervisor提供虚拟的作业平台来执行客体操作系统(guest operating systems),负责管理其他客体操作系统的执行阶段;这些客体操作系统,共同分享虚拟化后的硬件资源。

2.2 容器(Container)

1)为什么出现容器技术

​  如果现在我打算在一台完全隔离的环境中,尽量不影响其他应用的情况下,安装一个tomcat。如果目前提供的是一个虚拟机,那么我们除了要安装好操作系统之外,还要安装tomcat等服务,会非常麻烦,整个环境也很重(实际上我也只是仅需要一个tomcat服务而已)。因为我们额外的步骤会非常多,所以这种虚拟化方式过于重量级,尤其是在某些轻量级的需求面前它就显得欲发重量。所以这种情况下就出现了容器技术

2)容器技术原理简述

​  **用户空间(namespace)**仅仅运行用户进程而已,就不需要再主机级虚拟化技术上实现,它自己管理自己的内核,把虚拟出来的内核给剥离掉。给用户一个chroot环境,在这个虚根下,能够隔离和其它用户相关的用户环境。

​  在内核中的一个逻辑级别能够设置成隔离开来的区域,彼此之间互相不干扰,不影响的话,那么我们就可以做出来仅在用户空间,就能实现隔离的组件来。那这个在用户空间就能实现隔离的组件就称之为容器。每个空间就称为一个容器,因为每一个空间都容纳了一堆的进程和用户账号文件等等。

​  将内核分为多个空间,然后每个空间提供一个完整意义上的程序运行环境,容纳了文件,系统和进程以及彼此间交互的一些组件。我们把这些技术称之为容器

3)容器架构图

1.docker容器技术基础入门_第3张图片

2.3 namespace

1)基本概念

​  linux系统从版本2.4.19开始陆续引入了namespace的概念。当一个程序运行于主机之中时,其基本要求有:系统跟文件目录、运行pid进程号、主机名、网卡、ipc通信、程序运行用户这六大类。

​  linux将以上六类进行了内核级别的虚拟化,这六大类统称为namespace

namespace名称空间 被隔离的全局系统资源 在容器环境下的隔离效果 完成的内核版本
UTS 主机名和域名 每个容器能看到自己的hostname 2.6.19
IPC 信号量、消息队列和共享内存(进程间通信) 同一个IPC namespace的进程之间能互相通讯 2.6.19
PID 进程编号 每个PID namespace中的进程可以有其独立的PID,每个容器可以有其PID为1的root进程 2.6.24
Network 网络设备、网络栈、端口等(网络相关的系统资源) 每个容器拥有其独立的网络设备,IP地址,IP路由表,/proc/net目录,端口号 2.6.29
Mount 挂载点(文件系统) 每个容器能看到不同的文件系统层次结构 2.4.19
User 用户和用户组空间 每个container可以有不同的user和group id 3.8

注意:

​  因为centos6的内核为2.6,所以user name不支持,所以centos6天然不太支持容器,虽然可以通过升级内核来进行支持,不过建议直接使用centos7以上的系统

2)chroot介绍

  • 介绍

​  chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 / 位置。

​  在经过 chroot 之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件

  • 好处
  1. 增加了系统的安全性,限制了用户的权力
  2. 建立一个与原系统隔离的系统目录结构,方便用户的开发
  3. 切换系统的根目录位置,引导Linux系统启动以及急救系统等

2.4 cgroups

1)面临的问题

​  内核级必须实现可以限制每一个用户空间中进行所有可用的资源的总量,防止出现类似OOM等资源使用问题

​  可以在整体空间上做比例分配(比如1:2:1),也可以在单个空间中做具体的限制(比如该用户空间最高可用2G内存),此处引入````cgroups```概念

2)定义

​  cgroupsLinux control groups,linux为运行的任务分配cpu、ram等,当namespace为容器进行隔离之后,还需要对每个容器进行资源的使用进行控制,不能让其抢占其它容器的资源。

cgroups主要对一下内容进行资源控制:

  • blkio:块设备IO
  • cpu:CPU
  • cpuacct:CPU资源使用报告
  • cpuset:多处理器平台上的cpu集合
  • devices:设备访问
  • freezer:挂起或恢复任务
  • memory:内存用量及报告
  • perf_event:对cgroup中的任务进行统一性能测试
  • net_cls:cgroup中的任务创建的数据报文的类别标识

2.5 AUFS

1)AUFS的概念

​  AUFS,Union File System,联合文件系统,主要功能是将位于不同物理位置的目录合并成同一个目录,有点类似于hadoop中hdfs的分布式存储

2)linux的基本文件系统

linux系统启动,至少需要两种文件系统,一种是bootfs,一种是rootfs

  • bootfs:包含 boot loader 和 kernel。用户不会修改这个文件系统。实际上,在启动(boot)过程完成后,整个内核都会被加载进内存,此时 bootfs 会被卸载掉从而释放出所占用的内存。同时也可以看出,对于同样内核版本的不同的 Linux 发行版的 bootfs 都是一致的。
  • rootfs:包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp 等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。

同一个内核版本的所有linux系统的bootfs是相同的,rootfs不同

3)docker镜像

​  在docker images中,其采用的是分层技术,基础镜像中的rootfs会一直保存只读模式,docker利用union mount(联合挂载)来在这个rootfs上增加更多的只读文件系统,最后他们看起来就像一个文件系统即容器的rootfs

​  在docker的分层镜像中,除了支持aufs之外,还支持devicemapper,因为在aufs暂时还未被纳入linux内核主干,ununtu14支持aufs,所以docker在ubuntu上面使用aufs,而作为比较老旧的redhat系列上,docker使用的devicemapper(Centos7.4之前),Centos7.4之后使用的是overlay2

3.docker相关

  1. docker内部是基于LXC的,容器的创建、启用、停止、销毁也是用LXC的命令
  2. docker可以基于提前封装好的镜像(镜像提前封装好了想要运行的具体版本的服务)直接创建,另外,同一存放这些镜像的地方叫做镜像仓库
  3. docker限制了一个容器只运行一个进程(注1:该进程+其子进程)(注2:LXC本身是没这个限制的)
  4. docker的每个容器中都自带调试工具(如ps),因为各个环境之间是隔离的(当然,平时是不用启用的,平时只启用该容器的主进程)
  5. docker对开发人员极大的友好,可以忽略系统环境的不同,只要保证底层系统可以运行docker即可,开发人员可以基于同一的docker环境开发即可,不需要考虑底层环境;同理也极大的简化了发布/分发和变更工作
  6. docker增加了环境运维管理的复杂度
  7. docker的镜像是通过分层构建联合挂载来实现(如底层是centos,上层分别是nginx、mysql,然后centos与nginx、centos与mysql分别进行联合挂载,且默认centos只读),若想centos可改,就需要在这两层之间加中间层来实现;同时为了方便迁移,通常不在容器本地保存有效数据,而是在容器外部挂载一个共享存储
  8. docker中,数据与容器的分离,实现了可以把容器单独看作一个进程,可以直接停止删除,再次启用时保证数据还在即可,进程/容器可以运行在任何一个主机上,(比如,10台宿主机负载运行某个容器,数据单独挂载在公共服务器上)
  9. docker中,构建nmp,应用程序存在依赖关系,因此启动关闭顺序也有要求,因此需要一款容器编排工具来解决这个问题(如,docker的machine+swarm+compose组合、asf的mesos+marathon组合、kubernetes即k8s)
  10. docker研发了libcontainer容器引擎,替换了最开始的LXC;后来为了标准化的标准,又替换为了runC(runContainer)

4.扩展

  1. docker商业化后,分为了企业版和社区版,并将社区版重命名为Moby
  2. google的k8s狙击docker,并成立了CNCF公共组织,并将k8s捐出给CNCF,防止自己将其私有化
  3. k8s和docker都是用go语言开发

你可能感兴趣的:(docker)