什么是Docker
Docker 最初是dotCloud公司创始人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新,并与2013年3月以Apache 2.0授权协议开源),主要项目代码在GitHub上进行维护。Docker项目后来还加入了Linux基金会,并成立推动开放容器联盟。
Docker 自开源后受到广泛的关注和讨论,至今其GitHub项目已经超过3万6千个星际和一万多个fork。甚至由于Docker项目的火爆,在2013年底,dotCloud公司决定改名为Docker。Docker最初在Ubuntu12.04上开发实现的;Redhat则从RHEL6.5开始对Docker进行支持;Google也在其PaaS产品中广泛应用Docker。Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于LXC,从0.7以后开始去除LXC,转而使用自行开发的libcontainer,从1.11开始,则进一步演进为使用runC和containerd。
Docker 的基本概念
Docker 容器是资源分割和调度的基本单位,封装整个服务的运行时环境,用于构建、发布和运行发布式应用的一个框架。它是一个跨平台,可移植并且简单易用的容器解决方案。
Docker 容器可以快速自动化地部署应用,并通过操作系统内核技术(namespaces、cgroups等)为容器提供资源隔离与安全保障。Docker 作为轻量级的虚拟化方式,实现了PaaS平台高效部署、运行和维护。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等待,极大的简化了容器的创建和维护。使得Docker技术比虚拟机技术更为轻便,快捷。
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟化。因此容器要比传统虚拟机更为轻便。
![](https://i-blog.csdnimg.cn/blog_migrate/f614277c822993441d7298d3bb5909f0.png)
传统虚拟化结构对比Docker结构
为什么要使用Docker?#
- 更高效的利用系统资源
由于容器不需要进行硬件虚拟化以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
- 更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而Docker容器应用,由于直接运行于宿主机,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
- 一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug并未在开发过程中被发现。而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现“这段代码在我机器上没问题啊”这类问题。
- 持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并结合持续集成(Continuous lntegration)系统持续进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment)系统进行自动部署。而使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
- 更轻松的迁移
由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
- 更轻松的维护和扩展
Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大降低了应用服务的镜像制作成本。
Docker对比传统虚拟机
特性 | 容器 | 虚拟机 |
启动 | 秒级 | 需要几分 |
磁盘使用 | 一般为MB | 一般为几个GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 根据系统性能一般几个到机十个 |
Docker 体系结构简介
![](https://i-blog.csdnimg.cn/blog_migrate/a15cc6c381358239ceeec9751e09efa1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/78cdfbadf72aefc71575bad5f38961b5.png)
Docker 是一个客户/服务器(Client/Server,CS)架构(见上图)。
Docker客户端是远程控制器,可通过TCP REST向Docker Host 发送请求,包括创建容器、运行容器、保存容器、删除容器等请求。Docker服务端的Daemon 对客户端的请求进行相应的管理,随后通过 driver转发至容器中的libcontainer执行环境。libcontainer提供与不同Linux内核隔离的接口,类似命名空间及控制组。这种架构允许多个容器在共享同一个Linux内核的情况下完全隔离的运行。
Docker 镜像 (Images) | Docker 镜像是用于创建 Docker 容器的模板。 |
Docker 容器 (Container) | 容器是独立运行的一个或一组应用。 |
Docker 客户端 (Client) | Docker 客户端通过命令行或其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api)与Docker 的守护进程通信。 |
Docker 主机 (Host) | 一个物理或者虚拟的机器用来执行 Docker 守护进程和容器。 |
Docker 仓库 (Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine 是一个简化Docker安装的命令行工具, 通过一个简单的命令即可在响应的平台上安装Docker,比如VirtualBox、Digital Ocean、Microsoft Azure。 |
Docker 8大应用场景
![](https://i-blog.csdnimg.cn/blog_migrate/75d4f2d6dc266c8cb232cda4edb9087e.png)
(1)、简化配置
这是Docker公司宣传的 Docker 的主要使用场景。Docker 能将运行环境和配置放在代码中然后部署,同一个 Docker 的配置可以在不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。
(2)、代码流水线(Code Pipeline)管理
代码从开发者的机器到最终生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有微小的差别,Docker 给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。
(3)、提高开发效率
Docker 能提升开发者的开发效率。不同的开发环境中,Docker 都可以把两件事做好,一是可以在开发环境、生产环境之间直接迁移,二是可以让我们快速搭建开发环境。开发环境的机器通常内存比较小,之前使用虚拟机的时候,我们经常需要为开发环境的机器加内存,而使用Docker可以轻易的让几十个服务在Docker中跑起来。
(4)、隔离应用
有很多原因会让我们选择在一个机器上运行不同的应用,Docker 非常适合在较低的成本下实现多种应用的隔离。
(5)、整合服务器
Docker 隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker 可以比虚拟机提供更好的服务器整合解决方案。通常数据中心的服务器资源利用率只有30%,通过使用Docker 并进行有效的资源分配可以大幅度提高服务器资源的利用率
(6)、调适能力
Docker 提供了很多的工具,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug
(7)、多租户环境
另外一个Docker 的使用场景是在多租户的应用中,它可以避免关键应用的重写。我们一个特别的关于这个场景的例子是为物联网的应用开发一个快速、易用的多租户环境。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间,也浪费金钱。 使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和高效的diff命令
(8)、快速部署
在虚拟机之前,购入部署新的硬件资源需要消耗几天的时间。虚拟化技术(Virtualization)将这个时间缩短到了分钟级别。而Docker 通过为进程仅仅创建一个容器而无需启动一个操作系统,再次将这个过程缩短到了秒级。这正式Google和Facebook 都看重的特性。我们可以创建销毁Docker 容器而无需担心重新启动带来的开销
Docker 三大核心概念
Docker 包括三个基本概念
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
Docker 镜像(Image)
Docker 镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了 Apache 应用程序(或用户需要的其他软件)。可以把它称为一个 Apache镜像。
镜像是创建Docker 容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。
Docker 容器(Container)
Docker 容器类似于一个轻量级的沙箱,Docker 利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。可以将其启动、开始、停止、删除,而这些容器都是彼此相互隔离的、互不相见的。
可以把容器看做是一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子
Docker 仓库(Repository)
Docker 仓库类似于代码仓库,它是Docker集中存放镜像文件的场所。
仓库注册服务器是存放仓库的地方,其上往往存放着多个地方。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应改软件的各个版本。我们可以通过 <仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。以Nginx镜像为例,nginx 是仓库的名字,其内包含有不同的版本标签,如,1.12.2,我们可以通过 nginx:1.12.2来指定需要哪个版本的镜像。如果忽略了标签,比如nginx ,那将视为 nginx:latest。
Docker 仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。目前最大的公开仓库是Docker Hub, 存放了数量庞大的镜像供用户下载。国内还有(时速云、阿里云)等公开仓库。
当用户不希望公开自己的镜像文件,Docker 也支持用户在本地网络内创建一个只能自己访问的私有仓库。当用户创建了自己的镜像之后就可以使用push命令将其上传到指定的公有或者私有仓库。这样下次在另外一台机器上使用该镜像时,只需要将其从仓库上pull 下来就可以了。
Docker 基础命令
1 [root@docker ~]# docker --help
2 Usage:
3 docker [OPTIONS] COMMAND [arg...]
4 docker daemon [ --help | ... ]
5 docker [ --help | -v | --version ]
6
7 A
8 self-sufficient runtime for containers.
9
10 Options:
11 --config string Location of client config files (default "/root/.docker") #客户端配置文件的位置
12 -D, --debug=false Enable debug mode #启用Debug调试模式
13 -H, --host=[] Daemon socket(s) to connect to #守护进程的套接字(Socket)连接
14 -h, --help=false Print usage #打印使用
15 -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") #设置日志级别
16 --tls Use TLS; implied by --tlsverify
17 --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") #信任证书签名CA
18 --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") #TLS证书文件路径
19 --tlskey string Path to TLS key file (default "/root/.docker/key.pem") #TLS密钥文件路径
20 --tlsverify Use TLS and verify the remote #使用TLS验证远程
21 -v, --version Print version information and quit #打印版本信息并退出
22
23 Commands:
24 attach Attach to a running container #当前shell下attach连接指定运行镜像
25 build Build an image from a Dockerfile #通过Dockerfile定制镜像
26 commit Create a new image from a container's changes #提交当前容器为新的镜像
27 cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
28 create Create a new container #创建一个新的容器,同run 但不启动容器
29 diff Inspect changes on a container's filesystem #查看docker容器变化
30 events Get real time events from the server #从docker服务获取容器实时事件
31 exec Run a command in a running container #在已存在的容器上运行命令
32 export Export a container's filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
33 history Show the history of an image #展示一个镜像形成历史
34 images List images #列出系统当前镜像
35 import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
36 info Display system-wide information #显示系统相关信息
37 inspect Return low-level information on a container or image #查看容器详细信息
38 kill Kill a running container #kill指定docker容器
39 load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
40 login Register or log in to a Docker registry #注册或者登陆一个docker源服务器
41 logout Log out from a Docker registry #从当前Docker registry退出
42 logs Fetch the logs of a container #输出当前容器日志信息
43 pause Pause all processes within a container #暂停容器
44 port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
45 ps List containers #列出容器列表
46 pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
47 push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
48 rename Rename a container #重命名容器
49 restart Restart a running container #重启运行的容器
50 rm Remove one or more containers #移除一个或者多个容器
51 rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
52 run Run a command in a new container #创建一个新的容器并运行一个命令
53 save Save an image(s) to a tar archive #保存一个镜像为一个tar包(对应load)
54 search Search the Docker Hub for images #在docker hub中搜索镜像
55 start Start one or more stopped containers #启动容器
56 stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
57 stop Stop a running container #停止容器
58 tag Tag an image into a repository #给源中镜像打标签
59 top Display the running processes of a container #查看容器中运行的进程信息
60 unpause Unpause all processes within a container #取消暂停容器
61 version Show the Docker version information #查看容器版本号
62 wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
63
64 Run 'docker COMMAND --help' for more information on a command. #运行docker命令在帮助可以获取更多信息
Docker 镜像管理
搜索镜像 docker search
1 [root@server ~]# docker search centos #搜索所有的centos的docker镜像
2 NAME(名称) DESCRIPTION(描述) STARS(下载次数) OFFICIAL(官方) AUTOMATED(自动化)
3 centos The official build of CentOS. 5091 [OK]
4 ansible/centos7-ansible Ansible on Centos7 119 [OK]
docker search 参数说明: --automated=true I false:仅显示自动创建的镜像,默认为否; --no-trunc=true | false:输出信息不截断显示,默认为否; -s,--stars=X:指定仅显示评价为指定星级以上的镜像,默认为 0,即输出所有镜像。 例如,搜索所有自动创建的评价为 3+的带 nginx 关键字的镜像,如下所示:
1 [root@server ~]# docker search --automated -s 3 nginx
获取镜像 docker pull
镜像是运行容器的前提,官方的Docker Hub 网站已经提供了数十万个镜像供我们下载。可以使用Docker pull 从镜像仓库拉取镜像
docker pull
docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
1 [root@server ~]# docker pull centos #获取centos镜像
2 Using default tag: latest
3 latest: Pulling from library/centos
4 a02a4930cb5d: Pull complete
5 Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
6 Status: Downloaded newer image for centos:latest
查看镜像 docker images
1 [root@server ~]# docker images #查看docker镜像
2 REPOSITORY(来自哪个仓库) TAG(标签) IMAGE ID(唯一ID) CREATED(创建时间) SIZE(大小)
3 nginx latest 7042885a156a 7 days ago 109MB
4 centos latest 1e1148e4cc2c 4 weeks ago 202MB
1 # 新版本查看镜像
2 [root@server ~]# docker image ls
3 REPOSITORY TAG IMAGE ID CREATED SIZE
4 nginx latest 7042885a156a 7 days ago 109MB
5 centos latest 1e1148e4cc2c 4 weeks ago 202MB
列表包括了仓库名、标签、镜像ID、创建时间以及所占用的空间。
镜像ID则是镜像的唯一标识,一个镜像可以对应多个标签。
删除镜像 docker rmi
docker rmi [选项] <镜像1> [<镜像2> ...]
使用docker rmi 删除本地镜像,后面可以跟镜像ID或者标签。(删除镜像之前先用docker rm 删除依赖于这个镜像的所有容器)。注意docker rm 命令是移除容器。
1 [root@server ~]# docker rmi imageID/imageName/ # 删除docker镜像
导出镜像 docker save
如果要导出镜像到本地,提供给另外一台机使用,可以使用docker save 或者docker image save 命令。
1 [root@server ~]# docker save centos > /tmp/docker_centos.tar #导出docker镜像到本地
2 [root@server ~]# ll /tmp/docker_centos.tar
3 -rw-r--r-- 1 root root 210186752 1月 5 16:05 /tmp/docker_centos.tar
4
5 # 新版本也可用下面这种方法
6 [root@server ~]# docker image save nginx > /tmp/docker_nginx.tar #导出docker镜像到本地
7 [root@server ~]# ll /tmp/docker_nginx.tar
8 -rw-r--r-- 1 root root 190512640 1月 5 16:06 /tmp/docker_nginx.tar
导入镜像 docker load
从本地文件中导入docker镜像库
1 [root@server ~]# docker load < /tmp/docker_centos.tar #导入本地镜像到docker镜像库
2 [root@server ~]# docker image load < /tmp/docker_nginx.tar #新版本也可以用这种方法导入
3 [root@server ~]# docker image ls #查看导入的情况
4 REPOSITORY TAG IMAGE ID CREATED SIZE
5 centos latest 1e1148e4cc2c 4 weeks ago 202MB
6 nginx 1.11 5766334bdaa0 21 months ago 183MB
给镜像打标签 docker tag
利用docker tag可以给镜像添加一个新的标签,docker tag 原标签 新标签
1 [root@server ~]# docker image ls #打标签前查看
2 REPOSITORY TAG IMAGE ID CREATED SIZE
3 centos latest 1e1148e4cc2c 4 weeks ago 202MB
4 nginx 1.11 5766334bdaa0 21 months ago 183MB
5 [root@server ~]# docker tag centos centos:7.2 #给centos打一个新的标签
6 [root@server ~]# docker image tag nginx:1.11 nginx:1.12 #给nginx打一个新的标签
7 [root@server ~]# docker images
8 REPOSITORY TAG IMAGE ID CREATED SIZE
9 centos 7.2 1e1148e4cc2c 4 weeks ago 202MB
10 centos latest 1e1148e4cc2c 4 weeks ago 202MB
11 nginx 1.11 5766334bdaa0 21 months ago 183MB
12 nginx 1.12 5766334bdaa0 21 months ago 183MB
归类 : 自动化运维