Docker入门篇-概念

原创
2019/03/31 09:49
阅读数 0

概念

docker是什么

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化Docker容器目前强依赖unix系统内核,它借助unix系统内核的cgroupnamespace隔离机制,使相互之间的容器不会有任何影响

docker架构

Docker使用客户端 - 服务器架构。Docker 客户端与Docker 守护进程通信,后者负责构建,运行和分发Docker容器。Docker客户端和守护程序可以 在同一系统上运行,也可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序使用REST API,通过UNIX套接字或网络接口进行通信。

 

docker守护进程

Docker守护程序(dockerdDocker API请求并管理Docker对象,如像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。

docker客户端

Docker clientdocker)是许多Docker用户与Docker交互的主要方式。当您使用诸如此类的命令时docker run,客户端会将这些命令发送给它们dockerd,然后执行这些命令。该docker命令使用Docker APIDocker客户端可以与多个守护进程通信。

docker注册表(私服)

Docker 注册表存储Docker镜像。Docker Hub是任何人都可以使用的公共注册中心,Docker配置为默认在Docker Hub上查找镜像。您甚至可以运行自己的私人注册表。

使用docker pulldocker run命令时,将从配置的注册表中提取所需的镜像。使用该docker push命令时,镜像将被推送到配置的注册表。

docker对象

使用Docker时,您正在创建和使用镜像,容器,网络,卷,插件和其他对象。本节简要介绍其中一些对象。

镜像(IMAGES

镜像是只读的,用于创建一个容器的指令模板。通常,镜像基于另一个镜像,并带有一些额外的自定义。例如,您可以构建基于镜像ubuntu 镜像ubuntu进行基础上安装Apache Web服务器和应用程序,以及运行应用程序所需的配置详细信息。

您可以创建自己的镜像,也可以只使用其他人创建的镜像并在注册表中发布。要构建自己的镜像,可以 使用简单的语法创建Dockerfile文件,以定义创建镜像和运行镜像所需的步骤。Dockerfile中的每条指令都在镜像中创建一个图层。更改Dockerfile并重建镜像时,仅重建已更改的那些层。与其他虚拟化技术相比,这是使镜像如此轻量,小巧和快速的部分原因。

容器(CONTAINERS

容器是镜像的可运行实例。您可以使用Docker APICLI创建,启动,停止,移动或删除容器。您可以将容器连接到一个或多个网络,将存储连接到它,甚至可以根据其当前状态创建新镜像

默认情况下,容器与其他容器及其主机相对隔离。您可以控制容器的网络,存储或其他基础子系统与其他容器或主机的隔离程度。

容器由其镜像以及您在创建或启动时为其提供的任何配置选项定义。删除容器后,对其状态的任何未存储在持久存储中的更改都将消失。

docker容器的特点:

1灵活:即使是最复杂的应用也可以集装箱化。

2轻量级:容器利用并共享主机内核。

3可互换:您可以即时部署更新和升级。

4便携式:您可以在本地构建,部署到云,并在任何地方运行。

5可扩展:您可以增加并自动分发容器副本。

6可堆叠:您可以垂直和即时堆叠服务。

 

 

通过运行镜像启动容器。一个镜像是一个可执行的包,其中包括运行应用程序所需的所有内容-的代码,运行时,库,环境变量,和配置文件。一个容器中运行原生 Linux和共享主机与其它容器的内核。它运行一个独立的进程,不占用任何其他可执行文件的内存,使其轻量级。

相比之下,虚拟机(VM)运行一个完整的客户操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。通常,VM提供的环境比大多数应用程序需要的资源更多。

 

以下命令运行ubuntu容器,以交互方式附加到本地命令行会话,然后运行/bin/bash

 docker run -i -t ubuntu /bin/bash

运行此命令时,会发生以下情况(假设您使用的是默认注册表配置):

a如果您没有ubuntu本地镜像Docker会从您配置的注册表中提取镜像,就好像您手动执行docker pull ubuntu运行一样。

bDocker创建一个新容器,就像您手动执行docker container create 运行命令一样。

cDocker将读写文件系统分配给容器,作为其最后一层。这允许正在运行的容器在其本地文件系统中创建或修改文件和目录。

dDocker创建了一个网络接口,用于将容器连接到默认网络,因为您没有指定任何网络选项。这包括为容器分配IP地址。默认情况下,容器可以使用主机的网络连接连接到外部网络。

eDocker启动容器并执行/bin/bash。由于容器以交互方式运行并连接到终端(由于-i-t 标志),因此您可以使用键盘提供输入,同时将输出记录到终端。

f键入exit以终止/bin/bash命令时,容器会停止但不会被删除。您可以重新启动它或将其删除。

服务(SERVICE

Docker Engine支持Docker 1.12及更高版本中的swarm模式。

服务允许您跨多个Docker守护程序扩展容器,这些守护程序一起作为具有多个管理器和工作程序的群组一起工作。swarm的每个成员都是Docker守护程序,守护进程都使用Docker API进行通信。服务允许您定义所需的状态,例如在任何给定时间必须可用的服务的副本数。默认情况下,服务在所有工作节点之间进行负载平衡。对于消费者来说,Docker服务似乎是一个单独的应用程序。

基础技术

Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。同VM的方式不同, LXC 其并不是一套硬件虚拟化方法 - 无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法, 理解起来可能并不像VM那样直观。

虚拟化尤其是硬件虚拟化需要其解决的主要是以下4个问题:

隔离性 - 每个用户实例之间相互隔离, 互不影响。 硬件虚拟化方法给出的方法是VM, LXC给出的方法是container,更细一点是kernel namespace

可配额/可度量 - 每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU, memory可以方便实现, LXC则主要是利用cgroups来控制资源

移动性 - 用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法提供snapshotimage来实现,docker(主要)利用AUFS实现

安全性 - 这个话题比较大,这里强调是host主机的角度尽量保护container。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机容器中翻译运行的, 然而对于LXC, 用户的进程是lxc-start进程的子进程, 只是在Kernelnamespace中隔离的, 因此需要一些kernelpatch来保证用户的运行环境不会受到来自host主机的恶意入侵, dotcloud(主要是)利用kernel grsec patch解决的.

下面我们详细介绍Docker中每个容器都使用哪些技术手段类实现隔离的。

命名空间(Namespaces

Docker使用一种被称为namespaces提供隔离工作空间的技术来称为容器。运行容器时,Docker会为该容器创建一组 名称空间。这些命名空间提供了一层隔离。容器的每个方面都在一个单独的命名空间中运行,其访问权限仅限于该命名空间。

Docker EngineLinux上使用以下命名空间:

pid命名空间

1空间内的PID 是独立分配的,每个namespace中的pid是有自己的pid=1的进程

2每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程

3/proc目录只能看到自己namespace中的进程

net命名空间

1有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过netnamespace实现的

2每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来

3LXC在此基础上有5种网络类型,docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge连接在一起

ipc命名空间

只有在同一个Namespace下的进程才能相互通信

mnt命名空间

允许不同namespace的进程看到的文件结构不同

uts命名空间

UTS(UNIX Time-sharing System) namespace允许每个container拥有独立的hostnamedomain name, 使其在网络上可以被视作一个独立的节点而非Host上的一个进程

user namespace

每个container可以有不同的 user group id, 也就是说每个容器进程指定相同的用户,指定的用户之间互不相干,如mysql进行指定用户为mysql,用户组为mysql,这个用户和用户组只在当前容器中有效,在其它容器看不到该用户和用户组。

可参考资料:

https://www.cnblogs.com/linhaifeng/p/6657119.html

https://baike.baidu.com/item/Docker/13344470?fr=aladdin

控制组(Cgroups

cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子 subsystem {子系统前缀}.{资源项} 是典型的配置方法,

memory.usage_in_bytes 就定义了该group subsystem memory中的一个内存限制选项。

另外,cgroups中的 subsystem可以随意组合,一个subsystem可以在不同的group中,也可以一个group包含多个subsystem - 也就是说一个 subsystem

参考资料:

https://baike.baidu.com/item/Cgroup/4988200?fr=aladdin

https://baike.baidu.com/item/Docker/13344470?fr=aladdin

 

文件系统(Union file systems

Union file systems通过创建层来操作的文件系统,使它们非常轻量和快速。Docker Engine使用UnionFS为容器提供构建块。Docker Engine可以使用多种UnionFS变体,包括AUFSbtrfsvfsDeviceMapper

容器格式(Container format)

Docker Engine将命名空间,控制组和UnionFS组合成一个称为容器格式的包装器。默认容器格式是libcontainer。将来,Docker可以通过与BSD JailsSolaris Zones等技术集成来支持其他容器格式。

docker版本

Docker有两个版本:

社区版(CE

Docker Community EditionCE)非常适合希望开始使用Docker并尝试使用基于容器的应用程序的个人开发人员和小型团队。该版本目前免费

企业版(EE

Docker企业版(EE)专为企业开发和IT团队而设计,他们在生产中大规模构建,发布和运行业务关键型应用程序。该版本目前收费

 

该文档教程主要针对docker CE社区版进行讲解。


本文分享自微信公众号 - Java软件编程之家(gh_b3a87885f8f5)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部