【Docker技术入门与实践(第2版)】Docker入门_学习笔记

2023-10-28

第一章

1 Docker入门须知

1.1 Docker基本知识

       Docker是基于Go语言实现的开源容器项目,诞生于2013年年初,最初发 起者是dotCloud公司。Docker自开源后受到广泛的关注和讨论,目前已有多个相关项目(包括Docker三剑客、Kubernetes等),逐渐形成了围绕Docker容器的生态体系。现在主流的Linux操作系统都已经支持Docker。例如,红帽公司的RHEL 6.5/CentOS 6.5往上的操作系统、Ubuntu14.04往上的操作系统,都已经在软件 源中默认带有Docker软件包。

       Docker的构想是要实现“Build,Ship and Run Any App,Anywhere”, 即通过对应用的封装(Packaging)、分发(Distribution)、部署 (Deployment)、运行(Runtime)生命周期进行管理,达到应用组件“一次封装,到处运行”的目的。这里的应用组件,既可以是一个 Web应用、一个编译环境,也可以是一套数据库平台服务,甚至是一个操作系统或集群。

                    

1.2  Docker VS 虚拟化

       虚拟化是一种资源管理技术,是将计算机的各种实体资源,如服务 器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的 不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。

       虚拟化的核心是对资源的抽象,目标往往是为了在同一个主机上同时运行多个系统或应用,从而提高系统资源的利用率,并且带来降低成本、方便管理和容错容灾等好处。 从大类上分,虚拟化技术可分为基于硬件的虚拟化和基于软件的虚拟化:

       真正意义上,基于硬件的虚拟化技术不多见,少数如网卡中的单根多IO虚拟化(Single Root I/O Virtualization and Sharing Specification,SR-IOV)等技术。  

       基于软件的虚拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化(通常说的虚拟机技术即属于这个范畴)。其中,前者一般指的是一些 模拟设备或诸如Wine这样的软件。平台虚拟化又可以细分为如下几个子类:

       传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。

       Docker容器是在操作系统(OS)层面上实现虚拟化直接复用本地主机的操作系统,因此更加轻量级。

 

2. 核心概念和安装配置

  2.1 核心概念

   1.Docker镜像(Image)

       Docker镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。例如,一个镜像可以包含一个基本的操作系统环境,里面仅安装了Apache应用程序(或用户需要的其他软件)。可以把它称为一个Apache镜像

       镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并直接使用。

   2.Docker容器(Container)

       Docker容器类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。可以将其启动、开始、停止、删除,而这些容器都是彼此相互隔离的、互不可见的。可以把容器看做是一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子。

       镜像自身是只读的。容器从镜像启动的时候,会在镜像的最上层创建一个可写层。

  3.Docker仓库(Repository)

      Docker仓库类似于代码仓库,它是Docker集中存放镜像文件的场所有时候会看到有资料将Docker仓库和仓库注册服务器(Registry)混为 一谈,并不严格区分。实际上,仓库注册服务器是存放仓库的地方,其上往往存放着多个仓库。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。例如存放 Ubuntu操作系统镜像的仓 库称为Ubuntu仓库,其中可能包括14.04、12.04等不同版本的镜像。

       根据所存储的镜像公开分享与否,Docker仓库可以分为公开仓库 (Public)和私有仓库(Private)两种形式。目前,最大的公开仓库是官方提供的Docker Hub,其中存放了数量庞大的镜像供用户下载。国内不少云服务提供商(如时速云、阿里云等)也提供了仓库的本地源,可以提供稳定的国内访问。

       当然,用户如果不希望公开分享自己的镜像文件,Docker也支持用户在本地网络内创建一个只能自己访问的私有仓库。当用户创建了自己的镜像之后就可以使用push命令将它上传到指定的公有或者私有仓库。这样用户下次在另外一台机器上使用该镜像时,只需要将其从仓库上pull下来就可以了。Docker利用仓库管理镜像的设计理念与Git非常相似,实际上 在理念设计上借鉴了Git的很多优秀思想。

  2.2 Docker安装

   MacOS :https://docs.docker.com/docker-for-mac/install/

   Windows : https://docs.docker.com/docker-for-windows/

  ·Docker Platform : 支持在桌面系统或云平台安装Docker;

  ·Docker Hub : 官方提供的云托管服务,可以提供公有或私有的镜像仓库;

  ·Docker Cloud : 官方提供的容器云服务,可以完成容器的部署与管理, 可以完整地支持容器化项目,还有CI、CD功能;

  ·Docker DataCenter : 提供企业级的简单安全弹性的容器集群编排和管理。

   Docker目前只能运行在64位平台上且要求内核版本不低于3.10,实际上内核越新越好,过低的内核版本容易造成功能不稳定。Docker目前支持的最低Ubuntu版本为12.04 LTS,但实际上从稳定性上考 虑,推荐至少使用14.04 LTS版本。CentOS系统的要求与Ubuntu情况下类似:64位操作系统,内核版本至少为3.10。Docker目前支持CentOS 6.5及以后的版本,推荐使用CentOS 7系统。

  本人电脑安装简略步骤:

http://localhost/ 打开,看到如下页面,表示正确install nginx webserver.

命令行下输入: docker run --help  可查询docker run 命令所有的参数,其他命令也如此。

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

3. 使用Docker镜像

       Docker运行容器前需要本地存在对应的镜像,如果镜像没保存在本地,Docker会尝试先从默认镜像仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。镜像是运行容器的前提,官方的Docker Hub网站已经提供了数十万个镜像供大家开放下载。

   docker  pull  [OPTIONS]  NAME[:TAG|@DIGEST]  -------> Pull an image or a repository from a registry,如果不显式指定TAG,则默认会选择 latest 标签,就会下载仓库中最新版本的镜像。

       一般来说,镜像的latest标签意味着该镜像的内容会跟踪最新的非稳定版本而发布,内容是不稳定的。从稳定性上考虑,不要在生产环境中忽略镜像的标签信息或使用默认的 latest 标记的镜像。如下:

    docker  pull  nodejs:10.11.0  <=====>  docker  pull  registry.hub.docker.com/nodejs:10.11.0

如果从非官方的仓库下载,则需要在仓库名称前指定完整的仓库地址。docker  pull  hub.c.163.com/public/nodejs:10.11.0

3.1  docker images(获取镜像文件)

·Tag: 比如14.04、latest用来标注不同的版本信息。只是标记,并不能标识镜像内容;

·IMAGE ID(唯一标识镜像):  如果ID一样表示它们目前实际上指向同一个镜像; 它唯一标识了镜像。在使用镜像ID的时 候,一般可以使用该ID的前若干个字符组成的可区分串来替代完整的ID。

·created : 说明镜像最后的更新时间;

·size : 优秀的镜像往往体积都较小。镜像大小信息只是表示该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会存储一份,物理上占用的存储空间会小于各镜像的逻辑体积之和。

3.2  docker tag (取别名)

     为了方便在后续工作中使用特定镜像,还可以使用docker tag命令来为本地镜像任意添加新的标签。这些myubuntu:latest镜像的ID跟ubuntu:latest 完全一致。它们实际上指向同一个镜像文件,只是别名不同而已。docker tag 命令添加的标签实际上起到了类似链接的作用。docker  tag  ubuntu:latest   myubuntu:latest 

 3.3  docker inspect (获取镜像的详细信息)  

     使用 docker inspect  nginx(docker inspect e81eb098537d)命令可以获取该镜像的详细信息,包括制作者、适应架构、各层的数字摘要等。返回的是一个JSON格式的消息,如果我们只要其中一项内容时,可以使用参数 -f 来指定,例如,

     获取镜像的Architecture : docker inspect nginx( or e81eb098537d)  -f  {{".Architecture"}}

 3.4  docker history (获取镜像的历史信息)  

     使用history子命令,该命令将列出各层的创建信息。docker history nginx

      

3.5  docker rmi (删除镜像)

     使用docker rmi命令可以删除镜像,命令格式为docker rmi  IMAGE [IMAGE...],其中IMAGE可以为标签或ID。当同一个镜像拥有多个标签的时候,docker rmi命令只是删除该镜像多个标签中的指定标签而已,并不影响镜像文件。删除标签为hello-world:latest的镜像,由于该镜像没有额外的标签指向它,执行docker rmi命令,可以看出它会删除这个镜像文件的所有层.

     要想强行删除镜像,可以使用 -f 参数。通常并不推荐使用-f参数来强制删除一个存在容器依赖的镜像。 正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。

       

3.6  创建镜像:创建镜像的方法主要有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建(后续详解)。

3.6.1 基于已有镜像的容器创建

该方法主要是使用docker commit命令。命令格式为docker   commit[OPTIONS]CONTAINER[REPOSITORY[:TAG]],主要选项包括:

       ·-a,--author="":作者信息;

       ·-c,--change=[]:提交的时候执行 Dockerfile指令,包括CMD| ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|

VOLUME| WORKDIR 等;

        ·-m,--message="":提交消息;

        ·-p,--pause=true:提交时暂停容器运行。

Tip : 创建镜像 和 docker tag 打标签的别混淆

3.6.2   基于本地模板导入

        docker  import命令。命令格式为 docker  import [OPTIONS]  file|URL|- [ REPOSITORY [:TAG] ]。要直接导入一个镜像,可以使用OpenVZ提供的模板来创建,或者用其他 已导出的镜像模板来创建。例如:

   cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:14.04

3.7  存出、载入、上传镜像

     如果要导出镜像到本地文件,可以使用docker save命令    docker save -o nginx.tar nginx : latest

     可以使用docker load将导出的tar文件再导入到本地镜像库     docker load < nginx.tar <==> docker load --input nginx.tar

     可以使用docker push命令上传镜像到仓库,默认上传到Docker Hub官方仓库(需要登录)。命令格式:

docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORT]/]NAME[:TAG]

4.  操作docker 容器

        容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行 态环境和其他系统环境)和跑在上面的应用,那么Docker容器就是独立运行 的一个(或一组)应用,以及它们必需的运行环境。

4.1  创建容器

4.1.1  可以使用docker create命令新建一个容器

       使用docker create命令新建的容器处于停止状态,可以使用docker start命令来启动它。create命令run命令支持的选项都十分复杂,主要包括如下几大类:与容器运行模式相关、与容器和环境配置相关、与容器资源限制和安全保护相关。

        除了创建容器后通过start命令来启动,也可以直接新建并启动容器。新建并启动容器: 所需要的命令主要为docker run,等价于先执行docker create命令,再执行docker start命令。利用docker run来创建并启动容器时,Docker在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
  • 利用镜像创建一个容器,并启动该容器;
  • 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中;
  • 从网桥的地址池配置一个IP地址给容器;
  • 执行用户指定的应用程序;
  • 执行完毕后容器被自动终止。 
docker run -it ubuntu:14.04 /bin/bash 

-t : 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上。     - i : 让容器的标准输入保持打开。

某些时候,执行docker run会出错,因为命令无法正常执行容器会直接退 出,此时可以查看退出的错误代码。 默认情况下,常见错误代码包括:

·125: Docker daemon执行出错,例如指定了不支持的Docker命令参 数;

·126:所指定命令无法执行,例如权限出错;

·127:容器内命令无法找到。 命令执行后出错,会默认返回错误码。

4.1.2  终止容器

     更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。此时,可以通过添加 -d 参数来实现。可以用docker ps -qa命令看到所有容器的ID。

     可以使用docker stop来终止一个运行中的容器。该命令的格式为docker stop[-t|--time[=10]][CONTAINER...]。首先向容器发送SIGTERM信号,等待一段超时时间(默认为10秒)后, 再发送SIGKILL信号来终止容器。

  docker stop containerID

     docker kill 命令会直接发送SIGKILL信号来强行终止容器。当Docker容器中指定的应用终结时,容器也会自动终止。例如对 于上一节中只启动了一个终端的容器,用户通过exit命令或Ctrl+d来退出终端时,所创建的容器立刻终止,处于stopped状态

     docker restart 命令会将一个运行态的容器先终止,然后再重新启动。

4.2  进入容器

     进入容器进行操作有多种方法,包括使用官方的 attach 或 exec命令,以及第三方的nsenter工具等。

4.2.1 attach方法

       

  • --detach-keys[=[]]:指定退出attach模式的快捷键序列,默认是CTRL-p  CTRL-q;
  • --no-stdin=true|false:是否关闭标准输入,默认是保持打开;
  • --sig-proxy=true|false:是否代理收到的系统信号给应用进程,默认为 true。

      但是使用attach命令有时候并不方便。当多个窗口同时用attach命令连到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。

4.2.2  exec命令

通过指定 -it 参数来保持标准输入打开,并且分配一个伪终端。通过exec 命令对容器执行操作是最为推荐的方式。

  • -i,--interactive=true|false:打开标准输入接受用户输入命令,默认为false;
  • --privileged=true|false:是否给执行命令以高权限,默认为false;
  • -t,--tty=true|false:分配伪终端,默认为false; ·-u,--user="":执行命令的用户名或ID。

4.2.3 nsenter工具

4.3 删除容器

默认情况下,docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器。如果要直接删除一个运行中的容器,可以添加 -f 参数。Docker会先发送 SIGKILL信号给容器,终止其中的应用then强行删除。docker rm -f containerID

4.4 导入导出容器

       某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用 Docker的导入和导出功能。这也是Docker自身提供的一个重要特性。

       1.导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器 是否处于运行状态,可以使用docker export命令,该命令的格式为 docker export [-o|--output[=""]] CONTAINER。其中,可以通过-o选项来指定导出的tar 文件名,也可以直接通过重定向来实现。可将导出的tar文件传输到其他机器上,然后再通过导入命令导入到系统中,从而实现容器的迁移

   $ docker export -o test_for_run.tar ce5
   $ ls
   test_for_run.tar
   $ docker export e81 >test_for_stop.tar
   $ ls
   test_for_run.tar test_for_stop.tar

     2.导出的文件又可以使用docker import命令导入变成镜像,该命令格式为

      docker import  [OPTIONS]  file|URL|-  [REPOSITORY[:TAG]]

   $ docker import test_for_run.tar - test/ubuntu:v1.0
   $ docker images
   REPOSITORY        TAG      IMAGE ID       CREATED             VIRTUAL SIZE
   test/ubuntu       v1.0     9d37a6082e97   About a minute ago     171.3 MB

       既可以使用docker load命令来导入镜像存储文件到本地镜像库, 也可以使用docker import命令来导入一个容器快照到本地镜像库。 这两者的区别在于:

5. 访问Docker Hub库

5.1 初识Docker Hub

      根据是否为官方提供,可将这些镜像资源分为两类

       一种是类似centos这样的基础镜像,称为基础或根镜像。这些镜像是由Docker公司创建、验证、 支持、提供。这样的镜像往往使用单个单词作为名字。

      另一种类型,比如ansible/centos7-ansible镜像,它是由Docker用户ansible创建并维护的,带有用户名称为前缀,表明是某用户下的某仓库。可 以通过用户名称前缀user_name/镜像名来指定使用某个用户提供的镜像。

另外,在查找的时候通过- s N参数可以指定仅显示评价为N星以上的镜像。

    1. docker search  命令来查找官方仓库中的镜像

    2. docker pull  命令来将它下载到本地

    3. docker push 命令来将本地镜像推送到Docker Hub。

     自动创建允许用户通过Docker Hub指定跟踪一个目标网站(目前支持 GitHub或BitBucket)上的项目,一旦项目发生新的提交,则自动执行创建。要配置自动创建,包括如下的步骤:

  •  容器快照文件将丢弃所有的历史记录和元数据信息 (即仅保存容器当时的快照状态),
  • 镜像存储文件将保存完整记录,体积也更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
  •  1) 创建并登录Docker Hub,以及目标网站;*在目标网站中连接帐户到Docker Hub;
  • 2) 在Docker Hub中配置一个“自动创建”;
  • 3) 选取一个目标网站中的项目(需要含Dockerfile)和分支;
  • 4) 指定Dockerfile的位置,并提交创建。
  • 5) 可以在Docker Hub的“自动创建”页面中跟踪每次创建的状态。

  5.2 搭建本地私有仓库

       在本地将启动一个私有仓库服务,监听端口为5000。使用registry镜像创建私有仓库   docker run -d -p 5000:5000 registry  。默认情况下,会将仓库创建在容器的/ tmp/registry目录下。可以通过- v参数来将镜像文件存放在本地的指定路径。 例如下面的例子将上传的镜像放到/ opt/data/registry目录:

        docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry

       比较新的Docker版本对安全性要求较高,会要求仓库支持SSL/TLS证书。 对于内部使用的私有仓库,可以自行配置证书或关闭对仓库的安全性检查。修改Docker daemon的启动参数,添加如下参数,表示信任这个私 有仓库,不进行安全证书检查:

   DOCKER_OPTS="--insecure-registry 10.0.2.2:5000"

      如果要使用安全证书,用户也可以从较知名的CA服务商(如verisign) 申请公开的SSL/TLS证书,或者使用openssl等软件来自行生成。

6. Docker数据管理

       生产环境中使用Docker的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作。 容器中管理数据主要有两种方式:

  • 数据卷(Data Volumes): 容器内数据直接映射到本地主机环境;
  • 数据卷容器(Data Volume Containers): 使用特定容器维护数据卷。

6.1 数据卷

        在生产环境中,笔者推荐在使用数据卷或数据卷容器之外,定期将主机 的本地数据进行备份,或者使用支持容错的存储系统,包括RAID或分布式文件系统如Ceph、GPFS、HDFS等。数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount操作。

  • 数据卷可以在容器之间?享和重用,容器间传递数据将变得高效方便;
  • 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
  • 对数据卷的更新不会影响镜像,解耦了应用和数据;
  • 卷会一直存在,直到没有容器使用,可以安全地卸载它。

1.在容器内创建一个数据卷

     在用docker run命令的时候,使用- v标记可以在容器内创建一个数据卷。 多次重复使用-v标记可以创建多个数据卷。下面使用training/webapp镜像创建一个web容器,并创建一个数据卷挂载 到容器的/webapp目录:

   $ docker run -d -P --name web -v /webapp training/webapp python app.py

       注意: -P是将容器服务暴露的端口,是自动映射到本地主机的临时端口。

2.挂载一个主机目录作为数据卷

        使用-v标记也可以指定挂载一个本地的已有目录到容器中去作为数据卷 (推荐方式)。

   $ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

       上面的命令加载主机的/ src/webapp目录到容器的/ opt/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以将一些程序或数据放到本地目录中,然后在容器内运行和使用。另外,本地目录的路径必须是 绝对路径,如果目录不存在Docker,会自动创建。

        Docker挂载数据卷的默认权限是读写(rw),用户也可以通过 ro指定为只读:

   $ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro  training/webapp python app.py

       加了:ro 之后,容器内对所挂载数据卷内的数据就无法修改了。

3.挂载一个本地主机文件作为数据卷

         -v标记也可以从主机挂载单个文件到容器中作为数据卷(不推荐)。

   $ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash  这样就可以记录在容器输入过的命令历史。
   注意如果直接挂载一个文件到容器,使用文件编辑工具,包括vi或者sed--in- place的时候,可能会造成文件inode的改变,从Docker 1.1.0起,这会导致报错 误信息。所以推荐的方式是直接挂载文件所在的目录。

6.2 数据卷容器

       如果用户需要在多个容器之间共享一些持续更新的数据最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其他容器挂载。

       创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到 /dbdata:

   $ docker run -it -v /dbdata --name dbdata ubuntu
   root@3ed94f279b6f:/# ls
   bin  boot  dbdata  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run sbin  srv  sys  tmp  usr    
   var

       在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷:

   $ docker run -it --volumes-from dbdata --name db1 ubuntu
   $ docker run -it --volumes-from dbdata --name db2 ubuntu

      容器db1和db2都挂载同一个数据卷到相同的 /dbdata 目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。       

      可以多次使用--volumes-from参数来从多个容器挂载多个数据卷。还可以从其他已经挂载了容器卷的容器来挂载数据卷。使用--volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态。如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时 显式使用 docker rm-v 命令来指定同时删除关联的容器。

6.3 利用数据卷容器来迁移数据

1.备份

       使用下面的命令来备份dbdata数据卷容器内的数据卷:

   $ docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata

       这个命令稍微有点复杂,具体分析一下。首先利用ubuntu镜像创建了一个容器worker。使用--volumes-from dbdata参数来让worker容器挂载dbdata容器的数据卷(即dbdata数据卷); 

     使用-v $(pwd):/backup参数 来挂载本地的当前目录到worker容器的/backup目录。

      worker容器启动后,使用了tar cvf/backup/backup.tar/dbdata命令来将/ dbdata下内容备份为容器内的/ backup/backup.tar,即宿主主机当前目录下的backup.tar。

2.恢复

       如果要将数据恢复到一个容器,可以按照下面的步骤操作。首先创建一个带有数据卷的容器dbdata2:

   $ docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

       然后创建另一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器卷中:

   $ docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf  /backup/backup.tar

7. 端口映射与容器互联 *****

       多个容器之间有能够互相访问到对方的服务。除了通过网络访问外,Docker还提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主主机; 另 一个是互联机制实现多个容器间通过容器名来快速访问。 

 7.1 端口映射实现访问容器

      1.从外部访问容器应用

       在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。 当容器中运行一些网络应用,要让外部访问这些应用时,可以通过 -P 或 -p参数来指定端口映射。当使用-P(大写的)标记时,Docker会随机映射一个 49000~49900的端口到内部容器开放的网络端口:

   $ docker run -d -P training/webapp python app.py
   $ docker ps -l
   CONTAINER ID  IMAGE         COMMAND       CREATED        STATUS        PORTS                   NAMES
   bc533791f3f5  py_dem:latest python app.py 5 seconds ago  Up 2 seconds  0.0.0.0:49155->5000/tcp py_demo 

       此时,可以使用docker ps看到,本地主机的49155被映射到了容器的5000端口。访问宿主主机的49155端口即可访问容器内Web应用提供的界面。同样,可以通过docker logs命令来查看应用的信息:

   $ docker logs -f nostalgic_morse
   * Running on http://0.0.0.0:5000/
   10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 -
   10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -

        -p(小写的)可以指定要映射的端口,并且在一个指定端口上只可以绑定一个容器。支持的格式有

        IP:HostPort: ContainerPort  | IP : : ContainerPort | HostPort:ContainerPort。

      2.映射所有接口地址

      使用HostPort:ContainerPort格式将本地的5000端口映射到容器的5000端口,可以执行:

   $ docker run -d -p 5000:5000 training/webapp python app.py

     此时默认会绑定本地所有接口上的所有地址。多次使用 -p标记可以绑定多个端口。例如:

   $ docker run -d -p 5000:5000  -p 3000:80 training/webapp python app.py

     3.映射到指定地址的指定端口

     可以使用IP:HostPort:ContainerPort格式指定映射使用一个特定地址,比如localhost地址127.0.0.1:

     $ docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

     4.映射到指定地址的任意端口

    使用IP::ContainerPort绑定localhost的任意端口到容器的5000端口,本地主机会自动分配一个端口:

   $ docker run -d -p 127.0.0.1::5000 training/webapp python app.py

     还可以使用udp标记来指定udp端口:
      $ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

     5.查看映射端口配置
     使用docker port命令来查看当前映射的端口配置,也可以查看到绑定的地址:

   $ docker port py_demo 5000
   127.0.0.1:49155.

      注意: 容器有自己的内部网络和IP地址,使用docker inspect+容器ID可以获取容器的具体信息。

7.2 互联机制实现便捷互访

       容器的互联(linking)是一种让多个容器中应用进行快速交互的方式。 它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的IP地址。

       1.自定义容器命名

       连接系统依据容器的名称来执行。因此,首先需要定义一个好记的容器名字。 虽然当创建容器的时候,系统默认会分配一个名字,但自定义容器名字有两个好处:

       使用--name标记可以为容器自定义命名:

  • 自定义的命名比较好记,比如一个Web应用容器,我们可以给它起名叫 web,一目了然;
  • 当要连接其他容器时,即便重启,也可以使用容器名而不用改变,比如 连接web容器到db容器。
  •  

       $ docker run -d -P --name web test/demo python app.py

       使用docker ps来验证设定的命名:

   $ docker ps -l
   CONTAINER ID  IMAGE            COMMAND        CREATED       STATUS        PORTS                    NAMES
   aed84ee21bde  test/demo:latest python app.py  12 hours ago  Up 2 seconds  0.0.0.0:49154->5000/tcp  web

      也可以使用docker inspect来查看容器的名字: $ docker inspect -f "{{.Name}}" aed84ee21bde  ----->  /web

       容器的名称是唯一的。如果已经命名了一个叫web的容器,当你要再次使用web这个名称的时候,需要先用docker rm来删除之前创建的同名容器。

       在执行docker run的时候如果添加 --rm 标记,则容器在终止后会立刻删除。注意,--rm和 -d 参数不能同时使用

       2.容器互联

      使用--link参数可以让容器之间安全地进行交互。 下面先创建一个新的数据库容器:

   $ docker run -d --name db training/db2

       删除之前创建的web容器: $ docker rm -f web   然后创建一个新的web容器,并将它连接到db容器:
       $ docker run -d -P --name web --link db:db training/webapp python app.py

       此时,db容器和web容器建立互联关系:  --link参数的格式为 --link name:alias,其中name是要连接的容器名称,alias是这个连接的别名。使用docker ps来查看容器的连接,如下所示:

 $ docker ps
CONTAINER ID IMAGE         COMMAND      CREATED      STATUS    PORTS     NAMES
349169744e49 training/db2:latest su postgres -c '/usr    Up About a minute  5432/tcp  db, web/db
aed84ee21bde training/webapp:latest python app.py Up 2 minute  0.0.0.0:49154->5000/tcp 16 hours ago  web

       Docker相当于在两个互联的容器之间创建了一个虚机通道,而且不用映射它们的端口到宿主主机上。在启动db容器的时候并没有使用 -p 和 -P 标记, 从而避免了暴露数据库服务端口到外部网络上。Docker通过两种方式为容器公开连接信息:

  • 更新环境变量;
  • 更新/etc/hosts文件。

       Docker容器服务访问的两大基本操作--基础的容器端口映射机制和 容器互联机制。同时,Docker目前可以成熟地支持Linux系统自带的网络服务和功能,这既可以利用现有成熟的技术提供稳定支持,又可以实现快速的高性能转发。

       在生产环境中,网络方面的需求更加复杂多变,包括跨主机甚至跨数据中心的通信,这时候往往就需要引入额外的机制,例如SDN(软件定义网络) 或NFV(网络功能虚拟化)的相关技术。

8. 使用Dockerfile创建镜像 

      Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。

8.1 基本结构

      Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。 一般而言,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。例如:

   # This Dockerfile uses the ubuntu image
   # VERSION 2 - EDITION 1
   # Author: docker_user
   # Command format: Instruction [arguments / command] ..
   # Base image to use, this must be set as the first line
   FROM ubuntu
   # Maintainer: docker_user <docker_user at email.com> (@docker_user)
   MAINTAINER docker_user docker_user@email.com
   # Commands to update the image
   RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
   RUN apt-get update && apt-get install -y nginx
   RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
   # Commands when creating a new container
   CMD /usr/sbin/nginx

       其中,一开始必须指明所基于的镜像名称,接下来一般是说明维护者信 息。后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命 令。每运行一条RUN指令,镜像就添加新的一层,并提交。最后是CMD指令,用来指定运行容器时的操作命令。下面是Docker Hub上两个热门镜像的Dockerfile的例子,可以帮助读者对 Dockerfile结构有个基本的认识。

       第一个例子是在debian:jessie基础镜像基础上安装Nginx环境,从而创建 一个新的nginx镜像:

   FROM debian:jessie
   MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"
   ENV NGINX_VERSION 1.10.1-1~jessie
   RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC64107
       9A6ABABF5BD827BD9BF62 \
           && echo "deb http://nginx.org/packages/debian/ jessie nginx" >> /etc/apt/sources.list \
           && apt-get update \
           && apt-get install --no-install-recommends --no-install-suggests -y \
           ca-certificates \
           nginx=${NGINX_VERSION} \
           nginx-module-xslt \
           nginx-module-geoip \
           nginx-module-image-filter \
           nginx-module-perl \
           nginx-module-njs \
           gettext-base \
           && rm -rf /var/lib/apt/lists/*
   # forward request and error logs to docker log collector
   RUN ln -sf /dev/stdout /var/log/nginx/access.log \
       && ln -sf /dev/stderr /var/log/nginx/error.log
   EXPOSE 80 443
   CMD ["nginx", "-g", "daemon off;"]

       第二个例子是基于buildpack-deps:jessie-scm基础镜像,安装Golang相关环境,制作一个GO语言的运行环境镜像:

   FROM buildpack-deps:jessie-scm
   # gcc for cgo
   RUN apt-get update && apt-get install -y --no-install-recommends \
       g++ \
       gcc \
       libc6-dev \
       make \
       && rm -rf /var/lib/apt/lists/*
   ENV GOLANG_VERSION 1.6.3
   ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
   ENV GOLANG_DOWNLOAD_SHA256 cdde5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd
       7561275a87aeb
   RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
       && echo "$GOLANG_DOWNLOAD_SHA256  golang.tar.gz" | sha256sum -c - \
       && tar -C /usr/local -xzf golang.tar.gz \
       && rm golang.tar.gz
   ENV GOPATH /go
   ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
   RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
   WORKDIR $GOPATH
   COPY go-wrapper /usr/local/bin/

8.2 基本指令

1.FROM

      指定所创建镜像的基础镜像,如果本地不存在,则默认会去Docker Hub 下载指定镜像。格式为

      FROM <image>,或FROM <image>:<tag>,或FROM <image>@<digest>

     任何Dockerfile中的第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像,可以使用多个FROM指令(每个镜像一次)。

2.MAINTAINER

       指定维护者信息,格式为MAINTAINER<name>。例如:

   MAINTAINER image_creator@docker.com

       该信息会写入生成镜像的Author属性域中。

3.RUN

       运行指定命令。 格式为RUN <command>或 RUN["executable","param1","param2"]

      注意,后一个指令会被解析为Json数组,因此必须用双引号。 前者默认将在shell终端中运行命令,即/ bin/sh-c;后者则使用exec执行,不会启动shell环境。 指定使用其他终端类型可以通过第二种方式实现,例如RUN["/bin/bash","-c","echo hello"]。 每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。例如:

   RUN apt-get update \
           && apt-get install -y libsnappy-dev zlib1g-dev libbz2-dev \
           && rm -rf /var/cache/apt

4.CMD

    CMD指令用来指定启动容器时默认执行的命令。它支持三种格式:

  • ·CMD["executable","param1","param2"]使用 exec执行,是推荐使用的方式;
  • ·CMD command param1 param2在/bin/sh中执行,提供给需要交互的应用;
  • ·CMD["param1","param2"]提供给 ENTRYPOINT的默认参数。

   每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一 条会被执行。如果用户启动容器时手动指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。

5.LABEL

        LABEL指令用来指定生成镜像的元数据标签信息。 格式为LABEL<key>=<value><key>=<value><key>=<value>... 

   LABEL version="1.0"
   LABEL description="This text illustrates \ that label-values can span multiple lines."

6.EXPOSE

      声明镜像内服务所监听的端口。 格式为EXPOSE<port>[<port>...]。 例如:  

   EXPOSE 22 80 8443
   注意,该指令只是起到声明作用,并不会自动完成端口映射。在启动容器时需要使用-P,Docker主机会自动分配一个宿主机的临时端 口转发到指定的端口;使用-p,则可以具体指定哪个宿主机的本地端口会映射过来。

7.ENV

     指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动 的容器中也会存在。格式为ENV <key> <value>或ENV <key>=<value>... 例如:

   ENV PG_MAJOR 9.3
   ENV PG_VERSION 9.3.4
   RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/
       postgress && ...
   ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

      指令指定的环境变量在运行时可以被覆盖掉,如docker run  --env <key>=<value> built_image。

8.ADD

       该命令将复制指定的<src>路径下的内容到容器中的<dest>路径下。 格式为ADD  <src>  <dest>

       其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录),也 可以是一个URL,还可以是一个tar文件(如果为tar文件,会自动解压到<dest> 路径下)。<dest>可以是镜像内的绝对路径,或者相对于工作目录 (WORKDIR)的相对路径。 路径支持正则格式,例如:

   ADD *.c /code/

9.COPY

      格式为COPY<src><dest>。 复制本地主机的<src>(为Dockerfile所在目录的相对路径、文件或目录)下的内容到镜像中的<dest>下。目标路径不存在时,会自动创建。路径同样支持正则格式。当使用本地目录为源目录时,推荐使用COPY。

10.ENTRYPOINT

      指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执 行,所有传入值作为该命令的参数。  支持两种格式:

  • ENTRYPOINT ["executable", "param1", "param2"](exec调用执行);
  • ENTRYPOINT command param1 param2(shell中执行)。

     此时,CMD指令指定值将作为根命令的参数。 每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。在运行时,可以被-- entrypoint参数覆盖掉,如docker run--entrypoint。

11.VOLUME

    创建一个数据卷挂载点。格式为VOLUME ["/data"]。 可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。

12.USER

       指定运行容器时的用户名或UID,后续的RUN等指令也会使用指定的用户身份。格式为USER daemon。 当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在之前创建所需要的用户。例如:

   RUN groupadd -r postgres && useradd -r -g postgres postgres

      要临时获取管理员权限可以使用gosu或sudo。

13.WORKDIR

        为后续的RUN、CMD和 指令配置工作目录。

        ENTRYPOINT 格式为WORKDIR/path/to/workdir。可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:

   WORKDIR /a
   WORKDIR b
   WORKDIR c
   RUN pwd

则最终路径为 /a/b/c。

14.ARG

      指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行 docker build命令时才以-- build-arg<varname>=<value>格式传入。格式为ARG<name>[=<default value>]。则可以用docker build--build-arg<name>=<value>.来指定参数值。

15.ONBUILD

       配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令。格式为ONBUILD[INSTRUCTION]。 例如,Dockerfile使用如下的内容创建了镜像 image-A:

   [...]
   ONBUILD ADD . /app/src
   ONBUILD RUN /usr/local/bin/python-build --dir /app/src
   [...]

       如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A 指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条 指令:

   FROM image-A
   #Automatically run the following
   ADD . /app/src
   RUN /usr/local/bin/python-build --dir /app/src

       使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9- onbuild。

16.STOPSIGNAL

       指定所创建镜像启动的容器接收退出的信号值。例如: STOPSIGNAL signal

17.HEALTHCHECK

       配置所启动容器如何进行健康检查(如何判断健康与否),自Docker 1.12开始支持。格式有两种:

  • HEALTHCHECK[OPTIONS]CMD command:根据所执行命令返回值是否 为0来判断;
  • HEALTHCHECK NONE:禁止基础镜像中的健康检查。

     OPTION支持: ·--interval=DURATION(默认为:30s):过多久检查一次; ·--timeout=DURATION(默认为:30s):每次检查等待结果的超时; ·--retries=N(默认为:3):如果失败了,重试几次才最终确定失败。

18.SHELL

     指定其他命令使用shell时的默认shell类型。 默认值为["/bin/sh","-c"]。

注意: 对于Windows系统,建议在Dockerfile开头添加#escape=`来指定转义信 息。

 8.3 创建镜像

       编写完成Dockerfile之后,可以通过docker build命令来创建镜像。

       基本的格式为docker build[选项]内容路径,该命令将读取指定路径下 (包括子目录)的Dockerfile,并将该路径下的所有内容发送给 Docker服务端,由服务端来创建镜像。因此除非生成镜像需要,否则一般建议放置 Dockerfile的目录为空目录。有两点经验:

  • 如果使用非内容路径下的Dockerfile,可以通过 -f 选项来指定其路径。
  • 要指定生成镜像的标签信息,可以使用 -t 选项。

    例如,指定Dockerfile所在路径为/ tmp/docker_builder/,并且希望生成 镜像标签为build_repo/first_image,可以使用下面的命令:

   $ docker build -t build_repo/first_image /tmp/docker_builder/

    使用.dockerignore文件 可以通过.dockerignore文件(每一行添加一条匹配模式)来让 Docker忽略匹配模式路径下的目录和文件。例如:

   # comment
       */temp*
       */*/temp*
       tmp?
       ~*

 建议读者在生成镜像过程 中,尝试从如下角度进行思考,完善所生成的镜像。

  • 精简镜像用途:  尽量让每个镜像的用途都比较集中、单一,避免构造大而复杂、多功能的镜像;
  • 选用合适的基础镜像:  过大的基础镜像会造成生成臃肿的镜像,一般推 荐较为小巧的debian镜像;
  • 提供足够清晰的命令注释和维护者信息:  Dockerfile也是一种代码,需要 考虑方便后续扩展和他人使用;
  • 正确使用版本号:  使用明确的版本号信息,如1.0,2.0,而非latest, 将避免内容不一致可能引发的惨案;
  • 减少镜像层数:  如果希望所生成镜像的层数尽量少,则要尽量合并指 令,例如多个RUN指令可以合并为一条;
  • 及时删除临时文件和缓存文件:  特别是在执行apt-get指令后,/var/cache/ apt下面会缓存一些安装包;
  • 提高生成?度:  如合理使用缓存,减少内容目录下的文件,或使 用.dockerignore文件指定等;
  • 调整合理的指令顺序:  在开启缓存的情况下,内容不变的指令尽量放在 前面,这样可以尽量复用;
  • 减少外部源的干扰:  如果确实要从外部引入数据,需要指定持久的地 址,并带有版本信息,让他人可以重复而不出错。

9. 实战集锦

第九章只是针对这本书中涉及到的做个简单的简介,具体的内容以及想深入了解可以自行学习。

9.1 操作系统

       目前常用的Linux发行版主要包括Debian/Ubuntu系列和CentOS/Fedora系列。前者以自带软件包版本较新而出名;后者则宣称运行更稳定一些。选择哪个操作系统取决于读者的具体需求。同时,社区还推出了完全基于Docker 的Linux发行版CoreOS。 使用Docker,只需要一个命令就能快速获取一个Linux发行版镜像,这是以往包括各种虚拟化技术都难以实现的。这些镜像一般都很精简,但是可以支持完整Linux系统的大部分功能。带有OFFICIAL标记说明是官方镜像。

         3.2 Ubuntu:是一个以桌面应用为主的GNU/Linux操作系统,与Debian的不同在于它每6个月会发布一个新版本,每2年会推

         出一个长期支持(LongTerm Support,LTS)版本,一般支持3年。

  1.  BusyBox是一个集成了一百多个最常用Linux命令和工具(如 cat、echo、grep、mount、telnet等)的精简工具箱,它只有几 MB的大小, 很方便进行各种快速验证,被誉为“Linux系统的瑞士军刀”。BusyBox可运 行于多款POSIX环境的操作系统中,如Linux(包括 Android)、Hurd、FreeBSD等。

    $ docker pull busybox:latest
    $ docker run –it busybox
    
  2. Alpine操作系统是一个面向安全的轻型Linux发行版。它不同于通常的 Linux发行版,Alpine采用了musl libc和BusyBox以减小系统的体积和运行时资源消耗,但功能上比BusyBox又完善得多,因此得到开源社区越来越多的青 睐。在保持瘦身的同时,Alpine还提供了自己的包管理工具apk,可以通过https://pkgs.alpinelinux.org/packages查询包信息,也可以通过apk命令直接查 询和安装各种软件。Alpine Docker镜像也继承了Alpine Linux发行版的这些优势。相比于其他 Docker镜像,它的容量非常小,仅仅只有5MB左右(Ubuntu系列镜像接近 200MB),且拥有非常友好的包管理机制。官方镜像来自docker-alpine项目。

  3. Debian/Ubuntu:Debian和Ubuntu都是目前较为流行的Debian系的服务器操作系统,十分适合研发场景。Docker Hub上提供了官方镜像,国内各大容器云服务也基本 都提供了相应的支持。

    3.1 Debian系统

           Debian是由GPL和其他自由软件许可协议授权的自由软件组成的操作系 统,由Debian Project组织维护。Debian计划是一个独立、分散的组织,由 3000个志愿者组成,接受世界多个非盈利组织的资金支持,Software in the Public Interest提供支持并持有商标作为保护机构。Debian以其坚守Unix和自 由软件的精神,以及给予用户的众多选择而闻名。现在Debian包括了超过 25000个软件包并支持12个计算机系统结构。

          作为一个大的系统组织框架,Debian下面有多种不同操作系统核心的分 支计划,主要为采用Linux核心的Debian GNU/Linux系统,其他还有采用GNU Hurd核心的Debian GNU/Hurd系统、采用FreeBSD核心的Debian GNU/ kFreeBSD系统,以及采用NetBSD核心的Debian GNU/NetBSD系统,甚至还有 利用Debian的系统架构和工具,采用OpenSolaris核心构建而成的Nexenta OS系 统。在这些Debian系统中,以采用Linux核心的Debian GNU/Linux最为著名。众多的Linux发行版,例如Ubuntu、Knoppix和Linspire及Xandros等,都基 于Debian GNU/Linux。

  4. CentOS:(Community Enterprise Operating System,社区企业操作系统)是基于Red Hat Enterprise Linux源代码编译而成的。由于CentOS与Redhat Linux 源于相同的代码基础,所以很多成本敏感且需要高稳定性的公司就使用 CentOS来替代商业版Red Hat Enterprise Linux。CentOS自身不包含闭源软件。

  5. Fedora :Fedora是由Fedora Project社区开发,红帽公司赞助的Linux发行版。它的目标是创建一套新颖、多功能并且自由和开源的操作系统。对用户而言,Fedora是一套功能完备的、可以更新的免费操作系统,而对赞助商Red Hat而言,它是许多新技术的测试平台,被认为可用的技术最终会加入到Red Hat Enterprise Linux中。

     $ docker run -it centos[Fedora] bash
    

9.2 为镜像添加SSH服务

       比如attach、exec等进入容器的办法命令, 但这些命令都无法解决远程管理容器的问题。因此,当读者需要远程登录到容器内进行一些操作的时候,就需要SSH的支持了。 详情下载PDF查看第10章的内容:

  • 基于commit命令创建
  • 使用Dockerfile创建

9.3 Web服务与应用

  • Apache是一个高稳定性的、商业级别的开源Web服务器。目前Apache已经是世界使用排名第一的Web服务器软件。由于其良好的跨平台和安全性,Apache被广泛应用在多种平台和操作系统上。作为Apache软件基金会支 持的项目,它的开发者社区完善而高效。自1995年发布至今,一直以高标准 进行维护与开发。Apache名称源自美国的西南部一个印第安人部落:阿帕奇 族,它支持类UNIX和Windows系统。 

  • Nginx是一款功能强大的开源反向代理服务器,支持 HTTP、HTTPS、SMTP、POP3、IMAP等协议。它也可以作为负载均衡器、HTTP缓存或Web服务器。Nginx一开始就专注于高并发和高性能的应用场景。它使用类BSD开源协议,支持Linux、BSD、Mac、Solaris、AIX等类Unix系统,同时 也有Windows上的移植版本。

  • Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容 器,按照Sun Microsystems提供的技术规范,实现了对Servlet和Java Server Page(JSP)的支持。同时,它提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含 了一个HTTP服务器,也可以当作一个单独的Web服务器来使用。下面介绍如何定制Tomcat镜像。

  • Jetty是一个优秀的开源Servlet容器,以其高效、小巧、可嵌入式等优点深得人心,它为基于Java的Web内容(如JSP和Servlet)提供运行环境。Jetty 基于Java语言编写,它的API以一组JAR包的形式发布。开发人员可以将Jetty 容器实例化成一个对象,可以迅速为一些独立运行的Java应用提供Web服务。

  • LAMP(Linux-Apache-MySQL-PHP)是目前流行的Web工具栈,其中包 括:Linux操作系统,Apache网络服务器,MySQL数据库,Perl、PHP或者 Python编程语言。其组成工具均是成熟的开源软件,被大量网站所采用。和 Java/J2EE架构相比,LAMP具有Web资源丰富、轻量、快速开发等特点;和微软的.NET架构相比,LAMP更具有通用、跨平台、高性能、低价格的优势。因 LAMP无论是在性能、质量还是价格方面都是企业搭建网站的首选平台。

  • CMS:内容管理系统(Content Management System,CMS)指的是提供内容编辑服务的平台程序。CMS可以让不懂编程的用户方便又轻松地发布、更改和管理 各类数字内容(主要以文本和图像为主)。

       Ghost是一个广受欢迎的开源博客平台,使用JavaScript编写,以MIT协议 发布。它的设计非常简约,使用起来体验优异,非常适合做内容发布,故而 受到很多极客或技术工作者的喜爱。 

        WordPress是风靡全球的开源内容管理系统,是博客、企业官网、产品首 页等内容相关平台的主流实现方案之一。类似项目还有 Drupal、Joomla、Typo3等。WordPress基于PHP和MySQL,架构设计简单明了,支持主题,插件和各种 功能模块。更重要的是,WordPress拥有庞大的社区,在线资源非常丰富,并 且在各大网络空间商和云平台中受到广泛的支持。根据2013年8月的统计数 据,流量排名前一千万的网站中其使用率高达22%。

9.4 持续开发与管理

       持续集成(Continuous integration,CI)正是针对这类问题的一种开 发实践,它倡导开发团队定期进行集成验证。集成通过自动化的构建来完 成,包括自动编译、发布和测试,从而尽快地发现错误。CI所描述的软件开发是从原始需求识别到最终产品部署整个过程中,需求以小批量形式在团队的各个角色间顺畅流动,能够以较短地周期完成需求的小粒度频繁交付。整个过程中,需求分析、产品的用户体验和交互设计、开发、测试、运维等角 色需要密切协作。

       持续集成特点包括:从检出代码、编译构建、运行测试、结果记录、测试统计等都是自动完成的,减少人工干预需要有持续集成系统的支持,包 括代码托管机制支持,以及集成服务器等。 持续交付(Continuous delivery,CD)则是经典的敏捷软件开发方法的 自然延伸,它强调产品在修改后到部署上线的流程要敏捷化、自动化。甚至 一些较小的改变也要今早的部署上线,这跟传统软件在较大版本更新后才上线的思想不同。

  • Jenkins是一个得到广泛应用的持续集成和持续交付的工具。作为开源软 件项目,它旨在提供一个开放易用的持续集成平台。Jenkins能实时监控集成中存在的错误,提供详细的日志文件和提醒功能,并用图表的形式形象地展示项目构建的趋势和稳定性。Jenkins特点包括安装配置简单、支持详细的测试报表、分布式构建等。
  • Gitlab是一款非常强大的开源源码管理系统。它支持基于Git的源码管 理、代码评审、issue跟踪、活动管理、wiki页面,持续集成和测试等功能。 基于Gitlab,用户可以自己搭建一套类似 Github的开发协同平台。

9.5 数据库应用

       目前,主流数据库包括关系型(SQL)和非关系型(NoSQL)两种。在使用数据库容器时,建议将数据库文件映射到宿主主机,一方面减少容器文件系统带来的性能损耗,另一方面实现数据的持久化。

       关系数据库是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据,支持复杂的事物处理和结构化查询。代 表实现有MySQL、Oracle、PostGreSQL、MariaDB、SQLServer等。

       非关系数据库是新兴的数据库技术,它放弃了传统关系型数据库的部分强一致性限制,带来性能上的提升,使其更适用于需要大规模并行处理的场景。非关系型数据库是关系型数据库的良好补充,代表产品有 MongoDB、Redis、CouchDB等。

  • MongoDB是一款可扩展、高性能的开源文档数据库,是当今最流行的 NoSQL数据库软件之一。它采用C++开发,支持复杂的数据类型和强大的查 询语言,提供了关系数据库的绝大部分功能。由于MongoDB高性能、易部 署、易使用等特点,已经在很多领域都得到了广泛的应用。mongodb的默认服务端口:27017

  • MySQL是全球最流行的开源的开源关系数据库软件之一,因为其高性 能、成熟可靠和适应性而得到广泛应用。MySQL目前在不少大规模网站和应用 中被使用,比如Facebook、Twitter和Yahoo!等。

  • Redis是一个开源(BSD许可)的基于内存的数据结构存储系统,可以用 作数据库、缓存和消息中间件。

  • CouchDB是一款面向文档的NoSQL数据库,以JSON格式存储数据。它兼 容ACID,可以用于存储网站的数据与内容,以及提供缓存等。CouchDB里文档 域(Field)都是以键值对的形式存储的,对数据的每次修改都会得到一个新 的文档修订号。CouchDB侧重于AP(可用性和分区容忍度)。相比之下,MongoDB侧重于 CP(一致性和分区容忍度),Neo4j则提供了特有的面向图形的结构。

  • Cassandra是个开源(Apache License 2.0)的分布式数据库,支持分散的 数据存储,可以实现容错以及无单点故障等。Cassandra在设计上引入了P2P 技术,具备大规模可分区行存储能力,并支持Spark、Storm、Hadoop的集 成。目前Facebook、Twitter、Instagram、eBay、Github、Reddit、Netflix 等多家公司都在使用Cassandra。类似工具还有HBase等。

  • Memcached是一个高性能、分布式的开源内存对象缓存系统。最初是Danga Interactive为了优化LiveJournal的访问速度而编写的。目前已经非常广 泛的应用于各种Web应用中。以BSD license授权协议发布。Memcached守护进程基于C语言实现,基于libevent的事件处理可以实现 很高的性能。需要注意的是,由于数据仅存在于内存中,因此重启 Memcached或重启操作系统会导致数据全部丢失。

9.6 分布式处理与大数据平台

  • RabbitMQ是一个支持Advanced Message Queuing Protocol(AMQP)的开源消息队列实现,由Erlang编写,因以高性能、高可用以及可伸缩性出名。它支持多种客户端,如:Java、Python、PHP、.NET、Ruby、JavaScript等。它主要用于在分布式系统中存储和转发消息,方便组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。

    AMQP架构中有两个主要组件:Exchange和Queue,两者都在服务端,又称Broker,由RabbitMQ实现的。客户端通常有Producer和Consumer两种类型。在使用RabbitMQ过程中需要注意的是,它将数据存储在Node中,默认情 况为hostname。用户使用rabbitmqctl工具进行远程管理,或跨容器管理的时候,会需要设置持久化的cookie。如果需要了解关于Erlang Cookie的信息,可以参见 RabbitMQ官网的集群指南。

  • 除了通用的消息队列外,任务队列在分布式处理中也十分重要。任务队列的输入是工作的一个单元,称为任务,有多个工作者监听队列来获取任务 并执行。Celery是一个简单、灵活、高可用、高性能的开源(BSD许可)分布式任务处理系统,专注于实时处理的任务队列管理,同时也支持任务调 度。Celery基于Python实现,跟包括Django、Pyramid、Pylons、Flask、Tornado等Web框架都无缝集成,有庞大 的用户与贡献者社区。Celery可以单机运行,也可以在多台机器上运行,甚至可以跨越数据中心运行。

  • 作为当今大数据处理领域的经典分布式平台,Apache Hadoop主要基于 Java语言实现,由三个核心子系统组成:HDFS、YARN、MapReduce,其 中,HDFS是一套分布式文件系统;YARN是资源管理系统,MapReduce是运行 在YARN上的应用,负责分布式处理管理。如果从操作系统的角度看,HDFS 相当于Linux的ext3/ext4文件系统,而Yarn相当于Linux的进程调度和内存分配模块。

  • Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框 架,基于Scala开发。最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一。与Hadoop和Storm等其他大数据和MapReduce技术相比,Spark支持更灵 活的函数定义,可以将应用处理速度提升一到两个数量级,并且提供了众多 方便的实用工具,包括SQL查询、流处理、机器学习和图处理等: Spark体系架构包括如下三个主要组件:数据存储、API、管理框架。

  • Apache Storm是一个实时流计算框架,由Twitter在2014年正式开源,遵循 Eclipse Public License 1.0。Storm基于Clojure等语言实现。Storm集群与Hadoop集群在工作方式上十分相似,唯一区别在于Hadoop 上运行的是MapReduce任务,在Storm上运行的则是topology。MapReduce任务完成处理即会结束,而topology则永远在等待消息并处理(直到被停止)。

  • Elasticsearch是一个基于Lucene的开源搜索服务器,主要基于Java实现。 它提供了一个分布式的,多租户的全文搜索引擎,内含RESTful web接口。Elasticsearch提供了实时的分布式数据存储和分析查询功能,很容易扩展 到上百台服务器,支持处理PB级结构化或非结构化数据。配合 Logstash、Kibana等组件,可以快速构建一套对日志消息的分析平台。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Docker技术入门与实践(第2版)】Docker入门_学习笔记 的相关文章

随机推荐

  • 算法入门--递归

    不死神兔 有一对兔子 从出生后第3个月起每个月都生一对兔子 小兔子长到第三个月后每个月又生一对兔子 假如兔子都不死 问第二十个月的兔子对数为多少 规律 1 1 2 2 1 3 2 5 3 这就是暴力美学 不死神兔public class t
  • TF-IDF(词频-逆文档频率)介绍与python实现

    TF IDF term frequency inverse document frequency TF IDF介绍 TF IDF 词频 逆文档频率 是一种用于信息检索 Information retrieval 与数据挖掘 data min
  • 布林通道参数用20还是26_布林线指标参数设置为13、20、26、30、60、99,那个才是最佳?...

    布林线 Boll 指标是通过计算股价的 标准差 再求股价的 信赖区间 很多炒股新人不知道怎么设置布林线的参数 13 20 26 30 60 99那个才是最佳 下面详细介绍 一起来学习吧 布林带指标参数设置多少才最佳 布林带的参数一般默认的情
  • 系统用户名为中文导致PowerShell无法正确操作conda

    本文叙述的问题诱因 系统用户名为中文 本文最后给出了解决方案 并给出了原理猜测 conda版本 4 10 3 系统版本 Win11 专业版 21H2 现象 我在Win11使用Powershell时 发现终端提示 conda没有被初始化 需要
  • Spring系列篇--关于Spring Bean完整的生命周期【附有流程图,超级易懂】

    Welcome Huihui s Code World 接下来看看由辉辉所写的关于Spring的相关操作吧 目录 Welcome Huihui s Code World 一 Spring Bean是单例模式还是多例模式 二 论证Bean是单
  • AMD历代CPU发布时间

    1969年5月1日 AMD公司以10万美元的启动资金正式成立 1997 AMD推出AMD K6处理器 1998 AMD在微处理器论坛上发布AMD速龙处理器 以前的代号为K7 1999 AMD推出AMD速龙处理器 它是业界第一款支持Micro
  • ioctl函数详细分析

    IPv4 和 IPv6 的网络接口操作使用套接字 ioctl 命令 级别 中级 Katiyar Manish manish katiyar in ibm com 软件工程师 IBM Intel Microsoft HPShweta Gupt
  • 显式调用构造函数和析构函数

    今天跟同事聊天 他说到STL源码有用到显示调用析构函数 试一了一下 果然能行 include lt iostream gt using namespace std class MyClass public MyClass cout lt l
  • SqlServer傻瓜教程 — 表备份

    大家好 我们知道类似于ERP这种大型软件 最大的难点就在庞大数据库的整理和维护 表备份顾名思义 是对一个表进行备份 那么我们什么时候需要表备份呢 表备份是在操作大型ERP数据库的某一个表中有重要数据的时候 测试你对此表操作的存储过程 或者测
  • pytorch下import numpy失败_PyTorch的编译系统

    背景 本文以PyTorch 1 0为基础 PyTorch的编译首先是python风格的编译 使用了python的setuptools编译系统 以最基本的编译安装命令python setup py install 为例 这一编译过程包含了如下
  • 两台linux服务器互相自动备份

    将数据同步到其它服务器这里使用Linux同步文件工具rsync来进行文件的同步 rsync rsync是类unix系统下的数据镜像备份工具 remote sync 一款快速增量备份工具 Remote Sync 远程同步 支持本地复制 或者与
  • 【教3妹学算法-leetcode】数组能形成多少数对

    插 前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 坚持不懈 越努力越幸运 大家一起学习鸭 3妹 这么热的天气还要持续多久啊 快要被热死了 2哥 感觉还要有一阵子 今天刚入伏 3妹 啊 今年
  • 三极管的工作原理详解,图文+案例

    什么是三极管 三极管全称是 晶体三极管 也被称作 晶体管 是一种具有放大功能的半导体器件 通常指本征半导体三极管 即BJT管 典型的三极管由三层半导体材料 有助于连接到外部电路并承载电流的端子组成 施加到晶体管的任何一对端子的电压或电流控制
  • C语言程序设计 例7-5

    例7 5 原题 选择排序法 输入一个正整数n 1
  • C++解释器模式:Interpreter Pattern

    当有语言要解释时 请使用解释器模式为语言创建解释器 解释器模式的核心是解释器类 在解释器模式中一般会定义两种解释器 终结符解释器 Terminal Expression Interpreter 终结符解释器用于解释语言中的基本单位 对应语法
  • [架构之路-210]- 人人都是产品经理 - 互联网产品解决用户需求的分析思路和方法笔记

    目录 前言 一 产品需求分析思路和方法 产品需求 1 产品需求的内涵 什么是产品 什么是需求 需求的产品的关系 案例分析 理解需求的误区 2 需求的分类及层次 规律 拆解用户需求 需求分类 需求层次 马斯洛需求层次理论 需求层次的规律 拆解
  • K-means聚类之一(多维整型数据)

    算法介绍 k means 算法接受输入量 k 然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足 同一聚类中的对象相似度较高 而不同聚类中的对象相似度较小 聚类相似度是利用各聚类中对象的均值所获得一个 中心对象 引力中心 来进行计算
  • javascript对象概念大全

    http www css88 com archives 512 本文介绍了几乎所有关于对象的基本概念 什么是对象 如何创建对象 对象的属性的设置和读取 删除属性的方法 构造函数 对象原型 父类 子类 继承等等 1 对象 对象是一种复合数据类
  • Python爬虫小程序

    import base64 import string import time from selenium import webdriver from selenium webdriver chrome service import Ser
  • 【Docker技术入门与实践(第2版)】Docker入门_学习笔记

    第一章 1 Docker入门须知 1 1 Docker基本知识 Docker是基于Go语言实现的开源容器项目 诞生于2013年年初 最初发 起者是dotCloud公司 Docker自开源后受到广泛的关注和讨论 目前已有多个相关项目 包括Do