初学者的Docker指南:容器实用指南

当我开始使用Docker时,我迅速意识到它是多么强大。想象一下,您可以在几分钟内设置开发环境,而不是几个小时,或者在不同的机器上运行应用程序,而不再有经典的“它在我的机器上可以运行”的问题。

Docker通过将应用程序打包成轻量级、可移植的容器,简化了我们构建、交付和运行应用程序的方式。无论您是开发人员、数据科学家还是系统管理员,掌握Docker都可以为您节省麻烦,并使您的工作流程更加高效。

在本教程中,我将带您了解基础知识——安装Docker、理解关键概念以及运行您的第一个容器化应用程序。到最后,您不仅会知道Docker是如何工作的,还会获得实际操作经验,为更高级的主题打下坚实的基础。让我们开始吧!

什么是Docker?

Docker是一个开源的容器化平台,通过将软件及其依赖项打包成一个标准化的单元——容器,简化了应用程序的部署。与传统的虚拟机不同,Docker容器共享主机操作系统内核,使它们更加高效和轻量。

容器确保应用程序在开发、测试和生产环境中以相同方式运行。这减少了兼容性问题,并增强了在各种平台之间的可移植性。由于其灵活性和可扩展性,Docker 已成为现代 DevOps 和云原生开发工作流程中的重要工具。

Docker 官方标志。

安装 Docker

Docker 可以在各种操作系统上安装,包括 Windows、macOS 和 Linux。尽管核心功能在所有平台上保持一致,但安装过程根据系统略有不同。以下是针对您选择的操作系统安装 Docker 的分步说明。

在 Windows 上安装 Docker

  1. 下载 适用于 Windows 的 Docker Desktop

下载适用于 Windows 的 Docker Desktop 安装程序

  1. 运行安装程序并按照设置说明进行操作。

在Windows上安装Docker Desktop

  1. 如果提示,请启用WSL 2集成。
  2. 在PowerShell中运行docker –version以验证安装。

通过PowerShell检查安装后的Docker版本

5. 从运行菜单启动Docker Desktop应用程序。

在Windows上启动Docker Desktop应用程序

在macOS上安装Docker

  1. 下载Docker Desktop for Mac

下载Mac的Docker Desktop安装程序

  1. 打开下载的.dmg文件并将Docker拖动到应用程序文件夹中。
  2. 启动Docker并完成设置。
  3. 在终端中使用docker –version命令验证安装。

在 Linux(Ubuntu)上安装 Docker

  1. 更新软件包列表:sudo apt update
  2. 安装依赖项:sudo apt 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 的存储库:sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  5. 安装 Docker:sudo apt install docker-ce
  6. 验证安装:docker –version

基本 Docker 概念

现在您已经安装了 Docker,您可能迫不及待地想要开始运行容器。但在我们开始之前,了解 Docker 工作的一些关键概念非常重要。这些概念将帮助您更有效地使用 Docker,并避免常见的初学者陷阱。

Docker 的核心是 镜像,它们作为容器的蓝图;容器,是这些镜像的运行实例;以及 Docker Hub,一个用于分享和管理镜像的集中式仓库。

让我们更详细地探讨这些概念。

Docker镜像

Docker镜像是容器的基本构建块。它们是不可变的只读模板,包含运行应用程序所需的一切,包括操作系统、应用程序代码、运行时和依赖项。

镜像是使用Dockerfile构建的,它定义了逐层创建镜像的指令。

镜像可以存储在容器注册表中,并且可以从中检索,比如Docker Hub。

以下是一些处理镜像的示例命令:

  • docker pull nginx:从Docker Hub获取最新的Nginx镜像。
  • docker images:列出本地计算机上所有可用的镜像。
  • docker rmi nginx:从本地计算机中删除一个镜像。

Docker容器

Docker容器是Docker镜像的运行实例。容器提供了一个隔离的运行环境,应用程序可以在其中运行而不会相互干扰或影响主机系统。每个容器都有自己的文件系统、网络和进程空间,但共享主机内核。

容器遵循一个简单的生命周期,涉及创建、启动、停止和删除。以下是常见容器管理命令的详细介绍:

  1. 创建一个容器: docker createdocker run
  2. 启动一个容器: docker start
  3. 停止一个容器: docker stop
  4. 重新启动一个容器: docker restart
  5. 删除一个容器: docker rm

让我们看一个实际的例子。以下命令在后台模式下运行一个 Nginx 容器,将容器内的端口 80 映射到主机的端口 8080:

docker run -d -p 8080:80 nginx

运行此命令后,Docker 将拉取 Nginx 镜像(如果尚未可用),创建一个容器并启动它。

要检查所有正在运行和停止的容器:

docker ps -a

这将显示所有容器的列表以及它们的状态和分配端口等详细信息。

Docker Hub

Docker Hub是一个基于云的注册服务,用于查找、存储和分发容器镜像。用户可以将自定义镜像推送到 Docker Hub,并选择公开或私下共享它们。

以下是一些与 Docker Hub 交互的命令:

  • docker login:与 Docker Hub 进行身份验证。
  • docker push my-image:将自定义构建的镜像上传到 Docker Hub。
  • docker search ubuntu:搜索官方和社区镜像。
  • docker pull ubuntu:从 Docker Hub 下载 Ubuntu 镜像。

对容器化不太熟悉?通过容器化与虚拟化概念课程打下坚实基础。

运行您的第一个 Docker 容器

现在我们已经涵盖了 Docker 的核心概念,是时候将它们付诸实践了!让我们开始运行第一个容器,以确保 Docker 正确安装并按预期工作。

要测试您的 Docker 安装,请打开 PowerShell(Windows)或终端(Mac 和 Linux),并运行:

docker run hello-world

这将从 DockerHub 拉取hello-world镜像并在容器中运行它。

Docker hello-world 镜像示例

现在,让我们更进一步,运行一个真实的应用程序——Nginx 网络服务器。执行以下命令:

docker run -d -p 8080:80 nginx

上述命令执行以下操作:

  • -d标志使容器在分离模式下运行,这意味着它在后台运行。
  • -p 8080:80标志将容器内的 80 端口映射到您本地机器的 8080 端口,从而允许您访问网络服务器。

命令成功运行后,打开浏览器并访问:http://localhost:8080

在 localhost:8080 访问网络服务器

您应该会看到默认的 Nginx 欢迎页面,确认您的网络服务器正在容器内运行!

您还会在 Docker Desktop 中看到一个正在运行的容器:

Nginx 容器正在 8080 端口上运行

构建您的第一个 Docker 镜像

到目前为止,我们一直在使用来自 Docker Hub 的预构建镜像。但是如果你需要一个针对你的应用程序定制的环境呢?这就是构建你自己的 Docker 镜像的意义所在。

创建 Docker 镜像涉及编写一个 Dockerfile,这是一个自动化构建镜像的脚本。这确保了在不同环境之间的一致性和可移植性。一旦镜像构建完成,它可以作为容器运行,以在隔离的环境中执行应用程序。

在这一部分中,我们将学习编写 Dockerfile 的基本知识、构建自定义镜像以及将其作为容器运行。

Dockerfile 基础知识

A Dockerfile 是一个包含一系列指令的脚本,用于定义如何构建 Docker 镜像。它自动化了镜像创建过程,确保环境之间的一致性。每条指令在 Dockerfile 中都会在镜像中创建一个新的层。以下是一个简单的 Python Flask 应用程序的示例 Dockerfile 的分解:

# 包含 Python 运行时的基础镜像 FROM python:3.9 # 设置容器内的工作目录 WORKDIR /app # 将应用程序文件从主机复制到容器 COPY . /app # 安装 requirements.txt 中列出的依赖项 RUN pip install -r requirements.txt # 定义容器启动时运行 Flask 应用程序的命令 CMD ["python", "app.py"]

在上述命令中:

  • -v my-volume:/app/datamy-volume 存储挂载到容器内的 /app/data 目录。
  • 任何存储在 /app/data 中的数据,即使容器停止或被删除也会保持不变。

对上述 Dockerfile 的分解:

  • FROM python:3.9: 指定具有预安装Python 3.9的基础镜像。
  • WORKDIR /app: 将/app设置为容器内的工作目录。
  • COPY . /app: 将所有文件从主机的当前目录复制到容器中的/app
  • RUN pip install -r requirements.txt: 在容器内安装所有必需的依赖项。
  • CMD ["python", "app.py"]: 定义容器启动时要执行的命令。

构建和运行镜像

一旦定义了Dockerfile,就可以使用以下命令构建和运行镜像:

步骤 1:构建镜像

docker build -t my-flask-app .

上述命令:

  • 将当前目录(.)作为构建上下文。
  • 读取Dockerfile并执行其指令。
  • 将生成的镜像标记(-t)为my-flask-app

步骤 2:将镜像作为容器运行

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

上述命令:

  • 以分离模式运行容器(-d)。
  • 将容器内部端口5000映射到主机的端口5000(-p 5000:5000)。

运行后,您可以通过浏览器访问Flask应用程序,网址为http://localhost:5000

Docker卷和持久性

默认情况下,Docker容器内的数据是临时的——一旦容器停止或被删除,数据就会消失。为了跨容器重启持久化数据并在多个容器之间共享数据,Docker提供了卷,这是一种管理持久存储的内置机制。

与将数据存储在容器的文件系统内不同,卷由Docker单独管理,使其更高效,灵活且更易于备份。

在接下来的部分中,我们将探讨如何创建和使用Docker卷以确保容器中的数据持久性。

创建和使用Docker卷

第1步:创建卷

在使用卷之前,我们需要创建一个。运行以下命令:

docker volume create my-volume

这将创建一个名为my-volume的卷,Docker将单独管理它,而不与任何特定容器关联。第2步:在容器中使用卷

现在,让我们启动一个容器并在其中挂载卷:

docker run -d -v my-volume:/app/data my-app

在上述命令中:

  • -v my-volume:/app/datamy-volume 存储挂载到容器内的 /app/data 目录。
  • 存储在 /app/data 中的任何数据即使在容器停止或被删除后也会持久保留。

用于多容器应用的 Docker Compose

到目前为止,我们一直在使用单容器应用,但许多现实世界的应用需要多个容器协同工作。例如,一个 Web 应用可能需要一个后端服务器,一个数据库和一个缓存层——每个都在自己的容器中运行。手动使用单独的 docker run 命令管理这些容器很快就会变得乏味。

这就是 Docker Compose 的用武之地。

什么是 Docker Compose?

Docker Compose 是一个简化多容器应用程序管理的工具。您可以通过定义一个 docker-compose.yml 文件来定义整个应用程序堆栈,并使用单个命令部署,而不是运行多个 docker run 命令。

编写 Docker Compose 文件

现在,让我们创建一个真实世界的示例——一个简单的连接到 MongoDB 数据库 的 Node.js 应用程序。我们将在一个 docker-compose.yml 文件中定义它们,而不是分别管理这两个容器。

以下是我们在 Docker Compose 中定义多容器设置的方式:

version: '3' services: web: build: . ports: - "3000:3000" depends_on: - database database: image: mongo volumes: - db-data:/data/db volumes: db-data:

解析上面的文件:

  • version: '3':指定 Docker Compose 版本。
  • services::定义单独的服务(容器)。
  • web::定义 Node.js web 应用程序。
  • database::定义 MongoDB 数据库容器。
  • volumes::为 MongoDB 数据持久性创建一个命名卷(db-data)。

运行多容器应用程序

一旦 docker-compose.yml 文件准备好,我们可以使用单个命令启动整个应用程序堆栈:

docker-compose up -d

上一个命令以分离模式(-d)启动 web 和数据库容器。

要停止所有服务,请使用:

docker-compose down

这将停止并移除所有容器,同时保留卷和网络设置。

Docker 网络基础知识

到目前为止,我们专注于运行容器和管理存储,但当容器需要相互通信时会发生什么?在大多数实际应用中,容器不是孤立运行的,它们需要交换数据,无论是 Web 服务器与数据库通信,还是微服务之间互相交互。

Docker 提供了一系列网络选项,以适应不同的使用情况,从隔离的内部网络到外部可访问的配置。

准备提升您的 Docker 技能了吗?立即报名 中级 Docker,探索多阶段构建、高级网络等内容!

什么是 Docker 网络?

Docker 网络是一项内置功能,允许容器相互通信,无论是在同一主机上还是在分布式环境中跨多个主机。它提供了适用于不同部署场景的网络隔离、分段和连接选项。

Docker 支持多种网络类型,每种类型都适用于不同的用例:

  • 桥接(默认):同一主机上的容器通过内部虚拟网络进行通信。每个容器在桥接网络中都有自己的私有 IP 地址,它们可以通过容器名称相互访问。
    • 示例:docker network create my-bridge-network
    • 适用于在单个主机上运行多个容器,这些容器需要安全通信而不暴露服务给外部。
  • 主机:容器共享主机的网络堆栈,并直接使用主机的IP地址和端口。
    • 示例:docker run --network host nginx
    • 在需要高性能且不需要网络隔离的情况下非常有用,例如运行监控代理或低延迟应用程序。
  • 叠加:通过创建分布式网络,在不同主机上启用容器通信。
    • 示例:docker network create --driver overlay my-overlay-network
    • 适用于像Docker Swarm这样的编排部署,其中服务跨越多个节点。
  • Macvlan:为每个容器分配一个唯一的MAC地址,使其在网络上看起来像一个物理设备。
    • 示例: docker network create -d macvlan --subnet=192.168.1.0/24 my-macvlan
    • 用于容器需要直接网络访问时,比如集成传统系统或与物理网络交互时。

在自定义网络上运行容器

让我们来看看如何设置和使用自定义桥接网络以进行容器通信。

步骤1:创建自定义网络

在运行容器之前,我们首先需要创建一个专用网络:

docker network create my-custom-network

此命令创建一个隔离网络,容器可以加入以进行容器间通信。

步骤2:在网络上运行容器

现在,让我们启动两个容器并将它们连接到我们新创建的网络:

docker run -d --network my-custom-network --name app1 my-app docker run -d --network my-custom-network --name app2 my-app
  • 使用--network my-custom-network标志将容器连接到指定的网络。
  • 使用--name标志分配一个唯一的容器名称,使得更容易引用。

app11app2现在可以使用它们的容器名称进行通信。您可以在其中一个容器内部使用ping命令来测试连接性:

docker exec -it app1 ping app2

如果一切设置正确,您将看到一个确认容器可以通信的响应。

检查Docker网络

要验证网络配置和连接的容器,请使用:

docker network inspect my-custom-network

此命令提供有关网络的详细信息,包括IP范围、连接的容器和配置。

暴露和发布端口

运行需要从外部访问的容器时,可以暴露特定端口。

例如,要运行一个Nginx Web服务器并将其暴露在本地机器的8080端口上,请使用:

docker run -d -p 8080:80 nginx

这将容器内部的80端口映射到主机上的8080端口,使服务可以通过http://localhost:8080访问。

Docker网络的最佳实践

  • 使用自定义网络:避免在生产部署中使用默认的桥接网络,以减少容器之间的意外访问。
  • 利用基于DNS的发现:不要硬编码IP地址,使用容器名称实现动态服务发现。
  • 限制外部暴露:使用防火墙或网络策略控制服务访问。
  • 监控流量:使用诸如docker network inspect、Wireshark或Prometheus等工具分析网络流量并检测异常。
  • 优化覆盖网络:如果在分布式环境中部署,通过利用主机本地路由选项来调整覆盖网络,以减少延迟。

Docker最佳实践和下一步

现在您已经学习了Docker的基本知识,是时候提升您的技能并采用最佳实践,以帮助您构建安全、高效和易于维护的容器化应用程序。

以下最佳实践将帮助您简化Docker工作流程并避免常见陷阱。

  • 使用官方基础镜像: 始终优先选择官方和维护良好的基础镜像,以确保安全性和稳定性。官方镜像经过优化,定期更新,并且不太可能包含漏洞。
  • 保持镜像小巧: 通过选择最小化的基础镜像(例如,python:3.9-slim 而不是 python:3.9)来减小镜像大小。去除不必要的依赖和文件,以优化存储和拉取时间。
  • 使用多阶段构建: 通过分离构建和运行时依赖来优化 Dockerfile。多阶段构建确保只有必要的工件被包含在最终镜像中,从而减小大小和攻击面。
  • 正确标记镜像:始终使用版本标签(例如, my-app:v1.0.0),而不是latest,以避免在拉取镜像时出现意外更新。
  • 扫描镜像以查找漏洞:使用安全扫描工具,如docker scanTrivyClair,在部署之前识别和修复镜像中的安全漏洞。
  • 安全管理环境变量:避免将敏感凭证存储在镜像内部。使用Docker秘密、环境变量或外部秘密管理工具,例如AWS Secrets Manager或HashiCorp Vault。
  • 使用 .dockerignore 文件: 排除不必要的文件(例如,.git, node_modules, venv),以减小构建上下文大小,并防止意外包含敏感文件在镜像中。
  • 启用日志记录和监控: 使用 Prometheus、Grafana 和 Fluentd 等工具进行容器日志和监控。使用 docker logs 检查日志,并启用结构化日志以实现更好的可观测性。

一旦掌握了 Docker 的基础知识,就有许多高级主题可以探索。以下是一些值得进一步探索的领域:

  • Docker Swarm & Kubernetes: 探索 Docker Swarm(内置集群)和 Kubernetes(具有自动扩展和服务发现的企业级编排)用于生产级编排。
  • 容器安全最佳实践: 要保护容器化应用程序,请遵循 CIS Docker Benchmark 指南并实施基于角色的访问控制(RBAC)。
  • 使用Docker构建CI/CD流水线:使用GitHub Actions、GitLab CI或Jenkins自动化镜像构建、安全扫描和部署。
  • 云原生开发:利用Docker与AWS ECS、Azure Container Instances和Google Cloud Run等云平台进行可伸缩和托管部署。
  • 数据持久化策略:为了实现最佳存储管理,了解Docker卷、绑定挂载和tmpfs之间的区别。

结束

Docker 已经彻底改变了开发人员构建、发布和运行应用程序的方式,使其成为现代软件开发的重要工具。

在本教程中,我们涵盖了:

  • Docker 是什么以及为什么它很重要
  • 如何安装和运行您的第一个容器
  • 像镜像、容器和网络等关键概念
  • 使用 Docker 卷进行持久存储
  • 使用Docker Compose构建多容器应用
  • 安全性、性能和可伸缩性的最佳实践

但这只是一个开始!如果您想深入了解Docker,您可以参加 入门级 Docker入门课程。想要更深入的知识,可以学习 中级Docker课程,涵盖多阶段构建、Docker网络工具和Docker Compose。最后,您也可以考虑Docker认证,感兴趣的话可以查看2025年完整的Docker认证(DCA)指南

Source:
https://www.datacamp.com/tutorial/docker-tutorial