Docker 是一个管理平台,可以帮助开发人员将应用程序及其依赖项打包到称为容器的单元中。容器是轻量级的独立环境,可以在安装了 Docker 的任何机器上一致运行,无论是本地计算机还是远程云服务器。这使得在不同环境中开发、测试和部署应用程序变得容易,而不必再为兼容性问题担心。

Docker 的核心概念包含如下内容:

  • Docker Image:Docker 映像就像是容器的蓝图。它包含应用程序运行所需的一切,例如代码、系统工具、库和设置。映像可重复使用,因此可以在不同的计算机上使用相同的映像
  • Docker Container:容器是 Docker 映像的运行实例。它与其他容器和主机系统隔离,确保应用程序在任何地方的行为都相同。容器是轻量级的,因为它们共享主机的操作系统内核,而不像需要完整操作系统的传统虚拟机
  • Dockerfile:Dockerfile 是一个简单的文本文件,其中包含构建 Docker 映像的说明。它定义了基础映像(例如 Ubuntu 或 Alpine)、应用程序代码以及设置环境所需的步骤。当用户从 Dockerfile 构建映像时,Docker 会遵循说明并将所有内容打包到可用于容器的映像中

1] Docker 网络类型

Docker 具有内置网络系统,可管理容器、Docker 主机和外部网络之间的通信。它支持不同类型的网络来处理各种用例,确保在容器化环境中实现安全灵活的通信。

Docker 网络包括如下几种类型:

  1. bridge:桥接
  2. host:主机
  3. overlay:层叠
  4. IPvLAN:IP 地址 VLAN
  5. macvlan:mac 地址 VLAN
  6. None:无网络

1. brige

桥接网络是默认网络,Docker 中的桥接网络在主机系统和容器之间创建虚拟连接。此网络中的容器可以相互通信,但除非特别配置,否则与外部网络隔离。

每个容器在桥接网络中获取其 IP 地址。通过桥接,容器可以访问本地局域网(LAN)和互联网,但它们不会在 LAN 上显示为单独的物理设备。这种类型的网络通常用于单个主机上的容器通信。

2. host

在主机网络模式下,Docker 容器直接共享主机的网络,这意味着容器和主机之间没有网络隔离。容器使用与主机相同的 IP 地址,并且容器公开的任何端口都直接绑定到主机的网络。例如,如果将容器配置为侦听端口 80,它将绑定到主机的 IP 和端口 80(:80)。由于没有虚拟网络层,此设置可以提高性能,但它牺牲了其他 Docker 网络模式提供的隔离和安全性。它通常用于需要直接访问主机网络的特定情况。

3. overlay

Docker 使用层叠网络连接在不同主机上运行的容器,使它们能够像在同一个网络上一样进行通信。这种类型的网络跨越多个 Docker 主机,不需要操作系统级路由,因此非常适合分布式系统扩展应用程序。

层叠网络对于 Docker Swarm 集群至关重要,但它们也可以独立使用,以连接不同 Docker Engine 实例之间的容器。这使用户能够构建分布式环境,来自不同主机的容器可以无缝通信。

4. IPvLAN

IPvlan 是一种网络选项,可让您管理如何将 IP 地址分配给 Docker 容器。这意味着用户可以通过使用 VLAN 标记来更好地组织网络流量,这有助于区分不同的数据类型。如果想将容器化应用程序直接连接到物理网络(如办公室网络),同时提高与标准桥接网络相比的性能,此设置非常有用。总体而言,IPvlan 有助于创建更高效​​、更有条理的网络环境。

5. macvlan

macvlan 允许每个容器像网络上的物理设备一样运行。通过为每个容器分配唯一的 MAC 地址,使这些容器可以被识别为单独的物理设备。要使用 macvlan,需要将主机的一个网络接口专用于此目的。这意味着外部网络必须能够处理多个 MAC 地址。macvlan 非常适合需要将容器视为独立设备的场景,例如网络监控或需要特定网络权限时。这样,就可以既获得容器化的好处,同时又具有物理网络设备的灵活性。

6. None

“无网络” 是 Docker 网络中一种特殊的类型,其中容器没有任何网络接口,除了环回接口。本质上,它将容器与任何外部网络连接完全隔离。如果想要容器不与外界或其他容器通信,除非明确连接到另一个网络时,这种网络类型就非常有用。

简而言之,”无网络”的容器默认没有外部网络访问权限。

2] Docker 网络如何工作

Docker 使用主机网络来使容器能够通信。它通过使用 IPtables(Linux 系统中的一种控制流量在网络中流动的工具)设置特殊规则来实现这一点。这些规则会自动将正确的流量发送容器,因此用户无需手动设置它们。

每个 Docker 容器都有自己的虚拟网络环境,这被称为网络命名空间,可使其保持隔离。Docker 还在主机上创建虚拟网络接口,允许容器使用主机的网络与外界通信。

尽管 Docker 网络背后的过程很复杂,但 Docker 会为您处理一切,使其易于使用。

3] Docker 基本网络命令

以下是 Docker 创建和管理网络的基本命令。

1. 创建一个 Docker 网络

# docker network create my-network

这条命令会创建一个名为”my-network”的 Docker 网络。

2. 显示所有 Docker 网络

# docker network ls

这条命令会显示所有已经创建的 Docker 网络。

3. 检查一个 Docker 网络

# docker network inspect my-network

这条命令会显示有关”my-network”的详细信息,例如连接的容器、子网和配置信息等。

4. 移除一个 Docker 网络

# docker network rm my-network

这条命令会移除一个名为”my-network”的 Docker 网络。

5. 移除所有 Docker 网络命令

# docker network prune

这条命令会移除所有 Docker 网络。

4] 使用 Docker 网络基本步骤

使用 Docker 网络时,首先需要创建一个 Docker 网络,使用”docker network create”命令。创建网络时可以使用”-d”参数指定网络类型(例如 brige 或者 host)。如果不包含此标志参数,Docker 将默认创建桥接网络。

# docker network create demo-network -d bridge

Docker 网络创建完成后,可以使用 docker run 命令中的”–network”标志将新容器连接到该网络。命令如下:

# docker run -it --rm --name container1 --network demo-network busybox:latest

接下来,可以打开另一个终端窗口并启动另一个没有”–network”标志的容器:

# docker run -it --rm --name container2 busybox:latest

现在,尝试检查 container1 和 container2 两个容器间的网络连通性:

/* in container1 */
/ # ping container2
ping: bad address 'container2'

图.1 在容器中尝试检查网络连通性

由于 container1 和 container2 两个容器不在同一网络上,所以它们还无法通信。

在终端中输入如下命令,将 container2 连接至已经创建的 Docker 网络 demo-network:

# docker network connect demo-network container2

此时,再次检查两个容器间的连通性,就可以发现其网络已经互相连通了:

图.2 属于同一 Docker 网络的容器间网络连通性检查

虽然桥接网络通常用于连接容器,但我们也可以使用主机网络。将容器直接连接到主机的网络接口。要启用主机网络,需要运行如下命令:

# docker run -d --name nginx --network host nginx:latest

通过此命令,Nginx 默认监听容器网络端口 80,我们如下命令来访问它:

# docker exec nginx curl localhost:80

图.3 主机网络类型网络检查

通过图.3 可以看出,容器中的服务只针对容器网络中的主机有效,Docker 主机是不能直接访问其业务的。

如果想要禁用 Docker 网络,可以直接将容器的网络类型设置为”None”,例如:

# docker run -it --rm --network none busybox:latest

图.4 隔离网络类型容器

这样就会隔离容器,允许对未知服务进行沙盒处理。

对于已经连接到特定 Docker 网络的容器,也可以使用如下命令断开其连接:

# docker network connect demo-network container2

命令执行完成后,设置会立即生效。

我们还可以将网络与 Docker Compose 服务一起使用。使用 Compose 时,堆栈中的服务会自动添加到共享桥接网络中,从而减少手动配置项。以下是 Compose 文件示例:

version: "3"
services:
  app:
    image: php:7.2-apache
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: changeme

使用如下命令使用配置生效:

# docker-compose up -d

我们还可以在 Compose 文件中定义其他网络。在顶级 networks 字段中指定网络,并通过在每个服务的 networks 字段中引用它来连接的服务:

version: "3"
services:
  app:
    image: php:7.2-apache
    networks:
      - db
  helper:
    image: custom-image:latest
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: changeme
    networks:
      - db
networks:
  db:

在这个例子中,只有应用服务可以与 mysql 服务通信,而辅助服务无法访问数据库,因为它们不在同一个网络上。

发表回复

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