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日

相关文章

  • Odoo安装之docker部署

    本次介绍一下odoo在docker上的安装部署 安装docker docker在windows和mac上一般都用desktop版,方便操作,Linux上用命令行版即可。windowshttps://docs.docker.com/docker-for-windows/install/machttps://docs.docker.com/docker-for-…

    Docker 2023年4月13日
    00
  • 如何精简 Prometheus 的指标和存储占用

    前言 随着 Prometheus 监控的组件、数量、指标越来越多,Prometheus 对计算性能的要求会越来越高,存储占用也会越来越多。 在这种情况下,要优化 Prometheus 性能, 优化存储占用. 第一时间想到的可能是各种 Prometheus 的兼容存储方案, 如 Thanos 或 VM、Mimir 等。但是实际上虽然集中存储、长期存储、存储降采…

    Docker 2023年4月11日
    00
  • Armbian5.9.0安装docker及部署可视化portainer的详细教程

    这里是“Armbian5.9.0安装docker及部署可视化portainer的详细教程”的完整攻略,并包含两条示例说明。 安装docker 更新系统和安装需要的依赖: bash sudo apt-get update sudo apt-get upgrade sudo apt-get install apt-transport-https ca-certi…

    Docker 2023年5月15日
    00
  • 怎么通过DOCKER OVERLAY2目录名查找容器名和容器ID

    这篇“怎么通过DOCKER OVERLAY2目录名查找容器名和容器ID”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么通过DOCKER OVERLAY2目录名查找容器名和容器ID”文章吧。 通过DOCKER OVERLAY2目录名查找容器名和…

    Docker 2023年4月10日
    00
  • 远程云服务器上docker安装redis的过程

    首先明确一点,云服务环境你已经安装好了docker(可参考菜鸟教程:https://www.runoob.com/docker/centos-docker-install.html) 1.安装好以后,输入版本查看命令: docker -v 2.进入docker hub官网查看你所需要的redis的版本信息 docker hub     3.远程连接服务的工具…

    Docker 2023年4月10日
    00
  • 在Linux服务器上升级Docker的教程

    请看下面的内容。 升级Docker的前提条件 在Linux服务器上升级Docker的前提条件如下: 已经安装过 Docker。 你的操作系统和 Docker 的版本之间有兼容性。 升级Docker的步骤 接下来我们来讲解升级 Docker 的步骤: 第一步:备份 在升级之前,最好先做一次备份,以免升级出现问题导致数据丢失。你可以使用以下命令进行备份: sud…

    Docker 2023年5月15日
    00
  • Ubuntu15.10安装docker和docker-compose教程

    Ubuntu15.10安装docker和docker-compose教程 本文将介绍在Ubuntu15.10上安装docker和docker-compose的详细步骤。并且附带两个实例说明如何使用docker和docker-compose。 步骤1:安装Docker 首先,我们需要安装Docker。按照以下步骤进行操作: 更新软件包列表和依赖关系 sudo …

    Docker 2023年5月16日
    00
  • 详解在Ubuntu 14.04安装和使用Docker

    详解在Ubuntu 14.04安装和使用Docker 旨在为初学者提供一份详细的学习指南,以演示如何在Ubuntu 14.04上安装和使用Docker。以下是安装步骤及示例说明: 环境要求 在安装和使用Docker之前,请确保您已满足以下要求: Ubuntu 14.04 LTS操作系统 64位CPU架构 内核版本3.10以上 步骤1. 安装依赖 在安装Doc…

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