1. 概述

1.1 Docker 是什么

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app), 更重要的是容器性能开销极低。

1.2 Docker 的优势

作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。

  1. 更高效的利用系统资源 由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。

  2. 更快速的启动时间 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。

  3. 一致的运行环境 开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。

  4. 持续交付和部署 使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成 (Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署 (Continuous Delivery/Deployment) 系统进行自动部署。

  5. 更轻松的迁移 由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。

  6. 更轻松的维护和扩展 Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。

对比传统虚拟机总结:

特性 Docker 虚拟机
启动 秒级别 分钟级
硬盘使用 一般为MB 一般为GB
性能 接近原生 弱于原生
系统支持量 单机支持上千个容器 一般几十个

2. 安装与卸载

2.1 安装 (CentOS)

以 CentOS 为例,安装 Docker, 其他安装方式可参考 官方文档.

  1. 卸载旧版本

    为避免机器上曾经安装的旧版本 Docker 与本次安装过程产生冲突,可以使用以下命令卸载旧版本 Docker:

     sudo yum remove docker \
                     docker-client \
                     docker-client-latest \
                     docker-common \
                     docker-latest \
                     docker-latest-logrotate \
                     docker-logrotate \
                     docker-engine
    

    如果yum提示没有安装相关的包则可以忽略。

    当卸载 Docker 时,存储在/var/lib/docker/中的映像、容器、卷和网络不会自动删除。

  2. 从仓库安装

    首次安装 Docker 时,需要先添加 Docker 仓库,然后就可以从仓库中安装或更新 Docker 了。

    • 添加 Docker 仓库

      在添加 Docker 仓库前需要先安装yum-utils, 因为下一步要使用yum-config-manager工具来添加 Docker 仓库。

      值得注意的是,国内访问官方仓库比较慢,因此我们可以将官方仓库地址替换成国内的镜像地址,常用的镜像地址有:

      • 官方仓库地址:https://download.docker.com/linux/centos/docker-ce.repo
      • 阿里云:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
      • 清华大学:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
        sudo yum install -y yum-utils
        # 如需使用国内镜像源,将下面的--add-repo 参数替换成对应的镜象源地址即可
        sudo yum-config-manager \
            --add-repo \
            https://download.docker.com/linux/centos/docker-ce.repo
      
    • 添加完成后,可以使用yum命令来安装 Docker:

        sudo yum install docker-ce \
                        docker-ce-cli \
                        containerd.io \
                        docker-buildx-plugin \
                        docker-compose-plugin
      

      为了保证安全,安装过程中,可能还会提示接受 GPG 密钥,你需要验证一下指纹是否与060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35匹配,如果是,输入y接受即可。

      安装完成后,Docker 不会自动启动。同时,系统中还会还创建一个docker组,但是,默认情况下,它不会将任何用户添加到该组中。只有docker组中的用户可以执行docker命令,因此,推荐大家在安装完整成之后把自己加入到docker组,否则每次执行docker命令都要带上sudo.

        # 下次登陆生效
        sudo usermod -aG docker $USER
      

      -G选项表示将用户加入到指定次要组,-a选项表示将用户添加到指定组时,使用追加方式。

      如果省略-a选项,则将从未列出的组删除用户,用户也将会离开自己主要组。因此我们建议添加用户到指定次要组时,始终使用usermod-aG选项。

      当前登录的用户将从docker组继承权限,现在你可以在不使用sudo命令运行docker.

      https://www.myfreax.com/how-to-add-user-to-group-in-linux/

  3. 启动并测试

    安装完成后,通过以下命令启动 Docker:

     sudo systemctl start docker
    

    然后通过运行hello-world映像来验证 Docker Engine 安装是否成功:

     sudo docker run hello-world
    

2.2 卸载 (CentOS)

  1. 卸载 Docker 以及相关工具包
sudo yum remove docker-ce \
                docker-ce-cli \
                containerd.io \
                docker-buildx-plugin \
                docker-compose-plugin \
                docker-ce-rootless-extras
  1. (可选)删除 Docker 镜像和容器

    上一步只会移除系统中与 Docker 相关的软件,但主机上的映像、容器、卷或自定义配置文件不会自动删除。要删除所有图像、容器和卷,请执行以下操作:

     sudo rm -rf /var/lib/docker
     sudo rm -rf /var/lib/containerd
    

    另外,配置文件需要手动删除。

3. 镜像加速

国内从 DockerHub 拉取镜像有时会遇比较慢,此时可以修改拉取的源为国内镜像,国内常用的镜像源为:

  • 科大镜像:https://docker.mirrors.ustc.edu.cn/
  • 网易:https://hub-mirror.c.163.com/
  • 阿里云:https://<你的 ID="">.mirror.aliyuncs.com你的>
  • 百度云:https://mirror.baidubce.com
  • 七牛云加速器:https://reg-mirror.qiniu.com

其中比较特殊的是阿里云镜像源,如果想使用阿里云镜像源,需要先登陆阿里云:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors, 然后再选择左边菜单选中的「镜像加速器」, 此时就可以获取到加速器的地址了。

选择好镜像源后,在/etc/docker/daemon.json中写入如下内容(如果文件不存在则新建该文件):

{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com",
    "https://reg-mirror.qiniu.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

由于镜像服务可能出现宕机,建议同时配置多个镜像。

然后重启 Docker 服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

4. 使用方法

4.1 Docker 命令

4.1.1 服务相关命令

  • 启动 docker 服务

      sudo systemctl start docker
    
  • 停止 docker 服务

      sudo systemctl stop docker
    
  • 重启 docker 服务

      sudo systemctl restart docker
    
  • 查看 docker 服务状态

      sudo systemctl status docker
    
  • 设置开机启动 docker 服务

      sudo systemctl enable docker
    

4.1.2 镜像相关命令

  • 查看镜像:查看本地所有的镜像

      docker images
      # 只显示镜像 ID
      docker images -q
    
  • 搜索镜像:从远程仓库中查找镜像

      docker search <镜像名称>
    
  • 拉取镜像:从远程仓库中下载镜像到本地,指定镜像格式为:<镜像名称>:<tag>, 如果不指定tag则拉取最新版本。

      docker pull <镜像名称>
      docker pull <镜像名称>:<tag>
    
  • 删除镜像:删除本地镜像

      docker rmi <镜像名 id>
      # 默认会删除 latest 这个 tag, 没有则报错
      docker rmi <镜像名称>
      docker rmi <镜像名称>:<tag>
      # 组合使用,删除所有镜像
      docker rmi `docker images -q`
    

4.1.3 容器相关命令

  • 查看容器

      docker ps  # 产看正在运行的容器
      docker ps -a  # 产看所有容器
    
  • 创建容器

    1. 方法 1: 创建后立即进入(交互式容器)

       docker run -it --name=c1 centos:7 /bin/bash
      
    2. 方法 2: 以后台模式创建(守护式容器)

       docker -id —name=c2 centos:7
      

    参数说明:

    -i: 保持容器运行。通常与-t同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。

    -t: 为容器重新分配一个伪输入终端,通常与-i同时使用。

    -d: 以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec进入容器。退出后,容器不会关闭。

    -t创建的容器一般称为交互式容器,-id创建的容器—般称为守护式容器。

    --name: 为创建的容器命名。

  • 进入容器

      docker exec -it c2 /bin/bash
    
  • 启动容器

      docker start [name 或 id]
    
  • 停止容器

      docker stop [name 或 id]
    
  • 删除容器:如果容器是运行状态则删除失败,需要停止容器才能删除

      docker rm -f [name 或 id]
      docker rm -f `docker ps -aq`
    
  • 查看容器详细信息

      docker inspect c2
    

4.2 数据卷

  1. 数据卷的概念

    • 数据卷是宿主机中的一个目录或文件
    • 当容器目录和数据卷目录绑定后,对方的修改会立即同步
    • 一个数据卷可以被多个容器同时挂载
    • 一个容器也可以被挂载多个数据卷
  2. 数据卷作用

    • 容器数据持久化
    • 外部机器和容器间接通信
    • 容器之间数据交换
  3. 配置数据卷

    创建启动容器时,使用-v参数设置数据卷

     docker run .... -v 宿主机目录(文件): 容器内目录(文件)...
    

    ⚠️ 注意事项:

    1. 目录必须是绝对路径
    2. 如果目录不存在,会自动创建
    3. 可以挂载多个数据卷

4.3 端口映射

使用方法:-p 本地端口:容器端口

例如,创建 Nginx 容器,使用-p 80:80 进行端口映射:

docker run -id --name=nginx \
           -p 80:80 \
           -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
           -v $PWD/logs:/var/log/nginx \
           -v $PWD/html:/usr/share/nginx/html \
           nginx

4.4 Dockerfile

4.4.1 使用 Dockerfile 构建景象

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

需求案例:自定义一个 Centos7 镜像,要求默认登陆路径为/usr, 可以使用 vim 编辑文件。

Dockerfile 实现:

# 指定父镜像
FROM centos:7
# 描述作者信息
MAINTAINER xxx <xxx@gmail.com>
# 执行安装 vim 命令
RUN yum instal vim -y
# 指定默认工作目录
WORKDIR /usr
# 容器启动执行的命令
CMD /bin/bash

然后再使用docker build命令构建镜像:

docker build -f ./Dockerfile ./ -t centos:1.0 

4.4.2 Dockerfile 指令

除了FROM,MAINTAINER,RUN,WORKDIR,CMD这几个指令外,Dockerfile 还提供了许多其他指令,这里放上一个简洁版的指令表。

指令 作用 备注
FROM 指定父镜像 指定 dockerfile 基于那个 image 构建
MAINTAINER 作者信息 用来标明这个 dockerfile 谁写的
LABEL 标签 用来标明 dockerfile 的标签 可以使用 Label 代替 Maintainer 最终都是在 docker image 基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式:RUN command 或者 RUN [“command” ,“param1”,”param2”]
CMD 容器启动命令 提供启动容器时候的默认命令 和 ENTRYPOINT 配合使用。格式 CMD command param1 param2 或者 CMD [“command” ,“param1”,”param2”]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build 的时候复制文件到 image 中
ADD 添加文件 build 的时候添加文件到 image 中 不仅仅局限于当前 build 上下文 可以来源于远程服务
ENV 环境变量 指定 build 时候的环境变量 可以在启动的容器的时候 通过-e 覆盖 格式 ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有 ENV 那么 ENV 的相同名字的值始终覆盖 arg 的参数
VOLUME 定义外部可以挂载的数据卷 指定 build 的 image 那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p 来绑定暴露端口 格式:EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条 workdir 的路径的相对路径
USER 指定执行用户 指定 build 或者启动的时候 用户 在 RUN CMD ENTRYPONT 执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在 ONBUILD 关键字的镜像作为基础镜像的时候 当执行 FROM 完成之后 会执行 ONBUILD 的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该 STOPSIGNAL 指令设置将发送到容器的系统调用信号以退出
SHELL 指定执行脚本的 shell 指定 RUN CMD ENTRYPOINT 执行命令的时候 使用的 shell

更多 Dockerfile 命指令使用细节请参考:

  • Dockerfile 官方文档:https://docs.docker.com/engine/reference/builder/
  • Dockerfile 最佳实践文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
  • Docker 官方镜像 Dockerfile: https://github.com/docker-library/docs

4.5 Docker 服务编排 (Docker Compose)

Docker Compose 是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建启动和停止。使用步骤:

  1. 利用 Dockerfile 定义运行环境镜像
  2. 使用 docker-compose.yml 定义组成应用的各服务
  3. 运行 docker-compose up 启动应用

Docker Compose 可以基于 Compose 文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!

4.5.1 安装 Docker Compose

目前 Docker 官方用 GO 语言 重写 了 Docker Compose, 并将其作为了 docker cli 的子命令,称为 Compose V2. 接下来我们直接安装 Compose V2:

# 这里以 x86 架构的 64 位 linux 操作系统为例,请根据自己的操作系统情况到官方的 Release 页面复制下载链接:
# https://github.com/docker/compose/releases
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

上面这几条命会下载(目前)最新版本的 Docker Compose, 并在$HOME目录下为当前用户安装 Compose。

为二进制文件添加可执行权限:

chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

安装完成后查看版本信息:

docker-compose version

测试安装:

docker compose version
# Docker Compose version v2.16.0

4.5.2 使用案例

官方提供了一个 Flask + Redis 的使用案例:https://docs.docker.com/compose/gettingstarted/.

DockerCompose 的详细语法参考官网:https://docs.docker.com/compose/compose-file/.

其实 DockerCompose 文件可以看做是将多个 docker run 命令写到一个文件,只是语法稍有差异。

参考资料

  1. https://docs.docker.com/
  2. https://www.runoob.com/docker/docker-tutorial.html
  3. https://yeasy.gitbook.io/docker_practice/
  4. https://www.bilibili.com/video/BV1CJ411T7BK