docker实现原理以及简单体验(一)

简介

?由于科技技术的高度发展,在物理机服务器性能越来越高的今天,很多生产环境中使用的服务器,由于没有很多的用户访问,而导致性能过剩。而生产中又需要在多台服务器上部署业务。如果总是购买物理服务器,显然会造成经济成本大大增加,这时候就需要虚拟化技术来完成物理机性能的合理分配。
?虚拟化技术在上世纪已经诞生,但是上世纪的物理机性能显然无法提供大规模的虚拟化环境,所以没有流行开来。最现如今虚拟化技术已经以势不可挡之势步入各个公司的生产环境中,不经能够大幅节约成本,还可以提高 IT 敏捷性、灵活性和可扩展性。
?虚拟机技术中最先诞生的是主机级虚拟化,主机级虚拟化典型的代表便是KVM/XEN,它可以在物理机之上部署多台虚拟机同时运行,而各个虚拟机之间互不影响,即使某一台服务器由于各种原因“寿终正寝”之后,也不会影响到其它虚拟机和宿主机的正常运行。但是这种技术的缺点也很明显,每个虚拟机都有单独的内核空间,对系统的资源消耗相当大。
?而容器虚拟化技术则解决了这一难题,它不需要在运行是安装一个庞大的内核,而只是将运行某个服务的环境集成在一个容器中,大大减少了对系统资源的消耗,并且有“秒级”的自愈功能,一个容器宕机之后可立即弃之,随后头也不回的重启一个容器接替它的位置,当然此功能需要运维人员对容器进行很好的优化才能实现。

linux namespace的组成

?虽然容器虚拟化技术有种种好处,但是在宿主机之上运行N个容器,如何让这些容器之间的运行稳定,且各个容器之间环境互不影响,就成为了迫在眉睫的问题。每个容器占用系统资源较少,可麻雀虽少,也得五脏俱全。它也得具备主机名,网卡,用户等资源。为了解决此各个容器之间不冲突,就得使用到Linux Namespace
?namespace 是 Linux 系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在内核之中,各个docker容器运行时共享一个宿主机的内核。
?与此同时,每个宿主机之间要相互隔离的运行,并意识不到别的容器的存在,以为自己便是这个宿主机的主宰。那么一个容器必须有如下几个名称空间

MNT Namespace:独立的根文件系统,以实现在容器里面启动服务并且构建出容器的运行环境

[[email protected] ~]#docker exec -it k1 bash
[[email protected] /]# ls /
#独立根文件系统
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

IPC Namespace:保证容器内的进程间能够相互通信,但是不能跨容器访问其他容器的数据

UTS Namespace:用于系统标识,包含主机名和域名,用来唯一标识独立于宿主机系统和运行在其上的其他容器

[[email protected] ~]#docker exec -it k1 bash
[[email protected] /]# hostname
#主机名
3864270aea99
[[email protected] /]# uname -a
#内核版本,注意此处也是宿主机的内核版本
Linux 3864270aea99 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

PID Namespace:每个容器出有一个PID为1的进程,用来管理进程的创建和回收

[[email protected] ~]#docker exec -it k1 bash
[[email protected] /]# top
top - 03:13:35 up  2:17,  0 users,  load average: 0.00, 0.03, 0.06
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   995896 total,   146980 free,   216372 used,   632544 buff/cache
KiB Swap:  2097148 total,  2096884 free,      264 used.   558252 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
     #容器的PID
     1 root      20   0   11820   1680   1408 S  0.0  0.2   0:00.02 bash
    44 root      20   0   11820   1888   1508 S  0.0  0.2   0:00.02 bash
    57 root      20   0   56192   2008   1468 R  0.0  0.2   0:00.02 top

Net Namespace:网络是容器中非常重要的一环每个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP 协议栈等。在运行容器时会自动生成一些防火墙规则用于和外界通讯

容器内网卡逻辑架构图

查看容器内网卡

[[email protected] /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 4190  bytes 39525574 (37.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3233  bytes 179563 (175.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

查看宿主机的上容器网卡的映射

[[email protected] ~]#ifconfig
veth4ce4103: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c061:9aff:fe02:ce89  prefixlen 64  scopeid 0x20<link>
        ether c2:61:9a:02:ce:89  txqueuelen 0  (Ethernet)
        RX packets 3234  bytes 179605 (175.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4191  bytes 39525616 (37.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

查看自动生成的防火墙规则

[[email protected] ~]#iptables -vnL
Chain INPUT (policy ACCEPT 7764 packets, 77M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 7409   40M DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0
 7409   40M DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0
 4179   39M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
 3230  134K ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0 

User Namespace: 每个容器中都要单独的用户和组,和宿主机并不冲突,只是会把用户的作用范围限制在每个容器内

[email protected] ~]#docker exec -it k1 bash
[[email protected] /]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin

容器资源限制

?在使用VMware创建虚拟机时,每个虚拟在安装和启动之前都会有这么一个界面来设置这个虚拟机之前,可以设置此虚拟机占用宿主机的内存,CPU,网卡等硬件设备的大小。

?容器亦是如此,虽然一个容器内的程序可以在其“领地”内行使对所有资源使用权利,但还是要对其做资源限制,容器亦是如此,如果不对容器使用的资源做任何限制,当容器内的资源不够时,容器便会侵蚀宿主机的资源,直至把宿主机的资源占完,成为这台物理机新的“主人”。
?对容器的资源限制还可以提高对于宿主机的安全性,假设一个容器出现漏洞被别人拿到控制权后,资源限制可使其只能够使用这个容器中的资源,而无法对宿主机的资源形成危害。
?那么为了避免物理机的“主人”被其它容器取而代之,就需要一些手段来限制,主要使用的技术便是Linux control groups,简称Linux Cgroups。它的主要作用是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作。
?在容器使用的过程中,一旦内存超过期初给它分配了空间,那么内核将主动杀死这个容器所使用的进程。
此功能在内核层默认已经开启,验证系统的Cgroups是否开启

[[email protected] ~]#cat /boot/config-3.10.0-957.el7.x86_64 | grep CGROUP
CONFIG_CGROUPS=y
#CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
#CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y

Cgroup的具体实现

[[email protected] ~]#ll /sys/fs/cgroup/
总用量 0
drwxr-xr-x 2 root root  0 7月   3 21:02 blkio
lrwxrwxrwx 1 root root 11 7月   3 21:02 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 7月   3 21:02 cpuacct -> cpu,cpuacct
drwxr-xr-x 2 root root  0 7月   3 21:02 cpu,cpuacct
drwxr-xr-x 2 root root  0 7月   3 21:02 cpuset
drwxr-xr-x 4 root root  0 7月   3 21:02 devices
drwxr-xr-x 2 root root  0 7月   3 21:02 freezer
drwxr-xr-x 2 root root  0 7月   3 21:02 hugetlb
drwxr-xr-x 2 root root  0 7月   3 21:02 memory
lrwxrwxrwx 1 root root 16 7月   3 21:02 net_cls -> net_cls,net_prio
drwxr-xr-x 2 root root  0 7月   3 21:02 net_cls,net_prio
lrwxrwxrwx 1 root root 16 7月   3 21:02 net_prio -> net_cls,net_prio
drwxr-xr-x 2 root root  0 7月   3 21:02 perf_event
drwxr-xr-x 2 root root  0 7月   3 21:02 pids
drwxr-xr-x 4 root root  0 7月   3 21:02 systemd

blkio:块设备 IO 限制
cpu:使用调度程序为 cgroup 任务提供 cpu 的访问
cpuacct:产生 cgroup 任务的 cpu 资源报告
cpuset:如果是多核心的 cpu,这个子系统会为 cgroup 任务分配单独的 cpu 和内存
devices:允许或拒绝 cgroup 任务对设备的访问
freezer:暂停和恢复 cgroup 任务。
memory:设置每个 cgroup 的内存限制以及产生内存资源报告
ns:命名空间子系统
perf_event:增加了对每 group 的监测跟踪的能力,可以监测属于某个特定的 group 的所 有线程以及运行在特定 CPU 上的线程
?有了这些就具备了容器的基础运行环境,但是还需要有相应的容器创建与删除的管理工具、以及怎么样把容器运行起来、容器数据怎么处理、怎么进行启动与关闭等问题需要解决,于是容器管理技术便应运而生。

容器管理工具

?容器的管理技术早期诞生的有 Linux Container(LXC),它可以提供轻量级的虚拟化来隔离各个容器之间的通讯。但是LXC启动容器依赖于模板,而模板需要一步步创构建文件系统、准备基础目录及可执行程序等一堆步骤才可使容器运行,另外后期代码升级也需要重新从头构建模板。
?折旧与容器的理念背道而驰,容器本身是为了简化操作而诞生的,如此大费周折的启动一个容器,显然不是生产环境中所期望的,后来由于docker的诞生,便以势不可挡之势侵占了大部分LXC的市场。
?然而并不是说docker启动容器时不需要模板,docker也是需要的。只是它把这些模板包装成为一个个的镜像。而docker的镜像即可以保存在一个公共的地方供所有人共享使用,也可以保存在本地的私有仓库中使用。
?当我们在使用镜像时,只要把别人制作的镜像下载下来就可以使用。如果我们觉得别人的配置不符合生产环境中的需求,我们还可以在别人制作的镜像基础之上做自定义配置,配置完成后保存为自己的一个镜像。如此形成了前人栽树后人乘凉的良性循环,这也是容器技术越来越火爆的原因之一
docker官方镜像仓库地址:https://hub.docker.com/

docker 的组成

docker 主机(Host):一个物理机或虚拟机,用于运行 docker 服务进程和容器。
docker 服务端(Server):docker 守护进程,运行 docker 容器。
docker 客户端(Client):客户端使用 docker 命令或其他工具调用 docker API。
docker 仓库(Registry): 保存镜像的仓库,类似于 git 或 svn 这样的版本控制系
docker 镜像(Images):镜像可以理解为创建实例使用的模板。
docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务。

原文地址:https://blog.51cto.com/14163901/2417017

时间: 2024-10-08 20:55:52

docker实现原理以及简单体验(一)的相关文章

Docker 架构原理及简单使用

提示:文中有些内容为大神的博客内容,就不统一标注那里引用,只是再最下面标注参考连接谢谢 一.简介 1.了解docker的前生LXC LXC为Linux Container的简写.可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性.相当于C++中的NameSpace.容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求. 与传统虚拟化技术相比,它的优势在于: (1)与宿主机使用同一个内核,性能损耗小: (2

Docker工作原理

Docker架构的工作原理 对Docker不太熟悉的朋友可以参考博文:Docker简介及安装配置详解首先Docker是基于Go语言进行开发的,而且是基于C/S结构进行工作的,如图:从图中可以看出:(1)用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者:(2)Docker Daemon作为Docker架构中的主体部分,首先提供Server的功能使其可以接受Docker Client的请求:而后Engine(引擎)执行Docker内部的一系列工作,每一项工作

深入分析 Docker 镜像原理

摘要:近日, DaoCloud 软件工程师孙宏亮在 CSDN Container 微信群为大家带来了 Docker 镜像原理的深度分享,本次分享的重点是 Docker 镜像,分享的内容主要包含两个部分:1)Docker 镜像的基本知识:2)Dockerfile,Docker 镜像与 Docker 容器的关系. 嘉宾介绍:孙宏亮,硕士,浙江大学毕业,现为 DaoCloud 软件工程师,出版有<Docker 源码分析>,目前主要负责企业级容器云平台的研发工作.数年来一直从事云计算.PaaS 领域的

Docker深入浅出系列 | 容器初体验

Docker深入浅出系列 | 容器初体验 教程目标 Docker已经上市很多年,不是什么新鲜事物了,很多企业或者开发同学以前也不多不少有所接触,但是有实操经验的人不多,本系列教程主要偏重实战,尽量讲干货,会根据本人理解去做阐述,具体官方概念可以查阅官方文档,本章目标如下: 了解什么是Docker 了解Docker解决了什么 了解什么是镜像和容器 了解容器与虚拟机的区别 了解Vagrant与Docker的区别 了解Docker引擎和架构 了解Docker的镜像分层 了解VirturalBox和Do

搜索引擎原理之链接原理的简单分析

在google诞生以前,传统搜索引擎主要依靠页面内容中的关键词匹配搜索词进行排名.这种排名方式的短处现在看来显而易见,那就是很容易被刻意操纵.黑帽SEO在页面上推挤关键词,或加入与主题无关的热门关键词,都能提高排名,使搜索引擎排名结果质量大为下降.现在的搜索引擎都使用链接分析技术减少垃圾,提高用户体验.下面泡馆史明星就来简单的介绍链接在搜索引擎排名中的应用原理. 在排名中计入链接因素,不仅有助于减少垃圾,提高结果相关性,也使传统关键词匹配无法排名的文件能够被处理.比如图片.视频无法进行关键词匹配

【Cardboard】 体验 - Google Cardboard DIY及完成后简单体验

体验 - Google Cardboard DIY及完成后简单体验 今年的Google I/O最让我感兴趣的除了Material Design以外就是这个Google Cardboard了.据说是Google20%制度的产物,与其说是像某些人口中那种“和Facebook的Oculus竞争”的布局,我宁愿相信是Google文化所产生的geek式娱乐的产物. 先贴两张Google官方Google Cardboard的图,一张是组装图一张是拆分图: Google Cardboard是一个简单的平民级V

linux运维、架构之路-Docker架构原理

一.Docker架构原理介绍        Docker使用了C/S架构,客户端与守护进程通信,Docker守护进程负责构建,运行和分发Docker容器.Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程.Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信. 二.Docker介绍        Docker的英文翻译是”搬运工“的意思,他搬运的东西就是我们常说的集装箱Container,Container

poj 2356 Find a multiple 鸽巢原理的简单应用

题目要求任选几个自然数,使得他们的和是n的倍数. 由鸽巢原理如果我们只选连续的数,一定能得到解. 首先预处理前缀和模n下的sum,如果发现sum[i]==sum[j] 那么(sum[j]-sum[i])%n一定为0,直接输出i+1~j就够了. 为什么一定会有解,因为sum从1~n有n个数,而模n下的数只有0~n-1,把n个数放入0~n-1个数里,怎么也会有重复,所以这种构造方法一定没问题. 其实可以O(n)实现,嫌麻烦,就二重循环无脑了. #include <iostream> #includ

编译原理(简单自动词法分析器LEX)

编译原理(简单自动词法分析器LEX)源程序下载地址:  http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7%90%86%E7%AE%80%E5%8D%95LEX%EF%BC%88%E8%AF%8D%E6%B3%95%E8%87%AA%E5%8A%A8%E5%88%86%E6%9E%90%E5%99%A8%EF%BC%89.zip