容器點對點拓撲構建

使用方法

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
)

// 獲取命令行參數(shù)
/*
func argsParser() {
    app := cli.NewApp()
    app.Name = "init_network"
    app.Usage = "./init_p2p_container <docker_name1> <docker_name2>"
    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 <docker1_Name> -n1 <docker1_IP> -c2 <docker2_Name> -n2 <docker2_IP> init
     ./init_p2p_container -c1 <docker1_Name> -c2 <docker2_Name> 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 <docker1_Name> -n1 <docker1_IP> -c2 <docker2_Name> -n2 init")
            }
        }
        return nil
    }

    app.Run(os.Args)
}

// 執(zhí)行系統(tǒng)命令并打印輸出
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
}

//創(chuàng)建容器唆迁,并構建點對點連接
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()
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸭丛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唐责,更是在濱河造成了極大的恐慌鳞溉,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼠哥,死亡現(xiàn)場離奇詭異熟菲,居然都是意外死亡,警方通過查閱死者的電腦和手機朴恳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門抄罕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人于颖,你說我怎么就攤上這事呆贿。” “怎么了森渐?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵做入,是天一觀的道長冒晰。 經(jīng)常有香客問我,道長母蛛,這世上最難降的妖魔是什么翩剪? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮彩郊,結果婚禮上,老公的妹妹穿的比我還像新娘蚪缀。我一直安慰自己秫逝,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布询枚。 她就那樣靜靜地躺著违帆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪金蜀。 梳的紋絲不亂的頭發(fā)上刷后,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音渊抄,去河邊找鬼尝胆。 笑死,一個胖子當著我的面吹牛护桦,可吹牛的內(nèi)容都是我干的含衔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼二庵,長吁一口氣:“原來是場噩夢啊……” “哼贪染!你這毒婦竟也來了?” 一聲冷哼從身側響起催享,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤杭隙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后因妙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痰憎,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年兰迫,在試婚紗的時候發(fā)現(xiàn)自己被綠了信殊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡汁果,死狀恐怖涡拘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情据德,我是刑警寧澤鳄乏,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布跷车,位于F島的核電站,受9級特大地震影響橱野,放射性物質(zhì)發(fā)生泄漏朽缴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一水援、第九天 我趴在偏房一處隱蔽的房頂上張望密强。 院中可真熱鬧,春花似錦蜗元、人聲如沸或渤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽薪鹦。三九已至,卻和暖如春惯豆,著一層夾襖步出監(jiān)牢的瞬間池磁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工楷兽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留地熄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓拄养,卻偏偏與公主長得像离斩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瘪匿,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)跛梗,也就是一...
    悟名先生閱讀 4,149評論 0 13
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件棋弥、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,105評論 4 62
  • 寬廣的大海 我踏歌而行 風太大 潛在水中 高高珠峰巔 我揮斥方酋 山太高 我望峰而嘆 茫茫草原 我縱馬馳騁 馬太快...
    云在雨的那一邊閱讀 373評論 0 0
  • 【派別】文魁派 【導圖解說】中心圖是一棵竹子核偿。這是一個系列的中國風思維導圖。分別介紹了梅蘭竹菊顽染。他們的名字科屬以及...
    亞洲高手閱讀 2,009評論 1 0
  • 當下的大都市中漾岳,單身一族的人越來越多,一小部分人主動單身粉寞,他們集美貌與才華一身尼荆,他們財務自由,他們獨立自主唧垦,所以要...
    醒醒老師閱讀 369評論 0 0