Docker 网络工作原理详解

Docker 网络工作原理详解

Docker 网络是 Docker 中比较核心、也比较复杂的一个部分,本篇文章就来详细讲解 Docker 网络的工作原理。我们将先介绍 Docker 网络中的一些基本概念、网络模式,然后讲解 Docker 内置网络的实现原理、Docker 容器间的通信方式,最后通过两个示例演示 Docker 容器间的通信方式。

Docker 网络基本概念

在开始学习 Docker 网络的工作原理之前,我们需要了解一些基本概念。

Docker 网络模式

Docker 命令中提供了多种网络模式,分别是:

  • bridge 桥接模式:Docker 默认使用的网络模式,使用 docker0 这个虚拟网桥将容器连接到主机上。
  • host 主机模式:将容器直接放到主机的网络上,容器共享主机的网络栈,可以直接使用主机上面的 IP 地址。
  • none 无网络模式:关闭容器的网络,容器内无法访问网络,网络也无法访问容器。
  • container 容器模式:将容器连接到已经存在的容器的网络栈上,这样两个容器可以直接通信,而无需通过网络设备。

使用不同的网络模式可以实现不同的网络功能,选择合适的网络模式有助于提升网络性能和安全性。

Docker 网络驱动

Docker 网络驱动是指一组插件程序和库,容器使用它来实现网络流量的转发和管理。Docker 内置了多种网络驱动,包括 bridge、host、macvlan、overlay、ipvlan 等,也支持用户自定义网络驱动。

Docker 网络命名

Docker 在网络管理中使用的名称是非常重要的,一个网络名称可以代表一个虚拟网络,让多个容器连接在同一个虚拟网络中。Docker 支持使用自定义的名称来创建网络,也支持使用自动生成的名称。

Docker 网络流量

在 Docker 网络中,所有的网络流量都是要经过 Docker Host 的虚拟网桥 docker0 的。Docker 经过网桥来管理创建的每个容器和它们的网络配置。

Docker 内置网络实现原理

Docker 内置网络是 Docker 在 1.9 版本中推出的一个新的网络功能,它以插件方式实现了容器的互联。内置网络实现原理大致如下:

  1. Docker Host 的容器引擎会在安装时就创建一个虚拟网桥 docker0。容器启动后,Docker 会为每个容器创建一个网络命名空间,这个命名空间中包含一套网络设备(如 veth pair 设备)、路由表、iptables 规则等。
  2. Docker 在容器中创建一个名为 eth0 的网络接口,并将这个接口放在容器的命名空间中, eth0 对应 Docker Host 的虚拟网桥上的一个 veth pair 设备的其中之一。容器内的网络流量都需要通过 eth0 才能访问 docker0 上的其他容器或者宿主机上的其他设备。
  3. 对于一个加入了默认 bridge 网络的容器,在容器启动时,Docker 会默认为其配置一个 IP 地址和路由表规则,并将其添加到 bridge 网络的 Linux bridge 中。同时,Docker 还会给容器配一个 DNS 服务器(默认为以 Google 的 DNS 服务器)。

Docker 容器间通信方式

容器间通信方式视网络模式的选择不同而不同,这里我们讲解两种常见的 Docker 容器间通信方式。

bridge 网络模式下的容器间通信

在默认模式下,Docker 创建的容器会使用 bridge 网络模式,并且被分配到 Docker Host 的默认 bridge 网络上。在这种情况下,Docker 容器可以使用 Docker 自带的 DNS 服务器(通常为容器 IP 地址的最后一段加上 1)进行访问其他容器。

$ docker run -itd --name web nginx
$ docker run -itd --name db mysql

通过上面两条命令创建了一个 nginx 和一个 mysql 的容器。使用以下命令打开 nginx 容器并访问 mysql 容器:

$ docker exec -it web /bin/bash
root@nginx:/# ping db
PING db (172.17.0.2) 56(84) bytes of data.
64 bytes from db.docker_default (172.17.0.2): icmp_seq=1 ttl=64 time=0.127 ms
64 bytes from db.docker_default (172.17.0.2): icmp_seq=2 ttl=64 time=0.119 ms
64 bytes from db.docker_default (172.17.0.2): icmp_seq=3 ttl=64 time=0.185 ms

user-defined 网络模式下的容器间通信

使用 user-defined 网络模式下,每个容器会被分配到一个独立的虚拟网络中,并且可以设置子网和网关,同时可以自定义容器的访问规则。在这种情况下,Docker 容器可以使用容器名或 IP 地址进行通信。

$ docker network create my-net
$ docker run -itd --name web --net=my-net nginx
$ docker run -itd --name db --net=my-net mysql

创建了一个自定义网络,然后在这个自定义网络中创建了一个 nginx 和一个 mysql 的容器。使用以下命令打开 nginx 容器并访问 mysql 容器:

$ docker exec -it web /bin/bash
root@9b0b8a9ad976:/# ping db
PING db (172.19.0.2) 56(84) bytes of data.
64 bytes from db.my-net (172.19.0.2): icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from db.my-net (172.19.0.2): icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from db.my-net (172.19.0.2): icmp_seq=3 ttl=64 time=0.062 ms

两个示例

在这里我们演示两个容器间通信的例子,分别是在默认 bridge 网络下实现容器间服务发现,以及使用 user-defined 网络实现一个简单的多容器的 web 应用。

示例 1:在默认 bridge 网络下实现容器间服务发现

在这个例子中,我们将创建三个容器:web、redis、db,其中 web 容器提供 web 服务,redis 容器提供缓存服务,db 容器提供数据库服务。

  1. 创建三个容器:
$ docker run -d -p 8080:80 --name web nginx
$ docker run -d --name redis redis
$ docker run -d --name db mysql -e MYSQL_ROOT_PASSWORD=root
  1. 查看容器 ip:
$ docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

输出应该是这样的:

/web - 172.17.0.2
/redis - 172.17.0.3
/db - 172.17.0.4
  1. 将这些 IP 地址添加到 web 容器的 /etc/hosts 文件中:
$ for container in web redis db; do
     ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container)
     echo "$ip $container" >> /etc/hosts
  done

现在,web 容器可以使用 redis 和 db 的名称进行访问。例如,可以在 nginx 配置文件中使用这些名称:

upstream php {
   server redis:6379;
   server db:3306;
}

server {
   listen 80 default_server;
   server_name localhost;
   root /usr/share/nginx/html;

   location / {
      proxy_pass http://php;
   }
}

示例 2:使用 user-defined 网络实现多容器 web 应用

在这个例子中,我们将使用 user-defined 网络创建多个容器同时运行一个简单的 web 应用程序。该容器提供 Apache 服务器、PHP 环境和 MySQL 数据库。

  1. 创建自定义网络:
$ docker network create my-net
  1. 创建 MySQL 数据库容器:
$ docker run -d --name db --net my-net -e MYSQL_ROOT_PASSWORD=PASSWORD mysql
  1. 创建 Apache 服务器容器:
$ docker run -d --name web --net my-net -p 8080:80 -v "$PWD":/var/www/html php:7.2-apache

在这里,我们使用 PHP 官方镜像中的 Apache 服务器镜像来运行我们的 web 应用程序。我们将本地文件挂载到容器中作为 Apache 服务器的文档根目录。

  1. 在 Apache 服务器容器中安装 PHP 和 MySQL 扩展:
$ docker exec -it web docker-php-ext-install mysqli pdo pdo_mysql
  1. 创建一个简单的 PHP 网页:

在本地创建一个 index.php 文件,放在你想要的目录下(例如 /path/to/your/dir)。在文件中写入以下内容:

<?php
$servername = "db";
$username = "root";
$password = "PASSWORD";
$dbname = "test";

$conn = mysqli_connect($servername, $username, $password, $dbname);

if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

echo "Connected successfully to MySQL database!";

mysqli_close($conn);
?>

这个 PHP 网页将检查 MySQL 数据库的连接并输出一条消息。

  1. 访问你的 web 应用程序:

在浏览器中键入 http://localhost:8080/index.php,如果一切正常,你应该会看到一条消息 “Connected successfully to MySQL database!”。

总结

Docker 网络是 Docker 中比较核心、也比较复杂的一个部分。本文详细介绍了 Docker 网络的基本概念和原理,并演示了两个容器间通信的例子。通过深入了解 Docker 网络,我们可以更好地管理我们的 Docker 容器,提高容器应用的安全性和网络性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Docker 网络工作原理详解 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 如何快速通过Docker安装SQL Server

    让我们来详细讲解如何快速通过 Docker 安装 SQL Server 的完整攻略。 步骤一:安装 Docker Docker 是一种常用的虚拟化技术,它可以让应用程序在不同的环境中无缝运行。在安装 SQL Server 之前,你需要先安装 Docker。 可以去 Docker 官网下载安装包,安装完成后,打开命令行工具验证 Docker 是否已经正确安装:…

    Docker 2023年5月16日
    00
  • Docker 学习笔记

    概述 1. 什么是 Docker? Docker 是一个应用容器平台,管理项目中用到的所有环境(MySQL、Redis…) 2. Docker 和虚拟机的区别 虚拟机是携带操作系统的,本身很小的应用程序因为携带了操作系统而变得十分笨重,Docker 不携带操作系统,所以 Docker 的应用非常轻巧 在调用宿主机资源时,虚拟机利用 Hypervisor …

    2023年4月9日
    00
  • K8S 性能优化 – OS sysctl 调优

    前言 K8S 性能优化系列文章,本文为第一篇:OS sysctl 性能优化参数最佳实践。 参数一览 sysctl 调优参数一览 # Kubernetes Settings vm.max_map_count = 262144 kernel.softlockup_panic = 1 kernel.softlockup_all_cpu_backtrace = 1 …

    Docker 2023年4月9日
    00
  • Docker Desktop常见的几种启动失败问题解决方法

    请看下面的完整攻略。 Docker Desktop常见的几种启动失败问题解决方法 问题描述 在使用Docker Desktop时,有可能会遇到启动失败的情况。具体表现为,启动Docker Desktop程序后,界面没有任何反应、进入黑屏、显示错误提示等。这时,需要根据具体情况采取相应的解决方法。 解决方法 方法一:卸载/重装Docker Desktop 如果…

    Docker 2023年5月15日
    00
  • Docker 网络模式(四种)详细介绍

    Docker 网络模式(四种)详细介绍 Docker 容器的网络模式分为四种,分别是: Host 模式 Bridge 模式 Container 模式 None 模式 Host 模式 在 Host 模式中,Docker 容器使用主机的网络命名空间和 IP 地址。这意味着容器和主机共享同一个网络环境,容器可以通过主机的网络接口来访问外部网络。它适用于需要快速启动…

    Docker 2023年5月16日
    00
  • Docker 容器上部署 Zabbix

    首先,从 Docker Hub 上拉取 Zabbix 镜像。可以使用以下命令: docker pull zabbix/zabbix-server-mysql:latest 这会下载最新版本的 Zabbix Server 镜像和 MySQL 镜像。 然后,创建一个 Docker 网络以便容器可以相互通信: docker network create zabbi…

    Docker 2023年4月8日
    00
  • Docker命令

    Usage: docker COMMAND A self-sufficient runtime for containers Options: –config string Location of client config files (default “/root/.docker”) -D, –debug Enable debug mode -H, …

    Docker 2023年4月12日
    00
  • 解决docker run中使用 ./ 相对路径挂载文件或目录失败的问题

    在 Docker 中使用相对路径挂载本地文件或目录时,可能会遇到无法挂载的问题。这通常是由于 Docker 容器并不知道上层目录中相对路径的存在而造成的。 以下是如何解决这个问题的完整攻略: 问题描述 在 Docker 中使用 docker run 命令时,使用相对路径挂载本地文件或目录时可能会提示文件不存在或权限不足等错误,如下: docker run -…

    Docker 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部