自己动手写Docker系列 -- 6.2创建网络

【Docker基础系列】创建一个网络docker network create 阅读详情

简介

在前面的文章中,我们完成了一个IP管理和分配的工具类,能自动分配和回收子网的IP,本篇将继续上篇,开始网络的创建部分

源码说明

同时放到了Gitee和Github上,都可进行获取

本章节对应的版本标签是:6.2,防止后面代码过多,不好查看,可切换到标签版本进行查看

代码实现

主要是实现思路如下:

  • 创建网络:读取用户输入的子网,如何取第一个作为网关ip,创建虚拟网络(或者网卡);创建成功后,将网络信息序列化成JSON保存到本地,便于后序读取
  • 删除网络:根据输入的虚拟网络名,删除对应的网络

下面是具体的实现:

network命令新增

首先增加相关的命令操作:

新增network命令操作

func main() {
	......
	
	app.Commands = []cli.Command{
		command.InitCommand,
		command.RunCommand,
		command.CommitCommand,
		command.ListCommand,
		command.LogCommand,
		command.ExecCommand,
		command.StopCommand,
		command.RemoveCommand,
		command.NetworkCommand,
	}
	......
}

network 相关详细命令


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")
				}

				err := network.Init()
				if err != nil {
					return err
				}

				driver := context.String("driver")
				subnet := context.String("subnet")
				name := context.Args()[0]
				if err := network.CreateNetwork(driver, subnet, name); err != nil {
					return err
				}
				return nil
			},
		},

		{
			Name:  "list",
			Usage: "list container network",
			Action: func(context *cli.Context) error {
				if err := network.Init(); err != nil {
					return err
				}
				return network.ListNetwork()
			},
		},

		{
			Name:  "remove",
			Usage: "remove container network",
			Action: func(context *cli.Context) error {
				if len(context.Args()) < 1 {
					return fmt.Errorf("missing network name")
				}
				if err := network.Init(); err != nil {
					return err
				}
				if err := network.DeleteNetwork(context.Args()[0]); err != nil {
					return err
				}
				return nil
			},
		},
	},
}

如上,新增了创建新的网络、查看网络列表和删除网络的操作

创建新网络

在命令启动的时候,传入子网和虚拟网络名,我们根据这些去创建虚拟网络

func CreateNetwork(driver, subnet, name string) error {
	nw, err := drivers[driver].Create(subnet, name)
	if err != nil {
		return err
	}
	log.Infof("create network success")
	return nw.dump(defaultNetworkPath)
}

下面的网络信息:Network,做了一些小改造,增加了GatewayIP(网关IP)和Subnet(子网网段信息),保存了下来,因为使用IpRange字段,无法正常使用我们的IP回收操作

func (b *BridgeNetworkDriver) Create(subnet string, name string) (*NetWork, error) {
	_, ipRange, _ := net.ParseCIDR(subnet)
	// 得到网段的第一个IP作为网关IP
	ip, err := ipAllocator.Allocate(ipRange)
	if err != nil {
		return nil, err
	}
	ipRange.IP = ip
	n := &NetWork{
		Name:      name,
		IpRange:   ipRange,
		Driver:    b.Name(),
		GatewayIP: ip,
		Subnet:    subnet,
	}
	log.Infof("BridgeNetworkDriver creat network subnet: %s, gateway ip: %s", ipRange.String(), ip.String())
	// 初始化虚拟网络
	return n, b.initBridge(n)
}

下面是具体的虚拟化网络创建,基本是都是使用系统函数(博主目前还不是太懂这个,说不出东西了,先照抄吧…)

func (b *BridgeNetworkDriver) initBridge(n *NetWork) error {
	// try to get bridge by name, if it already exists then just exit
	bridgeName := n.Name
	if err := createBridgeInterface(bridgeName); err != nil {
		return err
	}
	log.Infof("createBridgeInterface success")

	// set bridge ip
	gatewayIp := *n.IpRange
	gatewayIp.IP = n.IpRange.IP

	if err := setInterfaceIp(bridgeName, gatewayIp.String()); err != nil {
		return err
	}
	log.Infof("setInterfaceIp success")

	if err := setInterfaceUp(bridgeName); err != nil {
		return err
	}
	log.Infof("crsetInterfaceUp success")

	if err := setupIpTables(bridgeName, n.IpRange); err != nil {
		return err
	}
	log.Infof("setInterfaceUp success")
	return nil
}

func createBridgeInterface(bridgeName string) error {
	_, err := net.InterfaceByName(bridgeName)
	if err == nil || !strings.Contains(err.Error(), "no such network interface") {
		return err
	}

	// create *netlink.Bridge object
	la := netlink.NewLinkAttrs()
	la.Name = bridgeName

	br := &netlink.Bridge{LinkAttrs: la}
	if err := netlink.LinkAdd(br); err != nil {
		return fmt.Errorf("bridge creating failed for bridge %s, err: %w", bridgeName, err)
	}
	return nil
}

func setInterfaceUp(interfaceName string) error {
	iface, err := netlink.LinkByName(interfaceName)
	if err != nil {
		return fmt.Errorf("error retrieving a link named [ %s ], err: %w", iface.Attrs().Name, err)
	}

	if err := netlink.LinkSetUp(iface); err != nil {
		return fmt.Errorf("error enabling interface for %s, err: %w", interfaceName, err)
	}
	return nil
}

func setInterfaceIp(name string, rawIp string) error {
	retries := 2
	var iface netlink.Link
	var err error
	for i := 0; i < retries; i++ {
		iface, err = netlink.LinkByName(name)
		if err == nil {
			break
		}
		log.Debugf("error retrieving new bridge netlink link [ %s ]... retrying", name)
		time.Sleep(2 * time.Second)
	}
	if err != nil {
		return fmt.Errorf("abandoning retrieving the new bridge ink from netlink, run [ip link] to troubleshoot the err: %w", err)
	}

	ipNet, err := netlink.ParseIPNet(rawIp)
	if err != nil {
		return fmt.Errorf("netlink.ParseIPNet err: %w", err)
	}

	addr := &netlink.Addr{
		IPNet:     ipNet,
		Peer:      ipNet,
		Label:     "",
		Flags:     0,
		Scope:     0,
		Broadcast: nil,
	}
	return netlink.AddrAdd(iface, addr)
}

func setupIpTables(bridgeName string, subnet *net.IPNet) error {
	iptablesCmd := fmt.Sprintf("-t nat -A POSTROUTING -s %s ! -o %s -j MASQUERADE", subnet.String(), bridgeName)
	cmd := exec.Command("iptables", strings.Split(iptablesCmd, " ")...)
	output, err := cmd.Output()
	if err != nil {
		return fmt.Errorf("iptablse err %v, %w", output, err)
	}
	return nil
}

上面就是虚拟网络的创建相关代码

查看已存在的虚拟网络

在查看的时候,需要初始化网络配置信息,及Init函数

我们写了一个网络配置信息的固定位置,所有的网络配置文件都会以其名称,存放到下面,网络驱动和配置也会加载到内存中

var (
	// 网络配置的默认存放位置
	defaultNetworkPath = "/var/run/mydocker/network/network/"
	// 不同网络的网络驱动
	drivers            = map[string]NetworkDriver{}
	// 不同网络的网络配置
	networks           = map[string]*NetWork{}
)

网络信息初始化的基本原理就是读取网络配置默认存放文件夹,加载所有的网络配置即可:

func Init() error {
	var bridgeDriver = BridgeNetworkDriver{}
	drivers[bridgeDriver.Name()] = &bridgeDriver

	if _, err := os.Stat(defaultNetworkPath); err != nil {
		if os.IsNotExist(err) {
			_ = os.MkdirAll(defaultNetworkPath, 0644)
		} else {
			return err
		}
	}

	_ = filepath.Walk(defaultNetworkPath, func(nwPath string, info os.FileInfo, err error) error {
		if strings.HasSuffix(nwPath, "/") {
			return nil
		}
		_, nwName := path.Split(nwPath)
		nw := &NetWork{
			Name: nwName,
		}

		if err := nw.load(nwPath); err != nil {
			log.Errorf("error load network: %v", err)
		}

		networks[nwName] = nw
		return nil
	})
	return nil
}

查看网络配置就比较简单了,遍历打印即可:

func ListNetwork() error {
	w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0)
	_, _ = fmt.Fprint(w, "NAME\tIpRange\tDriver\n")
	for _, nw := range networks {
		fmt.Fprintf(w, "%s\t%s\t\t%s\n",
			nw.Name,
			nw.IpRange.String(),
			nw.Driver,
		)
	}
	if err := w.Flush(); err != nil {
		return fmt.Errorf("flush error: %w", err)
	}
	return nil
}

删除网络

删除网络就是删除相关虚拟网络和配置文件

func DeleteNetwork(networkName string) error {
	nw, ok := networks[networkName]
	if !ok {
		return fmt.Errorf("no such network: %s", networkName)
	}

	// 将网关IP进行释放
	_, ipNet, _ := net.ParseCIDR(nw.Subnet)
	if err := ipAllocator.Release(ipNet, &nw.GatewayIP); err != nil {
		return fmt.Errorf("remove network gateway ip err: %w", err)
	}

	// 删除虚拟网络
	if err := drivers[nw.Driver].Delete(*nw); err != nil {
		return fmt.Errorf("remove network driver err: %w", err)
	}

	// 删除配置文件
	return nw.remove(defaultNetworkPath)
}

网络配置使用系统函数删除即可

func (b *BridgeNetworkDriver) Delete(network NetWork) error {
	bridgeName := network.Name
	br, err := netlink.LinkByName(bridgeName)
	if err != nil {
		return err
	}
	return netlink.LinkDel(br)
}

网络配置文件的删除:

func (nw *NetWork) remove(dumpPath string) error {
	if _, err := os.Stat(path.Join(dumpPath, nw.Name)); err != nil {
		if os.IsNotExist(err) {
			return nil
		} else {
			return fmt.Errorf("remvove path err: %w", err)
		}
	} else {
		return os.Remove(path.Join(dumpPath, nw.Name))
	}
}

运行测试

如下命令所示,创建和查看对应的网络

  • 编译程序,创建网络
  • 查看网络情况
  • 删除网络并确认
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  go build mydocker/main.go                                                                                                      ✔  ⚡  65111:00:01
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ./main network create --driver bridge --subnet 192.168.10.1/24 testbridge                                                      ✔  ⚡  65211:00:06
{"level":"info","msg":"load ipam file from: /var/run/mydocker/network/ipam/subnet.json","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"allocate subnet: 192.168.10.1/24, ip: 192.168.10.1","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"dump ipam file from: /var/run/mydocker/network/ipam/","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"BridgeNetworkDriver creat network subnet: 192.168.10.1/24, gateway ip: 192.168.10.1","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"createBridgeInterface success","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"setInterfaceIp success","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"crsetInterfaceUp success","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"setInterfaceUp success","time":"2022-04-16T11:00:11+08:00"}
{"level":"info","msg":"create network success","time":"2022-04-16T11:00:11+08:00"}

root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ./main network list                                                                                                            ✔  ⚡  65311:00:16
NAME         IpRange           Driver
testbridge   192.168.10.1/24               bridge

root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ip link show dev testbridge                                                                                                    ✔  ⚡  65411:00:19
7: testbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 6a:a8:a1:a4:74:b4 brd ff:ff:ff:ff:ff:ff
    
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ip addr show dev testbridge                                                                                                    ✔  ⚡  65511:00:24
7: testbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 6a:a8:a1:a4:74:b4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.1/24 brd 192.168.10.255 scope global testbridge
       valid_lft forever preferred_lft forever
    inet6 fe80::68a8:a1ff:fea4:74b4/64 scope link
       valid_lft forever preferred_lft forever
       
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  iptables -t nat -vnL POSTROUTING                                                                                               ✔  ⚡  65611:00:29
Chain POSTROUTING (policy ACCEPT 44 packets, 4188 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !testbridge  192.168.10.0/24      0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !testbridge  192.168.10.0/24      0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !testbridge  192.168.10.0/24      0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !testbridge  192.168.10.0/24      0.0.0.0/0
    0     0 MASQUERADE  all  --  *      !testbridge  192.168.10.0/24      0.0.0.0/0
    
root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ./main network remove testbridge                                                                                               ✔  ⚡  65711:00:35
{"level":"info","msg":"release subnet: 192.168.10.0/24, ip: 192.168.10.1","time":"2022-04-16T11:00:40+08:00"}
{"level":"info","msg":"load ipam file from: /var/run/mydocker/network/ipam/subnet.json","time":"2022-04-16T11:00:40+08:00"}
{"level":"info","msg":"release index: 0","time":"2022-04-16T11:00:40+08:00"}
{"level":"info","msg":"dump ipam file from: /var/run/mydocker/network/ipam/","time":"2022-04-16T11:00:40+08:00"}

root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ./main network list                                                                                                            ✔  ⚡  65811:00:42
NAME        IpRange     Driver

root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ip addr show dev testbridge                                                                                                    ✔  ⚡  65911:00:47
Device "testbridge" does not exist.

总体感觉下来好像是创建桥接网卡?和使用VMware的时候,会生成虚拟网卡,如果在没删除的时候,使用下面的命令查看,会得到

root@lw-Code-01-Series-PF5NU1G  ~/code/go/dockerDemo  ifconfig                                                                                                                       ✔  ⚡  66111:04:37
testbridge: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.1  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::fc2b:95ff:fe8d:5c98  prefixlen 64  scopeid 0x20<link>
        ether fe:2b:95:8d:5c:98  txqueuelen 1000  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 33  bytes 4700 (4.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

总体来说,书上的代码有点乱,抄下来,运行不起来,主要还是ip的分配和释放问题,所以本篇中进行了一些小的改造,初步达到预期

《自己动手写Docker》书摘之一: Linux Namespace Linux Namespace 介绍我们经常听到说Docker 是一个使用了Linux Namespace 和 Cgroups 的虚拟化工具,但是什么是Linux Namespace 它在Docker内是怎么被使用的,说到这里很多人就会迷茫,下面我们就先介绍一下Linux Namespace 以及它们是如何在容器里面使用的。概念Linux Namespace 是kernel 的一个功能,它可以隔离一 阅读详情

相关推荐

docker-compose文件中networks使用已经创建的网络

前置条件: docker版本为:18.06.1-ce,build e68fc7a docker-compose版本:1.22.0,build f46880fe 使用已经存在的网络 使用docker创建一个网络。给出示例如下: docker network create --driver=bridge --subnet=192.168.88.0/24 demo 执行命令查看网络是否创建...

WEL测试 2万+

【Docker】常用命令 docker network create

在深入探讨命令之前,我们首先需要了解Docker网络。Docker网络是用来连接Docker容器的虚拟网络。命令就是用来创建这些虚拟网络的。通过上述命令,可以创建一个名为my_network的桥接网络,并指定了自定义的子网和网关。通过本文的介绍,读者应该对命令有了更深入的了解。这个命令是创建Docker网络的关键工具,使得用户可以轻松地创建各种类型的网络,并根据需求进行定制。建议读者在实践中多多尝试,根据实际情况使用不同的选项和参数,以便创建出适合自己应用场景的网络。

好久不见的流星 4019

【docker+openvswitch系列三】ovs-docker配置网络

ovs-docker配置网络 docker和openvswitch的环境搭建教程参考: 【docker+openvswitch系列一】在ubuntu下搭建docker环境 【docker+openvswitch系列二】在ubuntu下搭建openvswitch环境 本文参考:https://www.cnblogs.com/whych/p/9601889.html 首先搬来了实验结构图: 正题: ...

weixin_44753983的博客 4492

如何创建Docker中的网络

需要注意的是两台不同宿主机中的容器要进行通信,首先要保证两台宿主机能进行通信,其次容器要在同一网段(不同网段容器自身存在隔离性),其次在设置IP时,建议自定义IP,因为两台宿主机相互隔离,容器IP规则为自增,防止IP冲突不能访问。首先先来了解下docker中的IP地址分配规则:docker中分配IP地址是根据一开始创建的docker桥接网卡有关系的,在创建时会产生一个地址段,当新的容器启动时,会根据以有的地址进行自增分配(增量为1),当某一容器关闭时,会自动回收,等待下一次的分配。

ly4983的专栏 7274

(十六)Docker 创建自定义网络及网络连通

目录 创建自定义的网络 桥接网络 bridge network 创建 网桥类型的自定义网络 1.查看所有的docker网络:docker network ls 2.创建自定义网络命令:docker network create 3.查看自己定义的网络相关信息 4.使用自定义网络中的网桥创建容器 5.再次使用 docker network inspect mynet 查看网络信息 创建自定义的网络 Docker提供用于创建这些网络的默认网络驱动程序。 默认可以创建如下几种网络: bri

Bertram的博客 1万+

保姆级教程:用Python+NumPy手把手模拟光学散射与记忆效应(附代码)

本文提供了一份详细的Python+NumPy教程,手把手教你模拟光学散射与记忆效应。从基础光波建模到散射介质实现,再到菲涅尔衍射和光学记忆效应验证,逐步构建完整的仿真系统。通过附带的代码示例,读者可以快速掌握计算光学仿真的核心技术,为医学成像、物理仿真等领域的研究提供实用工具。

weixin_30172941的博客 323

Docker网络详解与实战

Docker的技术依赖于Linux内核的虚拟化技术的发展,Docker使用到的网络技术有Network Namespace、Veth设备对、Iptables/Netfilter、网桥、路由等。本文结合实际使用入门学习Docker网络

huangjhai的博客 6500

从毫米波到计算机视觉:智能座舱监控系统的多模态技术融合

本文探讨了智能座舱监控系统中多模态技术融合的创新应用,涵盖毫米波雷达、红外传感与计算机视觉的协同架构。通过传感器时空对齐、低光照算法突破及隐私保护设计,系统在DMS、OMS等场景实现99.7%的检测准确率,同时优化成本至$45以内,为汽车智能化提供关键技术支撑。

d6e7f8的博客 902

Docker NetWork (网络)

Docker NetWork (网络)

m0_73096566的博客 1820

深入理解梅尔刻度、梅尔滤波器组和梅尔时频谱图

读取一段音频,使用短时傅里叶变换,得到普通的时频谱图,然后绘制梅尔滤波器组,值得注意的是,librosa的梅尔滤波器组函数还带有权重归一化功能,即对一个三角形滤波器的每个权重,都除以该三角形的面积,如果不希望进行该归一化,设置参数。从公式可见,对数部分可以以自然对数为底数,也可以以10为底数,不同的底数对应不同的系数,要确定当前的系数,只需要代入(1000Hz, 1000mel)即可。其中,m是当前滤波器的序号,表征了当前的时间段,k是当前频率的序号,表征了当前正在对哪一频率的。

DEDSEC_Roger的博客 1万+

TPAMI审稿人关注什么

写在开头:被tpami接收大概是每个cs er最开心的事情吧!今天阅读TPAMI的文章时,发现有扩刊的文章,也有不是扩刊的文章,那么这两类文章哪个更容易被接收呢?

carlous0的专栏 1684

自己动手写 Docker 系列文章总览

本文章系列起源于:《自己动手写 Docker》,编程实践方得真知,虽然大部分代码书中都有,但还是遇到了不少困难,下面是对于自己写的 Docker Demo 的总览

github_35735591的博客 2268

机器人动力学与控制学习笔记(一)————机器人控制概述

一、概述 1、机器人控制的目的 对自由运动机器人来说,控制的目的是要控制机器人手端的位置和姿态(以后统一简称为位姿),即所谓位置控制问题。这时希望机器人手端所达到的位置称为期望位置或期望轨迹。期望轨迹可以在机器人任务空间中给出,也可以通过逆运动学关系转化为机器人关节空间中的期望轨迹。期望轨迹通常有两种形式:一种是一个固定位置(即固定点),另一种是一条随时间连续变化的轨迹。自由运动机器人位置控制的目的,是要使机器人手端从任意起始位置出发都能到达期望轨迹。当期望轨迹是固定点时的位置控制称为定...

冰与火的青春的博客 6878

自己动手写Docker

小编分享 《自己动手写Docker》在详细分析Docker所依赖的技术栈的基础上,一步一步地通过代码实例,让读者可以自己循序渐进地用Go语言构建出一个容器的引擎。不同于其他Docker原理介绍或代码剖析的书籍,《自己动手写Docker》旨在提供给读者一条动手路线,一步一步地实现Docker的隔离性,构建Docker的镜像、容器的生命周期及Docker的网络等。《自己动手写Docker》涉及的代码都托管在GitHub上,读者可以对照书中的步骤从代码层面学习构建流程,从而精通整个容器技术栈。《自己动手写D

fatfatearth的博客 2917

Ollama 在不同操作系统上的详细使用,及用python进行调用实战

本文介绍了Ollama的安装配置及Python调用方法。主要内容包括:1)Windows/macOS/Linux/Docker等多种安装方式;2)Ollama基础命令,涵盖模型管理、运行和服务控制;3)Python调用教程,包含官方库使用、自定义客户端、多轮对话、参数设置等高级功能,以及直接API调用示例。文章提供了完整的代码片段,适合开发者快速上手使用Ollama进行本地大模型部署和开发。

数据知道的博客 1231

Matlab在线性代数中的应用(一):向量组的线性相关性

求列向量组A的一个最大线性无关组可用命令rref(A)将A化成行最简形,其中单位向量对应的列向量即为最大线性无关组所含向量,其它列向量的坐标即为其对应向量用最大线性无关组线性表示的系数。 01 — 例1 求下列矩阵列向量组的一个最大无关组。 解:编写脚本文件如下: >>format rat a=[1,-2,-1,0,2;-2,4,2,6,-6;2,-1,0,2,3;3,3,3,3,4]; b=rref(a) 求得: b...

wenyusuran的专栏 3235

自己动手写 Docker 系列 -- 6.5 启动时给容器配置网络

在上几篇文章中,我们使用自己程序创建的网桥和手动配置,让容器的网络功能正常,本篇就利用之前的知识,自动配置容器网络

github_35735591的博客 591

ROS Motion Planning运动规划库安装方法及进阶使用方法详细介绍

​今天偶然发现了一个优质的运动规划库:ai-winter/ros_motion_planning,比较适合从事ROS移动机器人运动规划研究领域的小伙伴学习和使用,相比于莱斯大学Kavraki实验室提供的开源的著名运动规划库OMPL、或着我之前介绍过的zhm-real开源的zhm-real/MotionPlanning和zhm-real/PathPlanning运动规划库,今天介绍的ROS Motion Planning运动规划库与ROS机器人中常用的Navigation导航框架的兼容性更好,库中的运动规划

慕羽★的博客 5576

自己动手写一个仿Docker虚拟容器

自己动手写一个仿Docker虚拟容器 本项目参照书籍《自己动手写Docker》 作者:陈显鹭(花名:遥鹭)-阿里云高级研发工程师等 项目地址:https://gitee.com/ShengHua666/can 项目环境:Linux 虚拟机 Ubuntu20.04 内核5.10.x,Go 1.17.1 项目运行: go mod init Bocker go mod tidy go build mydocker/main.go mv main can cp can /bin/ mv busybox.tar

huahua66123的博客 1343

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上)

网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与宿主机网络部分功能正常,为后面程序编写打下基础

github_35735591的博客 1092

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Docker入门必备书籍:《自己动手写Docker》

想自己动手写Docker?你需要看《自己动手写Docker》这本书! 《自己动手写Docker》在详细分析Docker所依赖的技术栈的基础上,一步一步地通过代码实例,让读者可以自己循序渐进地用Go语言构建出一个容器的引擎。不同于其他Docker原理介绍或代码剖析的书籍,《自己动手写Docke...

chuange6363的博客 236

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

动手学 docker

背景动手学docker最近,终于完成了动手学 docker系列的编写。动手学 docker是 动手学系列的首个系列。如果反馈的效果不错,后续还将推出动手学devops动手学kubernetes动手学istio等系列。动手学系列的构思来源于李沐老师的动手学深度学习。旨在通过“亲身实践“ + “微习惯”的方法来掌握某种技术/技能。目录动手学do...

dotNET跨平台 164

自己动手写Docker系列 -- 6.3 手动配置容器网络(下)

网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与外部网络部分功能正常,为后面程序编写打下基础

github_35735591的博客 471

【Docker系列四】Docker 网络

Docker 允许用户创建自定义网络,以满足特定的网络需求。自定义网络可以提供更好的隔离性、灵活性和可管理性。要创建一个自定义网络,可以使用命令。例如,创建一个名为my-network在这个例子中,--driver选项指定了网络驱动(如bridgeoverlay等),my-network是网络的名称。创建自定义网络后,可以将容器连接到这个网络。例如,启动一个容器并将其连接到my-network在这个例子中,--network选项指定了容器连接的网络。

优快云站内信: https://i.youkuaiyun.com/#/msg/chat/qyj19920704 1万+
上一篇: 自己动手写Docker系列 -- 6.1 ip分配管理
下一篇: Gitlab Java API 使用示例
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值