很高兴和你相遇
这里正在记录我的所思所学
订阅免费邮件通讯接收最新内容
首页 归档 想法 工具 通讯 播客 简历 主页

Docker 学习笔记 I

越来越无法忍受目前用的几台服务器各种软件配置都不一致,无法做到随时无障碍切换,于是决定学点 Docker。

什么是 docker

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护

  • 传统虚拟化

虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程

  • docker

容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟

Docker 的优势

  • 解决一致性问题
    • 开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。
    • 而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
  • 维护和扩展
  • 迁移方便
  • 快速启动

理解 Docker

镜像

  • 操作系统分为内核和用户空间
  • 对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持
  • Docker 镜像(Image),就相当于是一个 root 文件系统
  • 除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
  • 镜像不包含任何动态数据,其内容在构建之后也不会被改变

分层存储

  • 因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构
  • 镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成
  • 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层
  • 删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除

Docker 容器

  • 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。
  • 每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
  • 容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
  • 容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
  • 数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失。

仓库 Docker Registry

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

在虚拟机上安装 Docker

虚拟机版本

  • uname -r : 4.10.0-30-generic
  • sudo lsb_release -a : Description:Ubuntu 17.04

安装 Docker

  • sudo apt install docker. io

  • service docker start

  • sudo docker run hello-world

  • 出现如下内容

查看 docker 版本号

  • docker -v:Docker version 1.12.6, build 78d1802

镜像加速器(被坑以后才发现的问题)

在国内下载很多镜像往往会有龟速现象发生,这里使用官方提供的加速器 registry mirror。

  • The URL of the registry mirror for China is registry.docker-cn.com
  • 将此镜像设置为默认
    • 新建文件/etc/docker/daemon.json
    • 输入内容{ "registry-mirrors": ["[https://registry.docker-cn.com](https://registry.docker-cn.com/)"] }

使用 Docker 安装第一个软件

从 Docker Registry 获取镜像的命令是 docker pull

  • 命令格式 docker pull [选项] [Docker Registry 地址]<仓库名>:<标签>
  • 地址格式:<域名/IP>[: 端口号] 默认地址是 Docker Hub
  • 仓库名:两段式名称,既<用户名>/<软件名>

具体事例:sudo docker pull biocontainers/blast

  • 用户名是 biocontainers 。如果这里没有用户名,会从官方 library 中进行下载

  • 出现如下的界面

从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。

下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。

下载完成时显示的内容

运行第一个 docker 程序

  • 镜像安装成功后,以这个镜像为基础启动一个容器来运行
  • docker run 是运行容器的命令
  • 默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
  • sudo docker run biocontainers/blast blastp -help
  • 删除容器 docker rm

列出镜像

  • 命令 docker images
  • 列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间

  • 之前安装的 biocontainers/blast 占用了接近 2 个 G 的空间

删除本地镜像

  • docker rmi [选项] <镜像 1> [<镜像 2> ...]

    • <镜像> 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要
    • docker images 默认列出的就已经是短 ID
  • 实例 sudo docker rmi b2b

报错Error response from daemon: conflict: unable to delete b2b81d1fe174 (must be forced) - image is being used by stopped container 9bf4b361545d

原因是没有删除容器,所以无法删除镜像

  • 首先查看运行的容器有哪些:
    sudo docker ps -a -q

  • 然后删除相关的容器:
    sudo docker rm

  • 最后再删除镜像

    sudo dokcker rmi

删除流程如下图所示

  • 镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签
  • 删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消(untagged)
  • 并非所有的 docker rmi都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
  • 当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。
  • 镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。

用户权限设置

  • 默认情况下,Docker 命令的运行需要根用户权限。一个解决办法是把用户加入 docker 用户组
  • Docker 能够将/run/docker.sock的文件权限设为 660、用户组设为 docker。当把用户加入到 docker 用户组后,就无需使用 sudo 命令切换获取根用户权限。
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp - docker # 切换用户组
newgrp - `groups ${USER} | cut -d' ' -f1`

参考资料


本文作者:思考问题的熊

版权声明:本博客所有文章除特别声明外,均采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。

如果你对这篇文章感兴趣,欢迎通过邮箱或者微信订阅我的 「熊言熊语」会员通讯,我将第一时间与你分享肿瘤生物医药领域最新行业研究进展和我的所思所学所想点此链接即可进行免费订阅。


· 分享链接 https://kaopubear.top/blog/2017-09-08-LearnDocker1/