IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上) -> 正文阅读

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

简介

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

源码说明

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

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

思路梳理

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

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

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

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

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

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

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

准备工作

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

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

  • 单容器:
    • 容器能访问宿主机网络
    • 容器能访问外网
  • 多容器-同局域网能访问
  • 多容器-不同局域网能访问

手动网络配置

容器启动与网桥创建

创建网桥,将我们的网段设置为:162.16.0.0/24

$ ./main network create --driver bridge --subnet 162.16.0.1/24 testbridge
{"level":"info","msg":"allocate subnet: 162.16.0.1/24, ip: 162.16.0.1","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"dump ipam file from: /var/run/mydocker/network/ipam/","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"BridgeNetworkDriver creat network subnet: 162.16.0.1/24, gateway ip: 162.16.0.1","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"createBridgeInterface success","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"setInterfaceIp success","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"crsetInterfaceUp success","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"setInterfaceUp success","time":"2022-04-23T09:37:13+08:00"}
{"level":"info","msg":"create network success","time":"2022-04-23T09:37:13+08:00"}

$ ./main network list
NAME         IpRange         Driver
testbridge   162.16.0.1/24               bridge

在宿主机上查看我们网桥,使用ip命令进行查看,可以看到我们网桥成功创建,并设置了ip为:162.16.0.1,这将作为我们容器的网关IP

$ ip addr
10: testbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 4e:83:e8:ca:fd:f2 brd ff:ff:ff:ff:ff:ff
    inet 162.16.0.1/24 brd 162.16.0.255 scope global testbridge
       valid_lft forever preferred_lft forever
    inet6 fe80::4c83:e8ff:feca:fdf2/64 scope link
       valid_lft forever preferred_lft forever

使用brctl命令查看网桥,可以看到之前我自己试验和docker的网桥,还有我们刚刚创建的网桥,它并没挂载任务的网卡,所以目前interfaces为空

$ brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.ee3baaf9db1c       no              veth0
docker0         8000.0242d4fb76d9       no              veth0cf8b9a
testbridge              8000.000000000000       no

ping一下我们的网桥,可以看到可以接通,接下来开始生成容器

$ ping 162.16.0.1
PING 162.16.0.1 (162.16.0.1) 56(84) bytes of data.
64 字节,来自 162.16.0.1: icmp_seq=1 ttl=64 时间=0.068 毫秒
64 字节,来自 162.16.0.1: icmp_seq=2 ttl=64 时间=0.102 毫秒
64 字节,来自 162.16.0.1: icmp_seq=3 ttl=64 时间=0.102 毫秒
^C
--- 162.16.0.1 ping 统计 ---
已发送 3 个包, 已接收 3 个包, 0% 包丢失, 耗时 2034 毫秒
rtt min/avg/max/mdev = 0.068/0.090/0.102/0.016 ms

使用我们编程的docker demo启动容器

./main run -d -e bird=123 -name bird top
./main logs bird

Mem: 5858364K used, 26416068K free, 99272K shrd, 126360K buff, 2733672K cached
CPU:  0.0% usr  0.0% sys  0.0% nic 99.9% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.00 0.00 0.00 1/1249 6
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND

$ ./main exec bird env |grep bird
bird=123

如上所示,到此,基本准备工作完成,开始网络的配置

创建网卡,给容器配置

首先查看下我们容器目前的网卡情况,可以看到目前只有一个本地回环网卡lo,而且ping 127.0.0.1不通,网络没有ip也没有启动

$ ./main exec bird ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

$ ./main exec bird ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
ping: sendto: Network is unreachable

目前使用ip netns list 命令,没有办法看到我们容器的网络命名空间,需要采取一些手段,将其恢复

  • 查看我们容器的PID
  • 运行命令将进程网络命名空间恢复到主机目录
$ ps -aux|grep top
root        2769  0.0  0.0 539820 10860 ?        Ssl  07:01   0:00 /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:00 top
root       39469  0.0  0.0  12132  2600 pts/4    S+   09:58   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

# 上面的39207是我们的容器PID
ln -s /proc/39207/ns/net /var/run/netns/bird

# 查看网络命名空间列表看到我们的容器命名空间
$ ip netns list
bird
k8svip (id: 1)

下面创建一对Veth,给容器和网桥进行装配

# 创建一对veth,birdveth0 放到宿主机、birdveth1放到容器内
ip link add birdveth0 type veth peer name birdveth1

# 将birdveth1放到容器网络命名空间内
ip link set birdveth1 netns bird

在容器内查看,可以看到我们的容器装配了bridveth1

$ ./main exec bird ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: birdveth1@if12: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop qlen 1000
    link/ether de:ae:81:2c:df:9a brd ff:ff:ff:ff:ff:ff

下面我们配置启动相关的网络

# 启动本地回环网卡
./main exec bird ip link set dev lo up
# 启动我们装备的bridveth1网卡
./main exec bird ip link set dev birdveth1 up

# 查看相关的配置,发现两个网卡都起来了(有UP标识),并且lo网卡有了自己的ip 127.0.0.1
$  ./main exec bird ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
11: birdveth1@if12: <NO-CARRIER,BROADCAST,MULTICAST,UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether de:ae:81:2c:df:9a brd ff:ff:ff:ff:ff:ff

# ping下本地,发现也正常了
$ ./main exec bird ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.057 ms
64 bytes from 127.0.0.1: seq=1 ttl=64 time=0.100 ms
64 bytes from 127.0.0.1: seq=2 ttl=64 time=0.103 ms
64 bytes from 127.0.0.1: seq=3 ttl=64 time=0.099 ms
64 bytes from 127.0.0.1: seq=4 ttl=64 time=0.101 ms
^C
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.057/0.092/0.103 ms

# 随便ping一下,发现网络不行
$ ./main exec bird ping 162.16.0.1
PING 162.16.0.1 (162.16.0.1): 56 data bytes
ping: sendto: Network is unreachable

讲过上面的配置,我们使用lo网卡恢复了正常,虽然birdveth1网卡功能不正常,但也装配上了

下面开始,我们开始分配相关的ip

宿主机网卡挂载网桥,使连接网关正常

我们在创建网桥的时候,已经分配了网关ip:162.16.0.1

下面我们需要给我们的容器配置同局域网内的IP:162.16.0.2

$ ./main exec bird ip addr add 162.16.0.2/24 dev birdveth1

$ ./main exec bird ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
11: birdveth1@if12: <NO-CARRIER,BROADCAST,MULTICAST,UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether de:ae:81:2c:df:9a brd ff:ff:ff:ff:ff:ff
    inet 162.16.0.2/24 scope global birdveth1
       valid_lft forever preferred_lft forever

# root @ lw-Code-01-Series-PF5NU1G in ~/code/go/dockerDemo on git:main x [10:25:39]
$ ./main exec bird ping 162.16.0.1
PING 162.16.0.1 (162.16.0.1): 56 data bytes
--- 162.16.0.1 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss

分配IP后,我们看到birdveth1有了自己的ip地址,ping 网关ip 162.16.0.1 没有报网络错误,只是没有响应,这个是宿主机的网络还没有配置完成,继续进行配置

# 将birdveth0设置到网桥上
$ ip link set dev birdveth0 master testbridge
# 启动birdveth0
$ ip link set dev birdveth0 up

# 查看相关的信息,看到birdveth0已经启动
$ ip ad
10: testbridge: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 32:ec:92:ab:76:8f brd ff:ff:ff:ff:ff:ff
    inet 162.16.0.1/24 brd 162.16.0.255 scope global testbridge
       valid_lft forever preferred_lft forever
    inet6 fe80::4c83:e8ff:feca:fdf2/64 scope link
       valid_lft forever preferred_lft forever
12: birdveth0@if11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master testbridge state DOWN group default qlen 1000
    link/ether 32:ec:92:ab:76:8f brd ff:ff:ff:ff:ff:ff link-netns bird

# 从容器内ping我们的网关,OK
$ ./main exec bird 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.113 ms
64 bytes from 162.16.0.1: seq=1 ttl=64 time=0.151 ms
^C
--- 162.16.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.113/0.132/0.151 ms

# 但ping宿主机IP还是不行,需要进行路由的配置
$ ./main exec bird ping 192.168.1.5
PING 192.168.1.5 (192.168.1.5): 56 data bytes
ping: sendto: Network is unreachable

到此为止,我们将网关部分的链路打通,接下来开始打通宿主机和容器的网络

设置路由,使容器与宿主机网络互通

我们先查看下容器内容的路由

$ ./main exec bird ip route
162.16.0.0/24 dev birdveth1 scope link  src 162.16.0.2

根据教程,我们添加下默认路由配置(博主现在也没完全掌握这部分知识,后面补补这部分知识)

# 添加路由配置
$ ./main exec bird ip route add default via 162.16.0.1

# ping 宿主机网络已经通了
$  ./main exec bird ping 192.168.1.5
PING 192.168.1.5 (192.168.1.5): 56 data bytes
64 bytes from 192.168.1.5: seq=0 ttl=64 time=0.082 ms
64 bytes from 192.168.1.5: seq=1 ttl=64 time=0.156 ms
64 bytes from 192.168.1.5: seq=2 ttl=64 time=0.154 ms
^C
--- 192.168.1.5 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.082/0.130/0.156 ms

$ ping 162.16.0.2
PING 162.16.0.2 (162.16.0.2) 56(84) bytes of data.
64 字节,来自 162.16.0.2: icmp_seq=1 ttl=64 时间=0.161 毫秒
64 字节,来自 162.16.0.2: icmp_seq=2 ttl=64 时间=0.108 毫秒
^C
--- 162.16.0.2 ping 统计 ---
已发送 2 个包, 已接收 2 个包, 0% 包丢失, 耗时 1020 毫秒
rtt min/avg/max/mdev = 0.108/0.134/0.161/0.026 ms

总结

经过上面的折腾,我们将我们的容器和宿主机网络进行打通,下篇中将继续打通容易与外部网络,让容器能与外网进行访问

参考链接

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:50:00  更:2022-04-24 09:51:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:59:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码