[mydocker]---网络实现测试

1. 前言

根据前面几篇文章的内容, 本文就可以实现网络部分的内容了, 所以接下来就可以进行测试.

2. network测试

需要加上network命令.

2.1 增加network命令

包括network create, network list, network remove.

var NetworkCommand = cli.Command{
    Name:  "network",
    Usage: "container network commands",
    Subcommands: []cli.Command {
        {
            Name: "create",
            Usage: "create a container network",
            Flags: []cli.Flag{
                cli.StringFlag{
                    Name:  "driver",
                    Usage: "network driver",
                },
                cli.StringFlag{
                    Name:  "subnet",
                    Usage: "subnet cidr",
                },
            },
            Action:func(context *cli.Context) error {
                if len(context.Args()) < 1 {
                    return fmt.Errorf("Missing network name")
                }
                network.Init()
                err := network.CreateNetwork(context.String("driver"), context.String("subnet"), context.Args()[0])
                if err != nil {
                    return fmt.Errorf("create network error: %+v", err)
                }
                return nil
            },
        },
        {
            Name: "list",
            Usage: "list container network",
            Action:func(context *cli.Context) error {
                network.Init()
                network.ListNetwork()
                return nil
            },
        },
        {
            Name: "remove",
            Usage: "remove container network",
            Action:func(context *cli.Context) error {
                if len(context.Args()) < 1 {
                    return fmt.Errorf("Missing network name")
                }
                network.Init()
                err := network.DeleteNetwork(context.Args()[0])
                if err != nil {
                    return fmt.Errorf("remove network error: %+v", err)
                }
                return nil
            },
        },
    },
}

2.2 测试

root@nicktming:~/go/src/github.com/nicktming/mydocker# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:58:9a:c3 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
root@nicktming:~/go/src/github.com/nicktming/mydocker# 
root@nicktming:~/go/src/github.com/nicktming/mydocker# iptables -t nat -vnL POSTROUTING --line
Chain POSTROUTING (policy ACCEPT 2 packets, 120 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       14   998 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker network create --driver bridge --subnet 192.168.10.1/24 testbridge01
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker network list
NAME           IpRange           Driver
testbridge01   192.168.10.1/24   bridge
root@nicktming:~/go/src/github.com/nicktming/mydocker# ifconfig testbridge01
testbridge01 Link encap:Ethernet  HWaddr 02:f4:c8:97:df:39  
          inet addr:192.168.10.1  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
root@nicktming:~/go/src/github.com/nicktming/mydocker# iptables -t nat -vnL POSTROUTING --line
Chain POSTROUTING (policy ACCEPT 2 packets, 135 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       14   998 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
2        0     0 MASQUERADE  all  --  *      !testbridge01  192.168.10.0/24      0.0.0.0/0           
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker network remove testbridge01
root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker network list
NAME        IpRange     Driver

3. 创建容器

现在已经可以创建网络了, 以网桥为例, 创建网络的时候已经在宿主机上配置好了网桥. 下一步创建容器的时候会启动一个新的network namespace, 因此只需要在network namespace配置好网络和路由就可以了. 在前面几篇文章已经分析过了.

3.1 修改Run命令

增加netp参数.

var RunCommand = cli.Command{
    Name: "run",
    Flags: []cli.Flag {
        ...
        cli.StringFlag{
            Name:  "net",
            Usage: "container network",
        },
        cli.StringSliceFlag{
            Name: "p",
            Usage: "port mapping",
        },
        ...
    },
    Action: func(c *cli.Context) error {
        ...
        network := c.String("net")
        portMapping := c.StringSlice("p")
        ...

        Run(command, tty, &cg, rootPath, volumes, containerName, imageName, envSlice, network, portMapping)
        return nil
    },
}

修改Run方法

func Run(command string, tty bool, cg *cgroups.CroupManger, rootPath string, volumes []string, containerName, imageName string, envSlice []string, nw string, portMapping []string)  {

    ...
    /**
     *   Start() will not block, so it needs to use Wait()
     *   Run() will block
     */
    if err := cmd.Start(); err != nil {
        log.Printf("Run Start err: %v.\n", err)
        log.Fatal(err)
    }

    if nw != "" {
        // config container network
        network.Init()
        containerInfo := &container.ContainerInfo{
            Id:          id,
            Pid:         strconv.Itoa(cmd.Process.Pid),
            Name:        containerName,
            PortMapping: portMapping,
        }
        if err := network.Connect(nw, containerInfo); err != nil {
            log.Printf("Error Connect Network %v", err)
            return
        }
    }

    ...
}

在这里修改了一下ContainerUUID方法, 因为之前生成UUID方法是当前时间加一个一个随机数, 由于Veth设备的名字会取前5位, 所以启动很多容器的时候设备名都是一样的, 会报错.

func ContainerUUID() string {
    //str := time.Now().UnixNano()
    //containerId := fmt.Sprintf("%d%d", str, int(math.Abs(float64(rand.Intn(10)))))
    ////log.Printf("containerId:%s\n", containerId)
    //return containerId
    letterBytes := "1234567890"
    rand.Seed(time.Now().UnixNano())
    b := make([]byte, 10)
    for i := range b {
        b[i] = letterBytes[rand.Intn(len(letterBytes))]
    }
    return string(b)
}

3.2 测试

root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker run -it -p 80:80 -net testbridge01 busybox /bin/sh
2019/05/09 22:47:17 rootPath is empaty, set rootPath: /nicktming
2019/05/09 22:47:17 current path: /nicktming/mnt/15574132372127349531.
/ # ifconfig
cif-15574 Link encap:Ethernet  HWaddr 0A:A9:1E:91:0B:BD  
          inet addr:192.168.10.3  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::8a9:1eff:fe91:bbd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:508 (508.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 cif-15574
192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 cif-15574
/ # ping -c 1 192.168.10.3
PING 192.168.10.3 (192.168.10.3): 56 data bytes
64 bytes from 192.168.10.3: seq=0 ttl=64 time=0.042 ms

--- 192.168.10.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.042/0.042/0.042 ms
/ # ping -c 1 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.039 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.039/0.039/0.039 ms
/ # ping -c 1 192.168.10.1
PING 192.168.10.1 (192.168.10.1): 56 data bytes
64 bytes from 192.168.10.1: seq=0 ttl=64 time=0.067 ms

--- 192.168.10.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.067/0.067 ms
/ # ping -c 1 172.19.16.7
PING 172.19.16.7 (172.19.16.7): 56 data bytes
64 bytes from 172.19.16.7: seq=0 ttl=64 time=0.055 ms

--- 172.19.16.7 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.055/0.055/0.055 ms
/ # echo "nameserver 183.60.83.19" >> /etc/resolv.conf 
/ # echo "nameserver 183.60.82.98" >> /etc/resolv.conf 
/ # 
/ # cat /etc/resolv.conf 
nameserver 183.60.83.19
nameserver 183.60.82.98
/ # ping -c 1 www.baidu.com
PING www.baidu.com (119.63.197.139): 56 data bytes
64 bytes from 119.63.197.139: seq=0 ttl=51 time=53.213 ms

--- www.baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 53.213/53.213/53.213 ms
/ # nc -lp 80

在另外一台机器访问该容器的服务

telnet 150.109.72.88 80
Trying 150.109.72.88...
Connected to 150.109.72.88.
Escape character is '^]'.
hello world!

容器中可以看到

/ # nc -lp 80
hello world!

容器之间访问

root@nicktming:~/go/src/github.com/nicktming/mydocker# ./mydocker run -it -net testbridge01 busybox /bin/sh
2019/05/09 23:06:18 rootPath is empaty, set rootPath: /nicktming
2019/05/09 23:06:18 current path: /nicktming/mnt/7484077863.
/ # ifconfig
cif-74840 Link encap:Ethernet  HWaddr 0E:05:F7:07:54:73  
          inet addr:192.168.10.7  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::c05:f7ff:fe07:5473/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:418 (418.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping -c 1 192.168.10.3
PING 192.168.10.3 (192.168.10.3): 56 data bytes
64 bytes from 192.168.10.3: seq=0 ttl=64 time=0.080 ms

--- 192.168.10.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.080/0.080/0.080 ms

宿主机访问容器

root@nicktming:~/go/src/github.com/nicktming/mydocker# ping -c 1 192.168.10.3
PING 192.168.10.3 (192.168.10.3) 56(84) bytes of data.
64 bytes from 192.168.10.3: icmp_seq=1 ttl=64 time=0.051 ms

--- 192.168.10.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.051/0.051/0.051/0.000 ms

Iptables查看

root@nicktming:~/go/src/github.com/nicktming/mydocker# iptables -t nat -vnL PREROUTING
Chain PREROUTING (policy ACCEPT 425 packets, 18063 bytes)
 pkts bytes target     prot opt in     out     source               destination         
1614K   62M DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
    2   104 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:192.168.10.3:80
root@nicktming:~/go/src/github.com/nicktming/mydocker# 

4. 参考

1. 自己动手写docker.(基本参考此书,加入一些自己的理解,加深对docker的理解)

5. 全部内容

mydocker.png

1. [mydocker]---环境说明
2. [mydocker]---urfave cli 理解
3. [mydocker]---Linux Namespace
4. [mydocker]---Linux Cgroup
5. [mydocker]---构造容器01-实现run命令
6. [mydocker]---构造容器02-实现资源限制01
7. [mydocker]---构造容器02-实现资源限制02
8. [mydocker]---构造容器03-实现增加管道
9. [mydocker]---通过例子理解存储驱动AUFS
10. [mydocker]---通过例子理解chroot 和 pivot_root
11. [mydocker]---一步步实现使用busybox创建容器
12. [mydocker]---一步步实现使用AUFS包装busybox
13. [mydocker]---一步步实现volume操作
14. [mydocker]---实现保存镜像
15. [mydocker]---实现容器的后台运行
16. [mydocker]---实现查看运行中容器
17. [mydocker]---实现查看容器日志
18. [mydocker]---实现进入容器Namespace
19. [mydocker]---实现停止容器
20. [mydocker]---实现删除容器
21. [mydocker]---实现容器层隔离
22. [mydocker]---实现通过容器制作镜像
23. [mydocker]---实现cp操作
24. [mydocker]---实现容器指定环境变量
25. [mydocker]---网际协议IP
26. [mydocker]---网络虚拟设备veth bridge iptables
27. [mydocker]---docker的四种网络模型与原理实现(1)
28. [mydocker]---docker的四种网络模型与原理实现(2)
29. [mydocker]---容器地址分配
30. [mydocker]---网络net/netlink api 使用解析
31. [mydocker]---网络实现
32. [mydocker]---网络实现测试

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容