Docker 详解(上)
Docker 详解(上)
1、Docker 简介
什么是 Docker?
Docker 是一个开源的容器化技术,允许开发者和系统管理员构建、打包和运行应用程序在一个称为容器的隔离环境中。以下是 Docker 的一些关键概念和特点:
容器:容器是一种轻量级的、独立的、可执行的软件包,其中包含了运行某个应用所需的所有内容:代码、运行时、系统工具、系统库和设置。由于容器在任何环境中都以相同的方式运行,这消除了“在我的机器上可以运行”的问题。
镜像:Docker 镜像是容器运行的基础,可以看作是容器的“蓝图”。镜像是轻量级的、可执行的代码包,其中包含运行应用所需的所有内容,但与容器不同,它是不可变的。
Dockerfile:Dockerfile 是一个文本文件,其中包含一系列命令,用于从基础镜像创建一个新的 Docker 镜像。
Docker Hub:这是一个云端的服务,允许用户分享和下载 Docker 镜像。
隔离性:每个 Docker 容器都在自己的文件系统、网络和进程空间中运行。这为应用程序提供了隔离和安全性。
轻量性:与传统的虚拟化技术(如 VM)相比,Docker 容器非常轻量。多个容器可以共享同一台机器的操作系统内核,而不需要自己的操作系统实例。
可移植性:由于 Docker 容器包含了运行应用所需的所有内容,它们可以在任何支持 Docker 的环境中无缝运行,无论是开发者的本地机器、测试服务器还是云端生产环境。
版本控制:Docker 镜像支持版本化,这意味着你可以追踪镜像的更改,回滚到旧版本,或者在不同版本之间切换。
集成和自动化:Docker 可以与许多现代 CI/CD 工具(如 Jenkins、Travis CI 和 GitLab CI)无缝集成,从而实现容器的自动构建、测试和部署。
简而言之,Docker 提供了一种方法,使得应用程序和其依赖环境可以作为一个整体打包,确保应用程序在从开发到生产的整个生命周期中始终如一地运行。
Docker 和虚拟机有什么区别?
Docker 和虚拟机(VM)都提供了应用程序的隔离机制,但它们在技术和哲学上有很大的区别。以下是 Docker(容器技术)和虚拟机之间的主要区别:
基础架构:
Docker(容器): 容器共享宿主机的操作系统内核,但运行在自己独立的用户空间中。由于它们不需要完整的操作系统,所以它们启动得更快,更轻量。
虚拟机 (VM): 虚拟机包括完整的操作系统实例和模拟的硬件。这意味着它们需要更多的系统资源,启动时间也更长。
大小:
Docker: 通常只有几十 MB 的大小(取决于基础镜像)。
虚拟机: 通常是几 GB 的大小,因为它们需要完整的操作系统。
启动时间:
Docker: 秒或亚秒级启动时间。
虚拟机: 通常需要几分钟才能启动。
性能:
Docker: 由于容器直接运行在宿主机的操作系统上,并共享其内核,因此几乎没有性能开销。
虚拟机: 由于硬件模拟,通常存在一定的性能开销。
管理和操作:
Docker: 使用 Docker CLI 或 API 进行管理。命令和操作相对简单。
虚拟机: 通常使用如 VMware vCenter 或 Microsoft System Center 等工具进行管理。
隔离性:
Docker: 虽然容器之间是隔离的,但它们都使用同一个内核。因此,容器之间的隔离可能不如 VM 之间的隔离那么强。
虚拟机: 提供强隔离,因为每个 VM 都有自己的操作系统和资源。
应用场景:
Docker: 非常适合微服务、持续集成/持续部署、快速部署和可扩展的应用。
虚拟机: 适用于需要强隔离的环境、完整的操作系统环境或者不支持容器化的应用。
安全性:
Docker: 由于所有容器共享同一内核,如果内核受到攻击,所有容器都可能受到影响。
虚拟机: 提供了更强的隔离,因此在某些高安全要求的环境中可能更受欢迎。
兼容性:
Docker: 一次构建,处处运行。应用程序和其所有依赖被打包到一个容器中,确保它可以在任何支持 Docker 的平台上运行。
虚拟机: 虚拟机的迁移和兼容性可能更加复杂,因为它们包括完整的操作系统。
总的来说,Docker 和虚拟机有其各自的优势和适用场景。选择使用哪种技术取决于具体的需求和环境。
为什么要使用 Docker?
Docker 的出现解决了开发、测试和生产环境中一些长期存在的挑战。以下是使用 Docker 的一些主要原因和好处:
一致性:Docker 确保应用在从开发到生产的整个生命周期中始终如一地运行。这消除了“在我的机器上可以运行”这类问题。
轻量级与快速:与传统的虚拟机相比,Docker 容器非常轻量级并且启动速度快。这是因为容器共享宿主机的操作系统内核,而不需要启动完整的操作系统。
模块化与可扩展:Docker 使得应用可以被分解为单独的模块(容器)。每个模块(如数据库、后端API、前端应用)可以单独构建、部署和扩展。
版本控制:Docker 镜像支持版本化,这意味着你可以追踪容器的更改,回滚到旧版本,或者在不同版本之间切换。
资源高效:由于容器共享宿主机的内核,它们消耗的资源比虚拟机少得多,这意味着你可以在同样的硬件上运行更多的容器实例。
隔离:尽管 Docker 容器共享宿主机的内核,但每个容器都在其自己的进程、用户、文件系统和网络空间中运行,从而为应用提供了隔离。
开发与部署自动化:Docker 可以与持续集成/持续部署 (CI/CD) 工具无缝集成,从而实现应用的自动构建、测试和部署。
重用和共享:Docker Hub 和其他公共容器仓库允许开发者分享和重用其他人的容器镜像,从而加速开发和部署。
密度:与传统虚拟化相比,容器可以提供更高的实例密度。这意味着在给定的硬件上,你可以运行更多的应用实例。
跨平台和云原生:Docker 支持多种操作系统和云平台,使得应用更容易迁移到或在多个环境中部署。
安全增强:虽然容器共享同一个内核,但 Docker 提供了各种安全增强功能,如用户命名空间、只读文件系统和 AppArmor 策略,从而增强了容器的隔离和安全性。
开源:Docker 是开源的,这意味着任何人都可以贡献代码、修复错误或增加新功能。
总的来说,Docker 提供了一种高效、快速且一致的方法来部署和运行应用,从而使得开发、测试和生产环境的工作变得更加简单和流畅。
2、Docker 安装和设置
如何在 Ubuntu 上安装 Docker?
在 Ubuntu 上安装 Docker 相对简单。以下是一个基本的步骤指南:
更新包索引:
sudo apt-get update
安装所需的软件包,以确保通过 HTTPS 使用 APT:
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
添加 Docker 官方 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
添加 Docker 官方 APT 仓库:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
再次更新包索引:
sudo apt-get update
安装 Docker CE (Community Edition):
sudo apt-get install docker-ce
验证 Docker 是否正确安装:
sudo docker --version
为了避免每次使用 Docker 命令时都需要
sudo
,你可以将你的用户名添加到docker
组:sudo usermod -aG docker ${USER}
注:完成上述操作后,为使组更改生效,您可能需要退出并重新登录。
启动 Docker 服务(如果尚未启动):
sudo systemctl start docker
设置 Docker 在启动时自动运行:
sudo systemctl enable docker
至此,Docker 应该已经成功安装在您的 Ubuntu 机器上,并已准备好使用。您可以通过运行一个简单的测试如
sudo docker run hello-world
来验证 Docker 是否正确工作。这将从 Docker Hub 下载一个简单的测试镜像并在容器中运行它。
如何在 Windows 上安装 Docker?
在 Windows 上安装 Docker 有两种主要方法,具体取决于您的 Windows 版本和需求:
Docker Desktop for Windows: 适用于 Windows 10 专业版、企业版或教育版。它提供了一个完整的 Docker 体验,包括 Docker Compose, Docker CLI 客户端, Docker Kitematic 等。
Docker Toolbox: 为旧版本的 Windows 和不满足 Docker Desktop for Windows 系统要求的系统提供的方案。
以下是Docker Desktop for Windows的安装指南:
Docker Desktop for Windows:
前提条件:
Windows 10 64-bit: 专业版、企业版或教育版。
虚拟化技术必须在 BIOS 中启用。
Hyper-V 功能必须启用。
安装步骤:
前往 Docker 官方网站的下载页面:www.docker.com/products/docker-des...
下载 Docker Desktop for Windows 安装程序并运行它。
在安装期间,选择是否希望使用 Windows 而不是 Linux 容器(这可以之后在 Docker 设置中更改)。
完成安装后,Docker 将自动启动。您将在系统托盘中看到 Docker 的图标。
为了验证安装,您可以打开终端或命令提示符并输入
docker --version
。
Docker Toolbox:
如果您的系统不满足 Docker Desktop for Windows 的要求,您可以选择使用 Docker Toolbox。Docker Toolbox 使用 Oracle VirtualBox,而不是 Hyper-V,来创建和管理虚拟机。
安装步骤:
前往 Docker Toolbox 的 GitHub 发布页面:github.com/docker/toolbox/releases
下载最新的
.exe
安装程序。双击下载的
.exe
文件并遵循安装向导。一旦安装完成,您可以从开始菜单中找到并运行 “Docker Quickstart Terminal” 以启动一个新的 Docker 环境。
注意:不推荐在同一台机器上同时使用 Docker Desktop 和 Docker Toolbox,因为它们可能会出现冲突。
无论您选择哪种安装方法,都可以使用 Docker CLI 在 Windows 上运行和管理容器。但是,请记住,如果您使用的是 Docker Toolbox,则需要在 “Docker Quickstart Terminal” 中运行这些命令。
Docker 安装后有哪些基本命令可以查看其状态和版本?
安装 Docker 后,您可以使用以下基本命令来查看其状态和版本:
查看 Docker 版本:
docker --version
这会显示 Docker 的版本信息。如果您需要更详细的版本信息,可以使用:
docker version
这将展示客户端和服务器的详细版本信息。
查看 Docker 详细信息:
docker info
该命令提供了关于 Docker 系统的详细信息,包括正在运行的容器数量、存储、网络等相关信息。
查看 Docker 服务状态:
对于使用 systemd 的 Linux 发行版(如 Ubuntu 16.04 及更高版本):
sudo systemctl status docker
对于 Windows 或使用 Docker Desktop 的 Mac 用户,您可以查看系统托盘或顶部菜单栏中的 Docker 图标来查看 Docker 是否正在运行。
启动和停止 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 及更高版本):启动 Docker 服务:
sudo systemctl start docker
停止 Docker 服务:
sudo systemctl stop docker
重新启动 Docker 服务:
sudo systemctl restart docker
查看 Docker 服务状态:
sudo systemctl status docker
Windows(使用 Docker Desktop):
通过开始菜单或桌面图标启动 Docker Desktop。
为了停止 Docker Desktop,您可以右键点击系统托盘中的 Docker 图标并选择 “Quit Docker Desktop”。
macOS(使用 Docker Desktop):
通过应用程序文件夹或 Launchpad 启动 Docker Desktop。
要停止 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 镜像的步骤:打开终端或命令行工具。
使用以下格式的命令下载所需的镜像:
docker pull [IMAGE_NAME]:[TAG]
其中,
[IMAGE_NAME]
是您要下载的镜像的名称,[TAG]
是特定的版本标签。如果您不指定标签,Docker 通常会默认下载latest
标签的镜像。
例如:
- 要下载最新版本的 Ubuntu 镜像,您可以执行:
docker pull ubuntu:latest
- 要下载特定版本的 Ubuntu(例如 18.04),您可以执行:
docker pull ubuntu:18.04
命令执行后,Docker 将开始从 Docker Hub 下载指定的镜像。下载过程中,它会显示每一层的下载状态。
下载完成后,您可以使用以下命令查看本地可用的 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 容器的基本步骤:打开终端或命令行工具。
使用
docker run
命令来启动一个容器:docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG…]
[OPTIONS]
:可选的标志,例如-d
(后台运行),-p
(端口映射),-v
(挂载卷) 等。IMAGE[:TAG|@DIGEST]
:您想要运行的 Docker 镜像的名称,可选地带一个标签或摘要。[COMMAND] [ARG...]
:可选地,您可以覆盖镜像的默认命令。
示例:
运行一个简单的 echo 命令在
alpine
Linux 容器中:docker run alpine echo "Hello from Docker!"
交互式地运行一个
ubuntu
容器并进入 bash shell:docker run -it ubuntu /bin/bash
这里,
-i
表示交互模式,-t
为容器分配一个伪 TTY,这使我们能够与容器交互。在后台运行一个
nginx
web 服务器并映射端口:docker run -d -p 8080:80 nginx
这里,
-d
表示后台模式,-p
用于映射宿主机的端口 8080 到容器的端口 80。查看正在运行的容器: 使用以下命令可以查看当前正在运行的容器:
docker ps
如果您还想看到已经停止的容器,可以使用:
docker ps -a
停止容器: 如果您需要停止一个正在运行的容器,可以使用:
docker stop CONTAINER_ID_OR_NAME
这里的
CONTAINER_ID_OR_NAME
可以是容器的 ID 或者名称。
这只是
docker run
的基本使用。它有许多选项和变化,允许您设置环境变量,挂载卷,设置网络选项等等。您可以通过docker run --help
查看所有可用的选项。
如何查看正在运行的容器?
要查看当前正在运行的 Docker 容器,您可以使用
docker ps
命令。命令与输出解释:
查看正在运行的容器:
docker ps
当您执行这个命令时,它将列出所有当前正在运行的容器及其相关信息,如容器 ID、命令、创建时间、状态、端口信息等。
查看所有容器(包括已停止的):
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
类似,但更为强大。COPY
和ADD
: 将文件或目录从本地主机复制/添加到容器中。EXPOSE
: 声明容器内部服务使用的端口。ENV
: 设置环境变量。VOLUME
: 创建挂载点,用于挂载文件或目录。
构建由
Dockerfile
定义的镜像时,你会使用docker build
命令:docker build -t your_image_name:tag_name .
.
表示当前目录,-t
允许你为新镜像命名并(可选地)指定一个标签。使用
Dockerfile
的主要好处是,您可以确保镜像的构建过程是可重复且一致的,这对于持续集成和持续部署流程非常重要。扩展内容 - Dockerfile与Shell脚本之间有哪些异同?
Dockerfile
和 Shell 脚本都是自动化的工具,用于执行一系列的命令,但它们的目的、结构和使用场景有所不同。以下是它们之间的主要异同点:相同点:
自动化:两者都用于自动执行一系列命令,以消除手动操作的需要。
可读性:为了使其他开发者能够理解和维护,两者都应写得尽可能清晰。
命令序列:都可以用来执行多个命令,通常按顺序。
不同点:
目的:
Dockerfile
:其主要目的是构建 Docker 镜像。这个镜像可以用来启动容器,容器中会包含所需的应用程序和环境。Shell 脚本:它是一个广泛用途的工具,用于自动化一系列的命令。它可以用于安装软件、管理系统任务、处理文件和数据等。
结构:
Dockerfile
:它有一套明确定义的指令集,如FROM
,RUN
,CMD
,COPY
等。Shell 脚本:它可以包含任何可以在命令行上运行的命令,并且有更强大的逻辑和流程控制功能(如循环、条件语句等)。
层:
Dockerfile
:每个RUN
,COPY
和ADD
指令都会创建 Docker 镜像的一个新层。这有助于缓存和重用数据,但也需要关注每层的大小。Shell 脚本:执行的命令没有分层的概念。它仅按顺序执行命令。
上下文:
Dockerfile
:在构建过程中,Docker 使用所谓的“构建上下文”(通常是Dockerfile
所在的目录及其子目录)。COPY
和ADD
指令只能访问此上下文中的文件。Shell 脚本:没有这样的上下文限制,可以访问运行脚本的系统上的任何文件和目录。
运行环境:
Dockerfile
:它构建的命令是在一个临时容器内部执行的,这个容器是基于FROM
指令指定的基础镜像创建的。Shell 脚本:在它被执行的机器上的常规环境中运行,不受容器的约束。
状态持久性:
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. 添加文件和目录
使用
ADD
或COPY
指令将代码和资源从你的主机复制到镜像中。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 桥接模式的一些关键点:
私有内部网络:在桥接模式下,每个容器都有其自己的私有、内部 IP 地址,并且这些地址只能从主机或其他容器访问。这些容器默认不能直接从外部网络访问。
端口映射:为了从主机或外部网络访问容器中的应用,必须显式地映射容器的端口到主机的端口。例如,如果你有一个在容器的80端口运行的web服务器,你可以将它映射到主机的8080端口。然后,通过访问主机的8080端口,你可以访问容器中的web服务器。
网络隔离:由于容器在其自己的网络命名空间中运行,桥接模式为每个容器提供了网络隔离。即使容器在同一个
docker0
桥上,它们也只能通过IP地址进行通信,除非它们显式地建立了网络连接。与主机通信:桥接模式下的容器可以与宿主机通信。这是通过路由规则实现的,该规则允许从容器到
docker0
桥,然后到主机的其他网络接口。性能:桥接模式的性能通常足够大多数应用程序。然而,在某些高性能需求场景中,可能需要考虑其他网络解决方案,例如 host 模式。
自定义桥接网络:除了默认的
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:
在这个设置中,
webapp
和database
服务会自动在同一个网络mynetwork
中启动并可以互相通信。4. Overlay 网络
在使用 Docker Swarm 或 Kubernetes 这样的集群解决方案时,你可能会需要跨多个宿主机连接容器。Overlay 网络允许在集群中的不同主机上运行的容器进行通信。
5. 其他网络模式
除了上述的方法,Docker 还支持其他的网络模式,例如 host 模式、macvlan 和 none,但这些通常不是用来直接连接多个容器的。
总的来说,如果你的目标是在单个宿主机上连接多个容器,最好的选择通常是使用用户定义的桥接网络或 Docker Compose。如果你正在使用集群,则可能需要考虑使用 Overlay 网络或其他集群特定的解决方案。
本作品采用《CC 协议》,转载必须注明作者和本文链接