Docker学习(1)-Docker简介

https://suosuoli.cn/#suo博客参考

一、简介

统称来说,容器是一种工具,指的 是可以装下其它物品的工具,以方便人类归纳放置 物品 、存储和异地运输具体来说比如人类使用的 衣柜 、行李箱、 背包 等可以成为容器,但 今天 我们 所说 的容器是一种 IT 技术。

容器技术是虚拟化、云计算、大数据之后的一门新兴的并且是炙手可热的新技术, 容器 技术提高了硬件资源利用率、 方便 了 企业 的业务快速横向扩容、 实现 了业务 宕机自愈功能 ,因此未来数年会 是一个容器愈发流行的 时代 这是 一个对于IT 行业 来说非常有影响和价值的技术,而对于 IT 行业 的从业者来说, 熟练 掌握容器 技术无疑是一 个 很有前景 的行业 工作 机会。
容器技术最早出现 在 freebsd 叫做 jail 。

1.1docker 简介

1.1.1Docker 是 什么

https://www.docker.com/#官方链接

首先Docker 是 一个 在 2013 年 开源的 应用 程序 并且 是 一个 基于 go 语言编写是一个 开源的 PAAS 服务 Platform as a Service 平台即服务 的 缩写 go 语言是 由google 开发 docker 公司 最早 叫 dotCloud 后 由于 D ocker 开源后 大受欢迎就 将公司 改名为 Docker Inc 总部位于美国加州的旧金山 D ocker 是基于 linux 内核 实现 Docker 最早 采用 LXC 技术 LinuX Container 的简写 LXC 是 Linux 原生支持的容器 技术 可以提供轻量级的虚拟化 可以说 docker 就是基于 LXC 发展起来的,提供 LXC 的高级封装,发展标准的配置方法 而 虚拟化 技术 KVM Kernel-based Virtual Machine 基于 模块实现, D ocker 后 改为自己研发 并开源 的 runc 技术 运行容器。

Docker 相比 虚拟机的交付 速度 更快 资源消耗更低 D ocker 采用 客户端、服务端架构 ,使用远程 API 来管理和创建 Docker 容器 ,其可以轻松的创建一个轻量级的、 可 移植 的 、自给自足的容器, docker 的 三大理念是 build( 构建 、ship 运输 、 run 运行 D ocker 遵从 ap ache 2.0 协议 ,并通过 namespace 及cgroup 等)来提供容器的资源隔离与安全保障等 ,所以 Docke 容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机 6 8% 性能)的额外资源开销,因此可以大幅提高资源利用率 总而 言之 Docker 是一种用了新颖方式实现的轻量级虚拟机 类似于 VM 但是在原理和应用上和 VM 的差别还是很大的,并且 docker的专业叫法是应用容器(Application Container)。

1.1.2Docker 的组成

https://docs.docker.com/get-started/overview/#Docker 的组成

Docker 为客服端-服务器架构。Docker 服务端也就是 Docker 的守护进程(docker daemon),Docker 客户端通过 REST API 和守护进程通信,Docker daemon 负责创建、运行和分发容器。客户端和服务端可以运行于同一系统,也可以使用客户端连接远程服务进程。在同一系统时客户端和服务端通过 UNIX sockets 通信,不在同一系统则通过网络接口通信。

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

https://hub.docker.com/#官方仓库

在这里插入图片描述
在这里插入图片描述

Docker 组成
Docker 由多项技术组成,既包括 Linux 内核的功能,也包括 Docker 自己开发的库,还包括了 OCI 组织定义的容器标准。

Docker engine
Docker 引擎由 Docker 服务端守护进程、Docker 客户端及它们之间交流的 REST API组成。Docker 引擎是运行和管理容器的核心。

在这里插入图片描述
Server 服务端
Docker 服务端(Server):Docker 守护进程(dockerd),运行 docker 容器。并接受docker client(docker 命令工具)的指令,已进行相应的创建和运行容器的工作。其监听 Docker API 请求并管理 Docker 对象(镜像,容器,网络和存储等)。服务端守护程序之间也可以通讯以管理 Docker 服务。

Client 客户端
Docker 客户端(Client):用于向 Docker 服务端发送指令的命令行工具,在 linux下的客户端使用 docker 命令调用 docker REST API 和 服务端通讯。如:当运行如下命令时:

docker run -it -p 80:80 nginx:1.16.1

Docker 客户端将该命令发送给dockerd,dockerd进程解析该命令后会寻找nginx:1.16.1这个镜像,并启动为容器,-it表示交互式运行容器并为其分配一个伪终端,-p 80:80表示将主机的 80 端口映射到容器的 80 端口。

Registry 仓库
Docker 仓库(Registry): 保存镜像的仓库,类似于 git 或 svn 这样的版本控制系。
Docker Hub 是 Docker 建立的公开镜像仓库,任何人都可以使用。
运行docker pull IMAGE时,Docker 默认会到 Docker Hub 仓库拉取镜像 IMAGE。
运行docker run IMAGE时,如果本地没有该镜像,则 Docker 也会到 Docker Hub拉取该镜像并由 dockerd 创建容器运行。

Docker objects 对象
当使用 Docker 时,实际上就是创建和使用镜像、容器、网络和存储等对象。

images 镜像
Docker 镜像(Images):镜像可以理解为创建容器实例使用的模板。

镜像为包含创建容器所需指令的只读模板(read-only template)。一般来说,我们使用的镜像都是基于另一个镜像创建的,在前一个镜像的基础上进行了一些自定义。例如:可以基于 ubuntu 镜像创建另一个镜像,自定义的内容仅仅是安装 Apache 服务器和一些工具及使得这些软件能够运行的配置细节。

container 容器
Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务。

简单的说,一个容器就是一个镜像的可运行实例。可以使用 Docker API 来创建、启动、停止、移动或删除一个容器。默认情况下,各个容器之间及容器和运行 Docker 的主机系统之间都是隔离的。可以控制一个容器的网络、存储、或者其它的底层系统和其他容器之间的隔离细节。

一个容器被其对应的镜像和用户创建其时所提供的选项所定义,当一个容器被移除后,任何对其作出的更改(未存储在磁盘的信息)都将消失。

下面的命令运行了一个 ubuntu 镜像,以交互式运行在本地命令行会话中,并运行程序/bin/bash。

~$ docker run -it ubuntu /bin/bash

当运行上面的命令时,发生了以下事情(假设使用默认的镜像仓库配置):

如果本地没有名为ubuntu的镜像,Docker 就会从默认配置的镜像仓库拉取该镜像,相当于运行了命令
~$ docker pull ubuntu。
镜像拉取到本地后,Docker 创建一个新的容器,相当于运行命令docker container create
Docker 分配一个可读写的文件系统给该容器,作为其最后一层。这样使得运行的容器可以在自己的文件系统中创建和修改文件和目录。
Docker 创建一个网络接口来将容器连接到默认的网络上(如果不指定任何网络选项),该过程中 docker 分配了一个 IP 给容器。默认情况下容器是可以通过主机的网络接口访问外部网络的。
Docker 运行该容器并运行/bin/bash,由于容器是交互式运行并依附于当前终端(-it),所以可以在 bash 中输入命令来运行。
当运行键入exit后回车,就退出了/bin/bash,由于是交互式运行 ubuntu 容器,所以此时 ubuntu 容器也停止了运行,但是未被移除。后面还可以再次运行该容器。

services 服务
服务(Service)允许在多个 Docker daemon 之间进行容器伸缩管理。多个 Docker daemon共同工作结合多个manager和多个worker组成了 Docker swarm。Docker swarm 的每个成员都是一个 Docker daemon,各个 daemon 之间使用 Docker API 通讯。Service允许管理员定义预期的状态。Docker 引擎在 Docker1.12 版本后支持 swarm 模式。

1.1.3 Docker对比虚拟机

资源利用率更高:一台物理机可以运行数百个容器,但是一 般 只能运行数十个虚拟机 。
开销更小:不需要启动单独的虚拟机占用硬件资源。
启动速度更快:可以在数秒内完成启动。
体积小:不像虚拟机使用 GB 为计量单位,容器的大小使用 MB 为单位。

对比

指标VMs-虚拟化Container-容器
体积重量级,GB轻量级,MB
性能性能损失大接近 host 原生的性能表现
运行环境每个应用运行于自己的 OS所有容器应用运行于同一个 OS
虚拟化级别硬件级别的虚拟化 OS操作系统级的虚拟化
启动时间可能需要几分钟启动时间在几秒内,甚至几毫米
内存消耗消耗大量内存消耗少量内存,类似 OS 自己的进程
隔离级别所有虚拟机和应用之间完全隔离,比较安全进程级别的隔离,可能不安全

在这里插入图片描述
在这里插入图片描述
使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗。创建虚拟机的目的是为了运行应用程序,比如 Nginx、PHP、Tomcat 等web 程序,使用虚拟机无疑带来了一些不必要的资源开销。

容器技术的出现则减少了中间大量的运行和转换环节,节约了大量不必要的性能损耗和体积占用。
在这里插入图片描述
但是,如上图 一个宿主机 运行了 N 个 容器, 多个容器带来的以下问题怎么解决
1.怎么样保证每个容器都有不同的文件系统并且能互不影响?
2.一个 docker 主进程内的各个容器都是其子进程,那么实现同一个主进程下不同类型的子进程? 各个进程间通信能相互访问 内 数据吗
3.每个容器怎么解决IP及端口分配的问题
4.多个容器的主机名能一样吗
5.每个容器都要不要有 root 用户?怎么解决账户重名问题?
以上问题 怎么 解决?

幸运的是,在前人的基础上(Linux 提供的基础功能),docker 成功解决了上述问题。
其中最重要的两项技术都由 Linux 内核提供:Linux Namespace技术和Linux Control Group技术。

1.1.4Linux Namespace技术

Linux Namespace 是 Linux 系统的底层概念,其由内核实现。Linux 命名空间起源于 2002年 2.4.19 内核中的 mount 命名空间类。从 2006 年开始添加了其他名称空间,并一直持续。随着用户命名空间(User namespace)的引入,在内核 3.8 版本中完成了足够的容器支持功能。

到 Linux kernel 内核版本 4.10,已经有 7 种命名空间加入到其中。从完成的任务角度看,所有命名空间的功能都是相同的:每个进程都和一个命名空间相关联并且只能访问或者使用和该命名空间相关联的资源,这样一来每个进程对系统的资源都有一个唯一的角度。何种资源被隔离取决于为进程组所创建的命名空间类型。

一般,在 Linux 系统下,由于运行软件或者服务产生的新进程一般是由fork()系统调用生成,或者在 bash 中键入命令,bash 会调用exec()系统调用来生成普通的进程。但是容器进程是不一样的,当发送一个创建容器的请求给 Docker 引擎时,Docker 引擎最终会调用clone()系统调用来生成容器进程,使用该系统调用就可以创建带有命名空间的容器化的进程。

在运行 Docker 容器时,Docker 会为该容器创建一组命名空间(在内存中表现为各种数据结构),该容器的多个方面都被限定在这一组命名空间中。各个 docker 容器运行在同一个 docker 主进程并且共用同一个宿主机系统内核,各 docker 容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等。容器运行空间的相互隔离本质上是共同的内核上运行的不同的用户空间之间的隔离,目前内核提供的命名空间功能包括:

命名空间功能解释clone()系统调用使用的 flag引入时内核版本
MNT(mount namespace)提供磁盘挂载点和文件系统的隔离能力隔离挂载点(Mount point)CLONE_NEWNSLinux 2.4.19
IPC Namespace进程间通信相关的隔离功能隔离内核中的 System V IPC, POSIX message queuesCLONE_NEWIPCLinux 2.6.19
UTS Namespace(UNIX Timesharing System)提供主机名隔离能力隔离主机名和 NIS 域名CLONE+NEWUTSLinux 2.6.19
PID Namespace提供进程隔离能力隔离进程 ID 名字空间,不同的进程 ID 空间中进程 ID 从 1 开始CLONE_NEWPIDLinux 2.6.24
Net Namespace提供网络隔离能力隔离网络设备,栈,端口等CLONE_NEWNETLinux 2.6.29
User Namespace提供用户隔离能力隔离用户 ID 和组 IDCLONE_NEWUSERLinux 3.8
Cgroup Namespace提供 cgroup 的隔离隔离 Cgroup 的根目录CLONE_NEWCGROUPLinux 4.6

在 Linux 内核中,以下三个系统调用可以修改命名空间:

clone()系统调用,其使用 flag(上面表格中的 CLONE_NEW…) 来指定新的进程应当被合并到哪个新的命名空间。
unshare()系统调用,允许一个进程将其和其他进程共享的部分运行上下文分离开。
setns()系统调用, 进入一个文件描述符指定的名称空间。

命名空间参考链接
MNT Namespacehttp://man7.org/linux/man-pages/man7/mount_namespaces.7@@man-pages.html
IPC Namespacehttp://man7.org/linux/man-pages/man7/ipc_namespaces.7@@man-pages.html
UTS Namespacehttp://man7.org/linux/man-pages/man7/uts_namespaces.7@@man-pages.html
PID Namespacehttp://man7.org/linux/man-pages/man7/pid_namespaces.7@@man-pages.html
Net Namespacehttp://man7.org/linux/man-pages/man7/network_namespaces.7@@man-pages.html
User Namespacehttp://man7.org/linux/man-pages/man7/user_namespaces.7@@man-pages.html
Linux Control Groupshttp://man7.org/linux/man-pages/man7/cgroups.7@@man-pages.html

1.1.5 Cgroups介绍

Linux Cgroups 的全称是 Linux Control Groups,它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作。

Linux Control Groups 为内核的一项特性,该特性可将多个进程组织成层级结构的进程组,这些进程组所使用的各种资源即可以被限制和监控。内核的 Cgroups 接口通过叫做 cgroupfs 的伪文件系统(pseudo-filesystem)提供。进程的分组功能(Process groups)是在 cgroup 的核心代码(内核代码)中实现的,而资源的跟踪和限制功能则在一组分别控制每种资源类型(per-resource-type)的子系统中实现(这些子系统分别控制内存,CPU 等)

Cgroups 术语解释

cgroup:一个 cgroup 就是与多个限制和参数绑定的进程,这些限制和参数通过cgroup 文件系统定义。
subsystem:一个 subsystem 就是用来修改和控制属于某个 cgroup 的进程行为的内核组件。内核实现了多个不同的子系统,这使得例如控制某个 cgroup 的 CPU 时间和可用内存等工作可行,也可以进行如:监控某个 cgroup 使用的 CPU 时间、暂停和恢复某个 cgroup 内的进程等工作。
resource controller:subsystem 有时也被叫做 resource controller(资源控制器,简称控制器)。

属于某个控制器的 cgroups 被组织成层级结构。通过在 cgroup 文件系统中创建、删除和重命名子文件夹来定义该层级结构。在层级结构的每一层都可以定义属性(即限制措施)。

查看内核所支持的 Cgroups 特性
在使用 Docker 创建和使用容器时,如果不对其做任何资源限制,则宿主机 OS可能会允许其占用无限大的内存空间,有时候会因为容器中运行的程序代码bug 导致程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如 CPU、内存等。而 Cgroups的功能正是解决以上问题的 Linux 内核功能特性。要使用 Cgroups,编译内核时必须带上CONFIG_CGROUP_XXX选项。可以查看内核编译参数来确定是否支持 Cgroups 功能。

在 Ubuntu 18.04.3 LTS 查看

root@Docker-1:~# uname -r
4.15.0-29-generic # # 内核版本为4.15.0
root@Docker-1:~# cat /boot/config-4.15.0-29-generic |grep CGROUP
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
root@Docker-1:~# cat /boot/config-4.15.0-29-generic |grep CGROUP |grep -v "#" |wc -l
17  # ubuntu有17项Cgroups相关特性
同理在centos中也一样的查看 蚕食centos中提供Cgroups相关特性只有12个

Cgroups 在内核层默认已经开启,从 centos 和 ubuntu 对比结果来看,显然内核
较新的 ubuntu 支持的功能更多。

root@Docker-1:~# cat /boot/config-4.15.0-29-generic | grep "CG" | grep "MEM"
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
# CONFIG_MEMCG_SWAP_ENABLED is not set
CONFIG_SLUB_MEMCG_SYSFS_ON=y

Cgroups 控制器具体实现介绍
cgroups 的最初 release V1 版本在 kernel-1.6.24 版本,此时已有多个控制器被实现,然而由于开发这些控制器时未形成统一协调的开发过程,导致了在控制器之间出现了不一致及 cgroup 层级管理变得比较复杂。由于初代的开发原因,在kernel-3.10 版本又重新开发了 cgroup 的 V2 版本,新版本于 kernel-4.5 由官方发布。由于兼容原因,V1 和 V2 并存与内核,V2 只实现了 V1 版本的部分控制器。

Cgroups 的版本 2 的控制器大多继承于版本 1,差异和详细说明可以在man7.ogr找到:

man7.ogr
Cgroups 使用例子

root@Docker-1:~# df -TH
Filesystem     Type      Size  Used Avail Use% Mounted on
udev           devtmpfs  969M     0  969M   0% /dev
tmpfs          tmpfs     200M  9.5M  191M   5% /run
/dev/sda1      ext4       98G  2.1G   91G   3% /
tmpfs          tmpfs     1.0G     0  1.0G   0% /dev/shm
tmpfs          tmpfs     5.3M     0  5.3M   0% /run/lock
tmpfs          tmpfs     1.0G     0  1.0G   0% /sys/fs/cgroup  # cgroup所在地的文件系统类型为tmpfs
/dev/sda3      ext4       49G   55M   47G   1% /data
/dev/sda2      ext4      968M   80M  822M   9% /boot
tmpfs          tmpfs     200M     0  200M   0% /run/user/0
root@Docker-1:~# ll /sys/fs/cgroup/ # 目前系统的cgroups表现为多个目录
total 0
drwxr-xr-x 15 root root 380 Apr 16 22:41 ./
drwxr-xr-x  9 root root   0 Apr 16 22:41 ../
dr-xr-xr-x  4 root root   0 Apr 16 22:41 blkio/
lrwxrwxrwx  1 root root  11 Apr 16 22:41 cpu -> cpu,cpuacct/
lrwxrwxrwx  1 root root  11 Apr 16 22:41 cpuacct -> cpu,cpuacct/
dr-xr-xr-x  4 root root   0 Apr 16 22:41 cpu,cpuacct/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 cpuset/
dr-xr-xr-x  4 root root   0 Apr 16 22:41 devices/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 freezer/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 hugetlb/
dr-xr-xr-x  4 root root   0 Apr 16 22:41 memory/
lrwxrwxrwx  1 root root  16 Apr 16 22:41 net_cls -> net_cls,net_prio/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 net_cls,net_prio/
lrwxrwxrwx  1 root root  16 Apr 16 22:41 net_prio -> net_cls,net_prio/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 perf_event/
dr-xr-xr-x  4 root root   0 Apr 16 22:41 pids/
dr-xr-xr-x  2 root root   0 Apr 16 22:41 rdma/
dr-xr-xr-x  5 root root   0 Apr 16 22:41 systemd/
dr-xr-xr-x  5 root root   0 Apr 16 22:41 unified/

创建 Cgroups 和移动进程
cgroup 文件系统初始只包含单个根 cgroup(root cgroup),"/",所有进程都属于该组。要创建一个新的 group,即是在 cgroup 文件系统中创建一个新的目录:

~$ mkdi /sys/fs/cgroup/cpu/cg1  # 该动作就创建了一个新的cgroup

一个进程可以移动到 cgroup 中,通过将该进程的进程 PID 写入到cgroup.procs文件中即可:

~$ echo $$ > /sys/fs/cgroup/cpu/cg1/cgroup.procs 

root@Docker-1:~# echo $$
1469
root@Docker-1:~# ps -A |grep bash
  1350 tty1     00:00:00 bash
  1469 pts/0    00:00:00 bash

一次只能写一个 PID 到该文件。移动该进程的同时,其包含的线程也属于该组。

移除 cgroups
为了移除某个 cgroup,其必须没有子 cgroup 并且不包含任何进程。要移除cgroup 直接移除代表其的目录即可,里面的文件不用管。

容器管理工具简介
在 Linux 的 chroot、namespace、cgroups 的特性的支持下,具备了基础的容器运行环境,但是还需要有相应的容器创建与删除的管理工具、以及怎么样把容器运行起来、容器数据怎么处理、怎么进行启动与关闭等问题需要解决,于是容器管理技术出现了。早期主要使用了 LXC,目前主流使用 Docker。

https://linuxcontainers.org/#LCX官网
LXC
LXC 为 Linux Container 的简写。可以提供轻量级的虚拟化,以便隔离进程和资源。

Ubuntu 使用 LXC:

~$ apt install lxc lxd
~$ lxc-checkconfig #检查内核对lcx的支持状况,必须全部为lcx
~$ lxc-create -t 模板名称 -n lcx-test
~$ lxc-create -t download --name alpine12 -- --dist alpine  --release 3.9 --arch amd64
~$  lxc-start alpine12 #启动lxc容器
~$  lxc-attach  alpine12 #进入lxc容器

# 命令备注:
-t 模板: -t 选项后面跟的是模板,模式可以认为是一个原型,用来说明我们需
要一个什么样的容器(比如容器里面需不需要有vim, apache等软件).模板实际
上就是一个脚本文件(位于/usr/share/lxc/templates目录),我们这里指定
download模板(lxc-create会调用lxc-download脚本,该脚本位于刚说的模板目
录中)是说明我们目前没有自己模板,需要下载官方的模板
--name 容器名称: 为创建的容器命名
-- : --用来说明后面的参数是传递给download脚本的,告诉脚本需要下载什么样的模板
--dist 操作系统名称:指定操作系统
--release 操作系统: 指定操作系统,可以是各种Linux的变种
--arch 架构:指定架构,是x86还是arm,是32位还是64位

国内模板源地址
lxc 启动容器依赖于模板,但是做模板相对较难,需要手动一步步创构建文件系统、准备基础目录及可执行程序等,而且在大规模使用容器的场景很难横向扩展,另外后期代码升级也需要重新从头构建模板,基于以上种种原因便有了 docker。

1.1.6 Docker

Docker 启动一个容器也需要一个外部模板叫做镜像,docker 的镜像可以保存在一个公共的仓库共享使用,只要把镜像下载下来就可以使用,最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像,一个镜像可以被启动为多个容器。

Docker 的镜像是分层构建的,镜像底层为库文件且属于只读层即不能写入也不能删除和修改数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到容器目录,但是容器内的数据在删除容器后也会被随之删除。
在这里插入图片描述
pouch
pouch 为阿里巴巴在 docker 基础上开发并发开源的容器技术。
https://www.infoq.cn/article/alibaba-pouch#pouch介绍

https://github.com/alibaba/pouch#开源社区项目

1.1.7Docker 优缺点

Docker 优势
快速部署: 在极短时间内可以部署成百上千个应用,可以快速交付产品到生产中。
高效虚拟化: 不需要额外的 hypervisor 程序支持,直接基于 linux 内核提供的功能实现应用虚拟化,相比虚拟机大幅提高性能和效率。
节省成本: 提高服务器利用率,降低 IT 支出。
简化配置: 将运行环境和应用打包保存至容器,使用时直接启动即可。
快速迁移和扩展: 容器可以夸平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从 A 宿主机迁移到 B 宿主机,甚至是不同的平台之间迁移。

Docker 不足
隔离性: Docker 管理的容器提供进程级别的隔离,而不是虚拟机接近硬件级别的隔离。这样的隔离性下,内核的 BUG 会影响任何运行于其上的容器。
大量的容器管理: 在大量的容器部署和管理方面,Docker 有不小的挑战,但是 google 的Kubernetes 可以帮忙。

1.1.8Docker 容器的核心技术

实际上不仅仅是 Docker 容器,任何其他的容器,要想快速发展和进入到实际应用,都离不开下面的核心技术的支持。

容器规范
容器技术除了 docker 之外,还有 coreOS 的 rkt、阿里的 Pouch 等,为了保证容器生态系统的标准统一和维持健康可持续发展。包括 Linux 基金会、Docker、微软、红帽、谷歌、IBM 等公司在 2015 年 6 月共同成立了一个叫 open container initiative(OCI)的开源组织,其目的就是制定开放的标准的容器规范,目前 OCI 一共发布了两个规范,分别是 runtime spec 和 image format spec,有了这两个规范,不同的容器公司开发的容器只要兼容这两个规范,就可以保证不同公司之间使用的容器的可移植性和可操作性。

容器 runtime
runtime 是真正运行容器的地方,为了运行不同的容器,runtime 需要和操作系统内核紧密合作,以便为容器提供相应的运行环境。
目前主流的三种容器 runtime:
LXC:linux 上早期的 runtime,Docker 早期就是采用 lxc 作为 runtime。
runc:目前 Docker 默认的 runtime,runc 遵守 OCI 规范,因此可以兼容 lxc。
rkt:是 CoreOS 开发的容器 runtime,也符合 OCI 规范,所以使用 rktruntime也可以运行 Docker 容器。

runtime 只负责一件事,而且做得很好,那就是运行容器,Runc 运行容器时需要两种东西:
1.一个规格说明文件
2.表示某镜像的根文件系统的路径

容器管理工具
容器管理工具处于 runtime 和使用容器的用户之间,用于对用户提供图形或命令方式操作
管理容器,将用户操作传递给 runtime 执行。例如:
1.lxc 是 lxd 的管理工具。
2.Docker engine 是 Runc 的管理工具是,docker engine 包含后台 deamon 和 cli 两部分,大家经常提到的 Docker 就是指的 docker engine。
3.Rkt 的管理工具是 rkt cli。

容器构建定义工具
容器定义工和构建具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建。
Docker 生态使用 Docker image 来创建容器。而 Docker image 是使用 Dockerfile 来定义。

Docker image : 是 docker 容器的模板,runtime 依据 docker image 创建容器。
Dockerfile : 是包含了多个命令的文本文件,通过 dockerfile 即可创建出 docker image。
ACI(App container image):与 docker image 类似,是 CoreOS 开发的 rkt 容器的镜像格式。

镜像仓库 Registry
在 Docker 生态中,Registry 用来统一保存镜像,叫做镜像仓库。镜像仓库可以分为公共仓库和私有仓库。

Image registry:docker 官方提供的私有仓库部署工具。
Docker hub:docker 官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接下载使用。
Harbor:vmware 提供的自带 web 界面自带认证功能的镜像仓库,目前有很多公司使用该仓库中的镜像。

容器编排工具
Docker 虽然可以在单个主机上运行多个容器,但是当多个容器在多个主机运行的时候,单独管理特定容器是相当复杂的而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩容器的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等容器管理高级功能,这就是容器编排引擎。

容器编排技术通常包括容器管理、调度、集群定义和服务发现等功能。随着需求的提出,出现了很多的容器编排工具,如下:

Docker swarm:Docker 自家开发的容器编排引擎。
Kubernetes:google 开发的容器编排引擎,google 内部项目 Borg 的开源实现版本,且其同时支持 docker 和 CoreOS 的容器编排。
Mesos+Marathon:通用的集群组员调度平台,mesos(资源分配)与 marathon(容器编排平台)一起提供容器编排引擎功能。

1.1.9 Docker 容器依赖的技术

这里指的 Docker 依赖的技术不是指其实现依赖的内核特性等技术,而是其作为容器技术普遍面临的技术依赖,即其大规模普及和应用于生产时的缺陷。幸运的是,可以使用第三方的各种技术来弥补 Docker 在多种环境下的功能缺陷(也不能说是缺陷,只能说一个平台不是万能的,能面对各种境况。)

容器网络
Docker 自带的网络 docker network 仅支持管理单机上的容器网络,当多主机运行的时候需要使用第三方开源网络,例如 calico、flannel 等。

服务发现
容器的动态扩容特性决定了容器 IP 也会随之变化,因此需要有一种机制可以自动识别并将用户请求动态转发到新创建的容器上,kubernetes 自带服务发现功能,需要结合kube-dns 服务解析内部域名。

容器监控
可以通过原生命令 docker ps/top/stats 查看容器运行状态,另外也可以使heapster或Prometheus 等第三方监控工具监控容器的运行状态。

数据管理
容器的动态迁移会导致其在不同的 Host 之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决。

日志收集
Docker 虽然自带原生的日志查看工具 docker logs,但是容器内部的日志需要通过 ELK 等专门的日志收集分析和展示工具进行处理,docker 并不能分门别类的处理个容器日志。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值