Docker
Docker发展史
- 很久以前
2008年,Solomon Hykes 和他的朋友 Kamel Founadi、Sebastien Pahl 共同创立了一家名为 DotCloud 的公司,目标是利用一种叫做容器的技术来创建他们称作是“大规模的创新工具”:任何人都可以使用的编程工具。
2010年,dotCloud获得了创业孵化器Y Combinator的支持,并开始吸引到一些真正的投资,在接下来的3年中,dotCloud内部孵化了一款名为Docker的产品。
- 2013年
2013 年 3 月 Docker 创始人 Solomon Hykes 在 PyCon 大会上的演讲中首次公开介绍了 Docker 这一产品。在2013 年 PyCon 大会之后,Docker 的创新式镜像格式以及容器运行时迅速成为社区、客户和更广泛行业的实际标准和基石。Docker 的强大之处在于它通过可移植的形式和易于使用的工具在应用程序和基础设施之间创造了独立性。其结果是,Docker将容器技术大众化,并解决了困扰数百万开发人员的“matrix from hell”问题,使容器技术成为主流。
2013年3月20日,dotCloud发布了 Docker 的首个版本,并将Docker源码进行开源。https://github.com/docker/
2013年9月 红帽公司成为Docker的主要合作伙伴,利用Docker来驱动他的OpenShift云业务。随后,谷歌、亚马逊以及DigitalOcean也迅速的在其云服务平台提供了Docker的支持。主流云厂商的加入,加速Docker的发展进度。
随着Docker技术的开源,此项技术能够将Linux容器中的应用代码打包并轻松的在服务器之间迁移,Docker技术瞬时的风靡了全球,2013年底DotCloud Inc则更名为Docker Inc,并全力的主攻到Docker项目开发中。
- 2014年
2014年6月的DockerCon大会上Docker正式发布了Docker 1.0 版本。这也意味着Docker的稳定性和可靠性已经基本满足了生产环境的运行需求。会议上同时发布Docker Image的镜像仓库Docker Hubhttp://hub.docker.com/,并指出已经有超过14,000个Docker化的应用存储在他们的publc registry中。
也是同样的2014年6月,基于谷歌内部强大的Borg系统而开发出来的kubernetes横空处世,刷新了人们对容器的理解。
2014年8月份,Docker Inc宣布将用于PaaS业务服务的DotCloud软件出售给德国柏林的PaaS服务厂商CloudControl,自此以后,DotCloud正式的和Docker分道扬镳了。
2014年12月举行的DockerConEU大会上,Docker Swarm 和Docker Machine同时面世。Docker Swarm是一个Docker集群管理工具,而Docker Machine是部署Docker主机的命令工具。
2014年12月里,CoreOS宣布开发自家的容器运行环境rkt以及appc容器规范。
- 2015年
容器技术不只Docker,很早之前Google就投资了CoreOS来做竞争的容器–Rocket。那时是三家鼎立:Docker/Rocket/Warden,为了避免惨烈的竞争,大家终于统一意见,决定成立固定的标准来良好发展容器技术。
2015年6月,由Docker、IBM、微软、红帽及Google等厂商所组成的开放容器项目OCP联盟成立,该项目旨在建立软件容器的通用标准。OCP成立于Linux基金会之下,其使命是使用户和公司能够继续创新和开发基于容器的解决方案,并充满信心地保护其先前的开发工作,并且不会造成行业分散。作为该计划的一部分,Docker将捐赠其软件容器格式,运行时以及相关规范的代码。应用容器规范(“ appc”)计划的领导者,包括创始成员CoreOS,也将把他们的技术领导力和支持带到OCP。
2015 年,Docker 发布了 runC工具,runc是根据OCI标准生成的一个cli工具,一个轻量级的跨平台的容器运行时命令行小工具,可以直接利用 libcontainer 运行容器,而无需通过 docker engine。runC 的目标是使标准容器在任何地方都可用。
- 2016年
2016年6月的DockerCon上,Docker宣布了Open Container Initiative的正式成立。OCI意在业界一起合作,开发一个开放的、标准的容器格式和runtime。OCI也属于Linux基金会的协作项目,一直秉承着开放的模式来管理,其roadmap在GitHub上。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sheBxRG1-1659858398842)(https://tse1-mm.cn.bing.net/th/id/OIP-C.Yc2UdZDsJoa7TSJtT-ezzQHaEW?pid=ImgDet&rs=1)]
2016年,OCI标准制定后,Docker 将 containerd 独立拆分,并将其捐赠给了社区。将这个组件分解为一个单独的项目,使得 docker 将容器的管理功能移出 docker 的核心引擎并移入一个单独的守护进程(即 containerd)。
在2016年,人们认识到容器技术本身的价值时在于容器的编排,而此时的Docker项目令人惊讶的放弃了Swarm项目,而是想将容器的编排和集群的管理功能添加到Docker项目当中。而Kubernetes却与Docker不同的是推进民主化架构,使得通过暴露Kubernetes API的方法,让更多的人来不断丰富kubernetes的插件。
- 2017年
从2013年3月开始推出0.1.0版本,到17年2月1.13的版本都采用x.x的形式。从 2017 年第一季度开始,Docker 版本号遵循 YY.MM-xx 格式。
2017 年是容器成为主流技术的一年,这就是为什么 Docker 在 Linux 之外支持众多平台的原因(Docker for Mac,Docker for Windows,Docker for AWS,GCP 等)。
2017 年于 Austin 举办的 DockerCon 上开源Docker项目正式命名为 Moby 项目。由于这次改名,GitHub 上的 docker/docker 库也被转移到了 moby/moby,并且拥有了项目自己的 Logo,如下图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZulBfxV-1659858398842)(https://tse3-mm.cn.bing.net/th/id/OIP-C.QxIe2N55R9cOMuvxNjp9fgHaE8?pid=ImgDet&rs=1)]
于此同时,将Docker本身拆分为Docker-CE免费版和Docker-EE商业版。
Docker-CE目前是docker公司维护的开源项目,是一个基于Moby项目的免费的容器产品。
Docker-EE目前是docker公司维护的闭源项目,是docker公司的商业产品。
至此,容器天下三分。其中Moby由社区维护,Docker-CE由Docker公司维护,Docker-EE是Docker公司闭源的商业产品。
- 2018年
2018年3月 Docker 公司创始人Solomon Hykes 在 Docker 博客上宣布已正式从 Docker 公司离职,不再担任公司的日常运作工作。Solomon Hykes 表示,他未来的身份将是 Docker 的董事会成员、主要股东,以及 Docker 维护者,但不再负责担任公司的日常工作。
- 2019年及未来
2019年容器市场基本趋于稳定,一切都向着优化改进方向发展。Docker公司是底层容器引擎及运行时的。容器的编排进过几轮的激烈竞争,基本是GOOGLE的Kubernetes一家独大。
新的战斗已经由容器和编排的战场,逐渐迁移到应用领域。云原生CNCF将引领新的技术方向,微服务、ServcieMesh、Envoy、ServerLess等正在路上
五种存储驱动基本原理
- 1、AUFS
AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS能透明覆盖一或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。结构如下图所示:
- 2、Overlay
Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。结构如下图所示:
- 3、Device mapper
Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。前面讲的AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并不有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。Device mapper 驱动默认会创建一个100G的文件包含镜像和容器。每一个容器被限制在10G大小的卷内,可以自己配置调整。结构如下图所示:
- 4、Btrfs
Btrfs被称为下一代写时复制文件系统,并入Linux内核,也是文件级存储驱动,但可以像Device mapper一直接操作底层设备。Btrfs把文件系统的一部分配置为一个完整的子文件系统,称之为subvolume 。采用 subvolume,一个大的文件系统可以被划分为多个子文件系统,这些子文件系统共享底层的设备空间,在需要磁盘空间时便从底层设备中分配,类似应用程序调用 malloc()分配内存一样。为了灵活利用设备空间,Btrfs 将磁盘空间划分为多个chunk 。每个chunk可以使用不同的磁盘空间分配策略。比如某些chunk只存放metadata,某些chunk只存放数据。这种模型有很多优点,比如Btrfs支持动态添加设备。用户在系统中增加新的磁盘之后,可以使用Btrfs的命令将该设备添加到文件系统中。Btrfs把一个大的文件系统当成一个资源池,配置成多个完整的子文件系统,还可以往资源池里加新的子文件系统,而基础镜像则是子文件系统的快照,每个子镜像和容器都有自己的快照,这些快照则都是subvolume的快照。
当写入一个新文件时,在容器的快照里为其分配一个新的数据块,文件写在这个空间里,这个叫用时分配。而当要修改已有文件时,使用CoW复制分配一个新的原始数据和快照,在这个新分配的空间变更数据,变结束再更新相关的数据结构指向新子文件系统和快照,原来的原始数据和快照没有指针指向,被覆盖。
- 5、ZFS
ZFS 文件系统是一个革命性的全新的文件系统,它从根本上改变了文件系统的管理方式,ZFS 完全抛弃了“卷管理”,不再创建虚拟的卷,而是把所有设备集中到一个存储池中来进行管理,用“存储池”的概念来管理物理存储空间。过去,文件系统都是构建在物理设备之上的。为了管理这些物理设备,并为数据提供冗余,“卷管理”的概念提供了一个单设备的映像。而ZFS创建在虚拟的,被称为“zpools”的存储池之上。每个存储池由若干虚拟设备(virtual devices,vdevs)组成。这些虚拟设备可以是原始磁盘,也可能是一个RAID1镜像设备,或是非标准RAID等级的多磁盘组。于是zpool上的文件系统可以使用这些虚拟设备的总存储容量。
下面看一下在Docker里ZFS的使用。首先从zpool里分配一个ZFS文件系统给镜像的基础层,而其他镜像层则是这个ZFS文件系统快照的克隆,快照是只读的,而克隆是可写的,当容器启动时则在镜像的最顶层生成一个可写层。如下图所示:
当要写一个新文件时,使用按需分配,一个新的数据快从zpool里生成,新的数据写入这个块,而这个新空间存于容器(ZFS的克隆)里。当要修改一个已存在的文件时,使用写时复制,分配一个新空间并把原始数据复制到新空间完成修改。
docker安装
//安装最新版本Docker依赖环境
[root@localhost ~]# yum -y install yum-utils device-mapper-persistent-data lvm2
//安装docker使用的yum源
[root@localhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
//安装docker-ce,开启服务,并设置服务开机自启
[root@localhost ~]# yum -y install docker-ce --allowerasing
[root@localhost ~]# systemctl start docker.service
[root@localhost ~]# systemctl enable docker.service
Docker加速器配置
- 进入阿里云官网www.aliyun.com,搜索容器镜像服务,点击控制台,就可以看到镜像加速器
[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# vim /etc/docker/daemon.json
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://gxroeyl8.mirror.aliyuncs.com"]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
Docker基本用法
//查找镜像
[root@zjq ~]# docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 4109 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44
centos/httpd 35 [OK]
hypoport/httpd-cgi httpd-cgi 2 [OK]
clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2
solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK]
jonathanheilmann/httpd-alpine-rewrite httpd:alpine with enabled mod_rewrite 1 [OK]
dockerpinata/httpd 1
lead4good/httpd-fpm httpd server which connects via fcgi proxy h… 1 [OK]
......
//拉取镜像
[root@zjq ~]# docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
a2abf6c4d29d: Pull complete
dcc4698797c8: Pull complete
41c22baa66ec: Pull complete
67283bbdd4a0: Pull complete
d982c879c57e: Pull complete
Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
//列出镜像
[root@zjq ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest dabbfbe0c57b 7 months ago 144MB
//创建容器
[root@zjq ~]# docker create --name web httpd //创建一个以httpd为镜像web为名的容器
ebd36596d627e7813fa75ae792ca0177c0751aac967e96dfee8f16b379cd0e53
//在创建容器时就运行容器
[root@zjq ~]# docker run --name centos1 -it centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
[root@12d004f1a2d5 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@12d004f1a2d5 /]# exit
//开启容器
[root@zjq ~]# docker start web
web
//列出有哪些运行的容器
[root@zjq ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebd36596d627 httpd "httpd-foreground" 6 minutes ago Up 7 seconds 80/tcp web
//查看容器日志
[root@zjq ~]# docker logs web
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
......
//重启容器
[root@zjq ~]# docker restart web
web
//停止容器
[root@zjq ~]# docker stop web
web
//强制终止容器
[root@zjq ~]# docker kill web
//删除容器
[root@zjq ~]# docker rm centos1
centos1
//显示系统范围里的所有信息
[root@zjq ~]# docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
scan: Docker Scan (Docker Inc., v0.17.0)
Server:
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 2
Server Version: 20.10.17
......
//返回有关Docker对象的低级信息
[root@zjq ~]# docker inspect ebd36596d627
[
{
"Id": "ebd36596d627e7813fa75ae792ca0177c0751aac967e96dfee8f16b379cd0e53",
"Created": "2022-08-07T07:31:00.894157593Z",
"Path": "httpd-foreground",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
......
",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
......