docker——基础

什么是Docker

  • Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。
  • Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

为什么要使用 Docker

  • 作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
  • 更高效的利用系统资源:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。
  • 一致的运行环境:开发环境、测试环境、生产环境
  • 持续交付和部署:使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
  • 更轻松的迁移:由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。
  • 更轻松的维护和扩展:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
  • 对比传统虚拟机总结
特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

Docker的基本概念

包括三部分 镜像(Image)、容器(Container)、仓库(Repository)

Docker引擎

  • Docker 引擎是一个包含以下主要组件的客户端服务器应用程序。
    • 一种服务器,它是一种称为守护进程并且长时间运行的程序。
    • REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么。
    • 一个有命令行界面 (CLI) 工具的客户端。

Docker系统架构

  • Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。
  • Docker 容器通过 Docker 镜像来创建。
  • 客户端(Client)
    • Docker提供命令行界面(CLI)工具,客户端与Docker守护进程交互。
  • Docker_Host
    • 它包含容器,镜像和Docker守护程序。它提供完整的环境来执行和运行应用程序。
  • 注册表(Registry)
    • 它是全局映像库。可以访问并使用这些镜像在Docker环境中运行应用程序。

Docker镜像

  • 操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。
  • Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
  • 分层存储
    • 镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
    • 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
    • 分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

Docker容器

  • 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
  • 每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
  • 容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
  • 数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

Docker仓库

  • 一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
  • 一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
  • 仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务
  • 公有 Docker Registry
    • 最常使用的 Registry 公开服务是官方的 Docker Hub

    • 由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见的有 阿里云加速器、DaoCloud 加速器 等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。

    • 私有 Docker Registry

      • Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。
      • 除了官方的 Docker Registry 外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare Harbor 和 Sonatype Nexus。

Docker安装

  • Docker 在 1.13 版本之后,从 2017 年的 3 月 1 日开始,版本命名规则变为如下:版本格式 YY.MM Stable 版本 每个季度发行 Edge 版本 每个月发行
  • Docker 划分为 CE 和 EE。CE 即社区版(免费,支持周期三个月),EE 即企业版,强调安全,付费使用。
  • Docker CE 每月发布一个 Edge 版本 (17.03, 17.04, 17.05…),每三个月发布一个 Stable 版本 (17.03, 17.06, 17.09…),Docker EE 和 Stable 版本号保持一致,但每个版本提供一年维护。
  • 安装指南

Ubuntu 安装 Docker

  • 使用APT安装

    • 安装必要的一些系统工具
      • apt-get update
      • apt-get -y install apt-transport-https ca-certificates curl software-properties-common
    • 安装 GPG 证书
      • curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    • 写入软件源信息
      • sudo add-apt-repository “deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable”
    • 更新并安装 Docker CE
      • apt-get -y update
      • apt-get -y install docker-ce
  • 用脚本自动安装

    • curl -fsSL get.docker.com -o get-docker.sh
    • sh get-docker.sh --mirror Aliyun (不行)
    • sh get-docker.sh --mirror AzureChinaCloud (不行):Essential packages were removed and -y was used without --allow-remove-essential.
  • 目前使用

    • apt-get install -y docker.io
  • 删除docker

    • apt-get update
    • cd /etc/apt/
    • cd sources.list.d
    • rm -rf docker.list
    • apt-get autoremove docker-ce

CentOS 安装 Docker

  • 使用 yum 安装

    • yum install -y yum-utils
      device-mapper-persistent-data
      lvm2

    • yum-config-manager
      –add-repo
      https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo

    • 如果需要最新版本的 Docker CE 请使用以下命令:

      • yum-config-manager --enable docker-ce-edge
    • 如果需要测试版本的 Docker CE 请使用以下命令:

      • yum-config-manager --enable docker-ce-test
    • 安装 Docker CE

      • yum makecache fast
      • yum install docker-ce
  • 使用脚本自动安装

    • curl -fsSL get.docker.com -o get-docker.sh
    • sh get-docker.sh --mirror Aliyun

Windows 安装 Docker

  • Docker for Windows

Docker 镜像加速器

  • 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
    • Docker 官方提供的中国 registry mirror
    • 阿里云加速器
    • DaoCloud 加速器
  • Ubuntu 16.04+、Debian 8+、CentOS 7
    • 对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
			{
  				"registry-mirrors": [
    			"https://registry.docker-cn.com" (不行)
  					]
			}
  • 之后重新启动服务

    • systemctl daemon-reload
    • systemctl restart docker
  • Windows 10

    • 在系统右下角托盘 Docker 图标内右键菜单选择 Settings,打开配置窗口后左侧导航菜单选择 Daemon。在 Registry mirrors 一栏中填写加速器地址 https://registry.docker-cn.com,之后点击 Apply 保存后 Docker 就会重启并应用配置的镜像地址了。
  • 报错:Error response from daemon: Get https://registry-1.docker.io/v2/: net/http:

  • 原因:修改的加速器https://registry.docker-cn.com访问不了

  • 解决方法:修改成http://141e5461.m.daocloud.io 或者 https://v6lwz1lq.mirror.aliyuncs.com (目前使用的)

		    {
  				"registry-mirrors": [
    			"https://v6lwz1lq.mirror.aliyuncs.com"
  				]
			}
  • 检查加速器是否生效:docker info
  • docker重启:service docker restart

Docker镜像

获取镜像

  • docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
    • Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
    • 仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
  • 镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。
  • 官方镜像是一直在维护的,有任何新的 bug,或者版本更新,都会进行修复再以原来的标签发布,这样可以确保任何使用这个标签的用户可以获得更安全、更稳定的镜像。
  • docker rm:删除容器

列出镜像

  • docker images
  • docker image ls
  • 镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
  • 虚悬镜像:一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为 。 docker pull的时候,已存在的镜像名相同,这个镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消,从而成为了 。docker build 也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,可以用下面的命令专门显示这类镜像:docker image ls -f dangling=true
    • 使用命令删除:docker image prune

删除本地镜像

  • docker rmi
  • docker image rm [选项] <镜像1> [<镜像2> …]
    • docker image ls 默认列出的就已经是短 ID 了,一般取前3个字符以上,只要足够区分于别的镜像就可以了。
  • 删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 Untagged 的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker image rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
  • 当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像,但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己 docker pull 看到的层数不一样的源。
  • 删除所有仓库名为 redis 的镜像:
    • docker image rm $(docker image ls -q redis)
  • 删除所有在 mongo:3.2 之前的镜像:
    • docker image rm $(docker image ls -q -f before=mongo:3.2)

使用Dockerfile定制镜像

  • Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

  • FROM 指定基础镜像:所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。

  • 除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。

  • RUN 执行命令:RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:

    • shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。
    • exec 格式:RUN [“可执行文件”, “参数1”, “参数2”],这更像是函数调用中的格式。
  • 在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。

  • 没有使用很多个 RUN 对一一对应不同的命令,而是仅仅使用一个 RUN 指令,并使用 && 将各个所需命令串联起来。将之前的 7 层,简化为了 1 层。

  • 镜像是多层存储,每一层的东西并不会在下一层被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉。

镜像构建上下文(Context)

  • docker build 的工作原理:Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举。
  • 当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地文件复制进镜像,比如通过 COPY 指令、ADD 指令等。而 docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。
  • 当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
  • docker build -t mytomcat . 中的这个 .,实际上是在指定上下文的目录,docker build 命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。
  • 一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果该目录下没有所需文件,那么应该把所需文件复制一份过来。如果目录下有些东西确实不希望构建时传给 Docker 引擎,那么可以用 .gitignore 一样的语法写一个 .dockerignore,该文件是用于剔除不需要作为上下文传递给 Docker 引擎的。
  • 实际上 Dockerfile 的文件名并不要求必须为 Dockerfile,而且并不要求必须位于上下文目录中,比如可以用 -f …/Dockerfile.php 参数指定某个文件作为 Dockerfile。当然,一般大家习惯性的会使用默认的文件名 Dockerfile,以及会将其置于镜像构建上下文目录中。

Dockerfile指令

  • COPY 复制文件

    • COPY <源路径>…<目标路径>
    • COPY [“源路径”,…“目标路径”]
    • COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。
    • <源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则。
    • <目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
  • ADD 更高级的文件复制

    • 格式与COPY基本一致
    • 最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。
  • CMD 容器启动命令

    • CMD <命令>
    • CMD [“可执行文件”,“参数1”,“参数2”,…]
  • ENTRYPOINT 入口点

    • 指定容器启动程序及参数。
  • ENV 设置环境变量

    • ENV
    • ENV = =…
  • ARG 构建参数

    • ARG <参数名>[=<默认值>]
    • 构建参数和ENV的效果一样,都是设置环境变量。
  • VOLUME 定义匿名卷

    • VOLUME ["<路径1>","<路径2>",…]
    • VOLUME <路径>
    • 容器运行时尽量保持容器存储下不发生写操作,对于数据库需要保存动态数据的应用,其数据库文件应该保存于卷中。
  • EXPOSE 暴露端口

    • EXPOSE <端口1>[<端口2>…]
    • 声明运行时容器提供服务端口。这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
    • 在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
    • 要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
  • WORKDIR 指定工作目录

    • WORKDIR <工作目录路径>
    • 可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
    • Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器。
    • 每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。
  • USER 指定当前用户

    • USER <用户名>
    • USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录,USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份。
  • HEALTHCHECK 健康检查

    • HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
    • HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
  • ONBUILD 为他人作嫁衣

    • ONBUILD <其它指令>
  • 每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去。通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。

Docker容器

  • 容器是独立运行的一个或一组应用,以及它们的运行态环境。

启动容器

  • 启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
  • docker run
  • -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。
  • bash
  • 启动已终止容器:docker container start

守护态运行

  • 让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。
  • docker container ls 命令来查看容器信息、
  • docker container logs [container ID or NAMES] 获取容器的输出信息

终止容器

  • docker container stop 来终止一个运行中的容器
  • 当 Docker 容器中指定的应用终结时,容器也自动终止。
  • docker container ls -a 或者 docker ps -a 查看终止状态的容器
  • docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。

进入容器

  • docker attach 命令或 docker exec 命令
  • 推荐使用 docker exec 命令。因为使用docker attach命令的时候,使用exit命令退出时,会导致容器的停止。而docker exec命令不会。
  • docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

导入导出容器

  • 如果要导出本地某个容器,可以使用 docker export 命令。
  • 可以使用 docker import 从容器快照文件中再导入为镜像。
  • docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。

删除容器

  • docker container rm 来删除一个处于终止状态的容器。如果要删除一个运行中的容器,可以添加 -f 参数。
  • docker container prune 清理所有处于终止状态的容器

Docker 仓库

  • 仓库(Repository)是集中存放镜像的地方。
  • 一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。

Docker Hub

  • Docker 官方维护了一个公共仓库 Docker Hub(https://hub.docker.com/)。

拉取镜像

  • docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
  • 根据是否是官方提供,可将镜像资源分为两类。
    • 一种是类似 centos 这样的镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
    • 还有一种类型,比如 tianon/centos 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。可以通过前缀 username/ 来指定使用某个用户提供的镜像,比如 tianon 用户。

推送镜像

  • docker push 命令来将自己的镜像推送到 Docker Hub。

自动创建

  • 自动创建(Automated Builds)功能对于需要经常升级镜像内程序来说,十分方便。自动创建允许用户通过 Docker Hub 指定跟踪一个目标网站(目前支持 GitHub 或 BitBucket)上的项目,一旦项目发生新的提交或者创建新的标签(tag),Docker Hub 会自动构建镜像并推送到 Docker Hub 中。

私有仓库

  • docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。
  • 安装运行 docker-registry
  • 在私有仓库上传、搜索、下载镜像

Docker 数据管理

  • 在容器中管理数据主要有两种方式:数据卷(Volumes);挂载主机目录 (Bind mounts)。
  • 数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
    • 数据卷 可以在容器之间共享和重用
    • 对 数据卷 的修改会立马生效
    • 对 数据卷 的更新,不会影响镜像
    • 数据卷 默认会一直存在,即使容器被删除
  • Docker 新用户应该选择 --mount 参数,经验丰富的 Docker 使用者对 -v 或者 --volume 已经很熟悉了,但是推荐使用 --mount 参数。
  • 创建一个数据卷:docker volume create my-vol
  • 查看所有的 数据卷:docker volume ls
  • 启动一个挂载数据卷的容器:在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷。
  • 删除数据卷:docker volume rm my-vol
  • 数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。
  • 无主的数据卷可能会占据很多空间,要清理请使用以下命令:docker volume prune

Docker网络配置

  • Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
  • 外部访问容器
    • 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
    • 当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
    • -p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort。
    • docker port 来查看当前映射的端口配置。
  • 容器互联
    • 新建网络:docker network create -d bridge my-net
      • -d 参数指定 Docker 网络类型,有 bridge overlay。
    • 连接容器
    • 如果你有多个容器之间需要互相连接,推荐使用 Docker Compose。

Docker Compose

  • Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速的部署分布式应用。
  • 在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
  • 它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项(project)。

Compose 中有两个重要的概念

  • 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
  • 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
  • Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。

安装

  • 二进制包
  • curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose
  • chmod +x /usr/local/bin/docker-compose

卸载

  • 如果是二进制包方式安装的,删除二进制文件即可。

  • rm /usr/local/bin/docker-compose

  • 一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。

使用

  • 编写 docker-compose.yml 文件,这个是 Compose 使用的主模板文件。
  • 运行 compose 项目:docker-compose up

Docker Compose 命令

  • 对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
  • 基本格式:docker-compose [-f=…] [options] [COMMAND] [ARGS…]
    • -f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。
    • -p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名。
    • –x-networking 使用 Docker 的可拔插网络后端特性
    • –x-network-diver DRIVER 指定网络后端的驱动,默认为 bridge
    • –verbose 输出更多调试信息。
    • -v, --version 打印版本并退出。
  • config 验证 Compose 文件格式是否正确,若正确则显示配置,若格式错误显示错误原因。
  • down 此命令将会停止 up 命令所启动的容器,并移除网络
  • exec 进入指定的容器
  • images 列出 Compose 文件中包含的镜像
  • up 自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
    • docker-compose up -d,将会在后台启动并运行所有的容器。

Docker Compose 模板文件

  • 默认的模板文件名称为 docker-compose.yml,格式为 YAML 格式。
  • container_name 指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。
  • environment 设置环境变量。你可以使用数组或字典两种格式。
  • image 指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
  • ports 暴露端口信息。使用宿主端口:容器端口 (HOST:CONTAINER) 格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
  • volumes 数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。

你可能感兴趣的:(Docker)