Sonic+p4(1)

知识:

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:
#
#     //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