Sonic+p4(1)

語言: CN / TW / HK

知識:

Docker容器(打包環境加應用)

靜態映象執行container

docker run(start)形成拓撲

目的:switch1獲取switch2的網路統計資料

start.sh啟動拓撲,配置Ip地址,Pin通,每臺交換機收集本機資訊

test 用sonic telementary取得對端交換機資訊,並寫入資料庫

stop

load image

pull ubuntu(系統)

sonic.p4(映象)

docke.file

需求支援,在原有基礎上新增內容

sudo docker ps 正在執行的...

sudo docker run 執行 -> 靜態檔案變成作業系統

add bridge 加埠

add point

構造拓撲配置命名為switch1

ethenet0 統計資訊 arp廣播

reads資料庫(交換機收集的資訊存到資料庫,否則其他交換機無法配置)

test.ping 首先聯通 -c5 ping 包發5個

moliterlization -> grp(收集資料)

conters資料庫收集1,0口,1交換機,2交換機

sudo ./start sh.實驗 目的ip

交換機收集資料->流量轉發,資料收集->為了網路配置,更改方案

實驗

我們有以下拓撲:主機1(Ubuntu 14:04,192.168.1.2/24)<-->交換機1(Sonic)<-->交換機2(Sonic)<-->主機2(Ubuntu 14:04,192.168.2.2/24)

1)我們執行命令: ./install_requirement.sh 通過這種方式,我們安裝了 Docker、Open-VSSwitch和Bridge-Utils。

2)我們執行命令: ./load_image.sh 從Sonic-P4中載入影象並構建 ESA監控客戶端

3)我們執行命令: ./start.sh 建立和準備環境。一旦執行,我們應該執行5個容器。我們可以通過執行 ps docker 命令來檢查它。

4)我們等待~ 3分鐘,以便正確配置一切...我們執行命令: ./test.sh 這樣, 主機1將ping到主機 2,反之亦然,我們 將測量GNMI Client遙測

5)我們最終執行了命令:./stop.sh 這將刪除使用Docker和OVS(Open Virtual Switch)建立的容器和橋。我們還刪除了我們建立的Docker“管理”網路。

持續整合服務Travis

Dockerfile_golang1

Dokerfile_sonic

install_requirements.sh

load_image.sh

start.sh (建立拓撲)

#!/bin/bash

sudo docker run --net=none --privileged --entrypoint /bin/bash --name switch1 -it -d -v $PWD/switch1:/sonic docker-sonic-p4:latest
sudo docker run --net=none --privileged --entrypoint /bin/bash --name switch2 -it -d -v $PWD/switch2:/sonic docker-sonic-p4:latest
sudo docker run --net=none --privileged --entrypoint /bin/bash --name host1 -it -d ubuntu:14.04
sudo docker run --net=none --privileged --entrypoint /bin/bash --name host2 -it -d ubuntu:14.04

sudo ovs-vsctl add-br switch1_switch2
sudo ovs-docker add-port switch1_switch2 sw_port0 switch1
sudo ovs-docker add-port switch1_switch2 sw_port0 switch2

sudo ovs-vsctl add-br host1_switch1
sudo ovs-docker add-port host1_switch1 sw_port1 switch1
sudo ovs-docker add-port host1_switch1 eth1 host1

sudo ovs-vsctl add-br host2_switch2
sudo ovs-docker add-port host2_switch2 sw_port1 switch2
sudo ovs-docker add-port host2_switch2 eth1 host2


sudo docker exec -d host1 sysctl net.ipv6.conf.eth0.disable_ipv6=1
sudo docker exec -d host1 sysctl net.ipv6.conf.eth1.disable_ipv6=1
sudo docker exec -d host2 sysctl net.ipv6.conf.eth0.disable_ipv6=1
sudo docker exec -d host2 sysctl net.ipv6.conf.eth1.disable_ipv6=1

sudo docker exec -d host1 ifconfig eth1 192.168.1.2/24 mtu 1400
sudo docker exec -d host1 ip route replace default via 192.168.1.1
sudo docker exec -d host2 ifconfig eth1 192.168.2.2/24 mtu 1400
sudo docker exec -d host2 ip route replace default via 192.168.2.1


sudo docker exec -d switch1 ip netns add sw_net
sudo docker exec -d switch1 ip link set dev sw_port0 netns sw_net
sudo docker exec -d switch1 ip netns exec sw_net sysctl net.ipv6.conf.sw_port0.disable_ipv6=1
sudo docker exec -d switch1 ip netns exec sw_net ip link set sw_port0 up
sudo docker exec -d switch1 ip link set dev sw_port1 netns sw_net
sudo docker exec -d switch1 ip netns exec sw_net sysctl net.ipv6.conf.sw_port1.disable_ipv6=1
sudo docker exec -d switch1 ip netns exec sw_net ip link set sw_port1 up

sudo docker exec -d switch2 ip netns add sw_net
sudo docker exec -d switch2 ip link set dev sw_port0 netns sw_net
sudo docker exec -d switch2 ip netns exec sw_net sysctl net.ipv6.conf.sw_port0.disable_ipv6=1
sudo docker exec -d switch2 ip netns exec sw_net ip link set sw_port0 up
sudo docker exec -d switch2 ip link set dev sw_port1 netns sw_net
sudo docker exec -d switch2 ip netns exec sw_net sysctl net.ipv6.conf.sw_port1.disable_ipv6=1
sudo docker exec -d switch2 ip netns exec sw_net ip link set sw_port1 up

#########################################################################################################

#Bridge de gestion de contenedores
sudo docker network create \
    --driver bridge \
    --subnet=192.18.0.0/24 \
    --gateway=192.18.0.1 \
    --opt "com.docker.network.bridge.name"="gestion" \
    gestion

#Creacion de contenedor con gnmi_get
sudo docker run --privileged --entrypoint /bin/sh --name gnmicli -it -d gnmi_client

sudo ./iftobridge add-link mgmt1 switch1 gestion --sip="192.18.0.11/24"
sudo ./iftobridge add-link mgmt1 switch2 gestion --sip="192.18.0.12/24"
sudo ./iftobridge add-link mgmt1 gnmicli gestion --sip="192.18.0.10/24"

#Actualizacion de redisDB
sudo docker exec -d switch1 sh /sonic/scripts/update_redisDB.sh &
sudo docker exec -d switch2 sh /sonic/scripts/update_redisDB.sh &

#Activamos la telemetría en los switches:
sudo docker exec -d switch1 ./sonic/telemetry --port 8080 --insecure --logtostderr --allow_no_client_auth &
sudo docker exec -d switch2 ./sonic/telemetry --port 8080 --insecure --logtostderr --allow_no_client_auth &

#########################################################################################################

echo "Booting switches, please wait ~3 minutes for switches to load"
sudo docker exec -d switch1 sh /sonic/scripts/startup.sh
sudo docker exec -d switch2 sh /sonic/scripts/startup.sh

sleep 180

docker ps

stop.sh

#!/bin/bash

sudo docker rm -f switch1
sudo docker rm -f switch2
sudo docker rm -f host1
sudo docker rm -f host2
sudo docker rm -f gnmicli
sudo ovs-vsctl del-br switch1_switch2
sudo ovs-vsctl del-br host1_switch1
sudo ovs-vsctl del-br host2_switch2

sudo docker network prune -f

test.sh

#!/bin/bash

#Ping desde host1 a switch1
sudo docker exec -it host1 ping 192.168.1.1 -c5

#Ping desde switch1 a host1
sudo docker exec -it switch1 ping 192.168.1.2 -c5

#Ping desde host1 a host2
sudo docker exec -it host1 ping 192.168.2.2 -c5

#Ping desde host2 a switch2
sudo docker exec -it host2 ping 192.168.2.1 -c5

#Ping desde switch2 a host2
sudo docker exec -it switch2 ping 192.168.2.2 -c5

#Ping desde host2 a host1
sudo docker exec -it host2 ping 192.168.1.2 -c5

sleep 10

#Monitorización switch1
sudo echo "Paquetes recibidos por Ethernet 1 en switch1"
sudo docker exec -it gnmicli ./bin/gnmi_get -xpath_target COUNTERS_DB -xpath interface:Ethernet1/in-pkts -target_addr 192.18.0.11:8080 -target_name switch1 -insecure -logtostderr
sudo echo "Paquetes recibidos por Ethernet 0 en switch1"
sudo docker exec -it gnmicli ./bin/gnmi_get -xpath_target COUNTERS_DB -xpath interface:Ethernet0/in-pkts -target_addr 192.18.0.11:8080 -target_name switch1 -insecure -logtostderr

#Monitorización switch2
sudo echo "Paquetes recibidos por Ethernet 1 en switch2"
sudo docker exec -it gnmicli ./bin/gnmi_get -xpath_target COUNTERS_DB -xpath interface:Ethernet1/in-pkts -target_addr 192.18.0.12:8080 -target_name switch2 -insecure -logtostderr
sudo echo "Paquetes recibidos por Ethernet 0 en switch2"
sudo docker exec -it gnmicli ./bin/gnmi_get -xpath_target COUNTERS_DB -xpath interface:Ethernet0/in-pkts -target_addr 192.18.0.12:8080 -target_name switch2 -insecure -logtostderr

iftobridge

#!/bin/bash
# Copyright (C) 2014 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Check for programs we'll need.
search_path () {
    save_IFS=$IFS
    IFS=:
    for dir in $PATH; do
        IFS=$save_IFS
        if test -x "$dir/$1"; then
            return 0
        fi
    done
    IFS=$save_IFS
    echo >&2 "$0: $1 not found in \$PATH, please install and try again"
    exit 1
}

ovs_vsctl () {
    ovs-vsctl --timeout=60 "$@"
}

create_netns_link () {
    mkdir -p /var/run/netns
    if [ ! -e /var/run/netns/"$SPID" ]; then
        ln -s /proc/"$SPID"/ns/net /var/run/netns/"$SPID"
        trap 'delete_netns_link_source' 0
        for signal in 1 2 3 13 14 15; do
            trap 'delete_netns_link_source; trap - $signal; kill -$signal $$' $signal
        done
    fi
}

delete_netns_link_source () {
    rm -f /var/run/netns/"$SPID"
}

add_port () {
    SINT="$1"
    SCNT="$2"
    BRIDGE="$3"

    if [ -z "$SINT" ] || [ -z "$SCNT" ]; then
        echo >&2 "$UTIL add-link: not enough arguments (use --help for help)"
        exit 1
    fi

    shift 3
    while [ $# -ne 0 ]; do
        case $1 in
            --sip=*)
                SADDR=`expr X"$1" : 'X[^=]*=\(.*\)'`
                shift
                ;;
            *)
                echo >&2 "$UTIL add-link: unknown option \"$1\""
                exit 1
                ;;
        esac
    done

    if [ -z "$SADDR" ]; then
        echo >&2 "$UTIL add-link: not enough arguments (use --help for help)"
        exit 1
    fi

    # Commented we assume it already exists
    #if brctl addbr "$BRIDGE" ; then :; else
    #    echo >&2 "$UTIL: Failed to add bridge $BRIDGE"
    #    exit 1
    #fi

    if SPID=`docker inspect -f '{{.State.Pid}}' "$SCNT"`; then :; else
        echo >&2 "$UTIL: Failed to get the PID of the container"
        exit 1
    fi

    create_netns_link

    # Create a veth pair.
    asp="${SCNT}_${SINT}"
    asp2=`echo "$asp" | md5sum | cut -f1 -d" "`
    SPORTNAME=${asp2:0:12}

    ip link add "${SPORTNAME}_l" type veth peer name "${SPORTNAME}_c"
    
    # Add one end of veth to OVS bridge.
    if brctl addif "$BRIDGE" "${SPORTNAME}_l"; then :; else
        echo >&2 "$UTIL: Failed to add "${SPORTNAME}_l" port to bridge $BRIDGE"
        ip link delete "${SPORTNAME}_l"
        exit 1
    fi

    ip link set "${SPORTNAME}_l" up
    
    # Move "${PORTNAME}_c" inside the container and changes its name.
    ip link set "${SPORTNAME}_c" netns "$SPID"
    ip netns exec "$SPID" ip link set dev "${SPORTNAME}_c" name "$SINT"
    ip netns exec "$SPID" ip link set "$SINT" up

    if [ -n "$SADDR" ]; then
        ip netns exec "$SPID" ip addr add "$SADDR" dev "$SINT"
    fi

    # This is "just in case..."
    ifconfig "$BRIDGE" up

    # This is also "just in case..."
    sudo iptables -A FORWARD -p all -i "$BRIDGE" -j ACCEPT

}

del_port () {
    SINT="$1"
    SCNT="$2"

    if [ "$#" -lt 2 ]; then
        usage
        exit 1
    fi

    asp="${SCNT}_${SINT}"
    asp2=`echo "$asp" | md5sum | cut -f1 -d" "`
    SPORT=${asp2:0:12}


    ip link delete "${SPORT}_l"
}


usage() {
    cat << EOF
${UTIL}: Performs integration of Open vSwitch with Docker.
usage: ${UTIL} COMMAND

Commands:

  add-link SINT SCNT BRIDGE --sip="ADDRESS"
                    
  del-link SINT SCNT

Options:
  -h, --help        display this help message.
EOF
}

UTIL=$(basename $0)
search_path brctl
search_path docker
search_path uuidgen

if (ip netns) > /dev/null 2>&1; then :; else
    echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\
             "cannot proceed"
    exit 1
fi

if [ $# -eq 0 ]; then
    usage
    exit 0
fi

case $1 in
    "add-link")
        shift
        add_port "$@"
        exit 0
        ;;
    "del-link")
        shift
        del_port "$@"
        exit 0
        ;;
    -h | --help)
        usage
        exit 0
        ;;
    *)
        echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)"
        exit 1
        ;;
esac

實驗內容

問題1:在虛擬機器匯入檔案

解決方案:使用U盤匯入

問題2:許可權

解決方案: sudo passwd輸入新密碼

su root

增加許可權:sudo chmod -R 777

步驟1:./install_requirements.sh

問題3:docker容器無法訪問

sudo apt-get install docker.io