本文是《Docker 从入门到实践》的阅读总结。

一篇文章[宋宝华]说道,虚拟化无非有两种:虚拟出一个世界;虚拟出一个氛围。Docker就是在宿主OS上通过命名空间nameSpace虚拟出了一个氛围。结果就是,在容器中的应用看来,它感觉操作系统上只有它自己一个应用在运行。Docker的理念是,build, ship, and run everywhere. 这对于持续集成,快速交付有很大的吸引力。

  • 基本概念(镜像、容器和仓库)
  • 镜像image:静态、分层存储的文件系统,使用了Union FS技术。
  • 容器container:运行的实体,可以被创建、启动、停止、删除、暂停等。 
    容器的本质是进程,但有独立的命名空间。
    容器在运行时以镜像为基础,创建一个存储层。存储层的生命周期与容器相同,会随着容器删除而丢失。
    容器的存储层应当保持无状态化,文件写入操作应使用数据卷(volume), 或者绑定宿主目录。
  • 仓库注册表registry: 集中存储、分发镜像的服务。registry中可以包含多个Repository. 
    镜像的命名:【用户名/仓库名:标签】,缺省标签为latest. 
     
  • 使用镜像
  • 获取镜像:docker pull  [选项] [docker registry地址[:端口]/ ]仓库名[:label]  默认registry地址是library,即官方仓库。
  • 运行: docker run [opt] <image> [命令],
    如:docker run -it --rm ubuntu:16.04 bash , -it是交互式终端,--rm是运行结束后就删除container
  • 镜像管理:
  • 列出镜像: docker image ls
  • 查看系统占用空间:docker system df
  • 清理镜像:docker image prune
  • 镜像查找过滤: -f 参数
  • 删除镜像: docker image rm [opt] <镜像1> [<镜像2>]
  • 使用dockerfile 定制镜像
    Dockerfile是一个文本文件,内容格式如下:
    from nginx
    run echo ‘<h1>HelloWorld</h1>’ > /usr/share/nginx/html/index.htm
    from 选定了一个基础镜像。从空白镜像开始创建使用from scratch,直接将可执行文件复制进镜像中就这样做。
    run用来执行命令行命令。run一次会建立一层存储层,因此多条命令应该使用一个run,用&&连接起来。
  • 使用build 构建镜像
    在Dockerfile所在目录 运行 docker build -t <名称: 标签> .   -t 命令是输入名称标签列表。注意后面有一个. 表示上下文目录。 默认是读取上下文目录中的dockerfile.
  • 其他build方法
  • 从git 仓库构建: docker build https:github.io/xxx/xxx.git
  • 从网络上的tar包构建:docker build http://xxx/xx/tar.gz
  • 重定向读取Dockerfile构建: docker build - < Dockerfile   或者 cat Dockerfile | docker build -
  • 重定向从压缩包进行构建:docker build - < context.tar.gz
  • Dockerfile 指令.  
  • RUN: 运行一个命令。有两种形式:shell形式(RUN <命令>)或者exec形式(["命令","参数1","参数2"]),下同
  • COPY: COPY <源路径> <目标路径>
  • ADD: 与ADD格式和用法基本一致,但增加了从URL路径下载的功能,gzip压缩文件会自动解压。ADD 命令基本不用
  • CMD: 指定容器主进程的默认启动命令。例如,ubuntu镜像的CMD是 /bin/bash ,所以运行后是bash shell.
  • ENTERPOINT: 作用与CMD一样,指定容器主进程运行后的命令。用法1:使用ENTERPOINT可以将docker run <image> 后面的参数添加到ENTERPOINT内容后面,而使用CMD,docker run <image>后面的参数作为全新的cmd.  用法2:用ENTERPOINT运行一个SH文件:ENTERPOINT ["docker-enterpoint.sh"], docker run <image>后的参数作为sh程序的输入选项。
  • ENV环境变量: 定义键值对,使用时 $key可以展开获得value值
    格式:ENV <key> <value>
    ENV <key1>=<value1> (有空格需要双引号)
  •  ARG构建参数:ARG <key>[=<value>] 也是设置环境变量,但只是先声明,在build时用 --build-arg  <key>[=<value>] 重新覆盖
  • VOLUME: 事先指定某些目录,如果运行时用户没有挂载他们,就挂载为匿名卷,防止大量数据写入容器存储层中
    VOLUME ["<路径1>","<路径2>"]
    VOLUME <路径>
  • EXPOSE: 声明端口, docker run -P 时随机映射到EXPOSE声明的端口
    EXPOSE <port1> [<port2>]
  • WORKDIR: 指定工作目录。
    WORKDIR <工作目录>  指定以后各层的工作目录,例如在RUN命令前指定目录,相当于在同一行中使用cd命令。
  • USER: 指定以后执行命令的用户
    USER <用户名>   使用前要确保已经建立了要用的用户名,例如RUN groupadd -add redis && useradd -r -g redis  redis
  • ONBUILD: 下一次基于该镜像构建时执行。
    ONBUILD <其他指令>。
  • 多阶段构建:为了减小镜像的体积,发布时应该只包含运行环境和二进制文件,而不包括源码。使用from as 可以定义多个阶段,例如 FROM xxx:xxx as stage0, FROM xxx:xxx as stage1。 COPY --from=stage0 可以从stage0中复制出文件。
  • 操作容器
  • 启动容器 
  • docker run <image> [opt] [cmd/enterpoint] 从image启动容器。常用选项: -i 保持标准输入打开 -t 分配一个伪终端
  • docker container start [opt] <CONTAINER> 启动一个已经终止的容器
  • 终止容器:docker container stop [CONTAINER]  docker container ls -a #查看停止的容器
  • 后台运行
  • d参数后台运行:docker run -d #容器后台运行
  • 查看运行的容器,并显示输出信息:docker container ls, docker container logs <CONTAINER>
  • 进入容器:docker attach <CONTAINER ID> #进入后台运行着的容器 / docker exec -it <CON ID> bash
  • 导入和导出容器: 导出:docker export <CON> > exportCon.tar / 导入:docker import
  • 删除容器:docker container rm 清理处于终止状态的容器:docker container prune
  • 访问仓库
  • login、logout 、 search、push、pull  
  • 数据管理。有两种方式:数据卷(volumes)、挂载主机目录(Bind mounts)
  • 数据卷:独立于容器的生存周期,容器之间可以共享或重用
  • 创建数据卷:docker volume create my-vol,
  • 查看数据卷docker volume ls
  • 查看某个数据卷的信息 docker volume inspect my-vol
  • 挂载到容器:docker run -d --mount source=my-vol,target=/webapp <image>
  • 挂载主机目录:直接将本地主机目录挂载到容器中
  • docker run -d --mount type=bind,source=/src/webapp,target=opt/webapp <image>
  • inspect 查看状态。可以docker volume inspect <vol>,也可以docker inspect <image>
  • 使用网络
  • docker network
  • 高级网络配置