第一本Docker书
第一章 简介
1.1.1 提供一个简单轻量的建模方式
docker及其简洁,全部环境一台安装了肩同版本的Linux内核和二进制文件最小限的宿主机
大多数docker容器只需要不到1秒钟即可启动
由于去除了管理程序的开销,docker容器拥有很高大的性能,充分的利用资源
1.1.2 职责的逻辑分离
- 使用docker
- 开发人员只需要关心容器中运行的程序
- 运维人员只需要关心如何管理容器
- docker设计目的就是要加强开发人员写代码的开发环境与应用程序要部署环境的一致性
1.1.3 快速高效的开发生命周期
1.1.3 鼓励使用面向服务的架构
- docker鼓励面向服务的架构和微服务架构
- 推荐一个容器只运行一个应用程序或进程,形成一个分布式的应用模型,分布式的部署应用,扩展或调试应用变得简单,提高程序的内省性(什么意思?)
1.2docker组件
- 客户端和服务器:c/s架构,命令行工具docker与一整套RESTful API
- 镜像:镜像是基于联合(Union)文件系统的一种层级结构
- Registry: 类似于github
- 容器:
- 容器是基于镜像启动起来的,容器中可以运行一个或多个进程
- 可以认为,竟像是docker生命周期中的侯建或打包阶段,容器是启动或执行阶段。
- 总结,docker容器:
- 一个镜像格式
- 一系列标准操作
- 一个执行环境
1.3 我们能用docker做什么
- 加快本地开发和构建流程,高效,轻量化
- 独立的服务或应用在不同的环境中,得到相同的结果
- 创建隔离环境来进行测试,如Jenkins CI 启动一个测试容器
- 构建一个多用户的平台即服务(PaaS)基础设施(什么意思?)
- 提供软件即服务(SaaS)应用程序
- 高性能,超大规模的宿主机部署
1.4docker与配置管理
1.5 docker的技术组件
- Linux内核的x64主机上
- 内核版本 >=3.8
- Linux内核的命名空间(namespace):
- 文件系统隔离: 每个容器都有自己的root文件系统
- 进程隔离: 每个容器都隐形在自己的进程环境中
- 网络隔离: 容器间的虚拟网络接口和IP地址都是分开的
- 资源隔离和分组: 使用cgroups(即control group,Linux 的内核特性之一)将CPU和内存之类的资源独立分配给每个Docker容器
- 写时复制: 文件系统都是通过写时复制常见的,意味着文件系统时分层的,快速的,占用磁盘空间更小(什么意思?)
- 日志: 容器的stdout,stderr,stdin这些IO流都会被收集并计入日志,用来进行日志分析和故障排错。
- 交互式shell: 可以创建一个伪tty终端, 将其连接到STDIN,为容器提供一个交互式shell。
第二章 安装docker
2.1 安装docker的先决条件
- 运行64位CPU架构的计算机(x86_64和amd64),不支持32位CPU
- Linux 内核 >= 3.8
- 内核必须支持一种适合的存储驱动(storage driver)(默认粗出驱动通常是Device Mapper)
- 讷河必须支持并开启cgroup和命名空间(namespace)功能。
2.2 Ubuntu中安装docker
2.2.1 检查前提条件
- 检查内核:
- uname -a
- 检查 Device Mapper:
- ls -l /sys/class/misc/device-mapper(自2.6.9版本的Linux 内核开始已经集成Device Mapper)
- grep device-mapper /proc/devices
- cgroup和命名空间自2.6版本开始已经集成在Linux内核中了。2.6.38 以后的内核对cgroup和命名空间都义工了良好的支持,基本上没有bug
第三章 docker入门
- 查询docker信息
- docker info
- 运行容器
- docker run -i -t ubuntu /bin/bash
- -i 保证容器中的stdin是开启的
- -t 告诉docker分配一个伪tty终端
- ubuntu 告诉docker 用什么镜像来创建容器
- /bin/bash 在启动镜像后运行的命令
- 容器的命名
- docker run —name my_container1.2.3 -i -t ubuntu /bin/bash
- —name 可以指定容器的名字 只能使用[a-zA-Z0-9_.-](正则)
- 容器的启动。停止与重启
- docker run my_container
- docker stop ...
- docker restart ...
3.6 附着到容器上
- docker容器重新启动的时候,会沿用docker run 命令时指定的参数来运行,我们可以用docker attach 命令重新附着到该容器的会话上,输入命令后可能需要按下回车
3.7 创建守护式容器
除了交互式容器,还可以创建长期运行的容器(守护式容器 daemonized container)没有交互式会话,非常适合运行应用程序和服务
- docker run —name daemon -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
- -d 会将容器放到后台运行
3.8 docker 日志
- docker logs container_name 可以查看容器的日志输出
- docker logs -f container_name 可以像tail -f 那样看实时输出
- docker logs —tail 0 -f container_name 可以从查看当前命令后的实时输出
- docker logs —tail 10 container_name 可以获取日志最后的10条日志
3.9 容器内进程查看
- docker ps container_name
3.10 在容器内部运行进程
- docker 1.3之后,可以使用docker exec 命令在容器内部额外启动新进程,在容器中运行的进程有两种类型
- 交互式进程: 保持在前台运行
- 后台任务
- 创建后台任务
- docker exec -d c1 touch /etc/new_config_file
- -d 表明需要运行一个后台进程
- -d 之后,指定容器的名字,执行的命令
- 创建交互式进程
- docker exec -i -t c1 /bin/bash
- -t,-i创建TTY并捕捉STDIN
- 随后是容器名, 以及执行的敏玲
3.12 自动重启容器
- 可以通过设置—restart标志来设置重启
- docker run —restart=always —name c1 -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
- —restart=always无论退出代码是什么都会重启容器
- —restart=on-failure:5只有当退出代码为非0值时才能重启,并且可以添加参数,重启数量如5
3.13 深入容器
- docker inspect —formate='{{ .State.Running}}'可以获取更多的容器信息
- —formate 或 -f 可以获取制定的信息
- 可以同时制定多个容器
- f 没有表面这么简单,他可以支持完整的Go语言模板
- 可以浏览/var/lib/docker目录来深入了解docker的工作原理
- 该目录下存放docker镜像、容器以及容器的配置
3.14 删除容器
- 运行中的docker容器是无法删除的,只能先docker stop 或 docker kill来停止容器
- 目前没有办法一次性删除所有容器,不过可以
- docker rm 'docker ps -a -q'
- -a 显示所有容器 -q 表示只需要返回 容器ID
第四章 使用docker镜像和仓库
关于镜像的知识,镜像的管理、修改、创建、存储、共享、镜像仓库
4.1 什么是docker镜像
docker镜像是由文件系统叠加而成
- 最低端是一个引导文件系统,即bootfs,这很像典型的Linux/Unix 的引导文件系统。当容器启动,它将会被移到内存中,引导文件系统则会被卸载,以留出更多的内存供initrd磁盘镜像使用
- 第二层是root文件系统rootfs,rootfs可以是一种或多种操作系统(什么意思?),在docker中root文件系统永远只能是只读状态,并且使用联合加载技术,联合加载技术会将各层文件系统叠加到一起,这样文件系统就包含所有底层的文件和目录。
- 写实复制:
- 当docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏
- 每个只读镜像层都是只读的,并且以后永远不会变化
- 当创建一个新容器时,docker会构建出一个镜像栈,并在栈的最顶端添加一个读写层。这个读写层再加上其下面的镜像层以及一些配置数据,就构成了一个容器
- 容器的这种特点加上镜像分层框架(image-layering-framework),使我们可以快速构建镜像并运行
4.3 镜像拉取、查找
- docker pull image_name:tag 如果不指定tag 则默认下载latest
- docker search image_name
4.5 构建镜像
- docker commit (不推荐)
- docker build 和Dockerfile文件
4.5.3 用Dockerfile 构建镜像
- 基于DSL语法的指令来构建一个Docker 镜像,
4.5.10 Dockerfile指令
- CMD:
- 指定容器要运行时执行的命令
- 如果在docker run 时添加了执行命令,该字段失效
- ENTRYPOINT
- 类似于CMD
- 可以接受docker run传入的参数(docker run -t -i docker/study:v1 -g "daemon off;")
- ENTRYPOINT 可以和CMD公用
- ENTRYPOINT ["/usr/sbin/nginx"]; CMD ["-h"]
- 可以使用 --entrypoint标志覆盖该命令
- WORKDIR
- WORKDIR /opt/webapp/db
- 指定改字段的值后,会使ENTRYPOINT与CMD在指定目录执行
- 可以为容器设置最终工作目录
- 可以设置多次
- 可以通过-w参数覆盖最终工作目录的设置
- ENV
- ENV RVM_PATH /home/rvm/
- WORKDIR $RVM_PATH
- 在镜像构建过程总设置环境变量
- 可以通过环境变量前加上一个反斜杠进行转义
- 可以通过启动容器是-e 指定,该指定只会作用于运行时
- USER
- 用来指定镜像会以什么样的用户去运行
- 启动容器时增加-u 可以覆盖该值
- 如果不指定默认是root用户
- VOLUME
- VOLUME ["/opt/project", "/data"] 可以逗号分隔指定多个卷
- 卷可以将内容添加到镜像中,而不是将这些内容提交到镜像中
- ADD
- ADD software.lic /opt/application/software.lic
- 将构建环境下的文件和目录复制到镜像中
- 指向源文件的位置参数可以是一个URL,或者侯建上下文或环境中文件名或者目录
- 不能对构建目录或者上下文之外的文件进行ADD操作
- 会根据路径的最后一个字符是否是“/”来判断是目录或者文件
- 如果将一个归档文件(gzip、bzip2、xz)指定为源文件,docker会自动将归档文件解开(unpack) ADD latest.tar.gz /var/www/wordpress/,解开行为和-x选项的tar命令一样
- 如果URL方式指定源是归档文件,是不能解开的
- 在归档情况下,如果目的目录中有与归档文件解开的文件或目录,那么位置中的文件或目录不会覆盖
- 如果目的目录不存在,则创建这个全路径,新创建的文件和目录的模式为0755, 并且UID和GID都是0
- ADD命令会使构建缓存变得无效,会使后续指令都不能继续使用之前的侯建缓存
- COPY
- COPY conf.d/ /etc/apache2/
- 和ADD很像,不会做提取工作
- 和ADD一样 源以"/"结尾,会将目录复制过去,否则当做文件
- ONBUILD
- 为镜像添加触发器,当一个镜像被用作其他镜像的基础镜像时,该镜像的触发器被执行。
- 触发器会在构建过程中插入新指令,可以认为这些指令紧跟FROM之后指定的
- 触发器可以是任何构建指令(除了FROM,MAINTAINER,ONBUILD)
- ONBUILD ADD . /app/src
- ONBUILD RUN cd /app/src && make
- ONBUILD指令可以通过docker inspect 命令来查看
4.8 运行自己的Docker registry
- docker run -p 5000:5000 registry
- 需要将想上传到自己registry的镜像打包
- docker tag imageID host:port/{user}/static_web
- docker push host:port/{user}/static_web
- 并且可以运行 docker run -t -i host:port/{user}/static_web /bin/bash
第五章 在测试中使用docker
- 使用docker测试一个静态网站
- 使用docker创建并测试一个web应用
- 将docker用于持续集成
5.1 使用Docker测试静态网站
- docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website:{ro(只读)/rw(读写)} d/s1 nginx
- 如果构建中出现任何问题,进入到容器中排查,不要修改=>构建这样重复
- 静态文件的修改,可以直接修改宿主机的文件
5.2 使用Docker构建并测试web应用
- docker run -p 1338 --name webapp --link redis:db -t -i -v $PWD/webapp:/opt/webapp image /bin/bash
- --link 创建了两个容器之间的父子链接
- 可以增加 --ioc=false标志,关闭所有没有连接的容器间的通信。
- --linx 在docker 父容器中两个地方写入了链接信息
- /etc/hosts 文件中
- 包含链接信息的环境变量中,可以同过env查看
5.3 Docker用于持续集成
在docker镜像中运行docker,very interesting
docker run -p 8080:8080 —name jenkins —privileged -d dockerjenkins
加—privileged 参数可以启动docker的特权模式,这种模式允许我们以其宿主机具有的所有能力来运行容器,包括一些内核特性和设备访问。
镜像加速monitor
docker 100问
备注
什么意思? : 代表问题,需要了解