一、容器的历史

       容器技术的发展历史悠久,其起源可以追溯到1979年Unix V7引入的chroot命令。chroot命令允许将进程的根目录锁定在指定位置,从而实现文件系统隔离,这为现代容器技术奠定了思想基础。随后,容器技术经历了多个发展阶段:

  1. FreeBSD Jails(2000年):FreeBSD操作系统推出了Jails,实现了进程的沙箱化,增加了文件系统、用户、网络等隔离。
  2. Linux VServer(2001年):类似于Jails,Linux VServer通过修补Linux内核实现资源分区,创建了虚拟私有服务器(VPS)。
  3. Solaris Containers(2004年):Oracle发布了Solaris Containers,提供了系统资源控制和边界分离。
  4. Open VZProcess Containers(2005年和2006年):Google推出了Process Containers,后更名为Cgroups,并最终合并到Linux内核中。
  5. LXC(2008年):Linux容器(LXC)作为第一个完整的Linux容器管理器实现,结合了Cgroups和Linux Namespace的能力。
  6. Warden(2011年):由CloudFoundry推出,提供了隔离、短暂存在和资源控制的环境管理API。
  7. Docker(2013年):Docker的出现推动了容器技术的普及,引入了一整套管理容器的生态系统。
  8. Rocket(2014年):由CoreOS推出,旨在提供比Docker更严格的安全性和产品需求。
  9. Windows Containers(2016年):微软为Windows Server添加了容器支持。
  10. 容器工具成熟(2017年):Kubernetes等工具开始定义容器的某些功能,推动了容器生态系统的形成。
  11. 容器化成为基础(2018年):Kubernetes被用于大多数企业容器项目,推动了云供应商提供托管服务。
  12. 历史变革(2019年):新的运行时引擎开始替代docker运行引擎,如Containerd和CRI-O。
  13. 容器安全问题(2020年):随着容器技术的广泛使用,安全问题也日益凸显。

容器技术的发展是逐步演进的,每一次技术的创新和改进都为现代容器化技术的发展奠定了基础。docker并不是第一个容器化技术,但它的确是最知名的一个。


二、Docker的概述与简介

第四节  Docker概述_docker

        Docker英文译"人工码头”是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。

开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack集群

和其他的基础应用平台。

       Docker是一个开源项目,诞生于2013年初,最初是dotCloud公司(后由于Docker开源后大受欢迎就将公司改名为Docker Inc,总部位于美国加州的旧金山)内部的一个开源的PaaS服务它基于Google公司推出的Go语言实现。(Platform as a ServiceService)的业余项目。

       项目后来加入了Linux基金会,遵从了Apache 2.0协议,项目代码在GitHub上进行维护。

       Docker是基于linux内核实现,Docker最早采用Lxc技术,Lxc是Linux原生支持的容器技术,可以提供轻量级的虚拟化,可以说docker就是基于Lxc发展起来的,提供Lxc的高级封装,标准的配置方法,在Lxc的基础之上,docker 的三大理念是build(构建)、ship(运输)、run(运行),Docker遵从apache 2.0协议,并通过(namespace及cgroup等)来提供容器的资源隔离与安全保障等,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机。

三、Docker的主要目标

Docker的主要目标是提供一种轻量级的操作系统虚拟化解决方案,实现应用级别的封装、分发、部署和运行,确保应用在不同环境中的可移植性和一致性。具体来说,Docker的主要目标包括:

  1. "Build, Ship and Run Any App, Anywhere" :Docker致力于实现应用的可移植性,即在任何支持Docker的Linux发行版上都能运行应用程序。
  2. 提供一个简单、轻量的建模方式,使得用户可以快速上手,将程序“Docker化”,并利用“写时复制”(copy-on-write)模型,实现快速修改和容器创建 。
  3. 实现职责的逻辑分离,让开发人员专注于应用程序,运维人员专注于容器管理,加强开发与生产环境的一致性 。
  4. 缩短开发生命周期,从代码编写到测试、部署、上线运行,提高应用程序的可移植性、易于构建和协作 。
  5. 鼓励使用面向服务的架构和微服务架构,推荐单个容器运行一个应用程序或进程,形成分布式应用程序模型,简化分布式部署、扩展和调试 。

       Docker通过这些目标,旨在简化应用程序的打包、分发和部署流程,提高开发效率,降低运维复杂性,并实现高度的应用程序可移植性。

四、Docker在企业中主要的应用场景

Docker 在企业中的应用场景非常广泛,以下是一些主要的应用场景:

  1. 应用程序部署:Docker 技术可以帮助企业快速部署应用程序和依赖项,提高部署效率和可靠性。
  2. 多租户环境:在云计算环境中,Docker 可以为不同的租户提供隔离的运行环境,确保安全性和互不干扰。
  3. 开发与测试环境:Docker 可以为开发和测试团队提供一致的环境,避免“在我的机器上可以正常运行”的问题,提高开发效率。
  4. 持续集成与持续部署(CI/CD):通过将应用打包成 Docker 镜像,可以实现跨平台的一致性,提高构建和部署的速度。
  5. 微服务架构:Docker 为每个微服务提供独立的运行环境,确保服务之间的隔离性和独立性,同时促进微服务之间的灵活通信。
  6. 灾难恢复和备份:Docker 提供容器级别的快照和备份功能,可以快速恢复到特定状态,提高系统的灾难恢复能力。
  7. 企业生产环境中的容器网络方案:例如,PPTV 基于 Linux Bridge 的 Docker 网络解决方案,实现容器与传统环境应用的互通。
  8. 金融行业:金融行业利用 Docker 的轻量级和隔离性质进行金融应用部署,满足高安全性和高可用性的要求。
  9. 医疗行业:医疗行业通过 Docker 管理大量医疗数据,确保数据隐私和安全,同时提高信息系统的效率。
  10. 零售行业:零售行业使用 Docker 的可扩展性和容器编排工具支持,灵活应对市场变化,搭建跨地域零售平台。
  11. 电信行业:电信行业利用 Docker 的轻量级和可移植性,在网络功能虚拟化(NFV)方面进行广泛应用。
  12. 教育领域:教育领域使用 Docker 提供一致性的开发和测试环境,快速部署和管理学术应用。

       Docker 企业版(Docker Enterprise Edition, EE)还提供了增强的管理和安全功能,帮助企业在规模化生产环境中构建、交付和运行关键业务应用。此外,Docker 在企业中还可以实现传统应用现代化,提高IT效率,并通过较小的攻击面和镜像签名及扫描技术来确保更加安全。

五、Docker的组成部分

第四节  Docker概述_docker_02

第四节  Docker概述_docker_03

Docker主机(Host):一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机,node节点。

Docker服务端(Server):Docker守护进程,运行docker容器。

Docker 客户端(Client):客户端使用docker 命令或其他工具调用docker API 。

Docker仓库(Registry):保存镜像的仓库,官方仓库:https://hub.docker.com/,可以搭建私有仓库harbor。

Docker 镜像(Images):镜像可以理解为创建实例使用的模板Docker容器(Container):容器是从镜像生成对外提供服务的
一个或一组服务。

第四节  Docker概述_docker_04

第四节  Docker概述_docker_05

六、Docker 与物理主机、虚拟机的对比

第四节  Docker概述_应用程序_06

第四节  Docker概述_docker_07

资源利用率更高:一台物理机可以运行数百个容器,但是一般只能运行数十个虚拟机开销更小:不需要启动单独的虚拟机OS内核占用硬件资源启动速度更快:可以在数秒内完成启动

集成性更好:和CI/CD(持续集成/持续部署)相关技术结合性更好,实现自动化管理比如:

       理论上一台128G内存的物理服务器,运行java程序的虚拟机一般分配8G内存/4核的资源,只能运行16台左右虚拟机,但是改为运行docker容器每个容器分配4G内存,就可以运行32个左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可以节约一半以上的物理设备。


七、名称空间、资源限制、启动运行时RunC

1、名称空间(NameSpace)

Docker中有三个核心概念,分别是镜像、容器、仓库。

而镜像的概念主要就是把运行环境和,业务代码进行镜像打包,每个镜像都会存在多个"层”,镜像层都是只读的,不能往里写数据,如果想要写,就需要在其基础之上启动成一个容器,在容器层,我们是可写的。所以我们使用docker的实质是不断的提交容器不断的开辟容器在镜像的多个“层”中,有一个busybox的概念,我们将它理解为欺骗层。

虚拟化的技术就是来解决宿主机与虚拟机之间的耦合问题(简称"解耦”)

什么是解耦,可以查看链接  https://blog.csdn.net/shenwansangz/article/details/82284957

传统虚拟化是属于完全解耦的,docker 这种技术属于半解耦的Docker技术是如何解耦的呢?这就引入了NameSpace的概念:其目的是将某个特定的全局系统资源通过抽象的方法使得NameSpace中的进程看起来拥有他们自己的隔离的,全局系统资源实例,Docker技术通过Linux内核实现了六种NameSpace,如下:

第四节  Docker概述_应用程序_08

当Docker创建一个容器时,它会创建新的以上六种NameSpace的实例,然后把容器中的所有进程放到这些NameSpace之中,使得容器这个父进程只对自己的子进程有感知,而对于宿主机其他进程一无所知,从而产生一种它就是一个独立的系统的“错觉”。


2、资源限制(Cgroup)

Cgroup作用:控制程序对资源的占用。


Cgroup的具体作用如下:

限制资源的使用:Cgroup可以对进程组使用的资源总额进行限制。

优先级控制:通过分配CPU时间片数量及磁盘10带宽大小,实际上就是相当于控制子进程运行的优先级。

资源统计:Cgroup可以统计系统资源使用量,比如CPU使用时间,内存使用量等。可用于按量计费。

进程控制:恢复执行进程。

使用Cgroup,我们可以更具体地控制对系统资源的分配、优先顺序、拒绝、管理和监控。

可更好地根据任务和用户分配硬件资源,提高总体的效率,这样可以在docker容器中的服务受到外部干扰时,可以将其限制在容器之中,而不会影响宿主机或其他容器的运行,提高了安全性。

举列:

  cat /sys/fs/cgroup/cpu/cpu.shares----> 1024  #查看其CPU的权重

容器cpu:

      docker run -tid centos

      cat  /sys/fs/cgroup/cpu/cpu.shares----> 1024   #查看其CPU的权重


内存:

     cat /sys/fs/cgroup/memory/memory.limit_in_bytes  #查看内存的限制


交换空间限制:

    cat  /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes  #查看交换空间的限制



容器内存:

     cat  /sys/fs/cgroup/memory/memory.limit_in_bytes     #查看内存的限制
     cat   /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes   #交换空间的限制
     
默认是不对容器的内存做限制的,这样很危险,容器能使用到宿主机的所有CPU与内存,
所以一般我们要对容器的使用CPU与内存做一下限制
     
 限制cpu时间周期
假如需要给此容器分配cpu使用率的20%,则参数需要设置为20000,相当于每个周期分配给这个容器0.2s
[root@localhost ~]#   
docker run -itd --name=t1 --cpu-quota 20000 centos:7 /bin/bash
8167c75eef1a  67baaef63e0b8575b9aac91be5ab79edbb51abe7028388f923f2


压力测试
echo"net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf

[root@localhost ~]# docker exec -it  8167c75eef1a  /bin/bash
[root@8167c75eef1a /]# yum -y install bc

#计算圆周率
[root@8167c75eef1a/]# time echo "scale=5000; 4*a(1)" | bc -l -q
[root@localhost-]#docker stats 

第二种方式:
[root@localhost ~]# cd  /sys/fs/cgroup/cpu/docker/
[root@localhost docker]#  echo "20000" > 01e51947aa6402395f05a2573efa481



内存限制的参数:
-m或-memory
-m或-memory参数是可以指定容器能使用的最大内存,如果设置了此参数,
则运行容器启动时最低内存大小为4M(后期的docker版本最小限制为6M)

docker run -it --rm -m 2m ubuntu:18.04 bash
docker run -it --rm -m 4m ubuntu:18.04 bash

第四节  Docker概述_docker_09

第四节  Docker概述_应用程序_10


3、启动运行时RunC

第四节  Docker概述_Docker_11

在docker中,RunC是一个根据OCI(Open Container Initiative)标准创建并运行容器的CLI tool,一个遵循OCI标准的用来运行容器的命令行工具。

RunC是docker中最为核心的部分,容器的创建、运行、销毁等等操作最终都将通过调用runc完成。

所谓容器运行时(Container Runtime)包括了容器管理和容器镜像,Open Container Initiative,OCI是容器运行时的工业标准,包括了:

A)运行时标准 runtime-spec

B)容器镜像标准 image-spec

简单来说,容器镜像标准定义了容器镜像的打包形式,而运行时标准定义了如何去运行一个容器。

RunC是一个根据oC1标准创建并运行容器的CLI tool,是一个遵循OCI标准的用来运行容器的命令行工具,它也是一个Runtime的实现。

Runc作为容器的最底层运行环境,其上层通过Docker进行管理。
Runc就是docker中最为核心的部分,容器的创建,运行,销毁等等操作最终都将通过调用Runc完成。

独立运行
Runc作为容器的运行态,不包含镜像的管理,如果直接使用,需要先准备好镜像,这里直接使用已经构建好的
OCI Bundle OCI Bundle是指满足OC1标准的一系列文件,这些文件包含了运行容器所需要的所有数据,
它们存放在一个共同的目录,该目录包含以下两项:
            ①config.json包含容器运行的配置数据
            ②容器的 root filesystem

如果主机上安装了Docker,那么可以使用docker export命令将已有镜像导出为OCI Bundle的格式。

生成rootfs,直接使用Docker中的BusyBox模板

下载最新的版本
docker pull busybox

创建rootfs
mkdir rootfs
docker export $(docker create busybox)  |   tar  -C  rootfs   -xvf   -  .dockerenv
cd rootfs