Docker 网络

一、背景:

        想一下这个问题,容器和容器之间是否可以通过网络正常通信?宿主机和容器是否可以通信?如果可以通信,那为什么可以通信。如果不可以通信,如何让他们之间通信。接下来就详细的讲解下 docker 的网络。

二、Docker 网络现状

        1、首先删除所有的镜像和容器,如下所示:

 # 删除所有容器
docker rm -f $(docker ps -aq)# 删除所有镜像,这个 rmi 是专门删除镜像的命令
docker rmi -f $(docker images -aq) 

        2、 查看网卡信息,如下所示:

ip addr

        如果你出现的是下面的这种多个地址,那么你可以进行 删除 virbr0 和修改 ens33 的操作。

        3、docker 的容器和容器之间是如何进行网络访问的?如下所示:

# 运行 tomcat 容器
docker run -d --name tomcat01 tomcat# 进入容器
docker exec -it tomcat01 bash# 下载安装 ip 命令相关的安装包
apt-get update & apt-get install -y iproute2 # 查看ip
ip addr

        我们可以发现,172.17.0.2 是容器的地址,我们用宿主机测试下是否可以 ping 通容器的地址,如下所示,发现是可以 ping 通的。

三、原理分析:

        1、每启动一个 docker 容器,docker 就会给容器分配一个 IP,只要我们安装了 docker 就会有一个默认的网卡 docker0,使用的是桥接模式,veth-pair (虚拟网线,即一端连着容器,一端连着 docker0 的网卡)技术。

        再启动一个 tomcat 容器,命令如下:

# 运行 tomcat 镜像
docker run -d --name tomcat02 tomcat# 进入容器
docker exec -it tomcat02 bash# 下载安装 ip 命令相关的安装包
apt-get update & apt-get install -y iproute2 # 查看ip
ip addr

        查看容器和宿主机 ip 如下所示:

        我们发现,这个容器带来的网卡都是一对一对的,veth-pair 就是一对虚拟设备接口,他们都是成对出现,一端连着协议,一端彼此相连,veth-pair 充当于一个桥梁,连接各种网络设备。

        2、测试 tomcat02 是否可以 ping tomcat01,如下所示:

        结论: Tomcat01 Tomcat02 是公用的一个路由器 docker0,左右的容器在不指定网络的情况下,都是 docker0 来路由的,docker 会给我们分配一个默认的可用 IP

        Docker 使用的是 Linux 桥接,如下图所示:

四、Docker 的 Link 参数:

        1、思考一个场景,我们编写了一个微服务,比如 mysql 的连接地址为:database.url=ip:port ,如果数据库 IP 换掉了,我们想不重启解决这个问题,是否可以通过名字访问容器?

        测试是否可以通过容器名称 ping 通另一个容器,如下所示,ping 不通。

        我们使用 link 的方式再次启动一个容器 tomcat03 ,再次尝试,如下所示:

# 启动 tomcat03 容器
docker run -d --name tomcat03 --link tomcat01 tomcat# 进入容器
docker exec -it tomcat03 bash# 安装 ping 工具
apt-get update & apt-get install -y iputils-ping# 测试
ping tomcat01

        我们发现 tomcat03 是可以 ping tomcat01 的,那么反过来可以吗?显然是不可以的。

        因为我们在启动 tomcat03 的时候在本地配置了 tomcat01,如下所示:

        --link 参数就是在 hosts 中增加了 172.17.0.2 tomcat01 202aa737790a,但是我们现在已经不推荐这种方式了。即 docker0 不支持自定义网络。

五、自定义网络

        1、查看所有的 docker 网络,输入 docker network ls ,如下所示:

bridge:桥接 docker(默认,自己创建也使用 bridge 模式)

none:不配置网络

host:和宿主机共享网络

container:容器网络连通(用的少)

# 这两个命令是一样的,只不过 --net bridge 可以省略,是默认的
#  --net bridge, 这个就是我们的 docker0
# docker0 的特点是默认不能访问域名,但是可以通过 --link 打通,但是太麻烦,不推荐
docker run -d --name tomcat01 tomcat = docker run -d --name tomcat01 --net bridge tomcat

        2、我们可以自定义一个网络,首先输入 docker network --help 查看需要的参数,如下所示:

        接下来执行下面命令,并查看当前的网络信息

# --driver bridge ,桥接的方式
# --subnet 192.168.0.0/16 (16代表255*255个端口=65535) 192.168.0.2 到 192.168.255.255
# --gateway 192.168.0.1,设置网关 ip
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 xhf_net

        我们自己的网络就建好了,如下所示:

        3、接下来重新创建两个 tomcat 容器,测试是否互通,命令如下:

# 先启动 tomcat_01
docker run -d --name tomcat_01 --net xhf_net tomcat# 进入容器
docker exec -it tomcat_01 bash# 配置 dns,要不无法访问互联网
echo "nameserver 8.8.8.8" >> /etc/resolv.conf# 安装 ping 工具
apt-get update & apt-get install -y iputils-ping# 再启动 tomcat_02
docker run -d --name tomcat_02 --net xhf_net tomcat# 进入容器
docker exec -it tomcat_02 bash# 配置 dns,要不无法访问互联网
echo "nameserver 8.8.8.8" >> /etc/resolv.conf# 安装 ping 工具
apt-get update & apt-get install -y iputils-ping

        反向测试也没有问题,网络是互通的,即我们自定义的网络,docker 都已经帮我们维护好了对应关系,推荐这样使用。

        4、针对于 mysql redis 集群来说,好处是不同集群使用不同网络,保证集群安全、健康。

        5、如果此时我想 tomcat01 和 tomcat_01 互通,也就是和 xhf_net 打通,怎么操作?

# 将 xhf_net 和 tomcat01 打通
docker network connect xhf_net tomcat01

        查看 xhf_net 详情,如下所示,发现 xhf_net Containers 中多了一个 tomcat01 容器。

docker network inspect xhf_net

        6、假如我要跨网络操作别人,就需要用 docker network connect 来连接。即 docker 通过一个容器两个 IP 的方式,如:阿里云公网 IP 和私网 IP,将两个容器打通。

六、redis 集群实战

        我们创建一个 redis 集群,分配同一个网段,测试其中一个节点挂掉之后,其他的节点是否还可以继续工作。

        1、创建网卡 redis 和相关的配置文件,如下所示:

# 创建网卡
docker network create redis --subnet 172.38.0.0/16# 使用脚本创建6个配置文件
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379 
bind 0.0.0.0
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

        2、启动六个 redis 容器,如下所示:

# 启动redis-1
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \-v /mydata/redis/node-1/data:/data \-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 启动redis-2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \-v /mydata/redis/node-2/data:/data \-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 启动redis-3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \-v /mydata/redis/node-3/data:/data \-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 启动redis-4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \-v /mydata/redis/node-4/data:/data \-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 启动redis-5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \-v /mydata/redis/node-5/data:/data \-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 启动redis-6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \-v /mydata/redis/node-6/data:/data \-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

        3、创建集群,命令如下:

# 随便进入一个容器
docker exec -it redis-1 /bin/sh# 创建集群的命令
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

        4、测试主从,当主挂了之后,从是否会成为主

# 进入容器
docker exec -it redis-1 /bin/sh# 进入 redis 命令行模式
redis-cli -c# 查看集群信息
cluster info# 查看节点信息
CLUSTER nodes

#  随便存一个值,发现存在172.38.0.13:6379
set a b# 当172.38.0.13 这台服务挂了之后,测试是否能查询到值,停掉 redis-3
docker stop redis-3# 重新查询
get a# 重新查看节点状态,发现 172.38.0.13:6379 fail, 172.38.0.14 已经成为了 master
CLUSTER nodes 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/22596.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【编译之美】【4. 代码优化:为什么你的代码比他的更高效】

什么是代码优化 代码优化是编译器后端的两大工作之一&#xff0c;弄懂它&#xff0c;你就掌握了一大块后端技术。 代码优化的目标 代码优化的目标&#xff0c;是优化程序对计算机资源的使用。 代码优化的对象 大多数的代码优化都是在 IR 上做的&#xff0c;而不是在前一阶段…

数据结构---手撕图解堆的实现和TopK的应用

文章目录 重要的概念树的存储方式顺序存储链式存储 堆的概念堆的实现向上调整算法一些实现过程中的技巧实现搭建堆实现出堆的操作向下调整算法 堆排序TopK 重要的概念 要讲到堆&#xff0c;先要说两个关于二叉树的概念 满二叉树&#xff1a;一个二叉树如果每一层的节点数都是最…

FastDVDnet Towards Real-Time Deep Video Denoising Without Flow

FastDVDnet: Towards Real-Time Deep Video Denoising Without Flow Estimation 原文&#xff1a; https://ieeexplore.ieee.org/document/9156652 由于视频有着较强的时间相关性&#xff0c;那么一个好的视频去噪算法必将要充分利用这一特点。利用时间相关性主要体现为两个方面…

Serverless是什么?如何使用?有哪些优势?国内外有哪些Serverless平台?

111. Serverless是什么&#xff1f;如何使用&#xff1f;有哪些优势&#xff1f;国内外有哪些Serverless平台&#xff1f; 一、 Serverless是什么&#xff1f; 百度百科 Serverless 是云计算的一种模型。以平台即服务&#xff08;PaaS&#xff09;为基础&#xff0c;无服务器…

微调预训练的 NLP 模型

动动发财的小手&#xff0c;点个赞吧&#xff01; 针对任何领域微调预训练 NLP 模型的分步指南 简介 在当今世界&#xff0c;预训练 NLP 模型的可用性极大地简化了使用深度学习技术对文本数据的解释。然而&#xff0c;虽然这些模型在一般任务中表现出色&#xff0c;但它们往往缺…

OpenCv (C++) 使用矩形 Rect 覆盖图像中某个区域

文章目录 1. 使用矩形将图像中某个区域置为黑色2. cv::Rect 类介绍 1. 使用矩形将图像中某个区域置为黑色 推荐参考博客&#xff1a;OpenCV实现将任意形状ROI区域置黑&#xff08;多边形区域置黑&#xff09; 比较常用的是使用 Rect 矩形实现该功能&#xff0c;代码如下&…

SciencePub学术 | 区块链类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 区块链类重点SCIE&EI征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; SCI-01 【期刊简介】IF&#xff1a;4.0-4.5&#xff0c;JCR2区&#xff0c;中科院3区&#xff1b; 【检索情况】SCIE&EI双检&…

性能测试工具 Jmeter 测试 JMS (Java Message Service)/ActiveMQ 性能

目录 前言 ActiveMQ 介绍 准备工作 编写jndi.properties添加到ApacheJMeter.jar 中 下载 ActiveMQ 配置 Jmeter 进行测试 点对点 (Queues 队列) 配置 Jmeter 进行测试 发布/订阅 (Topic 队列) 配置发布 Publisher 配置订阅 Subscriber 总结 前言 JMeter是一个功能强大…

机械设计制造及其自动化专业向PLC方向发展的可行性

是的&#xff0c;机械设计制造及其自动化专业往PLC&#xff08;可编程逻辑控制器&#xff09;方向发展是可行的。PLC是一种用于控制和自动化各种机械设备和工业过程的计算机控制系统。它被广泛应用于工业自动化领域&#xff0c;包括制造业、能源行业、交通运输等。 我这里刚好…

ECMAScript 6 之二

目录 2.6 Symbol 2.7 Map 和 Set 2.8 迭代器和生成器 2.9 Promise对象 2.10 Proxy对象 2.11 async的用法 2.22 类class 2.23 模块化实现 2.6 Symbol 原始数据类型&#xff0c;它表示是独一无二的值。它属于 JavaScript 语言的原生数据类型之一&#xff0c;其他数据类型…

将媒体公司资产迁移到 Amazon S3 的技术方案

随着媒体公司的发展&#xff0c;他们在仓库中积累了大量的旧磁带和未数字化的视频。这些资产可能很有价值&#xff0c;但以目前的形式很难访问和货币化。此外&#xff0c;将这些资产存储在仓库中既有风险又昂贵。 媒体企业可以通过将其资产迁移到云存储来解决这些问题&#xf…

i.MX6ULL(十五) 根文件系统

Linux“三巨头”已经完成了 2 个了&#xff0c;就剩最后一个 rootfs( 根文件系统 ) 了&#xff0c;本章我们就来学 习一下根文件系统的组成以及如何构建根文件系统。这是 Linux 移植的最后一步&#xff0c;根文件系统 构建好以后就意味着我们已经拥有了一个完整的、可以运…