本文共 5484 字,大约阅读时间需要 18 分钟。
容器是一种基础工具;泛指任何可以用于容纳其它物品的工具,可以部分或完全封闭,被用于容纳、储存、运输物品;物体 可以被放置在容器中,而容器则可以保护内容物;
人类使用容器的历史至少有十万年,甚至可能有数百万年的历史;
v 容器的类型 ɝ 瓶 - 指口部比腹部窄小、颈长的容器。 ɝ 罐 - 指那些开口较大、一般为近圆筒形的器皿。 ɝ 箱 - 通常是立方体或圆柱体。形状固定。 ɝ 篮 - 以条状物编织而成。 ɝ 桶 - 一种圆柱形的容器。 ɝ 袋 - 柔性材料制成的容器,形状会受内容物而变化。 ɝ 瓮 - 通常是指陶制,口小肚大的容器。 ɝ 碗 - 用来盛载食物的容器。 ɝ 柜 - 指一个由盒组成的家俱。 ɝ 鞘 - 用于装载刀刃的容器。
要把信息系统称为容器,也需要容纳物品,物品是虚拟的,是我们的进程文件等等,放置在统一的封闭组件内部,这个组件称为容器 比较成熟的LXC
此前的主机虚拟化技术,每一个运行出来的实例,提供的是从底层的基础硬件开始,一直到高层的基础环境,让每一个对应的虚拟机实例自己拥有可视的而且隔离其他实例的基础硬件CPU,内存等等, 硬件划分后,提供给每个实例,从而让每个实例有了自己的操作系统内核空间和用户空间,作为对应的实例使用者,像使用正常操作系统一样。 隔离性非常好,因为每个主机都有内核,每一个虚拟机的进程是看不到底层Hypervisor 但是虚拟机也需要你自己去安装tomcat,nginx之类的,比较重量级 所以我们有了容器技术,也不是新技术 把中间的内核层剥离掉,提供给用户运行程序的切root环境,这个虚跟可以提供隔离其他用户空间的相关环境,在用户空间当中, 对用户最关键的是根文件系统rootfs(让不同用户空间隔离出来以后,各自都以为自己直接使用系统,每一个用户空间都需要由管理员账号以及其他附加用户和系统账号,root属于内核) 对用户而言我们需要隔离开来 主机名也是属于内核的,主机名和域名也 属于内核 现在把依附在一个用户空间切分成都要隔离的 网络地址,彼此间也需要隔离开来 IPC进程间通信,很多通信都是共享内存来实现的,第一个用户空间和第二个用户空间的进程能通信,这样也没有效果 每一个进程都有两棵树 文件系统和进程是一个棵数 ID为1的进程是用于管控所有子进程的 整个进程树也是需要隔离的 最重要的Control Groups: CGroups 一个用户空间资源有这么些类 NameSpace mount PID user hostname, domain network ipc Control Groups: CGroups 对应操作范围就围绕这些资源,这些都是内核实现, 为了再同一个内核之上做出彼此之间隔离的空间,在内核级就要把这些资源分区,这种分区在内核级是通过所谓的namespace来实现 内核级可以设置逻辑隔离开来区域,彼此之间不干扰,就可以做出多个所谓的仅在用户空间级别所能实现隔离的组件来,这个在用户空间就能实现隔离的组件就称为容器,每一个空间就单独称为容器,容纳了一堆进程和用户账号 隔离开每一个对应的用户空间的挂载点,告诉你是跟,但是其实可能是真正的用户空间,1进程下的子树而已,子树就虚拟成跟空间 在每个用户空间看见的接口要么是虚拟出的,要么是真实接口,这个接口在某一时刻只能属于一个用户空间,网卡可以分别属于不同的空间, 真正的跟用户只有一个,但是对一个空间,一个树来讲,模拟一个用户还是比容易的 在第一个特权空间上创建一个子目录假设/mnt/user1 属主属组都赋值给user1,把.mnt的user1当做是其他用户空间的跟,并且把user1映射为这个空间的root,因此就能实现用户空间级的隔离了 每一个用户空间内运行一个进程,这个进程负责管理这个空间的其他进程,这个叫超级管理,以区别真正的主机的跟 ipc也是隔离的,把一个空间运行的进程放到一个ipc内,一个进程彼此之间可以互相通信,但扩大空间就不允许了 真正容器的功能是靠内核来支撑的 用户空间就可以被分开 操作系统起来的可以当做一个特权的用户空间,基于这个特权空间,创建出彼此隔离的用户空间 每个隔离的用户空间通常是用来运行一个或多个进程,然后把新的应用程序附加上去 如果期望能够跟这个用户空间进行交互,还需要启动第二个进程,bash,启动bash,用户才能交互,远程还需要启动ssh 做好的用户空间有两种访问风格 1.做好的空间,给用户提供交互环境,让用户进行配置,这个配置可能在内部启动多个服务进程,tomcat之类的,httpd,mysql,启动的进程不止一个,就需要在这个空间内有个进程协调这些进程来运行,创建和终止,主控进程,init 这个时候就需要用到init,这种使用风格类似一个虚拟机 还可以让把每个进程需要的文件配置都打包好,直接跑起来,不交互 这是第二种方式, 让容器运行起来的目的就是运行一个进程,要部署一个lamp,原本的用户空间在的,另外一个用户空间来跑tomcat, 第二个跑httpd,第三个mysql,每一个用户空间只跑一个进程, 每一个空间就可以认为这个进程运行的切root 每一个空间跑一个进程,所以也不需要任何人管理了 容器的两种使用风格, 1。类似虚拟机一样使用 2.只针对单个进程提高单个隔离的用户空间,这种方式可以使每一个程序为自己代言,每一个程序依赖的环境打包在一起,打包好的文件当做一个程序,这个文件一启动就相当于一个用户空间 从此部署一个应用程序再也不需要手动解决各种依赖关系 以后相当于进程的封装器 wrapper 这就是现代容器使用方式和传统容器使用方式的不同 传统的容器像虚拟机一样来使用,里面可以运行多个进程,而现在一般一个容器只运行一个进程,各种外部依赖组件通通打包在一起 早期在系统各种资源是共享的,但是有了容器以后反而不共享,但是这种方式非常易于迁移和部署,这就是docker的方式 docker自身并不是容器 在用户空间可能遇到尴尬局面,三个空间运行了三个进程,第一个空间的进程吃掉了很多内存,第二个进程是个吃cpu的99%,第三个就用不了多少 虽然能做到资源的隔离 ,但是对应的底层资源用量的分配还是另外一个问题,之前的隔离仅仅是逻辑组件,而不是系统资源而namespace仅能做到隔离而不能做到资源分配的目的 资源分配需要新的组件 CGroups,控制组,能够实现以进程为单位,来尝试把cpu的时间分片,用量分配,内存分配,以指定比例或数量的方式分配给多个进程 cpu多核心 可以指定第一个进程只能使用第一核,可以使得将一个进程绑定在核心上,最多只能消耗这一个核心的资源 绑定在这个cpu,还可以限制这个cpu,假如有百分百,可以只使用其中百分之10 内存和IO都是按用量分 这些都是靠CGroups来分的 对每一个空间在资源级加以限制,有限资源可以按需求分配不同的运进程, 这种方式其实也有缺陷,如果其他进程都是空闲的,那么为什么不把多余的资源尽量给忙的进程用 如果是虚拟机或者公有云的方式来使用,这种限制是必要的 基于这两种方式,linux内核最终可以把用户控件划分成多个,每一个空间能够独立包装一部分仅是一个进程和其所依赖的环境容器是一种基础工具;泛指任何可以用于容纳其它物品的工具,可以部分或完全封闭,被用于容纳、储存、运输物品;物体 可以被放置在容器中,而容器则可以保护内容物; 由于在内核实现,没有再加一层内核进行调度,所以基本不会有什么性能浪费,因此接近于原生性能的方式,来运行进程 容器技术可以理解为就是用户空间隔离器 主机虚拟化代表产品kvm 容器的解决方案lxc,传统意义上的容器,每个lxc的事业就类似虚拟机一样 由于少了一个内核存,所以性能损耗几乎不存在 lxc=linux containment 大概在2009年才出现,linux内核级的容器特性 **当前的lxc大概使用了一下内核级的技术,来完成进程的容器化 1.内核中的各个名称空间(ipc表示主机名和域名的,主机名称标识, uts, mount, pid, network and user) Apparmor and SELinux profiles 实现各容器对应的进程之间的资源访问约束 ɝ Seccomp policies 和安全相关 ɝ Chroots (using pivot_root) 实现切跟 ɝ Kernel capabilities ɝ CGroups (control groups) **LXC containers are often considered as something in the middle between a chroot and a full fledged virtual machine. 是一个全功能的qieroot,但又不是完全意义上的虚拟机v The goal of LXC is to create an environment as close as possible to a standard Linux installation but without the need for a separate kernel.
架构图 这是内核级做了隔离,并给予所谓的cgroup,资源分配,这些内核功能,通过系统调用向外输出,lxc就是通过系统调用接口,调用这些功能,从而能创建让用户空间隔离的容器来 lxc是各应用程序,也需要依赖一些应用程序,libc,uclib, bionic 从这个角度来讲,lxc可以当作一个虚拟机,容器虚拟机 lxc,每个用户空间要当跟文件系统用,需要几个文件系统,这里面文件从何而来 ubuntu 底层容器跑的不是centos而是ubuntu,因为centos7内核更新慢,unbuntu更新快,所以底层跑的ubuntu来兼容老的,旧的centos不可能去实现新的ubuntu新内核的功能 好在企业内部不可能centos和ubuntu混用 可以在web-gui接口下进行 kvm,为虚拟机创建虚拟网卡,桥接来链接 lxc也一样,每一个用户空间,用不到网络就可以不分配网络接口, 要想准备容器,就类似也要准备桥,才能使得容器启动起来后,能拥有网络接口。网络接口会自动创建,会自动附加在桥上但是接口需要存在,否则默认加载桥的时候,是默认是不成功,网络接口可以不事先创建,但是桥需要有, lxc创建桥是由依赖的名称。但并非不可改变 lxc收录进epel仓库 rpm lxc |less **lxc可以依靠模板来创建 ** 检查环境 指明配置文件,config环境变量来定义文件的路径 enabled么有问题,可以使用 info 来查看容器相关信息 create来创建一个容器 –name 指明名称,-t指明模板 组织出来的容器 -P来执行lxc的路径,把一个当前文件系统的路径当作容器的跟来使用,这个跟在哪个目录下,可以使用- t来定义 放跟文件系统的 放容器 有很多模板文件 这是配置文件 模板文件所在目录,不使用这里的,可以使用-t绝对路径来使用其他配置模板 模板就是表明lxc如何去设定centos文件,创建目录,安装程序包,相当一个脚本,默认是链接互联网的仓库进行下载,可以修改成使用本地的 改成自己所需要的仓库路径,更新update可以直接注释掉 创建centos,下载好程序包以后,就会尝试去安装程序包 可以理解为是一个最小安装,只提供用户空间的操作系统 下载的文件路径 **这个目录不指明会当作根目录的,所有的容器部署在这底下,以容器名命名 刚刚部署好的容器,会设定一个root密码 ** 随机密码在里面,不想要可以在启动直接直接修改密码,切跟进入打passwd命令来修改密码 这就是一个容器已经创建好了start可以启动容器 info查看容器 stopped状态
指明容器终端的附加文件,如果不指明,lxc默认运行前台 当默认当前终端 运行在后台 会自动创建一对虚拟的网卡,一半放在容器上,一半放在桥,没有桥设备无法创建成功 brctl可以创建桥,启动桥,virbr0就激活了 用这个网桥配置地址,物理网卡配置iptables规则,就可以访问到外部网络里去了,现在有桥激活。就能创建了 添加一个地址 在本主机上添加一个10.的地址使容器和主机能够通信现在彼此就可以互相通信了,把lxc网关指向254
设定一个端口网络转发 iptables防火墙安全是面试必然问到的 ping外部主机就可以ping通了 因为构建出了一个nat桥,如果virbr0上企业网络名称空间,启动dnsmaster,可以做dhcp分配 现在这个容器可以当虚拟机一样使用 可以看到有几个容器,每一个容器用了多少cpu,磁盘IO 修改yum源 显示的是物理主机的内存http://lxc-webpanel.github.io/ python程序来帮你管理lxc容器 安装好后,尝试去克隆代码 git clone https://github.com/lxc-webpanel/LXC-Web-Panel.git 可以不编译,直接运行,监听在5000端口上 admin,admin 显示当前物理机系统以及有几个容器 传统的容器使用方式确实可以当做虚拟机来使用 docker是一个容器管理器转载地址:http://sckgn.baihongyu.com/