容器点对点拓扑构建

使用方法

image.png

代码

package main

import (
    "github.com/urfave/cli"
    "fmt"
    "os/exec"
    "io/ioutil"
    "os"
)

var (
    dockername1 string
    dockername2 string
    docker1Ip string
    docker2Ip string
    cmd string
)

// 获取命令行参数
/*
func argsParser() {
    app := cli.NewApp()
    app.Name = "init_network"
    app.Usage = "./init_p2p_container  "
    app.Action = func(c *cli.Context) error {
        if c.NArg() > 0 {
            dockername1 = c.Args().Get(0)
            dockername2 = c.Args().Get(1)
        }
        return nil
    }
    app.Run(os.Args)
}
*/
func argsParser(){
    app := cli.NewApp()
    app.Name = `./init_p2p_container -c1  -n1  -c2  -n2  init
     ./init_p2p_container -c1  -c2  remove
`

    app.Flags = []cli.Flag{
        cli.StringFlag{
            Name:        "container1Name, c1",
            Value:       "docker1",
            Usage:       "Input container1 name.",
            Destination: &dockername1,
        },
        cli.StringFlag{
            Name:        "container1Ip, n1",
            Value:       "192.168.10.1/24",
            Usage:       "Input container1 IP address.",
            Destination: &docker1Ip,
        },
        cli.StringFlag{
            Name:        "container2, c2",
            Value:       "docker2",
            Usage:       "Input container2 name.",
            Destination: &dockername2,
        },
        cli.StringFlag{
            Name:        "container2Ip, n2",
            Value:       "192.168.10.2/24",
            Usage:       "Input container2 IP address.",
            Destination: &docker2Ip,
        },
    }
    app.Action = func(c *cli.Context) error {
        if c.NArg() > 0 {
            cmd = c.Args().Get(0)
            if cmd == "init" {
                fmt.Println("Container1_Name:", dockername1, "    Container1_IP:", docker1Ip)
                fmt.Println("Container2_Name:", dockername2, "    Container2_IP:", docker2Ip)
                fmt.Println("Command:", cmd)
                initNetwork()
            }else if cmd == "remove"{
                fmt.Println("Container1_Name:", dockername1)
                fmt.Println("Container2_Name:", dockername2)
                fmt.Println("Command:", cmd)
                removeNetwork()
            }else {
                fmt.Println("Usage: ./init_p2p_container -c1  -n1  -c2  -n2 init")
            }
        }
        return nil
    }

    app.Run(os.Args)
}

// 执行系统命令并打印输出
func runCmd(s string) (str string) {
    //cmd := exec.Command(s)
    cmd := exec.Command("/bin/bash", "-c", s)

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println("Error:can not obtain stdout pipe for command:", cmd)
        return
    }

    if err := cmd.Start(); err != nil {
        fmt.Println("Error:The command is err.", err)
        return
    }

    bytes, err := ioutil.ReadAll(stdout)
    if err != nil {
        fmt.Println("Readall stdout:", err.Error())
        return
    }
    if len(bytes) >0 {
        fmt.Printf("Stdout: %s\n", bytes)
    }
    return string(bytes)
}

//判断文件/文件夹是否存在
func exists(path string) bool {
    _, err := os.Stat(path) //os.Stat获取文件信息
    if err != nil {
        if os.IsExist(err) {
            return true
        }
        return false
    }
    return true
}

//创建容器,并构建点对点连接
func initNetwork() {
    //run containers
    RunDocker1Cmd := fmt.Sprintf(
        "docker run -d --name %s --net=none ubuntu:ip tail -f /dev/null", dockername1)
    runCmd(RunDocker1Cmd)
    RunDocker2Cmd := fmt.Sprintf(
        "docker run -d --name %s --net=none ubuntu:ip tail -f /dev/null", dockername2)
    runCmd(RunDocker2Cmd)

    getDocker1IidCmd := fmt.Sprintf(`docker inspect --format "{{.State.Pid}}" %s`, dockername1)
    docker1Id := runCmd(getDocker1IidCmd)[0:5]
    getDocker2IidCmd := fmt.Sprintf(`docker inspect --format "{{.State.Pid}}" %s`, dockername2)
    docker2Id := runCmd(getDocker2IidCmd)[0:5]

    if exists("/var/run/netns") != true {
        runCmd("mkdir /var/run/netns")
    }

    //create container netns dir
    docker1NsDir := fmt.Sprintf("/var/run/netns/%s", docker1Id)
    if exists(docker1NsDir) != true {
        createDocker1NsDirCmd := fmt.Sprintf("ln -s /proc/%s/ns/net /var/run/netns/%s",
            docker1Id,
            docker1Id)
        runCmd(createDocker1NsDirCmd)
    }
    docker2NsDir := fmt.Sprintf("/var/run/netns/%s", docker2Id)
    if exists(docker2NsDir) != true {
        createDocker2NsDirCmd := fmt.Sprintf("ln -s /proc/%s/ns/net /var/run/netns/%s",
            docker2Id,
            docker2Id)
        runCmd(createDocker2NsDirCmd)
    }


    veth1 := fmt.Sprintf("v%s%s",
        string(dockername1[len(dockername1)-1]),
        string(dockername2[len(dockername2)-1]))
    veth2 := fmt.Sprintf("v%s%s",
        string(dockername2[len(dockername2)-1]),
        string(dockername1[len(dockername1)-1]))


    // create virtual link patch
    linkAddCmd := fmt.Sprintf("ip link add %s type veth peer name %s", veth1, veth2)
    runCmd(linkAddCmd)


    //set docker1 ip netns
    linkSet1Cmd := fmt.Sprintf("ip link set %s netns %s", veth1, docker1Id)
    runCmd(linkSet1Cmd)
    linkset1NsCmd := fmt.Sprintf("ip netns exec %s ip link set %s up", docker1Id, veth1)
    runCmd(linkset1NsCmd)
    linkSet1IPCmd := fmt.Sprintf("ip netns exec %s ip addr add %s dev %s",
        docker1Id, docker1Ip, veth1)
    runCmd(linkSet1IPCmd)


    //set docker2 ip netns
    linkSet2Cmd := fmt.Sprintf("ip link set %s netns %s", veth2, docker2Id)
    runCmd(linkSet2Cmd)
    linkset2NsCmd := fmt.Sprintf("ip netns exec %s ip link set %s up", docker2Id, veth2)
    runCmd(linkset2NsCmd)
    linkSet2IPCmd := fmt.Sprintf("ip netns exec %s ip addr add %s dev %s",
        docker2Id, docker2Ip, veth2)
    runCmd(linkSet2IPCmd)
}

func removeNetwork()  {
    getDocker1IidCmd := fmt.Sprintf(`docker inspect --format "{{.State.Pid}}" %s`, dockername1)
    docker1Id := runCmd(getDocker1IidCmd)[0:5]
    getDocker2IidCmd := fmt.Sprintf(`docker inspect --format "{{.State.Pid}}" %s`, dockername2)
    docker2Id := runCmd(getDocker2IidCmd)[0:5]

    RunRemoveNetns1Cmd := fmt.Sprintf("ip netns delete %s", docker1Id)
    RunRemoveNetns2Cmd := fmt.Sprintf("ip netns delete %s", docker2Id)
    runCmd(RunRemoveNetns1Cmd)
    runCmd(RunRemoveNetns2Cmd)

    RunDocker1Cmd := fmt.Sprintf(
        "docker rm -f %s", dockername1)
    runCmd(RunDocker1Cmd)
    RunDocker2Cmd := fmt.Sprintf(
        "docker rm -f %s", dockername2)
    runCmd(RunDocker2Cmd)
}

func main() {
    argsParser()
}

你可能感兴趣的:(容器点对点拓扑构建)