《第一本Docker书》章节试读

出版日期:2014-12
ISBN:9787115377332
作者:[澳]詹姆斯•特恩布尔(James Turnbull)
页数:252页

《第一本Docker书》的笔记-33 Docker入门 - 33 Docker入门

Docker开始

《第一本Docker书》的笔记-读书笔记 - 读书笔记

1. Docker简介:
Docker与传统虚拟化容器的不同之处在于Docker在虚拟化的容器环境中又增加了一个应用程序的部署引擎。这个引擎提供了一个轻量快速的环境,能够运行开发者的程序,并且方便高效地将程序从开发者的笔记本部署到测试环境和生产环境。Docker的目标是提供以下这些东西:
<1> 提供一个简单,轻量的建模方式。Docker很容易上手,用户很容易将自己的程序Docker化。另外Docker容器的创建非常快捷,大多数的Docker容器只需要不到一秒钟就可以启动,由于去除了管理程序的开销,所以Docker具有很高的性能,同一台宿主机可以运行很多的容器。
<2> 职责的逻辑分离。使用Docker,开发者只需要关心容器中的应用程序,运维人员只需要关心容器的管理。
<3> 快速高效的开发生命周期。Docker的目标之一就是缩短从开发到测试到部署上线的周期,使程序容易构建,容易移植。
<4> 鼓励面向服务的架构。由于Docker鼓励每个容器只运行一个应用程序,所以这样就形成了一个分布式的应用程序模型。在这种模型下,所有的项目都会变成一系列内部互联的容器,从而使得分布式地部署应用程序架构。

Docker的架构大致如此:


Docker是一个典型的CS架构,客户端只需要向服务端或者守护进程发出请求,然后服务端和守护进程会完成所有工作并且返回结果。镜像是Docker世界的基石,用户基于镜像运行和构建自己的容器,可以把镜像看做是容器的源代码。另外,Docker使用Registry保存用户构建的镜像。

Docker带给我们的好处分成以下几点:

<1> 加速本地开发和构建流程。本地开发人员可以构建,分享和部署Docker容器。
<2> 让独立的服务和应用程序在不同的环境中得到相同的结果。
<3> 创建一个隔离的环境进行测试。例如用Jenkins这样的集成测试工具创建一个新的用于测试的容器。
<4> Docker可以让开发者在本机就搭建好一个复杂的程序或架构,而不是上来就搞服务器。
<5> 为学习和测试构建一个轻量级的沙盒环境。
<6> 超大规模的宿主机部署

另外Docker还有个显著的特点是对不同的宿主机,应用程序和服务,可能会表现出不同的特性和架构,这样就进一步简化了应用程序开发的工作。另外,由于Docker的容器非常轻量级,所以重建容器的代价通常都比传统的状态修复低得多。

2. Docker常用命令
首先来创建第一个容器: sudo docker run -I -t -p 127.0.0.1:80:9001 ubuntu /bin/bash。这个命令解析一下:-i的意思是保证容器的STDIN是开启的,保证持久化的标准输入。 -t是为创建的容器分配一个伪tty中断,这样新创建的容器才能提供一个交互式shell。 除非这是一个运行后台服务的容器,否则这两个参数是最基本的参数。Docker首先会检查本地是否存在Ubuntu镜像,如果本地没有该镜像的话,Docker就会连接官方维护的Docker Hub,一旦找到就会下载保存到本地的宿主机中。-p参数会将Docker的网络端口和宿主机的端口相绑定。最后告诉容器要运行/bin/bash命令,启动一个bash shell。
docker ps 会列出当前系统中正在运行的容器,docker ps -a会列出当前系统的所有容器列表。
docker run --name xxxx -i -t ubuntu 可以为容器指定一个名称,在很多Docker命令中,都可以使用name来代替uuid,容器的名称有助于分辨容器,也有助于从逻辑上帮我们理清容器关系。
docker start 和 docker restart 可以帮助我们启动或者重启一个容器,可以使用docker stop关闭守护式容器。
docker attach 可以让我们重新附着到容器的会话上。
docker run -d 可以帮助我们创建一个守护进程放在后台长期运行。如果想查看后台容器都做了什么,可以使用docker logs ubuntu来获取容器的日志。与tail -f同理,也可以使用docker logs -f来监控实时的日志。
docker top 可以监控某容器中的运行进程。在Docker 1.3之后,还可以使用docker exec在容器内额外启动新进程,可以在容器内启动的进程分成后台任务和交互式任务两类。例如sudo docker exec -d daemon touch /etc/new_config中的-d就启动了一个后台任务,而sudo docker exec -t -i deamon /bin/bash则是启动了一个交互式任务。
docker inspect 获得更多的容器信息,这个命令会对容器进行详细的检查,然后返回配置信息,包括名称,网络配置和很多有用的数据。使用--format 或 -f 支持完整的Go语言,所以可以充分发挥Go语言的模板优势。
docker rm可以删除容器。

3. Docker镜像

Docker镜像是由文件系统叠加而成,最底端是一个文件引导系统,即bootfs,很类似于Linux的文件引导系统,用户大部分时间不会和引导文件系统有什么交互。再往上的第二层是root文件系统rootfs,rootfs可以是一种或者多种操作系统。
在传统Linux系统引导中,root文件系统会最先以只读的方式加载,当引导结束后才会变成读写状态。但是在Docker中,rootfs一直都会保持只读状态,并且Docker会利用联合加载技术在rootfs上加载更多的只读文件系统(联合加载是说通过叠加的方式一次同时加载多个文件系统,但在外面又只能看到一个文件系统)。Docker将这样的文件系统称为镜像。
Docker第一次启动一个容器时,初始的读写层是空的,当文件系统发生变化时,这些变化都会应用到这一层上,例如想修改一个文件,这个文件会从该读写层下面的只读层复制到读写层,然后修改,这时指针依然指向只读版本,直到修改结束,这时读写层又变成了只读状态。这被称为写时复制。
构建Docker镜像有两种方法:<1> 使用docker commit命令 <2> 使用docker build和Dockerfile文件。并不推荐使用docker commit,而应该使用更灵活强大的dockerfile方式。Dockerfile使用基本的DSL语法指令来构建一个Docker镜像,然后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像。Dockerfile由一系列的指令和参数组成。Dockerfile的指令会按顺序从上到下执行,所以应该根据需要合理安排制定的顺序。每条指令都会创建一个新的镜像并对镜像进行提交,Docker大致按照以下的步骤执行Dockerfile中的指令: Docker从基础镜像运行一个容器,执行一条指令并且对容器做出修改,执行类似docker commit的操作提交一个新的镜像层,Docker基于刚刚提交的容器创建一个新的镜像层,执行Dockerfile下一条指令直到执行结束。
每个Dockerfile的第一条指令都应该是FROM,后续指令都会基于该镜像进行,这个镜像称为基础镜像。由于Docker会将每一步构建过程都提交为镜像,所以他会将之前的镜像层看做是缓存,这样如果失败再次进行构建时不需要从头开始构建,这样可以节省大量的时间。但是这个带来的问题是比如apt-get update的命令也被缓存起来,所以可以执行REFERSHED_AT来制定最后构建时间。

4. 使用Docker进行开发测试和持续集成
sudo docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website nginx /bin/nginx 中的-v参数允许我们把宿主机的目录作为卷,挂在到容器中,从而实现容器之间的共享。卷在Docker中非常重要,卷是在一个或者多个容器内被选定的目录,可以绕过分层的联合文件系统为Docker提供持久数据和共享数据。这意味着对卷的修改会直接生效,从而绕过容器本身。即便容器停止,卷的内容也依然存在。例如:<1> 希望同时对代码进行开发和测试 <2> 代码修改频繁,不想频繁在开发过程中构建镜像。 <3> 希望在多个容器中共享资源。
另外的一个应用场景,例如我们搭建了一个Web的容器和一个Redis的容器,这样容器之间需要互相通信。有两种办法:<1> 将容器的网络端口绑定到宿主机的网络端口,从而访问宿主机的网络端口 <2> 内部网络。在安装Docker时,会创建一个新的网络接口,名字叫做Docker0,每个Docker容器都会在这个接口上分配一个IP地址。Docker0是一个虚拟的以太网桥,用于连接容器和本地宿主网络,所以Docker每创建一个容器就会创建一组互联的网络接口,这组接口一段在Docker0的一端,另外一端在容器上,所以其实就相当于通过Docker0作为整个内部网络的交换机。
另外,Docker很擅长快速创建和处理一个或多个容器,这个能力显然可以为持续集成测试提供帮助。Docker可以让部署以及这些步骤和宿主机的清理变得开销很低。
5. 插件
Fig由Orchard团队开发的开源工具,用Python编写,用于简单的容器编排。使用Fig可以用一个YAML文件定义一组要启动的容器,以及容器运行时的属性,Fig称这些容器为服务,并且这样定义:容器通过某些方法并指定一些运行时的属性来和其他容器产生交互。使用中可以看出使用Fig能够非常简单地构建一个需要多个Docker容器的应用程序。

服务发现是分布式程序之间管理相互关系的一种机制,一个分布式程序一般由多个组件组成,这些组件可以放在同一台机器上,也可以分步在多个数据中心,甚至分步在不同的地理区域。这些组件通常可以为其他组件服务,或者为其他组件提供消费服务。所谓服务发现的概念是允许某个组件在想要和其他组件交互时,自动找到对方,由于这些应用本身是分布式的,所以服务发现机制本身也需要是分布式的。而且服务发现作为分布式应用不同组件之间的胶水,还需要足够动态,可靠,适应性强,并且可以快速且一致地共享关于这些服务的数据。书中是使用Consul作为服务发现的工具,Consul是使用Go开发的工具,使用了Raft一致性算法来提供确定的写入机制。Consul暴露了键值存储系统和服务分类系统,并提供高可用性,高容错能力,并且保证强一致性。服务可以将自己注册到Consul,并以高可用且分布式的方式共享这些信息。另外,Consul还内置了强大的服务监控系统。

编配工具是一个快速发展的领域,工具的功能不尽相同,但是大多属于两种类型:调度和集群管理,服务发现。

《第一本Docker书》的笔记-第1页 - 1

第一章 简介
镜像是构建docker的即使,用户基于镜像来运行自己的容器。镜像是基于联合(Union)文件系统的一种层式的结构。
镜像是Docker声明周期中的构建或打包阶段,而容器则是启动或执行阶段
黄金镜像模型 -> Docker分层镜像模型
第三章 Docker入门
创建 -> 管理 -> 停止 -> 删除
docker run
docker run -i -t ubuntu /bin/bash
-i STDIN
-t tty
—name 容器命名
—restart (always / on-failure:5)
docker ps -a
查看当前系统中容器的列表
-l 最后一次运行的容器
docker start bob_the_container
重新启动已经停止的容器
docker attach
附着到容器上?(使用场景???)
docker run —name daemon_dave -d ubuntu /bin/sh -c ‘…...'
执行守护式容器
docker logs
docker top
docker exec
在容器内部额外启动新进程(使用场景???)
docker stop
停止守护式容器
docker inspect
docker rm sdf123132
删除容器
第四章 使用Docker镜像和仓库
什么是docker镜像?
Docker镜像是由文件系统叠加而成。最低端是一个引导文件系统bootfs。第二层是root文件系统rootfs,为了bootfs之上。联合加载(union mount)同时加载多个只读文件系统,但是在外面看起来是一次同时加载一个文件系统。Docker将这样的文件系统称为镜像。
当第一次启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统。当Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层(copy-on-write)。改文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏。(image-layering framework)
构建镜像
- docker commit:提交一个新的镜像层
- Dockerfile
用Dockerfile创建镜像
命令
FROM :指定一个已经存在的镜像
MAINTAINER:维护人
RUN:每条RUN指令都会创建一个新的镜像层
EXPOSE: 告诉Docker该容器内的应用程序将会使用容器内的指定端口。处于安全考虑,Docker并不会自动打开该端口,而是需要在docker
run运行时指定需要打开哪些端口(EXPOSE也可以帮助多个容器链接)
CMD:和RUN类似,RUN为构建竟像是需要运行的命令,CMD是容器启动时使用的命令(docker run可以覆盖CMD)
ENTRYPOINT:与CMD类似。docker run命令行中指定的任何参数都会被当做参数再次传递给ENTRYPOINT指令中的参数
WORKDIR
ENV
ADD: https://docs.docker.com/engine/articles/dockerfile_best-practices/#add-or-copy
COPY
USER
VOLUME:这个目录可以绕过联合文件系统,并提供如数据共享或者持久化的功能
ONBUILD
docker rmi【对比docker rm】
docker build
docker run -d -p 80 —name static_web jamtur01/static_web nginx -g “daemon off;”【需要nginx以前台的方式启动作为我们的服务器】
docker可以通过两种方法在宿主机上分配端口:
- 随机选择一个49000~49900
- 指定一个特定的端口
docker port 查看端口映射方式
第五章 在测试中使用Docker
静态网站
1.-v 挂载镜像
- ADD/COPY
Web应用
构建Sinatra
构建Redis镜像
- 构建Redis基础镜像
- 构建Redis Master
- 构建Redis Slave
- 关联
Sinatra关联Redis
方法:
- Docker自己的网络栈(内部网络):Docker创建了一个虚拟子网,这个子网由宿主机和所有的Docker容器共享/防火墙。如果直接使用内网IP,则可能产生硬编码。 ==》Docker link
- docker run -d —name reds xxx/redis
- docker run -p 4567 —name web —link redis:db -t -i -v $PWD/webapp:/opt/webapp xxx/sinatra /bin/bash
- —link创建链接两个父子容器。redis:db,redis为想要链接的容器(注意不是镜像),db为链接后的别名
- —icc=false
- 链接信息:/etc/hosts 和 环境变量【Dockerfile中的ENV和EXPOSE】
Jenkins
在Docker中运行Docker
第六章 使用Docker构建服务
docker run -d -P —volumes-from james_blog xxx/apache
—volumes-from 把指定容器里的所有卷都加入新创建的容器里【!!!!如果用docker rm删除了james_blog,那么卷和卷里的内容也就不存在了】
更新内容
docker start james_blog
备份卷
多容器(nodejs + redis集群)
1.redis base
docker run -h
捕获应用日志
logstash
docker run -d —name log stash —volumes-from redis_primary —volumes-from nodded xxx/logstash
第七章 使用Fig编配Docker
多个Docker宿主机进行协作
- 简单的容器编配(Fig)
- 分布式服务发现(Consul)
- kubernetes/mesos/helios/centurion/libswarm

《第一本Docker书》的笔记-第2页 - Docker 是容器界的 Tomcat

Docker 是一个能够把开发的应用程序自动部署到容器的开源引擎。这这这,跟 Tomcat 多像啊!

《第一本Docker书》的笔记-第1页 - 容器与虚拟机的区别

由于“客居”于操作系统,容器只能运行于与底层宿主机相同或相似的操作系统……结果是 Linux 上的容器只能虚拟 Linux 环境,使得容器的灵活性不如虚拟机,但是容器直接运行在操作系统内核之上,与虚拟机相比具有性能优势。
和传统的虚拟化以及半虚拟化(paravirtualization)技术相比,容器运行不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系统的系统调用接口。这降低了运行单个容器需要的开销,使得宿主机中可以运行更多的窗口。因此,单纯对这两种技术进行比较的话,容器其实拥有更为广泛的应用场景。毕竟,用 Linux 的话,虚拟化之后得到 Linux 环境往往更符合应用需求,在 Linux 上装个虚拟机跑 Windows 不是闲得蛋疼吗?


 第一本Docker书下载 更多精彩书评


 

外国儿童文学,篆刻,百科,生物科学,科普,初中通用,育儿亲子,美容护肤PDF图书下载,。 零度图书网 

零度图书网 @ 2024