Docker 学习笔记

来源:互联网 发布:淘宝怎么参加双11活动 编辑:程序博客网 时间:2024/05/17 06:03

一、什么是Docker

从航运说起,在较为久远的时代,货船装载货物是没有包装规范的,所以会有各种形状的货物(布袋、大箱子、豪华箱、木桶...),这样就使得货船不易管理货物以及规划仓储。在现代,一个具有时代意义的产物就诞生了——集装箱,这样航运规范化,每一样货物都会被装载到集装箱内进行运输,承货人只需要关心集装箱的数量与规格,而货主则只需要考虑货物需要什么规格的集装箱,如果将货物放置到集装箱内即可。

而Docker实际上也在完成这样一件事,但场景则转换到了应用程序部署。

试想,如果在部署应用程序的时候,如果我们可以忽略应用程序的特性(java web? nodejs? python?),只是专注于我们要将应用程序部署到一个可以运行的环境,同时这样的时候可以轻松地在任意一台机器上进行,是不是很爽,顿时感觉世界都美好了。

同样地事件发生在java web容器和.war上,事实上java web容器不关心你的代码是如何书写的,因为它只会看到.war,并尝试安装约定的接口运行.war,而部署时只要按约定将.java编译打包成.war就可以完成部署。如果把这件事放大到全部的应用程序级别,就和docker所做的事情很相似了。

只需要将docker能够识别的“特殊的包”交给docker,docker就能够构建出相应的运行环境。



再回到docker官宣,在很多时候我们使用VM来解决硬件不足的问题(为成百上千的应用购置相同规格成百上千的机器,显然十分土豪),而虚拟机允许我们在同一台物理机器上创建多个隔离的运行时环境,从而隔离每一个App,但显然,每一个app需要一个虚拟机环境,也就意味着每一次部署应用程序,都需要安装一次OS。


Docker为我们带来另一种解决方案,将虚拟机创建独立运行环境交由docker engine完成,而docker则依附于宿主操作系统来完成独立环境的构建,也就是说我们并不要安装虚拟机,也不需要在虚拟机内安装多个操作系统。


综上,docker是一种引擎,能够在宿主机器上创建的独立运行环境,并且能够快速地、统一地部署应用程序。


二、Image & Container

上文也借用船运集装箱来描述了一种部署流程的概念。在Docker里,实际上是使用了Image和container这两个概念来做到这样的事情的。

回到Java,我们当前知道Class是一个定义一个模型,Object则是运行时根据Class所创建。

而Image和container的关系类似,image是一种静态的文件结构,container则是运行时。(实际上dockerfile更像class,image由docker构建,这里只是静态动态上的一种比喻)


作为前提,我们应该知道一个独立的运行环境应该包含文件结构,其次才是程序的运行。而在docker,使用了aufs来完成文件结构,而aufs能够将不同物理位置的目录合并mount到同一个目录。


可以看到image由若干的read layer组成(这些read layer基于rootfs作为base layer,rootfs是系统的根文件系统),因为aufs的关系,再最终只会看到一个完整的文件结构。

也因此我们无法修改image中的layer。而一个container则是在image的最上层增加了一个read-writer layer。这一层则用于保存container的修改。

每一层layer都是一个增量,就像git,每一个提交只是告知改变。


但一个container并不是可以运行的,它还需要隔离的进程空间,以此完成的独立运行环境



那么,可以看到在docker的世界中,container就是一个和集装箱相似的概念,在任何装有docker引擎的机器上,都可以为container创建隔离进程空间,然后运行。


1. 创建镜像 docker build

构建上图的read-layer

2. 创建容器 docker create

在image上添加read-writer layer

3. 运行容器 docker start

将文件系统装载至隔离的进程空间

PS: 2、 3步可以合并为docker run


三、dockerfile & registry

在上文中,我们可以知道Image实际上是一些增量Layer和一个base layer的集合,那么下图所示的关系也就是十分正常的一种策略了。


一个Image以另一个Image作为基础增加layer,在这种模式下,image的复用也就变得可能。

例如:一个的python image和一个tomcat image都可以是在一个git image的基础上构建的,这样python image和tomcat image就不用重复构建git相关的layer,同时application image可以共用python image或者tomcat image,而aufs也决定了image之间的复用是直线型的。

那么docker又如何知晓每一个layer的内容(又或者是docker build),dockerfile就是这样的媒介,dockerfile定义了一系列layer和base layer.

FROM ubuntu MAINTAINER Victor Vieux <victor@docker.com> RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-ser

这是一个最简单的dockerfile, FROM声明了base layer,RUN定义了一层layer安装各种应用(实际上每一个命令都会为使得Image增加一个layer,为了控制image的size,layer的数量也是有限制的,应该竟可能地合并命令)


java / nodejs等项目拥有强大生命力,其中活跃的第三方社区必然是功不可没的,第三方可以提供优质的开源lib,让我们的代码过程更加便捷。

docker也是如此,registry使得docker image可以作为一种制品被保存在仓库之中,不同的开发人员可以下载和上传相应的image。

docker hub是一个官方最大的image库(可以类比github),同时也提供创建私有仓库的机制。



四、docker compose

对于复杂应用而言,并不能通过一个container就构建完成,可能会有多个container ,但如果我们多次docker run就会显得十分枯燥,docker提供compose来完成一个命令启动多个container的机制

common.ymlwebapp:  build:./webapp  environment:- DEBUG=false- SEND_EMAILS=false   development.ymlweb:extends:    file: common.yml    service: webapp  ports:-"8000:8000"  links:- db  environment:- DEBUG=truedb:  image: postgres

common.yml 定义了一个基础的配置文件,并定义了一个webapp服务

build命令会使用相应路径的Dockerfile文件来构建Image,

environment则配置了应用的环境变量


development.yml中的web 服务继承webapp服务,同时指定了端口和container之间的连接

db服务则使用image postgres进行构建


最后使用docker-compose命令来启动相应的服务

0 0
原创粉丝点击