温故知新Docker概念及Docker Desktop For Windows v3.1.0安装
阅读原文时间:2023年07月10日阅读:2

什么是Docker?

Docker是一个开放源代码软件项目,项目主要代码在2013年开源于GitHub。它是云服务技术上的一次创新,让应用程序布署在软件容器下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。

Docker利用Linux核心中的资源分脱机制,例如cgroups,以及Linux核心名字空间(name space),来创建独立的软件容器(containers),属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docker在容器的基础上进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护,使得其比虚拟机技术更为轻便、快捷。Docker可以在单一Linux实体下运作,避免因为创建一个虚拟机而造成的额外负担。

Docker和虚拟机的区别与特点

以下两张图分别介绍了虚拟机与Docker容器的结构。

对于虚拟机技术来说,传统的虚拟机需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给他的资源将全部被占用。每一个虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。

容器技术和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。容器内没有自己的内核,也没有进行硬件虚拟。

具体来说与虚拟机技术对比,Docker 容器存在以下几个特点:

  1. 更快的启动速度:因为Docker直接运行于宿主内核,无需启动完整的操作系统,因此启动速度属于秒级别,而虚拟机通常需要几分钟去启动。
  2. 更高效的资源利用率:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。
  3. 更高的系统支持量:Docker的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高。
  4. 持续交付与部署:对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至进行自动部署。
  5. 更轻松的迁移:由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
  6. 更轻松的维护与扩展:Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
  7. 更弱的隔离性:Docker属于进程之间的隔离,虚拟机可实现系统级别隔离。
  8. 更弱的安全性:Docker的租户root和宿主机root等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限和宿主机的root虚拟机权限是分离的,并且利用硬件隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击。

Docker、Moby、CNCF

  • Docker是一家商业公司开发的容器技术,早期是容器内核是基于LXC(LinuX Container),来实现容器的创建和管理的。

  • LXC: 早期有一种技术叫 jail(监狱,或叫沙盒),这种技术可让一个应用程序运行在一个沙箱中,该应用程序无论做出任何对系统的破坏都不会影响到真实的系统,仅仅只是沙箱中的虚拟环境。后来这种技术在Linux也引入了,叫vserver,即现在我们比较熟悉的chroot功能。但是在Linux系统中早期内核支持名称空间,是需要通过自己编写代码,调用系统调用来创建出UTS,Network,IPC,等不同的名称空间,结合chroot实现在一个操作系统上创建出一个用户空间,但这对普通用户来说,是很困难的,而LXC则提供了一组工具,将这些功能整合成工具,用户若需要创建容器,只需要使用lxc-create等命令行工具,就可以很轻松的创建容器,但是LXC在创建容器时,它需要借助于template(模板),当允许lxc-create来创建一个容器时,你可以在CentOS的系统上,创建一个Ubuntu的容器,或FreeBSD的容器等,都可以只有你提供相应的template和这些系统的软件包安装源即可; 但LXC这种方式带来的问题是使用上依然非常困难,应用模板的创建并不容易,而且又产生了很多冗余数据;如:我想创建两个Ubuntu的容器,我就需要安装两份相同的数据; 而且若我需要将一个容器迁移到另一台主机上,怎么做?LXC没有提供相应的工具。所以它并不适合大规模使用。Docker:它早期创建容器的内核是LXC,但它使用了比LXC更高效,更精巧的方式来创建容器,它不在使用模板来安装容器,而是将容器制作成镜像,当需要使用容器时,直接从镜像仓库中下载之前制作好的镜像到本地,直接启动容器即可。并且它的镜像采用一种叫做叠加镜像的方式解决数据冗余的问题,实际上它采用一种叫三层叠加镜像的方式来实现数据的高效利用 和 容器私有数据的保存。借助于共享存储来将容器的私有数据保存在宿主机的外部,当宿主机宕机时,只要在新的宿主机上下载镜像,启动容器,挂载数据即可恢复服务。具体如下图:

注: Docker为了管理容器方便,它定义一个容器中只能运行一个进程, 但实际上容器跟虚拟机类似,它是可运行多个进程的,只是为了管理方便,限制容器中只能运行一个进程。

  • CNCF是Linux基金会旗下的基金会,可以理解为一个非盈利组织。当年谷歌内部一直用于编排容器的Borg项目开源了,为了该项目更好的发展,谷歌与Linux基金会一起创办了CNCF。同时,谷歌把Borg用Go语言重写,更名为Kubernetes并捐赠到CNCF。成立这个组织的初衷或者愿景,简单说:推动云原生计算可持续发展;帮助云原生技术开发人员快速地构建出色的产品;CNCF通过建立社区、管理众多开源项目等手段来推广技术和生态系统发展。云原生计算技术栈非常宽阔,与之相对应的开源项目就非常多。CNCF会管理和推广这些项目。比如,源于谷歌的Kubernetes(容器编排引擎)开源项目就被吸收到CNCF,Kubernetes也因此受到更多的人关注。再比如,源于华为的KubeEdge(边缘计算平台)开源项目也被CNCF吸纳,也吸引了很多人参与进来。很多公司很乐于把自已的项目贡献给CNCF,这样能吸引到更多的专家参与进来一起开发。只有足够优秀的项目CNCF才会接纳,源创公司会在该项目上保持技术上的领先,也能扩大技术影响力,所以公司愿意分享项目到CNCF。

  • Libcontainer,又称为RunC,它是Docker官方提供的新Docker构建容器的核心程序,由于LXC在功能上,没有与时俱进,因此Docker官方,最终决定自己开发一个新的容器构建核心,它就是runC。

  • OCI(Open Container Initiative),它由Linux基金会主导于2015年6月创立,皆在围绕容器格式和运行时制定了一个开放的工业标准,它制定了两个规范标准:

    • 运行时标准(The Runtime Specifications (runtime-spec))
    • 镜像格式标准(The Image Specification (image-spec))
  • OCF(Open Container Format),OCF开放容器格式就是OCI的倡导下产生的标准

Docker我们知道它是一家商业公司,早期Docker刚出现时,以下轰动世界,为了让Docker技术,能够有更大的发展,Docker将自己的产品分成商业版和社区开源版,但是Docker的商业版在商业领域上始终没能活动 大佬们的信赖,没能得到太多融资,但是社区开源版确始终火热的不行,Docker为了能获得更多商业利益,它最终决定将社区版的Docker更名为Moby,希望能吸引更多关注的目光到它的商业版上,但事与愿违。 而此时Google发现自己秘密使用了十几年的容器技术竟然被Docker给开源了,而且还发展的如此红火,尽人皆知,但Google不希望自己在容器技术上的话语权落到Docker手中,它决定扶持一家小容器公司,但这家公司的产品在Google大力扶植下,依然是名落孙山,不是Docker的对手,最后,Google发现Docker在编排工具的开发上,好无建树,而自己拥有十几年的容器使用经验(Google内部的容器叫Borg(博格)),因此就组织了工程师开发了Kubernetes,又鉴于Docker一家公司为了商业目的,随意更改Docker社区版,改变Docker的性质,因此Google将Kubernetes捐给了CNCF,而CNCF是容器标准化基金会组织,它是Google联合多家知名公司,如:IBM,微软,Facebook等联合成立的组织。向世人表态为不会左右Kubernetes的发展进程,加上Kubernetes从其诞生就是站在Bong的肩膀上成立的,所以它一经发布就成为世人聚焦的目标,短短3年,就已经从0.1发展到1.1版本,以每年4个版本迭代,2018年为止,其市场占有率达到80%以上。

Docker在容器领域的优势

对于开发人员来说,是天大的好处,因为Docker的出现真正解决代码一次编写到处运行,无论底层是什么系统,只要能运行docker,将镜像做好后,直接编排好,然后在宿主机上启动容器即可。对于运维人员来说,带来的问题是,系统构架更加复杂,原本的调试进程的方式,在容器时代变的异常困难,因为容器中很可能没有各种调试工具等。

如NMP环境的构建上, 通常我们需要先部署MySQL容器,接着是PHP容器,最后是Nginx容器,这样的顺序部署才能让环境都正常工作,否则可能出现Nginx代理PHP服务器,结果找不到PHP服务器,因为容器启动后,它的IP地址会改变,那通过DHCP根据MAC不是可以固定分配IP吗?但其实是不可以的,因为容器是没有固定MAC的,它的网卡是虚拟的,是通过Linux上的"虚拟网线”创建的两个虚拟网卡,一端接入容器,一端接入Docker0(默认桥)桥上,这样就实现了容器能接入网络中,因此每次启动容器时,是无法知道这一次创建的虚拟网卡的MAC地址是多少的,因此必须使用其它方法来获取启动完成后的容器的IP地址,这也就是为啥容器需要编排,对于LNMP环境,Nginx要依赖PHP,因为它要代理PHP,而PHP又依赖MySQL,因为PHP应用程序要从MySQL中获取数据,因此必须先启动MySQL容器,这样才能获取MySQL容器当前使用的IP,接着启动PHP容器,将MySQL容器的IP传入到PHP容器中,这样PHP容器就可以知道MySQL的IP,而Nginx也是一样,这样编排后,LNMP环境中每个容器就都能获取它所依赖的容器的IP,就可以正常通信了。

为了解决部署容器的顺序问题,容器技术,必须结合编排工具一起使用,才能实现大规模应用。目前比较知名的编排工具:

  • Docker: machine+swarm+compose,这三个工具配合使用来实现编排。
  • 第三方提供的编排工具: mesos+marathon
  • Google: kubernetes-->简称k8s

Docker虚拟化限制

资源限制: 通常有两种,一种是弹性百分比限制能使用全部资源的百分比,另一种是决对资源限制。

实现资源限制的是Cgroups(Control Groups):

  1. blkio: 块设备IO
  2. cpu: CPU
  3. cpuacct: CPU资源使用报告
  4. cpuset: 多处理器平台上的CPU集合
  5. devices:设备访问
  6. freezer: 挂起或恢复任务
  7. memory: 内存用量及报告
  8. perf_event:对cgroup中的任务进行统一性能测试
  9. net_cls:cgroup中的任务创建的数据报文的类别标识符

核心概念:镜像、容器与仓库

Docker主要包含三个基本概念,分别是镜像、容器和仓库,理解了这三个概念,就理解了 Docker 的整个生命周期。以下简要总结一下这三点:

  • 镜像:Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
  • 容器:容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间容器可以被。创建、启动、停止、删除和暂停等等,说到镜像与容器之间的关系,可以类比面向对象程序设计中的类和实例。
  • 仓库:镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。一个Docker Registry中可以包含多个仓库;每个仓库可以包含多个标签;每个标签对应一个镜像,其中标签可以理解为镜像的版本号。

Docker三剑客

  • docker-compose:Docker镜像在创建之后,往往需要自己手动pull来获取镜像,然后执行run命令来运行。当服务需要用到多种容器,容器之间又产生了各种依赖和连接的时候,部署一个服务的手动操作是令人感到十分厌烦的。

docker-compose技术,就是通过一个.yml配置文件,将所有的容器的部署方法、文件映射、容器连接等等一系列的配置写在一个配置文件里,最后只需要执行docker-compose up命令就会像执行脚本一样的去一个个安装容器并自动部署他们,极大的便利了复杂服务的部署。

  • docker-machine:Docker技术是基于Linux内核的cgroup技术实现的,那么问题来了,在非Linux平台上是否就不能使用docker技术了呢?答案是可以的,不过显然需要借助虚拟机去模拟出Linux环境来。

docker-machine 就是docker公司官方提出的,用于在各种平台上快速创建具有docker服务的虚拟机的技术,甚至可以通过指定driver来定制虚拟机的实现原理(一般是virtualbox)。

  • docker-swarm:swarm是基于docker平台实现的集群技术,他可以通过几条简单的指令快速的创建一个docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。

Docker的版本

Docker按版本划分,可以区分为CEEECE即社区版(免费,支持周期三个月),EE即企业版,强调安全,付费使用。

Docker的基本架构

  1. Registry: 在Docker中称为镜像仓库,Docker的镜像仓库有点类似与yum源仓库,但它的组织方式是这样的:官方提供的Docker镜像仓库地址: hub.docker.com,当然国内也有很多docker镜像站,Docker镜像仓库的组织格式为:

    • 应用程序名:版本号
    • 其中: 应用程序名为仓库名
    • 版本号: 为仓库中镜像名.也是它的tag标签号

    以Nginx为例:

    Nginx:为仓库名,nginx:1.15这就是一个镜像名.同时一个镜像可能有多个名字,比如: 1.15是Nginx的最新发行版,则还会给它提供一个名字叫: nginx:lasted 即最新版,这个名字会随着Nginx发布的最新版而改变。nginx:1.14另外我们知道,Nginx的发行版中,次号码为偶数表示,此版本为稳定版,

    为奇数则为开发版,所以这种版本通常也会有一个名字: nginx:stated即稳定版的nginx镜像。

  2. 状态图

  1. 镜像构成

Docker镜像包含了启动容器所需的文件系统及其内容,因此它用于创建并启动docker容器。docker镜像采用分层构建的机制,最底层为bootfs,其上为rootfs

  • bootfs: 用于系统引导文件系统,包括bootloaderkernel,容器启动完成后,bootfs会被卸载,以节省内存空间。
  • rootfs: 它在运行中的docker容器中变现为根文件系统。

如: docker exec -it nginx1 /bin/sh,登录后,ls /可以看到全部的根文件系统目录。

  • 传统OS: 系统启动时,内核挂载rootfs时,为确保不会误删除文件,通常会先以只读模式挂载,完整性自检完成后,再重新以读写模式挂载rootfs
  • Docker: 它在启动内核,挂载rootfs时,始终是以只读模式挂载, 而后在通过联合挂载技术额外挂载一个可写层,实现读写操作。
  1. 层结构

Docker的镜像层级,从上到下分别为:

  • 可写层
  • add Apache 和 add emacs(类似于vim的编辑器): 这两层为自己通过yum安装在镜像中的工具。
  • Debian: 这是为安装的工具提供的基本的最小安装的根文件系统已共Apache能运行起来.这里使用的是Debian,还可以使用CentOS等。
  • bootfs: 这一层则是启动Debian这个rootfs所需的bootloader和kernel,通常在将Debian启动起来后,它将自动被卸载。
  1. 实现叠加挂载镜像的文件系统

overlayfs:从kernel3.18以后被整合到Linux内核中了. 它叫 叠加文件系统, 再早期Docker实现叠加挂载是使用Aufs(Advanced multi-layered unification filesystem:高级多层统一文件系统), 而此文件系统是2006年开发,但因代码质量问题,一直未被整合到kernel中; 据说它的代码有3万行,而ext4这种文件系统总代码量4千多行。所以早期要使用docker有两种方式 一种手动给内核打aufs的补丁,另一种就是使用Ubuntu系统,因为它比较早的将Aufs整合到它的kernel中了。不过现在目前 CentOS系统已经能支持overlayfs的第2版了,所以可以直接使用docker即可。

最新稳定版安装包:Docker Desktop Installer.exe

双击桌面的Docker Desktop图标运行它。

启动后,将在桌面右下角的状态栏出现一个Docker图标。

在图标上右键,点击Dashboard图标,进入面板界面。

因为网络原因,直接请求默认官方镜像地址https://registry-1.docker.io可能会因为网络问题失败。

国内有一些加速Docker镜像的源,其中包括:

  • https://hub-mirror.c.163.com (网易节点)
  • https://docker.mirrors.ustc.edu.cn (科大节点)

此外,阿里云还可以用账号创建专属的加速节点,地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

右键Docker Desktop在状态栏的图标,找到Settings菜单。

Docker Engine菜单中,找到Json配置项的registry-mirrors节点,添加我们需要配置的加速源地址,然后点击Apply & Restart即可。

官方镜像库

查看Docker版本

docker version

查看Docker信息

docker info

搜索Docker镜像

docker search $keyword

拉取Docker镜像

docker pull $imageName:tag

还可以直接指定镜像库来拉取,比如

docker pull $mirrorPath$imageName:tag

列举已有镜像

docker images

或者可使用:

docker image ls

删除已有镜像

docker image rm $imageName/$imageId

如果想要强制删除,可以加上-f参数

docker image rm -f $imageName/$imageId

创建指定镜像的容器但不运行

docker container create $imageName:tag

创建指定镜像的容器并运行

docker container run $imageName:tag

扩展格式:

docker container run [options] Image [Command] [参数...]

options:

  • -t: 启动镜像时,给其添加一个终端访问接口,以便能够启动后,连接登录。
  • -i: 启动为交互模式。
  • --rm: 停止后,直接删除该容器。
  • -d: 运行到后台。
  • --name <ImageName>: 为启动的容器名一个名字。
  • --network <NetName>: 将容器加入一个指定的网络中。

例如:

docker container run -it --name n1 nginx:latest

创建并后台运行一个容器-d

docker container run -itd --name n2 nginx:latest

启动已创建好的指定容器(含已停止)

docker container start $containerId

停止/杀掉已允许的指定容器

docker container stop $containerId
docker container kill $containerId

查看容器中运行进程信息

docker container top $containerId

查看Docker可用网络

docker network ls

可查看到,当docker安装完成后,它会自动创建一个bridge的桥,这个桥是NAT桥,它是直接桥接在物理网卡上的,可直接和物理网络通信。

查看正在运行的容器

docker ps

查看所有已知的容器(含已停止)

docker ps -a

强制关闭指定容器(数据可能丢失)

docker kill $containerName/$containerId

停止指定容器(数据不丢失)

docker stop $containerName/$containerId

重启已停止的容器

docker restart $containerName/$containerId

删除已停止的容器

docker rm $containerId

注意:如果容器还在运行,将无法删除,需要先停止或者强制杀掉。

登录已运行的容器根目录

docker exec -it $containerName/$containerId /bin/sh

如需退出容器,使用命令exit即可。

查看已运行容器的日志

docker logs $containerName/$containerId

查看已运行容器的元数据

docker inspect $containerName/$containerId

通过此命令,还可以定制一些返回参数,例如获取容器IP

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $containerName/$containerId

查看并监控容器资源

docker stats

  • [CONTAINER]:以短格式显示容器的ID。
  • [NAME]:容器的名称。
  • [CPU %]:CPU 的使用情况。
  • [MEM USAGE / LIMIT]:当前使用的内存和最大可以使用的内存。
  • [MEM %]:以百分比的形式显示内存使用情况。
  • [NET I/O]:网络I/O数据。
  • [BLOCK I/O]:磁盘I/O数据。
  • [PIDS]:PID 号。

给指定镜像打标签

docker tag $sourceImage:$tag $targetImage:$tag

登录指定镜像源库

docker login

在Docker Desktop中默认就是登录docker.hub.com官方镜像库。

如需指定第三方或者私有库,只需要定制可选参数即可。

docker login -u $userName -p $passWord $mirrorServerUrl

注销或退出镜像源库

docker logout $mirrorServerUrl

推送/上传本地镜像到镜像源库

docker push $imageName:tag

导出已有本地镜像

docker save -o $fileName $imageName:tag

该文件会保存到当前目录,通过ls可查看。

导入打包好的镜像导出包

docker load -i $fileName

从配置创建本地镜像

docker build [OPTIONS] PATH|URL|-

docker build -t $tag $dockerFileName

导出容器快照

docker export $containerId > $filename

导入容器快照为镜像

cat $filename | docker import - $imageName:tag

从容器创建镜像

docker commit -m $description $containerId $imageName:tag

Docker Compose简介

定义和运行多个Docker容器的应用(Defining and running multi-container Docker applications)

Docker Compose是Docker官方的开源项目,使用Python编写,实现上调用了Docker服务的API进行容器管理,通过Compose,您可以使用YML文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从YML文件配置中创建并启动所有服务。

安装Docker Compose

幸运的是,Docker Desktop For Windows已经自带了Docker Compose

查看Docker Compose版本

docker-compose version

卸载Docker Compose

rm /usr/local/bin/docker-compose

或者

pip uninstall docker-compose

Docker Compose使用流程

Compose使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。

  • 使用docker-compose.yml定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

  • 最后,执行docker-compose up命令来启动并运行整个应用程序。

构建docker-compose.yml文件

# yaml 配置
version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

该Compose文件定义了两个服务:webredis

  • web:该web服务使用从Dockerfile当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口5000。此示例服务使用Flask Web服务器的默认端口5000。
  • redis:该redis服务使用Docker Hub的公共Redis映像。

通过Docker Compose运行

docker-compose up


# -d 是后台运行
docker-compose up -d

通过设定的端口,访问服务。

查看Docker Compose中运行的容器

docker-compose ps

停止Docker Compose中容器

docker-compose stop

启动已存在的Docker Compose容器

docker-compose start

停止并删除Docker Compose所有容器及依赖

docker-compose down

查看Docker Compose中容器日志

docker-compose logs

重新构建Docker Compose中容器

docker-compose build

拉取Docker Compose中依赖的镜像最新版

docker-compose pull

重启Docker Compose的容器

docker-compose restart

删除所有已停止Docker Compose容器

docker-compose rm
  • –f, –force,强制直接删除,包括非停止状态的容器
  • -v,删除容器所挂载的数据卷

在Docker Compose指定容器上运行命令

docker-compose run $seviceName $command

例如:docker-compose run ubuntu ping www.baidu.com

缩放Docker Compose容器中的数量

docker-compose scale $seviceName=$count

例如:docker-compose scale web=3 db=2

暂停Docker Compose中容器

docker-compose pause


docker-compose pause $seviceName

恢复已暂停的Docker Compose容器

docker-compose unpause

停掉Docker Compose中容器

docker-compose kill


docker-compose kill $seviceName

查看Docker Compose配置

docker-compose config

创建Docker Compose中容器

docker-compose create [options] [SERVICE...]
  • –force-recreate:重新创建容器,即使配置和镜像没有改变,不兼容–no-recreate参数
  • –no-recreate:如果容器已经存在,不需要重新创建,不兼容–force-recreate参数
  • –no-build:不创建镜像,即使缺失
  • –build:创建容器前,生成镜像

进入Docker Compose中指定顺序容器

docker-compose exec [options] SERVICE COMMAND [ARGS...]


docker-compose exec –index=$serviceIndex $serviceName /bin/bash
  • -d 分离模式,后台运行命令。
  • –privileged 获取特权。
  • –user USER 指定运行的用户。
  • -T 禁用分配TTY,默认docker-compose exec分配TTY。
  • –index=index,当一个服务拥有多个容器时,可通过该参数登陆到该服务下的任何服务,例如:docker-compose exec –index=1 web /bin/bash,web服务中包含多个容器

查看Docker Compose指定容器对外公开端口

docker-compose port $serviceName
  • –protocol=proto,指定端口协议,TCP(默认值)或者UDP
  • –index=index,如果同意服务存在多个容器,指定命令对象容器的序号(默认为1)

推送Docker Compose服务中依赖镜像

docker-compose push

Docker Compose模板文件

简介

Compose允许用户通过一个docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Compose模板文件是一个定义服务、网络和卷的YAML文件。Compose模板文件默认路径是当前目录下的docker-compose.yml,可以使用.yml或.yaml作为文件扩展名。

Docker-Compose标准模板文件应该包含version、services、networks 三大部分,最关键的是services和networks两个部分。

Compose目前有三个版本分别为Version 1,Version 2,Version 3,Compose区分Version 1和Version 2(Compose 1.6.0+,Docker Engine 1.10.0+)。Version 2支持更多的指令。Version 1将来会被弃用。

例如:

version: '2'
services:
  web:
    image: dockercloud/hello-world
    ports:
      - 8080
    networks:
      - front-tier
      - back-tier

  redis:
    image: redis
    links:
      - web
    networks:
      - back-tier

  lb:
    image: dockercloud/haproxy
    ports:
      - 80:80
    links:
      - web
    networks:
      - front-tier
      - back-tier
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

networks:
  front-tier:
    driver: bridge
  back-tier:
    driver: bridge

镜像(Image)

image是指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。

services:
  web:
    image: dockercloud/hello-world

构建(build)

服务除了可以基于指定的镜像,还可以基于一份Dockerfile,在使用up启动时执行构建任务,构建标签是build,可以指定Dockerfile所在文件夹的路径。Compose将会利用Dockerfile自动构建镜像,然后使用镜像启动服务容器。

build都是一个目录,如果要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定。

如果同时指定image和build两个标签,那么Compose会构建镜像并且把镜像命名为image值指定的名字。

services:
  web:
    build: .


services:
  redis:
    image: redis:alpine
  web:
    build:
      context: F:\XXXXX\compose_hello
    ports:
    - published: 5000
      target: 5000
version: '3'

上下文(Context)

context选项可以是Dockerfile的文件路径,也可以是到链接到git仓库的url,当提供的值是相对路径时,被解析为相对于撰写文件的路径,此目录也是发送到Docker守护进程的context

services:
  web:
    build:
      context: F:\XXXXX\compose_hello

构建配置文件(DockerFile)

使用dockerfile文件来构建,必须指定构建路径

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile-alternate

执行命令(Command)

使用command可以覆盖容器启动后默认执行的命令。

services:
  web:
    command: bundle exec thin -p 3000

容器名称(ContainerName)

Compose的容器名称格式是:<项目名称><服务名称><序号>

可以自定义项目名称、服务名称,但如果想完全控制容器的命名,可以使用标签指定:container_name: app

依赖关系(Depends On)

在使用Compose时,最大的好处就是少打启动命令,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后的问题。

下述YAML文件定义的容器会先启动redis和db两个服务,最后才启动web服务。

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

容器端口(Ports)

ports用于映射端口的标签,使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。

当使用HOST:CONTAINER格式来映射端口时,如果使用的容器端口小于60可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。

ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

域名标签(Extra Host)

添加主机名的标签,会在/etc/hosts文件中添加一些记录。

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

启动后查看容器内部hosts:

162.242.195.82  somehost
50.31.209.229   otherhost

挂载数据卷(Volume)

挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER]格式,或者使用[HOST:CONTAINER:ro]格式,后者对于容器来说,数据卷是只读的,可以有效保护宿主机的文件系统。

Compose的数据卷指定路径可以是相对路径,使用.或者..来指定相对目录。

volumes:
  // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql
  // 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql
  // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
  - ./cache:/tmp/cache
  // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro
  // 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql

如果不使用宿主机的路径,可以指定一个volume_driver。

volume_driver: mydriver

域名解析(Dns)

自定义DNS服务器。可以是一个值,也可以是一个列表。

dns:8.8.8.8
dns:
    - 8.8.8.8
      - 9.9.9.9

对外端口清单(Expose)

暴露端口,但不映射到宿主机,只允许能被连接的服务访问。仅可以指定内部端口为参数

expose:
    - "3000"
    - "8000"

链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”(如 SERVICE:ALIAS)

links:
    - db
    - db:database
    - redis

网络模式(Net)

设置网络模式。

net: "bridge"
net: "none"
net: "host"