云计算和容器化技术的发展改变了应用程序的开发、部署和管理方式。这种转变给网络环境带来了重大变化,为DevOps和SRE工程师带来了新的挑战和机遇。然而,在这种转变中,出现了明显的知识差距,特别是在理解物理网络和硬件背景下网络的复杂性方面。
对 API 驱动的基础设施配置的日益依赖已经消除了许多底层网络复杂性,使工程师能够更高效地部署和管理应用程序。虽然这种抽象简化了部署过程,但也导致对网络基本原则的熟悉程度降低。因此,工程师经常发现自己面临着在复杂的分布式环境中进行故障排除、优化和保护网络通信的挑战。
覆盖网络,特别是在Docker和Kubernetes等容器化技术范围内,已经成为弥合这一知识差距的重要概念。通过提供位于物理网络基础架构之上的虚拟网络层,覆盖网络提供了一个强大的抽象,可简化网络任务并实现可扩展的安全配置。
容器网络的演变
要充分理解覆盖网络的重要性,必须了解容器网络的历史发展。在 Docker 的早期,网络主要集中在单主机连接上,同一主机上的容器可以使用桥接网络相互通信。然而,随着容器化的普及和对多主机网络的需求的出现,Docker 引入了更复杂的网络解决方案。
随着 Docker Swarm(集群)的引入,多主机网络成为现实,使运行在不同主机上的容器能够无缝通信。最初,这是使用链接和大使容器实现的,它们充当容器间通信的代理。然而,这些方法在可扩展性和灵活性方面存在局限性。
随着容器生态系统的发展,出现了更多动态和可扩展的网络解决方案,例如覆盖网络。覆盖网络提供了一种创建跨多个主机的虚拟网络的方法,允许容器进行通信,就像它们在同一网络上一样,而不管它们的物理位置如何。这为开发更复杂和分布式容器化应用程序铺平了道路。
了解叠加网络
覆盖网络是在一个或多个现有网络基础结构(如物理网络或其他覆盖网络)之上构建的虚拟网络。它创建了一个单独的逻辑网络拓扑,可以跨越多个物理网络或设备,提供抽象级别,简化网络任务并实现灵活的动态网络配置。
叠加网络的概念并不新鲜,几十年来一直在各种网络环境中使用。然而,云计算和容器化技术已经将覆盖网络带到了最前沿,因为它们提供了一种解决与这些环境相关的网络挑战的方法。
从本质上讲,覆盖网络是一种逻辑结构,用于封装网络流量并将其路由到底层网络基础设施上。它使用各种封装和隧道协议(如 VXLAN、NVGRE 和 IPsec)在节点之间创建虚拟链接,而不管其物理位置或底层网络拓扑如何。
覆盖网络的主要优势之一是它们能够实现节点之间的无缝通信,而不管它们的物理位置或底层网络架构如何。通过抽象物理网络的复杂性,覆盖网络允许应用程序和服务相互通信,就好像它们位于同一本地网络上一样,即使它们分布在多个数据中心或云提供商中。
覆盖网络还为网络配置提供了高度的灵活性和敏捷性。它们允许网络管理员以编程方式创建、修改和拆除虚拟网络,而无需更改物理网络。这样可以快速配置和扩展网络资源,并能够动态适应不断变化的应用程序需求和流量模式。
此外,叠加网络还提供增强的安全性和隔离功能。通过封装流量并在不同应用程序或租户之间创建逻辑隔离,覆盖网络可以帮助防止未经授权的访问和数据泄露。它们还支持实施精细的安全策略和访问控制,从而进一步增强网络的整体安全态势。
Docker 网络和覆盖网络
Docker 是采用最广泛的容器化平台,原生支持各种网络模式,包括桥接网络、主机网络和覆盖网络。其中,叠加网络已成为一种强大的解决方案,用于实现跨多个主机的容器之间的通信,使其特别适合在容器化环境中部署分布式应用程序。
Docker 网络驱动程序
Docker 网络由一组驱动程序促进,这些驱动程序为容器配置网络接口、管理网络连接并确保隔离和安全性。这些驱动程序在确定容器如何相互交互以及与外部网络交互方面起着至关重要的作用。
一些关键的 Docker 网络驱动程序包括:
-
**桥接:**Docker 中的默认网络驱动程序,用于在主机上创建虚拟桥接网络并将容器连接到该网络。同一网桥网络上的容器可以使用其 IP 地址相互通信。
-
**主机:**此驱动程序删除了容器和主机之间的网络隔离,允许容器直接使用主机的网络堆栈。这可以提供更好的性能,但会牺牲容器化的安全性和隔离优势。
-
**覆盖:**覆盖驱动程序支持跨多个 Docker 主机创建分布式网络。它允许在不同主机上运行的容器相互通信,就像它们在同一网络上一样,而无需在主机之间显式路由。
-
**Macvlan:**此驱动程序为每个容器分配一个 MAC 地址,使其在网络上显示为物理设备。这允许容器直接连接到物理网络,使它们能够接收可路由 IP 地址。
-
**Ipvlan:**与 Macvlan 驱动程序类似,Ipvlan 驱动程序为每个容器提供唯一的 IP 地址。但是,它不是分配 MAC 地址,而是使用与主机接口相同的 MAC 地址,从而减少了 MAC 地址管理的开销。
这些驱动程序中的每一个都有自己的用例、优势和局限性。了解这些驱动程序的特征和行为对于根据应用程序的特定要求优化容器网络至关重要。
Docker 中的覆盖网络
Docker 的叠加网络允许将多个 Docker 主机聚集在一起,并作为一个统一系统进行管理。在 Docker 群集中创建覆盖网络时,它会跨越群集中的所有节点,从而创建一个虚拟网络,允许容器无缝地相互通信,无论它们在哪个节点上运行。连接到覆盖网络的每个容器都会收到一个唯一的 IP 地址,即使容器被重新调度或移动到不同的节点,该地址也会保持一致。
Docker 中的覆盖网络使用 VXLAN(虚拟可扩展 LAN)协议在底层物理网络上的容器之间封装和隧道传输网络流量。VXLAN 是一种广泛采用的标准,通过将第 2 层以太网帧封装在 UDP 数据包中,可以创建大规模的多租户网络。
在 Docker 中使用覆盖网络带来了几个关键优势:
1 . **多主机网络:**叠加网络使运行在不同主机上的容器能够无缝地相互通信,就像它们位于同一本地网络上一样。这对于部署跨多个节点的分布式应用程序(例如微服务体系结构或群集数据库)至关重要。
2 . **服务发现:**Docker 的覆盖网络与内置的服务发现机制集成,允许容器使用服务名称而不是 IP 地址来发现并相互连接。这简化了复杂的多容器应用程序的配置和管理。
3 . **负载均衡:**Docker 中的覆盖网络支持跨多个容器实例对传入流量进行负载均衡。这支持服务的水平扩展,并有助于确保高可用性和性能。
4 . **安全性:**默认情况下,覆盖网络提供一定程度的隔离和安全性。附加到覆盖网络的容器只能与同一网络上的其他容器通信,并且容器之间的流量使用 IPsec 加密,从而提供额外的安全层。
Kubernetes 网络和 CNI 插件
Kubernetes 是领先的容器编排平台,它有自己的网络模型,并依靠 CNI(容器网络接口)插件为容器提供网络连接和策略实施。CNI 是一个标准化接口,允许不同的网络提供商为 Kubernetes 实现自己的网络解决方案。
在 Kubernetes 中,每个 Pod(一组一个或多个容器)都有自己唯一的 IP 地址,并且 Pod 中的容器可以使用 localhost 相互通信。但是,为了实现集群中不同节点之间的 Pod 之间的通信,Kubernetes 依赖于 CNI 插件。
Kubernetes 中使用的一些流行的 CNI 插件包括:
1 . **Flannel:**Flannel 是一个简单而轻量级的 CNI 插件,它为 Kubernetes 集群提供了一个扁平的覆盖网络。它使用 VXLAN 或 host-gw(主机网关)作为后端来封装和路由 Pod 之间的流量。
2 . Calico:Calico 是一个高度可扩展且灵活的 CNI 插件,它提供高级网络功能,例如网络策略,并支持叠加和非叠加模式。它使用 BGP(边界网关协议)进行路由,使用 IPIP (IP-in-IP) 或 VXLAN 进行封装。
3 . Weave Net:Weave Net 是一个功能齐全的 CNI 插件,它使用 VXLAN 创建虚拟网络覆盖。它为 Kubernetes 提供了一个简单易用的网络解决方案,具有内置加密和对网络策略的支持。
这些 CNI 插件与底层网络组件(如 Open vSwitch (OVS) 或 iptables)交互,以配置 Pod 的网络接口和路由。它们还实现网络策略,允许基于标签和选择器对 Pod 之间的流量进行精细控制。
Kubernetes 中的网络策略提供了一种定义规则的方法,这些规则控制哪些 Pod 可以相互通信。它们充当 Pod 的防火墙,根据 Pod 标签、命名空间或 IP 范围等因素指定允许或拒绝哪些流量。网络策略由 CNI 插件实现,并使用 iptables 或其他机制在内核级别强制执行。
通过利用 CNI 插件和网络策略,Kubernetes 为容器化应用程序提供安全高效的联网,确保 Pod 可以相互通信,同时保持所需的隔离和访问控制级别。
使用叠加网络部署 MinIO
为了说明叠加网络在容器化环境中的有效性,让我们探索一个真实世界的扫描:使用叠加网络部署 MinIO 高性能 S3 兼容对象存储解决方案。
MinIO 被设计为云原生和容器友好型,使其成为部署在容器化环境中的理想候选者。它提供了一个可扩展的分布式存储层,可以很容易地与各种应用程序和服务集成。
第 1 步:创建叠加网络
创建将由 MinIO 部署使用的覆盖网络。该网络将跨越 Docker 集群中的所有节点,使 MinIO 节点能够相互通信以及与客户端应用程序通信。
docker network create --driver=overlay --attachable minio-overlay-network
步骤 2:定义 MinIO 服务
使用 Docker Compose 文件定义 MinIO 服务 ( minio-compose.yml
):
version: '3.8'
services:
minio:
image: minio/minio:latest
command: server /data
volumes:
- minio-data:/data
networks:
- minio-overlay-network
deploy:
mode: global
placement:
constraints:
- node.role == worker
volumes:
minio-data:
networks:
minio-overlay-network:
external: true
此 Compose 文件使用官方 MinIO Docker 映像定义 MinIO 服务,将其附加到 minio-overlay-network 覆盖网络,并指定全局部署模式以在 docker 集群中的每个工作节点上运行该服务的一个实例。
步骤 3:部署 MinIO 堆栈
使用以下命令将 MinIO 堆栈部署到 Docker 集群:
docker stack deploy --compose-file minio-compose.yml minio
Docker 集群将在集群中的工作器节点之间分发 MinIO 服务,并在每个节点上创建一个服务实例。覆盖网络将实现 MinIO 实例之间的无缝通信。
此外,要使用 docker service create 在多主机环境中部署容器,将使用 --network minio-overlay-network 标志和值,如以下命令所示,将 MinIO 部署为覆盖网络中的复制服务:
docker service create --name minio_service --network minio-overlay-network --replicas 4 -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin" minio/minio server /data
预期成果:
Service 'minio_service' created with 4 replicas in 'minio-overlay' network.
第 4 步:检查 MinIO 覆盖网络
使用 Docker Swarm 和覆盖网络部署 MinIO 服务后,必须检查网络配置以确保正确连接并解决任何问题。Docker 提供了用于检索有关网络的详细信息 docker network inspect
的命令。
要检查 minio-overlay-network
,请运行以下命令:
docker network inspect minio-overlay-network
此外,还可以使用 docker network inspect 命令通过筛选和格式设置选项检索有关网络的特定信息。
此命令将显示有关覆盖网络的全面详细信息,包括其配置、连接的容器和网络端点。
输出示例:
[
{
"Name": "minio-overlay-network",
"Id": "nvk9xhel1f1qs1nuzf2trbiv1",
"Created": "2023-06-03T15:30:00.123456789Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.1.0/24",
"Gateway": "10.0.1.1"
}
]
},
"Containers": {
"0e1f2d3c4b5a": {
"Name": "minio_service.1.abc123def456",
"EndpointID": "1a2b3c4d5e6f",
"MacAddress": "02:42:0a:00:01:03",
"IPv4Address": "10.0.1.3/24",
"IPv6Address": ""
},
...
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": {},
"Peers": [
...
]
}
]
输出提供了有关 minio-overlay-network 的宝贵信息,包括:
-
网络 ID 和名称
-
范围(例如,群)
-
驱动程序(例如,覆盖)
-
IP 地址管理 (IPAM) 配置
-
连接的容器及其网络终结点
-
网络选项和标签
通过检查覆盖网络,您可以验证 MinIO 服务容器是否正确连接,并识别任何与网络相关的问题。
例如,要获取覆盖网络的子网,请执行以下操作:
docker network inspect --format='{{range .IPAM.Config}}{{.Subnet}}{{end}}' minio-overlay-network
此命令将输出 minio-overlay-network 的子网配置。
步骤 5:访问 MinIO 容器和服务
部署 MinIO 服务并验证覆盖网络后,您可以访问 MinIO 容器和服务以与对象存储进行交互。
**访问 MinIO 容器:**您可以直接在容器环境中执行命令(如 docker exec)或附加到容器以执行交互任务。此方法用于与容器中运行的 MinIO 的特定实例直接交互。
要访问容器内运行的 MinIO 服务器,您可以使用 docker exec 命令打开容器中的 shell 或执行命令。
首先,检索 MinIO 服务副本的容器 ID:
CONTAINER_ID=$(docker ps --filter "name=minio_service" --format "{{.ID}}" | head -n 1)
然后,在 MinIO 容器内打开一个 shell:
docker exec -it $CONTAINER_ID sh
进入容器后,您可以运行 MinIO CLI 命令或直接与 MinIO 服务器交互。
例如,要使用 MinIO CLI 列出存储桶中的对象:
mc ls minio/my-bucket
此命令将列出存储在“my-bucket”存储桶中的对象。
*访问 MinIO 服务:*这涉及将 MinIO 部署视为一个整体的交互,尤其是在可能运行多个 MinIO 副本的 Docker Swarm 环境中。缩放服务、更新服务或通过服务的已发布端口访问 MinIO Web 控制台等操作都属于此类别。
要访问部署在 Docker Swarm 集群中的 MinIO 服务,您可以使用以下 docker service
命令。
列出正在运行的服务:
docker service ls
预期成果:
ID NAME MODE REPLICAS IMAGE PORTS
abc123def456 minio_service replicated 4/4 minio/minio *:9000->9000/tcp
验证 MinIO 服务副本的状态:
docker service ps minio_service
预期成果:
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
def456abc123 minio_service.1 minio/minio node1 Running Running 5 minutes ago
ghi789jkl012 minio_service.2 minio/minio node2 Running Running 5 minutes ago
jkl012mno345 minio_service.3 minio/minio node3 Running Running 5 minutes ago
mno345pqr678 minio_service.4 minio/minio node4 Running Running 5 minutes ago
输出显示 MinIO 服务的每个副本的详细信息,指示它们已在 Docker 群集中的不同节点上启动并运行。
**访问 MinIO Web 控制台:**要访问 MinIO Web 控制台,请打开 Web 浏览器并导航到 http://<swarm-manager-ip>:9000
。替换 <swarm-manager-ip>
为 Docker 集群中任何节点的 IP 地址。
系统将提示您输入访问密钥和私有密钥。从 MinIO 服务器日志或服务创建期间设置的环境变量中获取这些凭据。
登录后,您可以使用 MinIO Web 控制台管理存储桶、上传/下载对象以及执行各种对象存储操作。
通过访问 MinIO 容器、服务和 Web 控制台,您可以有效地与使用叠加网络部署的分布式对象存储进行交互。这使您可以跨集群中的多个节点无缝管理数据。
从服务中更新或删除网络
若要更新已启动并正在运行的服务的网络,可以使用以下 docker service update --network-add
命令:
docker service update --network-add minio-overlay-network <service-id>
预期成果:
<service-id>
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
如果服务错误地附加到网络,您可以使用 --network-rm 命令将其从该网络中删除:
docker service update --network-rm minio-overlay-network <service-id>
第 5 步:测试 MinIO 连接
使用 MinIO 客户端 (mc) 或任何兼容 S3 的 SDK 或工具测试 MinIO 部署的连接性和功能。
本概述演示了 Docker 中的覆盖网络如何简化分布式存储解决方案(如 MinIO)的部署和管理。通过利用覆盖网络,MinIO 实例可以在 Docker 集群中的多个节点之间无缝通信,为容器化应用程序提供可扩展且具有弹性的存储层。
结论
覆盖网络已成为弥合DevOps和SRE工程师在现代网络领域面临的知识鸿沟的重要概念。通过提供强大的抽象层来简化网络复杂性,覆盖网络支持在容器化环境中部署可扩展、灵活和安全的网络配置。
Docker 中对覆盖网络的原生支持以及通过 CNI 插件与 Kubernetes 的集成使分布式应用程序的部署和管理方式现代化。这些技术大大简化了与现代云原生架构相关的网络挑战,允许跨多个主机的容器之间的无缝通信。
总之,覆盖网络与 Docker 和 Kubernetes 等容器化技术相结合,为应对现代网络挑战提供了强大的工具集。通过了解和利用这些技术,工程师可以构建可扩展、灵活和安全的基础设施,从而推动数字时代的创新和业务成功。随着容器化采用率的不断提高,掌握覆盖网络将成为DevOps和SRE专业人员的一项基本技能,使他们能够自信地驾驭现代网络的复杂性和专业知识。