无论对开发还是对算法工作,Docker 都是一项非常重要的技术栈。

Docker 强在哪里呢?怎么使用?我可以用 Docker 做什么复杂的事情?

本文详细介绍了 Docker 的方方面面。

参考视频:尚硅谷 Docker 核心基础

1. Docker 基本概念

1.1 面试的时候,经常会问的问题:

  • 什么是镜像?什么是容器?
  • 容器虚拟化技术和虚拟机有什么区别?
  • Docker File 是什么?编写过吗?

1.2 Docker 有啥用?

  • 开发和运维交互的时候,经常是开发能够正常运行,运维不能正常部署。
  • 特别是版本迭代之后,不同版本环境的兼容,对运维是考验。

1.3 Docker 是啥?

  • Docker 是 Go 语言开发的云开源项目。

  • BUILD, SHIP AND RUN ANY APP ANYWHERE,也就是应用组件的封装、分发、部署、运行等生命周期的管理。

  • Docker 是一种 软件带环境安装 的标准解决方案。

  • 一次封装,处处运行。

  • Docker 是解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

1.4 Docker 工作核心:

  • Docker 打破过去 程序即应用 的观念,通过 镜像 image 将应用程序所需的系统环境,自下而上打包,使应用程序跨平台间无缝接轨运作。

1.5 Docker 能干啥?

  • (之前的)虚拟机技术,就是带环境安装的一种解决方案。虚拟机模拟的是整套操作系统。但是问题是:资源占用多,冗余步骤多,启动慢。
  • 容器虚拟化技术,是另一种虚拟化技术,Linux 容器 LXC。Linux 容器不是一个完整的操作系统,而是只需要软件工作所需要的库资源和设置。容器没有自己的内核,也没有对硬件的模拟,所以更轻。容器间有隔离,因此耦合度低。
  • Docker 是一个浓缩的,小型化的 Linux 系统。是容器的落地应用。
  • 开发/运维 DevOps ,概念也就是开发自运维,开发自己实现运维的工作。Docker 起到很大帮助。
  • Docker 一次构建,随处运行。能够更快速的应用交付和部署,更便捷的升级和扩容缩容,更简单的系统运维,更高效的计算资源利用。

1.6 Docker 的组成有啥?

  • 镜像 image:镜像是模板。
  • 容器 container:容器是镜像的实例。
  • 仓库 repository:仓库是存储镜像的地方。
  • 类似于类、对象和存储空间。
  • 容器是一个简易版的 Linux 环境和运行在其中的应用程序。
  • Docker 本身是一个容器运行载体,管理引擎,Docker Daemon 负责管理 image 和 container。打包好的运行环境是 image,通过 image 可以同时生成多个 container。container 实现具体服务。repository 就是存储 image 的仓库。
  • Docker 是一个 Client - Server 结构的系统,Docker 守护进程运行在主机上,通过 Socket 连接客户端访问,守护进程从客户端接受命令,并管理运行在主机上的容器。容器是运行时环境。

1.7 Docker 为啥快?

  • Docker 不需要 Hypervisor 实现硬件资源虚拟化,因此在 CPU、内存利用率上效率更高。
  • Docker 直接用宿主机内核,而不需要 Guest OS,避免了加载内核的时间,提高效率。

2. Docker 安装配置

2.1 安装命令:

  • yum install -y epel-release
  • yum install -y docker-io

2.2 配置使用及验证命令:

  • vim /etc/sysconfig/docker
  • service docker start
  • docker version

3. Docker 命令

3.1 测试命令:

  • docker run hello-world

    image-20210103154828502

3.2 帮助命令:

  • docker version
  • docker info:更详细的介绍。
  • docker --help:Linux 有问题问男人 man 命令。Docker 有问题问 docker --help 就能查到。查到的命令格式为docker [options] command [args]

3.3 镜像命令:

  • 主要包括四大类内容:
    • docker images
    • docker search 镜像名字
    • docker pull 镜像名字
    • docker rmi 镜像ID
  • docker images [OPTIONS]:查看本 机镜像。属性内容包括:REPOSITORY 仓库源,TAG 标签,IMAGE 镜像ID,CREATED 创建时间, SIZE 大小。OPTIONS 包括:
    • -a:本地所有镜像(包括中间件)。
    • -q:只显示镜像 ID。
    • --digests:显示镜像摘要。
    • --no-trunc:显示完整镜像信息。
  • docker search [OPTIONS]:去 docker hub 上查找镜像。OPTIONS 包括:
    • --no-trunc:显示完整镜像信息。
    • -s:收藏数不小于指定值。
    • --automated:只列出 automated build 类型镜像。
  • docker pull:下载镜像。
  • docker rmi:删除镜像。
    • docker rmi 镜像1 [, 镜像2] ... :删除多个镜像。
    • docker rmi $(docker images -qa):删除全部镜像。
  • docker commit [OPTIONS] [容器 ID] [目标镜像名]:[标签名]:提交容器副本,使其成为新镜像。
    • -m:描述信息。
    • -a:作者信息。
  • docker history 镜像名:列出镜像变更历史。

3.4 容器命令:

  • docker run [OPTIONS] 容器名 or ID [COMMAND] [args]:新建并拉取容器。OPTIONS 包括:

    • --name:容器名称。
    • -i:以交互模式运行容器。
    • -t:为容器重新分配一个伪输入终端。-t 和 -i 通常同时使用。
    • -d:后台运行,也就是守护进程。注意,docker 容器后台运行必须要对应一个前台进程,否则会自杀。所以部分程序需要前台运行。
    • -P:随机端口。-p [Host 端口 : Docker端口] 指定端口。
  • docker ps [OPTIONSJ] :查看 docker 内部正在运行的进程。OPTIONS 包括:

    • -a:正在运行 + 历史运行。
    • -l:显示最近创建的容器。-n 是最近的 n 个容器。
    • -q:只显示容器编号。
    • --no-trunc:不间断输出。
  • exit:容器停止退出。

    • CTRL + P + Q:容器不停止退出。
  • docker start 容器名 or ID:启动容器。

  • docker restart 容器名 or ID: 重启容器。

  • docker stop 容器名 or ID

  • docker kill 容器名 or ID

  • docker rm 容器 ID:删除容器。删除多个容器:

    • docker rm -f $(docker ps -a -q)
    • docker ps -a -q | xargs docker rm
  • docker logs [OPTIONS] 容器 ID:

    • -t:显示时间。

    • -f:跟随更新显示。

    • --tail:显示最后多少条。

    • 例如:

    docker run -d centos /bin/sh -c "while true;do echo helloWorld;sleep 2;done"
    docker ps
    docker logs -t -f ID

    image-20210104111833827

  • docker top 容器 ID:查看容器内部的进程。

  • docker inspect 容器 ID:查看容器内部细节。

  • docker exec [OPTIONS] 容器 ID:启动新终端,进入正在运行的容器,并以命令行交互。

    • -i:以交互模式运行容器。
    • -t:为容器重新分配一个伪输入终端。-t 和 -i 通常同时使用。
  • docker attach [OPTIONS] 容器 ID:直接进入容器启动命令终端,不启动新进程,命令行交互。

  • docker cp 容器 ID : 容器内路径 目的主机路径 :从容器内拷贝数据到本机。

4. Docker 镜像

4.1 Docker 镜像是啥?

  • Docker 镜像是一种轻量级、可执行的独立软件包。
  • 包含运行环境和开发的软件。
  • 包含运行软件全部内容,包括代码、运行时环境、库、环境变量、配置文件。

4.2 UnionFS 联合文件系统是啥?

  • UnionFS 联合文件系统是一种分层、轻量级、高性能的文件系统。对文件系统的修改被作为一系列提交,进行叠加,并放到一个目录里面。
  • Docker 镜像的基础是 UnionFS 联合文件系统。镜像通过分层继承,基于基础镜像,制作各种具体镜像应用。

4.3 Docker 镜像加载原理是啥?

  • Docker 镜像是由一层层文件系统构成,是 UnionFS 联合文件系统。

  • Docker 调用宿主机器的 bootfs,自己只需要提供 rootfs,因此占用空间小,速度快。

  • 系统底层是 bootfs,即 boot file system,用于加载内核,使用完后自动卸载。各个系统的 bootfs 基本是通用的。内容包括:

    • bootloader:boot 加载器,负责引导加载 kernel。
    • kernel:内核。
  • 之后是 rootfs,即 root file system,包含 Linux 系统的 /dev, /bin, /etc 等。rootfs 是不同操作系统发行版,如 Ubuntu, Centos 等。

    image-20210104115052100

4.4 Docker 镜像为啥采用分层结构?

  • Docker 镜像采用分层结构,主要为了共享资源
  • 例如,镜像共同基于 Base 镜像,就只需要保存一份 Base 镜像即可。
  • 镜像的每一层都可以共享。

4.5 Docker 镜像和 Docker 容器有啥关系?

  • Docker 镜像都是只读的。
  • 容器启动时,一个新的可写层被加载到镜像顶部,即容器层
  • 容器层之下的都是镜像层
  • 将容器提交为镜像:docker commit 命令。

5. Docker 容器数据卷

Docker 容器数据卷是啥?

  • 容器希望将数据持久化,以及共享数据。
  • 容器数据卷能保存容器的数据。
  • 容器数据卷是 Docker 中的 rdb 和 aof 文件(Redis)。

Docker 容器数据卷能干啥?

  • 容器数据持久化。
  • 容器间数据继承和共享。
  • 主机到容器、容器到主机的数据共享。

Docker 容器数据卷有啥特点?

  • 数据卷在容器间共享或重用数据。
  • 数据卷中的更改可以直接生效。
  • 数据卷的更改不影响镜像更新。
  • 数据卷的生命周期持续到没有容器使用它为止。

容器卷怎么添加?

  • 直接命令添加。
  • DockerFile添加。

容器卷直接命令怎么添加?

  • docker run -it -v 宿主机绝对路径目录 : /容器内目录 镜像名:dockerj -v 命令实现挂载。
  • 只能加一个数据卷。
  • docker inspect 随后可以在 bind 中看到绑定信息。
  • 绑定后,容器和宿主机实现数据共享。
  • 容器停止退出后,主机修改数据可以同步成功。
  • docker run -it -v 宿主机绝对路径目录 : /容器内目录:ro 镜像名:设为容器只能看主机修改的数据,不能自己修改。

容器卷通过 DockerFile 怎么添加?

  • DockerFile 中使用 VOLUME 指令来给镜像添加一个或多个数据卷。

  • 编写 DockerFile。

    FROM centos
    VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
    CMD echo "Finished, success1."
    CMD /bin/bash
  • 构建 DockerFile。构建时会一层一层执行 DockerFile 文件。构建后生成新镜像。

    docker build -f /mydocker/dockerfile2 -t bluestragglers/centos .
  • 运行 bluestragglers/centos,运行时就会自动构建相应的数据卷。

    docker run -it bluestragglers/centos /bin/bash
  • docker 挂载主机目录后访问出现 cannot open directory. :Permission denied

    • 解决办法:挂载目录后加一个 --privileged=true,即可。

数据卷容器是啥?

  • 挂载数据卷的容器是数据卷容器。

  • 其他容器可以挂载这个父容器,实现数据共享。

  • 实现数据的传递依赖。

  • 实际生产中用这个比较少,容易引起各种错误。

数据卷容器怎么实现传递依赖?

  • run 的时候加入 --volumes-from 可以实现数据卷容器挂载。

    docker run -it --name dc02 --volumes-from dc01 bluestragglers/centos

6. DockerFile

6.1 DockerFile 是啥?

  • DockerFile 是对 Docker image 的源码级描述。
  • DockerFile 是构建 Docker 镜像的构建文件,是一系列命令和参数构成的脚本。
  • DockerFile 是生产流程,Docker image 是产品模板,Docker container 是最终产品。
  • 构建需要三步:
    • 编写 DockerFile 文件。
    • docker build
    • docker run

6.2 DockerFile 构建有啥讲究?

  • 每个保留字都必须大写字母,后接至少一个参数。
  • 每条指令创建一个新镜像层,并对镜像进行提交。

6.3 DockerFile 执行是啥流程?

  • docker 从基础镜像运行容器。
  • 执行指令,修改容器。
  • 执行类似 docker commit,提交新镜像层。
  • docker 基于新镜像,运行新容器。
  • 继续执行指令,直到完成。

6.4 DockerFile 有啥保留字指令?

  • FROM:基础镜像。当前编写的新镜像是基于哪个镜像的。

  • MAINTAINER:作者和邮箱。

  • RUN:容器构建时需要的命令。

  • EXPOSE:容器对外暴露的端口。

  • WORKDIR:创建容器后终端默认工作目录。

  • ENV:构建镜像过程中设置环境变量。

    ENV MY_PATH /usr/mytest
    WORKDIR $MY_PATH
  • ADD:将宿主机目录下的文件拷贝进镜像,并且解压缩

  • COPY:和 ADD 类似。但将宿主机目录下的文件仅拷贝进镜像。

  • VOLUME:容器数据卷,用于数据保存、共享和持久化。

  • CMD:指定一个容器启动时要运行的命令。CMD 可以有多个命令,但最后只有一个生效,最后一个会把前面的覆盖掉。

    • shell 格式。
    • exec 格式。
    • 参数列表格式。
  • ENTRYPOINT:和 CMD 类似,但所有命令都会执行,不会覆盖。

  • ONBUILD:触发器,父镜像里面有,被子镜像继承后,父镜像的 onebuild 会被触发。

6.5 DockerFile 有啥案例?

  • Base 镜像

  • mycentos 镜像:

    image-20210104171207896

    编写 DockerFile:

    FROM centos
    MAINTAINER bluestragglers
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    EXPOSE 80
    
    v echo $MYPATH
    CMD echo "success!"
    CMD /bin/bash

    构建:

    docker build -f /dockerfile -t mycentos:1.3 .

    构建结果:

    image-20210104193125671

    运行:

    docker run -it mycentos:1.3

    运行时,发现登录后路径发生了改变,可以进行 vim 编辑,有网络组件,可以查看 ifconfig。

    使用 docker history 镜像名,发现镜像更新是层层更新的。

  • CMD/ENTRYPOINT 镜像:

    编写 DockerFile:

    FROM centos
    RUN yum install -y curl
    CMD ["curl", "-s", "http://ip.cn"]

    构建:

    docker build -f /dockerfile2 -t myip .

    运行:

    docker run -it myip

    运行显示 IP 对应地址。

    令该镜像作为父镜像,用 ONBUILD 夹在里面,让其他镜像用 FROM 继承,则构建时:

    image-20210104195935216

    可以见到,触发了触发器 ONBUILD。

  • Tomcat9 镜像

7. Docker 安装常用软件

Docker 咋安装软件?

  • 搜索镜像,拉取镜像,查看镜像,启动镜像,停止容器,移除容器。

Docker 咋安装和运行 MySQL?

  • docker search mysql

  • docker pull mysql

  • 运行:

    image-20210104205037215

  • docker exec -it 容器 ID /bin/bash:进入执行。

    image-20210104205505999

  • 外部连接:ip + 端口号,即可实现外部连接。