器→工具, 工具软件

Docker简明教程

钱魏Way · · 34 次浏览

在公司部署算法模型时会涉及到的Docker的使用,于是抽时间整理一些资料,供自己使用。

Docker简介

Docker是一种开源的容器化平台,它使得开发者和系统管理员可以轻松地创建、部署和运行应用程序。Docker使用容器来隔离应用程序和其环境,解决了“在我的机器上可以运行,但在其他地方不行”的问题。以下是Docker的一些核心概念和特点:

核心概念

  • 容器:容器是一个轻量级、可移植、自给自足的软件运行环境。它允许应用程序在几乎任何计算环境中运行,而与基础架构无关。容器类似于虚拟机,但更加灵活和高效。
  • 镜像:Docker镜像是一个轻量级的、独立的、可执行的软件包,包含运行应用程序所需的一切:代码、运行时、库、环境变量和配置文件。
  • Dockerfile:Dockerfile是一个文本文件,包含了创建Docker镜像的命令。开发者可以通过Dockerfile定义应用程序的环境,使其在任何地方都能以相同的方式运行。
  • Docker Hub:Docker Hub是一个服务,允许用户共享和下载Docker镜像。它是Docker生态系统的中心部分,提供了一个集中的资源交换平台。
  • Docker Compose:Docker Compose是一个工具,用于定义和运行多容器Docker应用程序。通过Compose,你可以使用一个YAML文件来配置应用程序的服务。

特点

  • 可移植性:Docker确保应用程序在任何环境中都能以同样的方式运行。
  • 轻量级:容器利用并共享主机内核,不需要像虚拟机那样为每个应用程序提供一个操作系统。
  • 微服务架构:Docker支持微服务架构,使得应用程序可以被分解为小的、独立的服务。
  • 持续集成和持续部署:Docker与现代CI/CD流程兼容,加快了软件开发和部署的速度。

使用场景

  • 开发和测试:Docker为开发和测试提供了一致的环境,确保应用程序在不同环境中的一致性。
  • 简化配置:Docker简化了配置过程,开发者只需关注容器内的应用程序。
  • 快速部署和扩展:Docker容器可以快速启动和停止,这对于自动扩展和效率至关重要。

工作流程

  • 开发:开发者在本地创建和测试容器。
  • 构建:使用Dockerfile构建镜像并存储于注册中心。
  • 运行:从注册中心拉取镜像并在生产环境中运行为容器。

Docker的这些特点使其成为当今开发和运维领域的一个重要工具,特别适用于追求快速、一致和可靠的软件部署和运行的场景。

Docker原理

Docker架构

Docker的架构是基于客户端-服务器模型的,由以下几个主要部分组成:

  • Docker Daemon(守护进程):负责管理Docker对象,如镜像、容器、网络和卷。Docker Daemon监听Docker API请求,并管理Docker服务。通常在宿主机上运行。
  • Docker Client(客户端):用户与Docker交互的主要方式。当用户使用Docker命令时,Docker Client会发送这些命令到Docker Daemon,Docker Daemon随后执行这些命令。Docker Client可以在同一系统上的Docker Daemon上运行,也可以通过配置连接到远程Docker Daemon。
  • Docker Registries(注册中心):存储Docker镜像。Docker Hub是公共的注册中心,用户可以从中拉取(pull)镜像或推送(push)镜像。注册中心既可以是公共的(如Docker Hub),也可以是私有的。

Docker对象

Docker对象是Docker技术的基本构建块,主要包括容器、镜像、网络和卷等。这些对象是使用Docker时经常互动和操作的核心元素。下面详细介绍这些对象:

容器(Containers)

  • 定义:容器是Docker的基本运行单元,是一个轻量级、可执行的独立环境,用于运行应用程序和其依赖。
  • 特点:容器是从镜像创建的实例。它们可以被启动、开始、停止、移动和删除。每个容器都是相互隔离的、保证安全的平台。

镜像(Images)

  • 定义:镜像是一个轻量级、独立的、可执行的软件包,包含运行一个应用程序所需的所有内容:代码、运行时、库、环境变量和配置文件。
  • 作用:镜像用于创建Docker容器。通常,一个镜像基于另一个镜像,但包含一些额外的定制化。

网络(Networks)

  • 定义:Docker网络是一种连接Docker容器的方式,以便它们可以互相沟通。
  • 类型:Docker提供多种网络类型(如bridge、host、overlay等),用于处理不同的网络需求。

卷(Volumes)

  • 定义:卷是Docker用于数据持久化的机制。
  • 作用:容器内的数据在默认情况下是临时的,当容器被删除时,这些数据也会丢失。卷允许你将容器内的数据持久化或共享数据。

Dockerfile

  • 定义:Dockerfile是一个文本文件,包含了一系列的指令,用来定义如何构建一个Docker镜像。
  • 作用:通过Dockerfile,可以自动化镜像的构建过程。

Docker Compose文件

  • 定义:Docker Compose文件通常是一个YAML文件,用于定义多容器Docker应用程序。
  • 作用:它允许你使用一个文件来配置应用程序的服务,使得服务的部署更加简化和可重复。

通过这些对象,Docker提供了一个完整、灵活且强大的容器化平台,可以用来运行和管理应用程序和服务。

Docker镜像

Docker注册中心

Docker注册中心(Docker Registry)是用于存储和分发Docker镜像的服务。它是Docker生态系统中的关键组件之一,让用户可以轻松地分享、存储和管理Docker镜像。

注册中心分公有与私有,最著名的公共Docker注册中心是Docker Hub。

Docker Hub

Docker Hub是Docker的官方公共注册中心,提供了一个广泛的Docker镜像库。它是Docker用户最常用的平台之一,用于发现、共享和管理Docker镜像。安装好Docker/Docker Desktop后,其registry server是默认指向https://hub.docker.com的。在国内该hub源访问速度异常慢,尤其是大一点的镜像经常出现timeout。幸运的是,我们可以通过切换至国内镜像仓库来解决这一问题。

国内镜像推荐:

  • 中科院软件所镜像站:https://docker.nju.edu.cn/

修改方法:修改配置文件daemon.json,增加或修改如下内容:

{
  "registry-mirrors": [
    "https://docker.nju.edu.cn/"
  ]
}

配置文件所在位置:

  • Linux: /etc/docker/daemon.json
  • Windows: %USERPROFILE%\.docker\daemon.json 或者 %programdata%\Docker\config\daemon.json
  • MacOS: ~/.docker/daemon.json

如果使用的Docker Desktop,那就更好办了,只需要在配置界面找到Docker Engine选项,修改之后然后点击Apply & Restart按钮,即可生效。

镜像的拉取与推送

Docker镜像的拉取(pull)和推送(push)是Docker生态系统中的两个基本操作,它们使得用户能够从Docker注册中心下载镜像以及上传镜像到注册中心。下面是这两个操作的详细介绍:

镜像拉取(Pull)

拉取操作是从Docker注册中心下载镜像到本地环境的过程。这通常发生在用户需要在本地创建容器之前。

  • 命令:使用 docker pull [镜像名称] 命令来拉取镜像。例如,docker pull nginx 将从Docker Hub拉取最新的nginx镜像。
  • 标签:可以指定镜像的标签来拉取特定版本的镜像,如 docker pull nginx:1.17。
  • 默认注册中心:如果没有指定注册中心,默认会从Docker Hub拉取镜像。
  • 过程:Docker会检查本地是否已有该镜像及其层。如果本地不存在,Docker会从注册中心下载镜像及其必要的层。

镜像推送(Push)

推送操作是将本地的Docker镜像上传到Docker注册中心的过程。这通常发生在用户构建了新镜像或修改了现有镜像后。

  • 命令:使用 docker push [镜像名称] 命令来推送镜像。例如,docker push myimage:latest 将上传名为 myimage 的镜像。
  • 标签:在推送前,需要给镜像打上标签,标签通常包含版本信息或其他描述信息。
  • 认证:在推送到私有注册中心或Docker Hub的私有存储库时,需要进行用户认证。
  • 过程:Docker会上传镜像的所有新层到注册中心。如果某些层已存在于注册中心,Docker会跳过这些层,只上传缺失的层。

镜像的构建

Docker镜像的构建是一个将应用及其依赖环境打包成一个镜像的过程。这个过程通常是通过一个名为 Dockerfile 的文本文件来完成的。

Docker镜像是由多个层(layer)构成的。每执行一条 Dockerfile 指令,就会创建一个新的层。这种层叠的方式使得镜像构建、存储和传输更为高效。共同的层可以在多个镜像间共享。在构建过程中,Docker会重用之前构建的层,如果没有发生变化的话。这大大加快了构建过程,尤其是在进行小改动或频繁构建时。

构建步骤

  • 选择基础镜像:从一个已有的镜像开始构建,通常是一个最小化的操作系统,如 ubuntu 或 alpine。
  • 安装软件和依赖:通过运行安装命令来安装所需的软件包和依赖。
  • 添加应用代码:将应用代码添加到镜像中,通常是通过 COPY 或 ADD 指令。
  • 设置环境变量:配置运行应用所需的环境变量。
  • 声明暴露端口:使用 EXPOSE 指令声明应用运行时需要暴露的端口。
  • 指定启动命令:用 CMD 或 ENTRYPOINT 指令指定容器启动时运行的命令。

构建命令

  • 命令:使用 docker build 命令来根据 Dockerfile 创建镜像。
  • 标记:通常会使用 -t 参数来为新建的镜像标记一个名称和标签。

构建示例

以下是一个简单的 Dockerfile 示例,用于构建一个运行Python Flask应用的Docker镜像。

示例 Dockerfile:

# 使用官方Python运行时作为父镜像
FROM python:3.8-slim

# 设置工作目录
WORKDIR /app

# 将当前目录内容复制到工作目录内
COPY . /app

# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 使端口80可供此容器外的环境使用
EXPOSE 80

# 定义环境变量
ENV NAME World

# 在容器启动时运行app.py
CMD ["python", "app.py"]

解释

  • FROM: 指定基础镜像。在这个例子中,我们使用Python 3.8的官方镜像。
  • WORKDIR: 设置工作目录为 /app。这是后续命令的执行目录。
  • COPY: 将当前目录下的文件复制到容器的 /app 目录。
  • RUN: 执行命令安装依赖。这里使用 pip 安装txt 文件中列出的Python包。
  • EXPOSE: 声明容器运行时需要暴露的端口。这里暴露80端口。
  • ENV: 设置一个环境变量。这里设置 NAME 为 “World”。
  • CMD: 指定容器启动时执行的命令。这里当容器启动时运行py。

构建和运行镜像

构建镜像:docker build -t my-python-app .

这个命令会根据 Dockerfile 在当前目录下构建一个新的镜像,并标记为 my-python-app。

运行容器:docker run -p 4000:80 my-python-app

这个命令启动一个新的容器,将容器的80端口映射到主机的4000端口。这样就可以通过访问主机的4000端口来访问容器中的应用。

Dockerfile命令

Dockerfile 中的命令用于指定如何构建Docker镜像,每个命令都有特定的作用和用法。以下是一些常用的Dockerfile命令:

  • FROM: 指定基础镜像,所有后续操作都基于这个镜像进行。
  • RUN: 执行命令行命令,常用于安装软件包、创建目录等。
  • CMD: 提供容器启动时执行的默认命令,只能出现一次。如果用户启动容器时指定了其他命令,CMD命令将被忽略。
  • LABEL: 添加元数据,如作者、版本、描述等。
  • EXPOSE: 声明容器运行时监听的端口。
  • ENV: 设置环境变量。
  • ADD: 复制文件、目录或远程文件URL到镜像中,也可以解压缩本地的 .tar 文件。
  • COPY: 复制新文件或目录到镜像中。
  • ENTRYPOINT: 配置容器启动时运行的命令,可以与CMD命令联合使用来设置默认参数。
  • VOLUME: 创建挂载点目录,并标记出应挂载的外部目录。
  • USER: 设置运行容器时的用户名或UID。
  • WORKDIR: 设置工作目录,如果目录不存在,Docker会自动创建它。
  • ARG: 定义构建时的变量,可以在构建时通过 docker build –build-arg <varname>=<value> 来设置。
  • ONBUILD: 设置当镜像被用作其他构建的基础时触发的命令。
  • STOPSIGNAL: 设置停止容器时发送什么系统调用信号给容器。
  • HEALTHCHECK: 告诉Docker如何测试容器是否仍在运行正常。
  • SHELL: 设置执行命令时使用的默认shell。

Docker容器管理

Docker容器管理涉及容器的创建、运行、监控、停止和删除等多种操作。以下是一些基本的Docker容器管理命令和概念:

容器的创建

docker run 是 Docker 中最常用的命令之一,用于创建并启动一个新容器。这个命令具有多种参数,可以用来定制容器的行为。以下是一些常用的 docker run 参数:

基本参数

  • -d:分离模式。在后台运行容器。
  • –name [容器名称]:为容器指定一个名称。
  • –rm:容器退出时自动清理容器文件系统。

资源分配

  • -m 或 –memory [内存限制]:限制容器使用的内存总量。
  • –cpus [CPU数]:限制容器使用的CPU数量。

网络相关

  • -p [主机端口]:[容器端口]:将容器的端口映射到主机的端口。
  • –network [网络类型]:指定容器的网络类型。比较常用的为bridge和host
    • bridge(桥接网络),当你运行一个没有指定网络的容器时,它会自动连接到这个默认的桥接网络。适用于运行独立容器或者需要通信的容器组。
    • host(主机网络),移除了网络隔离,容器直接使用宿主机的网络。适用于需要直接访问宿主机网络的容器。比如性能要求高的场景。

卷挂载

  • -v [主机目录]:[容器目录]:将主机上的目录或卷挂载到容器中。
  • –mount type=[类型],source=[源],target=[目标]:更为复杂的挂载方式。

环境变量

  • -e [环境变量] 或 –env [环境变量]:设置容器中的环境变量。

容器行为

  • –entrypoint:覆盖镜像默认的入口点。
  • –restart [重启策略]:设置容器的重启策略。

交互式操作

  • -i:交互模式。保持STDIN开放,即使没有附加。
  • -t:分配一个伪终端。

一个常见的 docker run 命令示例可能是这样的:

docker run -d -p 80:80 –name webserver -v /mydata:/data nginx

这条命令将创建并运行一个新的容器,使用名为 nginx 的镜像,以分离模式运行,容器名称设置为 webserver。它还将容器的80端口映射到主机的80端口,并将主机上的 /mydata 目录挂载到容器的 /data 目录。

docker run 命令的选项非常多,可以通过 docker run –help 查看更多选项和详细信息。

容器的管理

# 查看容器
docker ps:列出正在运行的容器。
docker ps -a:列出所有容器,包括未运行的。
# 停止和启动容器
docker stop [容器ID或名称]:停止一个正在运行的容器。
docker start [容器ID或名称]:启动一个已停止的容器。
# 删除容器
docker rm [容器ID或名称]:删除一个已停止的容器。要删除运行中的容器,可以使用 -f 选项强制删除。
# 进入容器
docker exec -it [容器ID或名称] /bin/bash:在运行中的容器内启动一个交互式的Shell。
# 查看容器日志
docker logs [容器ID或名称]:查看容器的输出,帮助调试和监控容器行为。
# 容器监控
使用 docker stats 查看容器的实时性能数据,如CPU、内存使用情况等。
# 容器间的交互
通过Docker网络功能,容器可以相互通信。使用 docker network 命令来管理容器的网络。

Docker Compose

Docker Compose 是一个用于定义和运行多容器Docker应用的工具。它使用一个配置文件来定义多个容器及其配置,使得部署和管理容器化应用变得更加简单和高效。以下是Docker Compose的主要特点和功能:

配置文件

  • docker-compose.yml:Compose使用YAML文件来配置应用服务。在这个文件中,你可以配置所需的服务、网络和卷。

一键部署

  • 启动多个容器:使用一个命令 docker-compose up,就可以同时启动配置文件中定义的所有服务。
  • 依赖管理:Compose可以管理服务之间的依赖关系,确保服务按正确的顺序启动。

服务定义

  • 服务:在Compose中,服务是应用的不同组成部分。例如,一个web应用可能包含web服务、数据库服务和缓存服务。
  • 可扩展性:可以轻松地扩展服务的实例数量。

网络和卷管理

  • 网络:Compose允许定义和使用自定义网络,便于容器间通信。
  • 卷:支持定义持久化存储卷,用于数据保存和共享。

开发环境

  • 环境隔离:每个Compose项目都在自己的环境中运行,避免不同项目间的冲突。
  • 开发效率:对于开发环境,Compose使得启动和停止服务变得非常简单,有利于开发和测试。

兼容性

  • Docker兼容性:Compose完全兼容Docker命令,易于与现有Docker工作流集成。
  • 应用场景
  • 开发和测试:非常适合本地开发和测试。
  • 小型生产部署:虽然主要用于开发和测试,但也可以用于小型的生产环境。

案例:

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

在这个例子中,定义了两个服务:web 和 redis。web 服务通过 build: . 从当前目录的 Dockerfile 构建镜像,并将容器的5000端口映射到主机的5000端口。redis 服务则直接使用了Docker Hub上的 redis:alpine 镜像。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注