Docker 详解(上)

Docker 详解(上)

1、Docker 简介

  • 什么是 Docker?

    • Docker 是一个开源的容器化技术,允许开发者和系统管理员构建、打包和运行应用程序在一个称为容器的隔离环境中。以下是 Docker 的一些关键概念和特点:

      1. 容器:容器是一种轻量级的、独立的、可执行的软件包,其中包含了运行某个应用所需的所有内容:代码、运行时、系统工具、系统库和设置。由于容器在任何环境中都以相同的方式运行,这消除了“在我的机器上可以运行”的问题。

      2. 镜像:Docker 镜像是容器运行的基础,可以看作是容器的“蓝图”。镜像是轻量级的、可执行的代码包,其中包含运行应用所需的所有内容,但与容器不同,它是不可变的。

      3. Dockerfile:Dockerfile 是一个文本文件,其中包含一系列命令,用于从基础镜像创建一个新的 Docker 镜像。

      4. Docker Hub:这是一个云端的服务,允许用户分享和下载 Docker 镜像。

      5. 隔离性:每个 Docker 容器都在自己的文件系统、网络和进程空间中运行。这为应用程序提供了隔离和安全性。

      6. 轻量性:与传统的虚拟化技术(如 VM)相比,Docker 容器非常轻量。多个容器可以共享同一台机器的操作系统内核,而不需要自己的操作系统实例。

      7. 可移植性:由于 Docker 容器包含了运行应用所需的所有内容,它们可以在任何支持 Docker 的环境中无缝运行,无论是开发者的本地机器、测试服务器还是云端生产环境。

      8. 版本控制:Docker 镜像支持版本化,这意味着你可以追踪镜像的更改,回滚到旧版本,或者在不同版本之间切换。

      9. 集成和自动化:Docker 可以与许多现代 CI/CD 工具(如 Jenkins、Travis CI 和 GitLab CI)无缝集成,从而实现容器的自动构建、测试和部署。

      简而言之,Docker 提供了一种方法,使得应用程序和其依赖环境可以作为一个整体打包,确保应用程序在从开发到生产的整个生命周期中始终如一地运行。

  • Docker 和虚拟机有什么区别?

    • Docker 和虚拟机(VM)都提供了应用程序的隔离机制,但它们在技术和哲学上有很大的区别。以下是 Docker(容器技术)和虚拟机之间的主要区别:

      1. 基础架构:

        • Docker(容器): 容器共享宿主机的操作系统内核,但运行在自己独立的用户空间中。由于它们不需要完整的操作系统,所以它们启动得更快,更轻量。

        • 虚拟机 (VM): 虚拟机包括完整的操作系统实例和模拟的硬件。这意味着它们需要更多的系统资源,启动时间也更长。

      2. 大小:

        • Docker: 通常只有几十 MB 的大小(取决于基础镜像)。

        • 虚拟机: 通常是几 GB 的大小,因为它们需要完整的操作系统。

      3. 启动时间:

        • Docker: 秒或亚秒级启动时间。

        • 虚拟机: 通常需要几分钟才能启动。

      4. 性能:

        • Docker: 由于容器直接运行在宿主机的操作系统上,并共享其内核,因此几乎没有性能开销。

        • 虚拟机: 由于硬件模拟,通常存在一定的性能开销。

      5. 管理和操作:

        • Docker: 使用 Docker CLI 或 API 进行管理。命令和操作相对简单。

        • 虚拟机: 通常使用如 VMware vCenter 或 Microsoft System Center 等工具进行管理。

      6. 隔离性:

        • Docker: 虽然容器之间是隔离的,但它们都使用同一个内核。因此,容器之间的隔离可能不如 VM 之间的隔离那么强。

        • 虚拟机: 提供强隔离,因为每个 VM 都有自己的操作系统和资源。

      7. 应用场景:

        • Docker: 非常适合微服务、持续集成/持续部署、快速部署和可扩展的应用。

        • 虚拟机: 适用于需要强隔离的环境、完整的操作系统环境或者不支持容器化的应用。

      8. 安全性:

        • Docker: 由于所有容器共享同一内核,如果内核受到攻击,所有容器都可能受到影响。

        • 虚拟机: 提供了更强的隔离,因此在某些高安全要求的环境中可能更受欢迎。

      9. 兼容性:

        • Docker: 一次构建,处处运行。应用程序和其所有依赖被打包到一个容器中,确保它可以在任何支持 Docker 的平台上运行。

        • 虚拟机: 虚拟机的迁移和兼容性可能更加复杂,因为它们包括完整的操作系统。

      总的来说,Docker 和虚拟机有其各自的优势和适用场景。选择使用哪种技术取决于具体的需求和环境。

  • 为什么要使用 Docker?

    • Docker 的出现解决了开发、测试和生产环境中一些长期存在的挑战。以下是使用 Docker 的一些主要原因和好处:

      1. 一致性:Docker 确保应用在从开发到生产的整个生命周期中始终如一地运行。这消除了“在我的机器上可以运行”这类问题。

      2. 轻量级与快速:与传统的虚拟机相比,Docker 容器非常轻量级并且启动速度快。这是因为容器共享宿主机的操作系统内核,而不需要启动完整的操作系统。

      3. 模块化与可扩展:Docker 使得应用可以被分解为单独的模块(容器)。每个模块(如数据库、后端API、前端应用)可以单独构建、部署和扩展。

      4. 版本控制:Docker 镜像支持版本化,这意味着你可以追踪容器的更改,回滚到旧版本,或者在不同版本之间切换。

      5. 资源高效:由于容器共享宿主机的内核,它们消耗的资源比虚拟机少得多,这意味着你可以在同样的硬件上运行更多的容器实例。

      6. 隔离:尽管 Docker 容器共享宿主机的内核,但每个容器都在其自己的进程、用户、文件系统和网络空间中运行,从而为应用提供了隔离。

      7. 开发与部署自动化:Docker 可以与持续集成/持续部署 (CI/CD) 工具无缝集成,从而实现应用的自动构建、测试和部署。

      8. 重用和共享:Docker Hub 和其他公共容器仓库允许开发者分享和重用其他人的容器镜像,从而加速开发和部署。

      9. 密度:与传统虚拟化相比,容器可以提供更高的实例密度。这意味着在给定的硬件上,你可以运行更多的应用实例。

      10. 跨平台和云原生:Docker 支持多种操作系统和云平台,使得应用更容易迁移到或在多个环境中部署。

      11. 安全增强:虽然容器共享同一个内核,但 Docker 提供了各种安全增强功能,如用户命名空间、只读文件系统和 AppArmor 策略,从而增强了容器的隔离和安全性。

      12. 开源:Docker 是开源的,这意味着任何人都可以贡献代码、修复错误或增加新功能。

      总的来说,Docker 提供了一种高效、快速且一致的方法来部署和运行应用,从而使得开发、测试和生产环境的工作变得更加简单和流畅。

2、Docker 安装和设置

  • 如何在 Ubuntu 上安装 Docker?

    • 在 Ubuntu 上安装 Docker 相对简单。以下是一个基本的步骤指南:

      1. 更新包索引:

        sudo apt-get update
      2. 安装所需的软件包,以确保通过 HTTPS 使用 APT:

        sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
      3. 添加 Docker 官方 GPG 密钥:

        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
      4. 添加 Docker 官方 APT 仓库:

        sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
      5. 再次更新包索引:

        sudo apt-get update
      6. 安装 Docker CE (Community Edition):

        sudo apt-get install docker-ce
      7. 验证 Docker 是否正确安装:

        sudo docker --version
      8. 为了避免每次使用 Docker 命令时都需要 sudo,你可以将你的用户名添加到 docker:

        sudo usermod -aG docker ${USER}

        注:完成上述操作后,为使组更改生效,您可能需要退出并重新登录。

      9. 启动 Docker 服务(如果尚未启动):

        sudo systemctl start docker
      10. 设置 Docker 在启动时自动运行:

        sudo systemctl enable docker

        至此,Docker 应该已经成功安装在您的 Ubuntu 机器上,并已准备好使用。您可以通过运行一个简单的测试如 sudo docker run hello-world 来验证 Docker 是否正确工作。这将从 Docker Hub 下载一个简单的测试镜像并在容器中运行它。

  • 如何在 Windows 上安装 Docker?

    • 在 Windows 上安装 Docker 有两种主要方法,具体取决于您的 Windows 版本和需求:

      1. Docker Desktop for Windows: 适用于 Windows 10 专业版、企业版或教育版。它提供了一个完整的 Docker 体验,包括 Docker Compose, Docker CLI 客户端, Docker Kitematic 等。

      2. Docker Toolbox: 为旧版本的 Windows 和不满足 Docker Desktop for Windows 系统要求的系统提供的方案。

      以下是Docker Desktop for Windows的安装指南:

      Docker Desktop for Windows:

      1. 前提条件:

        • Windows 10 64-bit: 专业版、企业版或教育版。

        • 虚拟化技术必须在 BIOS 中启用。

        • Hyper-V 功能必须启用。

      2. 安装步骤:

        1. 前往 Docker 官方网站的下载页面:www.docker.com/products/docker-des...

        2. 下载 Docker Desktop for Windows 安装程序并运行它。

        3. 在安装期间,选择是否希望使用 Windows 而不是 Linux 容器(这可以之后在 Docker 设置中更改)。

        4. 完成安装后,Docker 将自动启动。您将在系统托盘中看到 Docker 的图标。

        5. 为了验证安装,您可以打开终端或命令提示符并输入 docker --version

      Docker Toolbox:

      如果您的系统不满足 Docker Desktop for Windows 的要求,您可以选择使用 Docker Toolbox。Docker Toolbox 使用 Oracle VirtualBox,而不是 Hyper-V,来创建和管理虚拟机。

      1. 安装步骤:

        1. 前往 Docker Toolbox 的 GitHub 发布页面:github.com/docker/toolbox/releases

        2. 下载最新的 .exe 安装程序。

        3. 双击下载的 .exe 文件并遵循安装向导。

        4. 一旦安装完成,您可以从开始菜单中找到并运行 “Docker Quickstart Terminal” 以启动一个新的 Docker 环境。

      注意:不推荐在同一台机器上同时使用 Docker Desktop 和 Docker Toolbox,因为它们可能会出现冲突。

      无论您选择哪种安装方法,都可以使用 Docker CLI 在 Windows 上运行和管理容器。但是,请记住,如果您使用的是 Docker Toolbox,则需要在 “Docker Quickstart Terminal” 中运行这些命令。

  • Docker 安装后有哪些基本命令可以查看其状态和版本?

    • 安装 Docker 后,您可以使用以下基本命令来查看其状态和版本:

      1. 查看 Docker 版本:

        docker --version

        这会显示 Docker 的版本信息。如果您需要更详细的版本信息,可以使用:

        docker version

        这将展示客户端和服务器的详细版本信息。

      2. 查看 Docker 详细信息:

        docker info

        该命令提供了关于 Docker 系统的详细信息,包括正在运行的容器数量、存储、网络等相关信息。

      3. 查看 Docker 服务状态:

        对于使用 systemd 的 Linux 发行版(如 Ubuntu 16.04 及更高版本):

        sudo systemctl status docker

        对于 Windows 或使用 Docker Desktop 的 Mac 用户,您可以查看系统托盘或顶部菜单栏中的 Docker 图标来查看 Docker 是否正在运行。

      4. 启动和停止 Docker 服务:

        如果您需要启动或停止 Docker 服务,可以使用以下命令:

        • 启动 Docker:

          sudo systemctl start docker

        • 停止 Docker:

          sudo systemctl stop docker

        • 重新启动 Docker:

          sudo systemctl restart docker

      这些命令应为您提供关于 Docker 状态和版本的足够信息。当然,Docker CLI 还有许多其他命令供您使用,但这些是查看基本信息的命令。

3、基本操作

  • 如何启动和停止 Docker 服务?

    • 启动和停止 Docker 服务的方法取决于您的操作系统。以下是一些常见操作系统上启动和停止 Docker 服务的方法:

      Linux(使用 systemd,如 Ubuntu 16.04 及更高版本):

      1. 启动 Docker 服务:

        sudo systemctl start docker
      2. 停止 Docker 服务:

        sudo systemctl stop docker
      3. 重新启动 Docker 服务:

        sudo systemctl restart docker
      4. 查看 Docker 服务状态:

        sudo systemctl status docker

        Windows(使用 Docker Desktop):

      5. 通过开始菜单或桌面图标启动 Docker Desktop。

      6. 为了停止 Docker Desktop,您可以右键点击系统托盘中的 Docker 图标并选择 “Quit Docker Desktop”。

      macOS(使用 Docker Desktop):

      1. 通过应用程序文件夹或 Launchpad 启动 Docker Desktop。

      2. 要停止 Docker Desktop,在顶部菜单栏上的 Docker 图标上点击并选择 “Quit Docker Desktop”。

      对于那些不使用 Docker Desktop 而使用 Docker Toolbox 或其他设置的用户,启动和停止 Docker 可能需要不同的步骤。如果您使用的是 Docker Toolbox,您通常会使用 “Docker Quickstart Terminal” 启动 Docker 环境。

  • 如何下载 Docker 镜像?

    • 下载 Docker 镜像的最常见方式是使用 docker pull 命令从 Docker Hub(或其他 Docker 注册表)下载。Docker Hub 是最大的公共 Docker 容器镜像库,拥有大量的官方和社区创建的镜像。

      以下是使用 docker pull 命令下载 Docker 镜像的步骤:

      1. 打开终端或命令行工具

      2. 使用以下格式的命令下载所需的镜像:

        docker pull [IMAGE_NAME]:[TAG]

        其中,[IMAGE_NAME] 是您要下载的镜像的名称,[TAG] 是特定的版本标签。如果您不指定标签,Docker 通常会默认下载 latest 标签的镜像。

      例如:

      • 要下载最新版本的 Ubuntu 镜像,您可以执行:
        docker pull ubuntu:latest
      • 要下载特定版本的 Ubuntu(例如 18.04),您可以执行:
        docker pull ubuntu:18.04
      1. 命令执行后,Docker 将开始从 Docker Hub 下载指定的镜像。下载过程中,它会显示每一层的下载状态。

      2. 下载完成后,您可以使用以下命令查看本地可用的 Docker 镜像

        docker images

        请注意,docker pull 默认从 Docker Hub 下载镜像。如果您需要从其他注册表下载镜像(例如 GitLab, Quay.io, Google Container Registry 等),您需要指定完整的注册表 URL。例如:

        docker pull quay.io/user/image_name:tag_name

        此外,确保您只从已知和可信的来源下载镜像,因为恶意的 Docker 镜像可能包含有害的代码。

  • 如何运行一个 Docker 容器?

    • 运行 Docker 容器的基本命令是 docker run. 使用这个命令,您可以基于一个镜像启动一个容器。以下是如何运行一个 Docker 容器的基本步骤:

      1. 打开终端或命令行工具

      2. 使用 docker run 命令来启动一个容器:

        docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG…]

        • [OPTIONS]:可选的标志,例如 -d (后台运行), -p (端口映射), -v (挂载卷) 等。

        • IMAGE[:TAG|@DIGEST]:您想要运行的 Docker 镜像的名称,可选地带一个标签或摘要。

        • [COMMAND] [ARG...]:可选地,您可以覆盖镜像的默认命令。

      示例

      1. 运行一个简单的 echo 命令在 alpine Linux 容器中

        docker run alpine echo "Hello from Docker!"
      2. 交互式地运行一个 ubuntu 容器并进入 bash shell

        docker run -it ubuntu /bin/bash

        这里,-i 表示交互模式,-t 为容器分配一个伪 TTY,这使我们能够与容器交互。

      3. 在后台运行一个 nginx web 服务器并映射端口

        docker run -d -p 8080:80 nginx

        这里,-d 表示后台模式,-p 用于映射宿主机的端口 8080 到容器的端口 80。

      4. 查看正在运行的容器: 使用以下命令可以查看当前正在运行的容器:

        docker ps

        如果您还想看到已经停止的容器,可以使用:

        docker ps -a
      5. 停止容器: 如果您需要停止一个正在运行的容器,可以使用:

        docker stop CONTAINER_ID_OR_NAME

        这里的 CONTAINER_ID_OR_NAME 可以是容器的 ID 或者名称。

      这只是 docker run 的基本使用。它有许多选项和变化,允许您设置环境变量,挂载卷,设置网络选项等等。您可以通过 docker run --help 查看所有可用的选项。

  • 如何查看正在运行的容器?

    • 要查看当前正在运行的 Docker 容器,您可以使用 docker ps 命令。

      命令与输出解释

      1. 查看正在运行的容器:

        docker ps

        当您执行这个命令时,它将列出所有当前正在运行的容器及其相关信息,如容器 ID、命令、创建时间、状态、端口信息等。

      2. 查看所有容器(包括已停止的):

        docker ps -a

        使用 -a--all 选项,您可以查看所有容器,无论它们是否正在运行。

      输出列的简要说明:

      • CONTAINER ID: 容器的唯一标识符。

      • IMAGE: 容器基于的镜像。

      • COMMAND: 容器启动时运行的命令。

      • CREATED: 容器创建的时间。

      • STATUS: 容器的状态(如正在运行、已退出、已暂停等)。

      • PORTS: 任何开放的网络端口及其在主机上的映射。

      • NAMES: Docker 为容器分配的名称。您也可以在创建容器时使用 --name 选项指定一个名称。

      这些命令为您提供了一个快速查看正在运行的容器及其状态的方法。如果您需要更详细的容器信息,可以考虑使用 docker inspect 命令,它返回关于容器的详细信息。

4、Dockerfile 和容器构建

  • 什么是 Dockerfile?

    • Dockerfile 是一个文本文件,其中包含了一系列的指令和命令,用于定义如何构建一个 Docker 镜像。通过使用 Docker 的构建工具和这个 Dockerfile,用户可以自动化镜像的创建过程,确保它是可重复且一致的。

      以下是一个简单的 Dockerfile 示例,它基于 Ubuntu 镜像,安装了 Python,并创建了一个新目录:

      使用官方的 ubuntu 镜像作为基础

      FROM ubuntu:latest

      设置维护者信息

      LABEL maintainer="youremail@example.com"

      更新软件包列表并安装 python

      RUN apt-get update && apt-get install -y python3

      设置工作目录

      WORKDIR /app

      创建一个新目录

      RUN mkdir mynewdir

      这只是一个非常基本的例子。实际的 Dockerfile 可能会包含更复杂的指令和命令,以满足特定应用程序或服务的需求。

      常见的 Dockerfile 指令

      • FROM: 定义基础镜像。每个 Dockerfile 的开始都必须是一个 FROM 指令。

      • LABEL: 提供元数据,如维护者的信息。

      • RUN: 执行命令并创建新的镜像层。它通常用于安装软件包。

      • WORKDIR: 设置工作目录。后续的指令(如 RUN, CMD, ENTRYPOINT)都会在这个目录中执行。

      • CMD: 提供容器的默认执行命令。只能有一个 CMD 指令,如果有多个,只有最后一个会被执行。

      • ENTRYPOINT: 允许你配置容器作为可执行程序运行。与 CMD 类似,但更为强大。

      • COPYADD: 将文件或目录从本地主机复制/添加到容器中。

      • EXPOSE: 声明容器内部服务使用的端口。

      • ENV: 设置环境变量。

      • VOLUME: 创建挂载点,用于挂载文件或目录。

      构建由 Dockerfile 定义的镜像时,你会使用 docker build 命令:

      docker build -t your_image_name:tag_name .

      . 表示当前目录,-t 允许你为新镜像命名并(可选地)指定一个标签。

      使用 Dockerfile 的主要好处是,您可以确保镜像的构建过程是可重复且一致的,这对于持续集成和持续部署流程非常重要。

    • 扩展内容 - Dockerfile与Shell脚本之间有哪些异同?

      • Dockerfile 和 Shell 脚本都是自动化的工具,用于执行一系列的命令,但它们的目的、结构和使用场景有所不同。以下是它们之间的主要异同点:

        相同点:

        1. 自动化:两者都用于自动执行一系列命令,以消除手动操作的需要。

        2. 可读性:为了使其他开发者能够理解和维护,两者都应写得尽可能清晰。

        3. 命令序列:都可以用来执行多个命令,通常按顺序。

        不同点:

        1. 目的

          • Dockerfile:其主要目的是构建 Docker 镜像。这个镜像可以用来启动容器,容器中会包含所需的应用程序和环境。

          • Shell 脚本:它是一个广泛用途的工具,用于自动化一系列的命令。它可以用于安装软件、管理系统任务、处理文件和数据等。

        2. 结构

          • Dockerfile:它有一套明确定义的指令集,如 FROM, RUN, CMD, COPY 等。

          • Shell 脚本:它可以包含任何可以在命令行上运行的命令,并且有更强大的逻辑和流程控制功能(如循环、条件语句等)。

          • Dockerfile:每个 RUN, COPYADD 指令都会创建 Docker 镜像的一个新层。这有助于缓存和重用数据,但也需要关注每层的大小。

          • Shell 脚本:执行的命令没有分层的概念。它仅按顺序执行命令。

        3. 上下文

          • Dockerfile:在构建过程中,Docker 使用所谓的“构建上下文”(通常是 Dockerfile 所在的目录及其子目录)。COPYADD 指令只能访问此上下文中的文件。

          • Shell 脚本:没有这样的上下文限制,可以访问运行脚本的系统上的任何文件和目录。

        4. 运行环境

          • Dockerfile:它构建的命令是在一个临时容器内部执行的,这个容器是基于 FROM 指令指定的基础镜像创建的。

          • Shell 脚本:在它被执行的机器上的常规环境中运行,不受容器的约束。

        5. 状态持久性

          • Dockerfile:每个指令的执行状态都被保存为新的镜像层,这些层可以被后续指令使用或缓存。

          • Shell 脚本:通常不保存其中间状态(除非显式编写脚本来这么做)。

        总结,尽管 Dockerfile 和 Shell 脚本都可以执行命令,但它们是为不同的目的和上下文设计的。Dockerfile 专门用于构建 Docker 镜像,而 Shell 脚本为广泛的任务提供了更大的灵活性和控制。

  • 如何编写一个 Dockerfile?

    • 编写一个 Dockerfile 涉及到为应用程序或服务定义一个明确、高效和可重复的镜像构建过程。以下是编写一个 Dockerfile 的基本步骤:

      1. 定义基础镜像

      使用 FROM 指令来定义你的镜像基于哪个基础镜像。例如,如果你的应用程序是一个 Python 应用,你可能会选择一个 Python 基础镜像。

      FROM python:3.9

      2. 设置元数据

      使用 LABEL 指令为你的镜像添加元数据,例如维护者的信息。

      LABEL maintainer="your-email@example.com"

      3. 运行必要的命令

      使用 RUN 指令来安装必要的依赖和设置环境。例如,你可能需要安装一些软件包或 Python 库。

      RUN pip install flask numpy

      4. 添加文件和目录

      使用 ADDCOPY 指令将代码和资源从你的主机复制到镜像中。COPY 命令是推荐的方式,因为它更简单、透明。

      COPY ./app /app

      5. 设置工作目录

      使用 WORKDIR 指令来设置后续指令的工作目录。

      WORKDIR /app

      6. 设置环境变量

      如果你的应用程序需要某些环境变量来运行,你可以使用 ENV 指令设置它们。

      ENV FLASK_ENV=production

      7. 暴露必要的端口

      如果你的应用程序是一个网络服务,你需要使用 EXPOSE 指令声明它会在哪些端口上监听。

      EXPOSE 5000

      8. 定义默认命令

      使用 CMD 指令定义容器启动时默认执行的命令。

      CMD ["flask", "run"]

      你也可以使用 ENTRYPOINT 指令,但它的行为略有不同。ENTRYPOINT 定义了容器启动时始终会执行的命令,而 CMD 则提供了默认的参数,但它们可以被 docker run 命令行参数覆盖。

      9. 构建镜像

      保存你的 Dockerfile,然后在同一目录中运行以下命令来构建你的 Docker 镜像:

      docker build -t your-image-name:your-tag .

      其中 your-image-name 是你为新镜像选择的名称,your-tag 是你为它选择的标签(例如 latest),. 指的是 Docker 构建上下文的路径(在这种情况下,是当前目录)。

      以上只是一个简化的 Dockerfile 示例。实际上,Dockerfile 可以包含更多的指令和选项,使你能够创建高度定制化的 Docker 镜像。

  • 如何使用 Dockerfile 构建自己的镜像?

    • 使用 Dockerfile 构建自己的镜像是一个相对简单的过程。以下是具体的步骤:

      1. 创建 Dockerfile

      首先,在一个目录中创建一个名为 Dockerfile 的文件。这个目录也应该包含你的应用代码和其他任何你想包含在 Docker 镜像中的文件。

      例如:

      /my-app-directory
       ├── Dockerfile
       ├── app.py
       └── requirements.txt

      2. 编写 Dockerfile

      打开 Dockerfile 文件并开始编写指令。以下是一个简单的 Python Flask 应用的例子:

      使用官方 Python 镜像作为基础镜像

      FROM python:3.9-slim

      设置工作目录

      WORKDIR /usr/src/app

      将当前目录的内容复制到容器的工作目录中

      COPY . .

      安装应用依赖

      RUN pip install --no-cache-dir -r requirements.txt

      声明应用监听的端口

      EXPOSE 5000

      定义容器启动时运行的命令

      CMD ["python", "app.py"]

      3. 构建镜像

      在包含 Dockerfile 的目录中打开终端或命令提示符,并使用 docker build 命令构建镜像。你需要为你的镜像命名,并可以给它一个标签。以下命令将镜像命名为 my-flask-app 并标记为 v1

      docker build -t my-flask-app:v1 .

      注意命令末尾的 . ,它表示 Docker 构建上下文的路径(在这种情况下,是当前目录)。

      4. 验证镜像

      构建完成后,可以使用 docker images 查看所有可用的镜像,你应该能在列表中看到你刚才构建的 my-flask-app 镜像。

      docker images

      5. 运行镜像

      要运行你的镜像,可以使用 docker run 命令:

      docker run -p 5000:5000 my-flask-app:v1

      上述命令将容器的 5000 端口映射到主机的 5000 端口,这样你就可以在主机的浏览器或其他工具中访问应用。

      这样,你就使用 Dockerfile 构建并运行了自己的 Docker 镜像!

5、Docker 网络

  • Docker 容器是如何进行网络通信的?

    • Docker 为容器提供了多种网络模式来支持不同的网络通信场景。以下是 Docker 网络的一些关键概念和模式:

      1. Docker 网络模式

      • Bridge(桥接)模式:这是默认的网络模式。在这种模式下,Docker 守护进程会创建一个私有的虚拟网络桥,容器会连接到这个虚拟桥。然后,所有出站连接都似乎是从这个桥发出的,它允许容器访问外部世界。但是,其他计算机、包括宿主机,都无法直接访问该容器,除非显式地为容器暴露端口。

      • Host 模式:在这种模式下,容器共享宿主机的网络命名空间,这意味着它共享宿主机的IP地址和端口范围。容器将能够直接使用主机的网络,没有任何隔离。

      • None 模式:此模式会为容器创建一个特定的网络命名空间,但不为它配置任何网络接口、IP、路由等。这是完全隔离的网络。

      • Overlay(叠加)模式:这是为 Docker 集群(如 Docker Swarm)设计的网络模式。在 Swarm 模式中,多个 Docker 守护进程可以连接到同一个 Swarm 并协调服务。Overlay 网络允许在这些守护进程上运行的容器之间进行网络通信,即使它们在不同的主机上。

      • Macvlan 模式:这种模式允许你为容器分配一个 MAC 地址,因此它似乎是在宿主机的物理网络上的另一台物理设备。

      2. 端口映射

      为了使外部系统可以访问 Bridge 模式下的容器,Docker 提供了端口映射功能。使用 -p 标志,你可以指定如何将宿主机的端口映射到容器的端口。例如,你可能将宿主机的 8080 端口映射到容器的 80 端口。

      3. Docker Compose 和网络

      Docker Compose 是一个工具,用于定义和运行使用多个容器的应用。当你使用 Compose 定义了多个服务时,它们默认会被放在同一个网络上,因此可以互相访问。

      4. 自定义网络

      Docker 允许你创建自定义网络,为你的容器提供更细粒度的网络配置。例如,你可以创建一个新的桥接网络,并为它指定一个特定的 IP 地址范围。

      5. 网络驱动

      Docker 使用插件式的网络驱动架构,允许第三方为 Docker 创建新的网络驱动。

      总体而言,Docker 提供了丰富的网络功能,使得容器之间和容器与外部世界之间的通信变得灵活和简单。

  • 什么是 Docker 网络桥接模式?

    • Docker 的网络桥接模式是 Docker 容器网络的默认模式。当 Docker 守护进程启动时,它会在主机上创建一个名为 docker0 的虚拟以太网桥。当创建一个新的容器时,Docker 会为该容器分配一个虚拟以太网接口,与 docker0 桥接,并为这个接口分配一个私有 IP 地址。

      以下是关于 Docker 桥接模式的一些关键点:

      1. 私有内部网络:在桥接模式下,每个容器都有其自己的私有、内部 IP 地址,并且这些地址只能从主机或其他容器访问。这些容器默认不能直接从外部网络访问。

      2. 端口映射:为了从主机或外部网络访问容器中的应用,必须显式地映射容器的端口到主机的端口。例如,如果你有一个在容器的80端口运行的web服务器,你可以将它映射到主机的8080端口。然后,通过访问主机的8080端口,你可以访问容器中的web服务器。

      3. 网络隔离:由于容器在其自己的网络命名空间中运行,桥接模式为每个容器提供了网络隔离。即使容器在同一个 docker0 桥上,它们也只能通过IP地址进行通信,除非它们显式地建立了网络连接。

      4. 与主机通信:桥接模式下的容器可以与宿主机通信。这是通过路由规则实现的,该规则允许从容器到 docker0 桥,然后到主机的其他网络接口。

      5. 性能:桥接模式的性能通常足够大多数应用程序。然而,在某些高性能需求场景中,可能需要考虑其他网络解决方案,例如 host 模式。

      6. 自定义桥接网络:除了默认的 docker0 桥,Docker 还允许你创建自定义的桥接网络。这在需要对容器间的通信进行更细粒度控制时是非常有用的。

      总的来说,桥接模式是 Docker 容器网络的基础,为容器提供了一个简单、隔离和私有的通信方式。然而,对于更复杂的网络需求,Docker 还提供了其他的网络模式和工具。

  • 如何连接多个 Docker 容器?

    • 连接多个 Docker 容器的方式主要是通过 Docker 的网络功能来实现的。以下是连接多个容器的常见方法:

      1. Docker 用户定义的桥接网络

      默认的桥接模式虽然有用,但有时你可能需要更精细的网络控制或更易于发现的容器名称。用户定义的桥接网络提供了自动的 DNS 解析,使容器可以通过其容器名称作为主机名进行互相访问。

      创建用户定义的桥接网络:

      docker network create my_bridge_network

      然后启动容器时将它们连接到这个网络:

      docker run –network=my_bridge_network –name container1 -d image1
      docker run –network=my_bridge_network –name container2 -d image2

      在这种设置中,container1 可以通过 container2 的名称访问 container2,反之亦然。

      2. Docker 链接(已被视为过时)

      在 Docker 的早期版本中,使用 --link 选项来连接容器是一种常见的方法。但这已被视为过时,不推荐使用,因为用户定义的网络提供了更多功能和灵活性。

      3. Docker Compose

      Docker Compose 是一个工具,用于定义和运行多容器 Docker 应用程序。使用 Compose,你可以在一个 docker-compose.yml 文件中定义你的网络和服务,然后使用一个命令将所有服务启动和连接起来。

      一个简单的 docker-compose.yml 例子:

      version: '3'
      ​
      services:
       webapp:
       image: my-web-app
       networks:
       - mynetwork
      ​
       database:
       image: my-database
       networks:
       - mynetwork
      ​
      networks:
       mynetwork:

      在这个设置中,webappdatabase 服务会自动在同一个网络 mynetwork 中启动并可以互相通信。

      4. Overlay 网络

      在使用 Docker Swarm 或 Kubernetes 这样的集群解决方案时,你可能会需要跨多个宿主机连接容器。Overlay 网络允许在集群中的不同主机上运行的容器进行通信。

      5. 其他网络模式

      除了上述的方法,Docker 还支持其他的网络模式,例如 host 模式、macvlan 和 none,但这些通常不是用来直接连接多个容器的。

      总的来说,如果你的目标是在单个宿主机上连接多个容器,最好的选择通常是使用用户定义的桥接网络或 Docker Compose。如果你正在使用集群,则可能需要考虑使用 Overlay 网络或其他集群特定的解决方案。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!