自己动手写Docker系列 -- 6.3 手动配置容器网络(下)

自己动手写Docker 一.容器简介 1.容器与虚拟机 2.容器的用途 3.Docker版本 二.基础技术 1.Namespace 1.1 UTS Namespace 1.2 IPC Namespace 1.3 PID Namespace 1.4 Mount Namespace 1.5 User Namesapce 1.6 Network Namespace 2.Cgroups 2.1 Cgroups中... 阅读详情

简介

网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与外部网络部分功能正常,为后面程序编写打下基础

源码说明

同时放到了Gitee和Github上,都可进行获取

本章节对应的版本标签是:5.8,防止后面代码过多,不好查看,可切换到标签版本进行查看

思路梳理

在以前的文章中,我们完成了基础容器的功能,在单机情况下基本可用,但没有网络那就不完善

网络部分目前就写了一个IP分配管理工具,和network命令,用于创建网桥

在本人尝试过程中,如果不对网络配置部分有一定的了解,对应后面网络部分的编写和理解会感到很懵

所以我们需要进行一定的热身,先手工给我们的容器配置上网络,后面再用代码完成这部分的功能

关于如何手工进行配置,在《自己动手写Docker》和文章:好文 Linux Network Namespace 与 Bridge 网桥中,都有了很好的描述

跟着上面的链接走一遍了,基本上就通了(PS:如果在ping 114.114.114.114 始终不行,可能是之前的网络配置过于乱了,将iptables规则进行清理或者重启下主机)

对于手动创建网络和配置网络,这里就不再重复,本文的重点放到如果应用上面的知识给目前的容器配置网络

手动配置容器网络

实验环境基于代码的标签:6.2

该部分代码,完成了基本的容器功能和网桥的创建,基于这个基础,我们要做的事情如下:

  • 单容器:
    • 容器能访问宿主机网络(上篇中已完成)
    • 容器能访问外网
  • 多容器-同局域网能访问
  • 多容器-不同局域网能访问

下面我们继续来完善配置

添加Iptables规则,让容器能访问外网

上篇中我们完成了宿主机与容器的网络连通,但容器目前还是不能访问外网,我们需要添加如下的iptables规则

iptables -t nat -A POSTROUTING -s 162.16.0.0/24 -j MASQUEREAD

目前宿主机的iptables规则如下,看到docker也配置了这样的一条命令

$ iptables  -t  nat  -nL --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

# 下面看到docker也添加了一条这样的规则
Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
2    MASQUERADE  all  --  182.18.0.0/24        0.0.0.0/0
3    MASQUERADE  all  --  162.16.0.0/24        0.0.0.0/0

Chain DOCKER (2 references)
num  target     prot opt source               destination
1    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

下面我们从容器内访问下:114.114.114.114,看到成功访问

$ ./main exec bird ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=77 time=32.301 ms
64 bytes from 114.114.114.114: seq=1 ttl=72 time=33.687 ms
64 bytes from 114.114.114.114: seq=2 ttl=75 time=33.727 ms
64 bytes from 114.114.114.114: seq=3 ttl=84 time=34.131 ms
64 bytes from 114.114.114.114: seq=4 ttl=82 time=35.087 ms
64 bytes from 114.114.114.114: seq=5 ttl=95 time=33.474 ms
^C
--- 114.114.114.114 ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max = 32.301/33.734/35.087 ms

新增同局域网内的容器,进行访问

和上篇基本一样的操作,将新起动的容器分配同上一个容器一样的局域网ip:162.16.0.3

# 新启动容器2
$ ./main run -d -e bird=123 -name bird2 top
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-23T14:38:34+08:00"}
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-04-23T14:38:34+08:00"}
{"level":"info","msg":"all command is : top","time":"2022-04-23T14:38:34+08:00"}
{"level":"info","msg":"parent process run","time":"2022-04-23T14:38:34+08:00"}

# 新建veth,设置宿主机端的veth
$ ip link add birdveth2 type veth peer name birdveth3
$  ip link set dev birdveth2 master testbridge
$ ip link set dev birdveth2 up

# 设置容器2内部的veth
$ ps -aux|grep top
root        2769  0.0  0.0 539820 10860 ?        Ssl  07:01   0:01 /usr/libexec/xdg-desktop-portal
root        2773  0.0  0.0 500052 29516 ?        Ssl  07:01   0:00 /usr/libexec/xdg-desktop-portal-gtk
root       39207  0.0  0.0   1328     4 pts/4    S    09:47   0:01 top
root       64560  0.0  0.0   1328     4 pts/4    S    14:38   0:00 top
root       64749  0.0  0.0  12132   724 pts/4    R+   14:47   0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox top

$ ln -s /proc/64560/ns/net /var/run/netns/bird2

$ ip netns list
bird2
bird (id: 2)
k8svip (id: 1)

$ ip link set birdveth3 netns bird2
$ ./main exec bird2 ip link set dev lo up
$ ./main exec bird2 ip link set dev birdveth3 up
$ ./main exec bird2 ip addr add 162.16.0.3/24 dev birdveth3

# 成功ping通网关
$  ./main exec bird2 ping 162.16.0.1
PING 162.16.0.1 (162.16.0.1): 56 data bytes
64 bytes from 162.16.0.1: seq=0 ttl=64 time=0.135 ms
64 bytes from 162.16.0.1: seq=1 ttl=64 time=0.152 ms
^C
--- 162.16.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.135/0.143/0.152 ms

# 容器2能成功联通容器1
$  ./main exec bird2 ping 162.16.0.2
PING 162.16.0.2 (162.16.0.2): 56 data bytes
64 bytes from 162.16.0.2: seq=0 ttl=64 time=0.138 ms
64 bytes from 162.16.0.2: seq=1 ttl=64 time=0.154 ms
^C
--- 162.16.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.138/0.146/0.154 ms


# 容器1能成功联通容器2
$  ./main exec bird ping 162.16.0.3
PING 162.16.0.3 (162.16.0.3): 56 data bytes
64 bytes from 162.16.0.3: seq=0 ttl=64 time=0.090 ms
64 bytes from 162.16.0.3: seq=1 ttl=64 time=0.154 ms
^C
--- 162.16.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.090/0.122/0.154 ms

$ ./main exec bird2 ip route add default via 162.16.0.1

$ ./main exec bird2 ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=82 time=32.376 ms
64 bytes from 114.114.114.114: seq=1 ttl=92 time=37.692 ms
^C
--- 114.114.114.114 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 32.376/35.034/37.692 ms

经过试验,我们处于同一个局域网的容器是能够联通的

配置DNAT,让外部能够访问内部服务

首先我们在容器内监听95端口,然后在宿主机内访问95端口是能正常访问的

# 在容器内监听95端口,能收到相关指令
$ ./main exec bird nc -lp 95
jkjfdks
kfjskd
��������
quit
exit
exit()
quit()

# 在宿主机中进行telnet并发送指令,如上可以进行显示(ctrl + ],后输入quit,退出telnet)
$ telnet 162.16.0.2 95
Trying 162.16.0.2...
Connected to 162.16.0.2.
Escape character is '^]'.
jkjfdks
kfjskd
^C^C
quit
exit
exit()
quit()
^]
telnet> quit
Connection closed.

但是如同我们在使用docker的过程中,我们是映射了端口的,如:docker run -tid --name centos8-2 -p 90:90 centos:8 bash

在上面的示例中,我们访问容器所在宿主机90端口,就能访问到容器的90端口,下面我们就通过配置来达到这个目的

进行下面的配置,下面会将宿主机95端口上的请求,都转到容器 162.16.0.2的95端口上

# 配置规则
$ iptables -t nat -A PREROUTING -p tcp -m tcp --dport 95 -j DNAT --to-destination 162.16.0.2:95

# 查看规则,看到docker也是通过相关配置达到这个目的的
$ iptables  -t  nat  -nL --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
2    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:95 to:162.16.0.2:95

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
2    MASQUERADE  all  --  182.18.0.0/24        0.0.0.0/0
3    MASQUERADE  all  --  162.16.0.0/24        0.0.0.0/0
4    MASQUERADE  tcp  --  172.17.0.3           172.17.0.3           tcp dpt:90

Chain DOCKER (2 references)
num  target     prot opt source               destination
1    RETURN     all  --  0.0.0.0/0            0.0.0.0/0
2    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:90 to:172.17.0.3:90
# 在宿主机上监听95端口
nc -lp 95

# 新开shell或者在和宿主机同一个局域网的主机上进行telnet连接
telnet 192.168.1.5 95 

重新启动容器监听后,看到相关的输出,证明外部也访问容器服务了

$ ./main exec bird nc -lp 95
jkjfdskfjs

总结

不同局域网的互通,尝试了下,有点难度,目前本人的知识理解还不能做到,只能后面再补上了,先通过实现这部分的功能

【docker+openvswitch系列三】ovs-docker配置网络 ovs-docker配置网络 docker和openvswitch的环境搭建教程参考: 【docker+openvswitch系列一】在ubuntu下搭建docker环境 【docker+openvswitch系列二】在ubuntu下搭建openvswitch环境 本文参考:https://www.cnblogs.com/whych/p/9601889.html 首先搬来了实验结构图: 正题: ... 阅读详情

相关推荐

docker容器网络配置

文章目录docker容器网络docker的4种网络模式及其配置bridge模式container模式host模式none模式利用ip netns创建名称空间并配置IP使其通信ip netns命令创建Network Namespace操作Network Namespace转移设备veth pair创建veth pairveth设备重命名容器常规操作查看容器的主机名在容器启动时注入主机名手动指定容器要使用的DNS手动往/etc/hosts文件中注入主机名到IP地址的映射开放容器端口 docker容器网络 Doc

weixin_55734444的博客 2764

自己动手写Docker学习笔记

从零实现一个Docker

weixin_49687704的博客 1063

Docker容器网络

Docker容器网络、Docker容器网络配置、容器常用操作

时羽天的博客 1877

动手实现docker全过程

Github项目地址命名空间就像一层隔板,有了这层隔板,就会让隔板内的人以为自己独享这片天地,这层隔板有各种各样的,比如,,等等,暂时可以这么理解。IPC Namespace 是 Linux Namespace 机制的一部分,专门用于隔离进程间通信资源。它在容器技术中的作用是确保每个容器有自己的 IPC 资源,而不会与宿主机或其他容器共享,从而增强了安全性和资源隔离能力。而像这样的命名空间还有很多,docker就是采取这些Namespace来实现隔离的。容器是什么,docker又是什么?想清楚这一点,我们才

Rinai的博客 1385

Docker怎样配置容器间的网络通信?

Docker通过Linux内核的​​ 实现容器网络隔离,每个容器拥有独立的网络栈(IP地址、路由表、端口范围)。容器与主机间通过​​ 连接,一端在容器内(显示为eth0),另一端连接到宿主机网桥或物理网卡。bridgehostoverlaymacvlan,分别对应不同通信场景。

iddlw75046的博客 1581

FPGA新手避坑指南:手把手教你搞定RTL8211千兆网PHY的时序配置(附Verilog代码)

本文详细解析了FPGA与RTL8211千兆网PHY芯片的时序配置问题,重点介绍了TXDLY/RXDLY引脚设置、FPGA发送端和接收端的Verilog实现,以及调试与验证的完整流程。通过硬件电路设计和代码示例,帮助开发者解决网络连接不稳定、丢包等常见问题,提升千兆网通信的稳定性。

weixin_28732953的博客 538

【容器系列】500行代码手写docker-以新命名空间运行程序

本系列教程主要是为了弄清楚容器化的原理,纸上得来终觉浅,绝知此事要躬行,理论始终不及动手实践来的深刻,所以这个系列会用go语言实现一个类似docker的容器化功能,最终能够容器化的运行一个进程。本章要完成的任务则是golang启动一个sh的进程,并且sh的进程将在新的命名空间中运行。届时运行效果如下:在正式开始编写代码前,先来看看linux namespace涉及的一些原理。

我活在当下,我巨他妈勇敢。 365

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡

ADRV9009学习资料保存:基于XC7Z100+ADRV9009的双收双发无线电射频板卡 一、板卡概述 基于XC7Z100+ADRV9009的双收双发无线电射频板卡是基于XilinxZYNQFPGA和ADI的无线收发芯片ADRV9009开发的专用功能板卡,用于5G小基站,无线图传,数据收发...

9353

【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上)

网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与宿主机网络部分功能正常,为后面程序编写打下基础

github_35735591的博客 1092

LC与RC滤波电路实战对比:从原理到选型指南

本文深入对比了LC与RC滤波电路的核心原理与实战应用。LC滤波利用电感与电容的无损能量搬运,适合高频、大电流电源滤波,效率高但需注意谐振风险;RC滤波通过电阻消耗能量实现滤波,结构简单、成本低,适用于低频信号处理或小电流供电场景。文章提供了从工作原理、性能维度到具体选型的完整指南,帮助工程师根据项目需求(如频率范围、负载电流、效率)做出精准选择。

weixin_29240711的博客 499

手机OIS马达拆解:从苹果的悬丝到三星的滚珠,不同方案如何影响你的拍照体验?

本文深度解析手机OIS马达技术,对比苹果悬丝式、三星滚珠式和LG记忆合金式三种主流方案的机械原理与成像体验差异。通过详实的数据和测试结果,揭示不同OIS技术如何影响防抖性能、模组厚度及长期可靠性,为摄影爱好者和技术爱好者提供实用选购建议。

weixin_42554408的博客 303

自己动手写 Docker 系列文章总览

本文章系列起源于:《自己动手写 Docker》,编程实践方得真知,虽然大部分代码书中都有,但还是遇到了不少困难,下面是对于自己写的 Docker Demo 的总览

github_35735591的博客 2268

NotebookLM平替实测:用Open Notebook+Ollama零成本搭建私有AI知识库

本文提供了一份详细的实战指南,教你如何利用Open Notebook与Ollama,在本地零成本搭建一个功能强大且完全私有的AI知识库。通过Docker容器化部署,实现数据绝对安全、模型自由选择与离线运行,是NotebookLM等云端工具的绝佳平替方案,尤其适合注重数据隐私的教育工作者、研究者及小团队。

weixin_29052717的博客 513

自己动手写 Docker 系列 -- 6.5 启动时给容器配置网络

在上几篇文章中,我们使用自己程序创建的网桥和手动配置,让容器的网络功能正常,本篇就利用之前的知识,自动配置容器网络

github_35735591的博客 591

在 SAP BTP Cloud Foundry 环境中开发 SAP HANA 的完整实战路线图

SAP HANA Cloud迁移路径解析:从本地到云原生的数据库现代化 本文梳理了SAP HANA在Cloud Foundry环境中的架构定位和实施路径,针对不同起点的项目提供迁移建议。核心内容包括: SAP HANA Cloud在Cloud Foundry中的双重角色:既作为平台服务提供数据库实例,又通过HDI容器管理MTA应用中的数据库工件。 针对四类典型项目起点的迁移策略: 绿地项目:直接采用CAP+SAP HANA Cloud组合 已有HANA service或XS advanced项目:需对照兼容

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 262

工业级稳定!C# 实现 Modbus RTU 多设备并发通信实战

摘要:本文提出一种基于C#的Modbus RTU多设备并发通信方案,解决工业自动化中单线程通信的串口抢占、数据阻塞等问题。采用任务队列+线程安全锁+异步调度的三层架构,实现16台及以上RTU设备的稳定并发读写。方案包含串口管理单例、Modbus通信核心和任务调度层,支持超时重试、异常捕获等工业级容错机制。通过NModbus库和.NET框架,提供可直接用于工业现场的代码实现,已在工控项目中长期验证,有效提升多设备通信效率和稳定性。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 577

docker — 容器网络

1. 挂在 host 网络上的容器共享宿主机的 network namespace。1. none 网络的 driver 类型是 null,IPAM字段为空。挂载 none 网络上的容器只有 lo,无法与外界通信。即容器的网络配置与 host 网络配置完全一样。docker0 网络创建时已默认配置了 Subnet。docker0 是一个 linux bridge。容器创建时,默认挂载在 docker0 上。c3 加入 net2 并配置静态IP。c3 与 c2 可以通信。其中c1加入net1。

qq_41619571的博客 6939

C# 从数秒到毫秒:MySQL+Redis百万数据优化实战全解析

在处理百万级数据时,传统单体数据库常面临查询效率低下、数据库负载过高和用户体验差等问题。为解决这些性能瓶颈,可以采用MySQL分库分表、Redis缓存和异步统计的组合策略。 数据库分片:通过水平分表和分库实现,将单表数据分散到多个物理表或数据库实例中,降低单点负载。 Redis缓存:利用Redis缓存高频数据,减少数据库查询压力,提升响应速度。 异步统计:通过消息队列(如RabbitMQ)解耦统计任务,后台处理非实时任务,避免阻塞主流程。 这些优化策略能够显著提升系统性能,确保在高并发和大数据量场景下的稳定

墨夶的博客 852

Docker学习(6) 容器网络

Docker 容器网络

wang_8218的博客 2611

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Docker 容器网络及其配置说明

自定义 docker0 网桥的网络属性信息需要修改 /etc/docker/daemon.json 配置文件在客户端上像 dockerd 直接传递 "-H|–host"选项指定要控制哪台主机上的 docker 容器/ #再创建一个容器,使用默认的bridge桥/ # ls/ #

mry6的博客 3507

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Docker:手动配置容器网络

docker容器的网络是net命名空间与虚拟设备的结合,容器在启动时会创建一对虚拟接口veth pair,这一对接口分别放到本地和容器中,在本地的veth会被分配类似vethxxxx的名称并被桥接到指定网桥的上(默认为docker0),可以通过brctl show命令查看网桥上挂载的接口,在容器中的veth会从网桥获取一个未使用地址,该veth的名称会被更改为eth0并配置默认路由到vethxxx

xitongfengxi的专栏 1162

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Docker网络配置:容器间通信与容器访问外网的方法

本文深入探讨Docker网络配置的核心概念与实践方法,主要包含以下内容: 容器间通信:通过桥接网络、覆盖网络等Docker原生网络驱动实现容器互联 外网访问:配置NAT规则、端口映射和代理服务实现容器访问外部网络 网络模型:解析Docker的网络架构,包括bridge、host、none等网络模式 实践方法:提供TCP/UDP服务器示例代码,演示网络编程基础 性能考量:分析带宽、延迟、吞吐量等关键网络指标 文章采用从理论到实践的递进结构,涵盖网络分层模型、协议原

未来 95% 的 AI 应用将变得隐形,广泛融入日常生活。 2076

Docker容器网络配置

docker容器网络配置

灼烧的疯狂 1486

Docker续6:容器网络

新建两台主机:node1主控 192.168.1.78node2被控 192.168.1.79。

m0_70848838的博客 1708

docker容器网络与配置

docker容器网络与配置 文章目录docker容器网络与配置一. docker4种网络模式1. 用 ` docker network ls ` 可以查看3种网络模式2. docker网络模式3. bridge模式,桥接模式4. container模式,容器模式5. host模式,主机模式6. none模式,无网络模式二. docker容器网络配置1. 网络名称空间的创建与配置1.1 内核名称空间的创建1.2 启动两个lo网卡1.3 创建veth pair 将veth0和veth1两个虚拟网卡连接了起来1.

mushuangpanny的博客 1417
上一篇: 【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上)
下一篇: 自己动手写 Docker 系列 -- 6.5 启动时给容器配置网络
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值