零入门容器云网络-7:基于golang编程实现给ns网络命名空间添加额外的网卡

news2024/11/19 6:27:19

已发表的技术专栏(订阅即可观看所有专栏)
0  grpc-go、protobuf、multus-cni 技术专栏 总入口

1  grpc-go 源码剖析与实战  文章目录

2  Protobuf介绍与实战 图文专栏  文章目录

3  multus-cni   文章目录(k8s多网络实现方案)

4  grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录


本篇文章主要是想通过golang编程来实现,为veth pair链接的网络命名空间添加网卡,配置veth pair的IP

1、测试环境介绍

一台centos虚拟机

# 查看操作系统版本
cat /etc/centos-release
# 内核版本
uname -a
uname -r 
# 查看网卡信息
ip a s eth0

在这里插入图片描述

2、创建命名空间–>启动一个进程–>获取进程号

打开xshell一个终端,输入下面的命令:

相关命令如下

ip netns list
ip netns add ns1
ip netns exec ns1 ip a s
ip netns exec ns1 sh
echo $$

在这里插入图片描述

获取到ns1使用的进程号

此终端,不要关闭。

重新再打开一个终端,编译,运行下面的测试代码。

3、编写代码,为ns1网络命名空间,添加veth2虚拟网卡,并设置IP

下面代码的主要过程:

创建veth pair —>获取ns1的进程号—>将veth2网卡移动到ns1网络命名空间里—>获取当前二进制文件所在主网络命名空间—>切换到ns1网络命名空间里—>给veth2网卡设置IP—>再切换到主网络命名空间里—>给veth1网卡设置IP

package main

import (
	"flag"
	"fmt"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	"golang.org/x/sys/unix"
	"net"
	"os"
	"runtime"
)

const (
	veth1Name = "veth1"
	veth2Name = "veth2"
)

var pid int

func main() {

	flag.IntVar(&pid, "pid", 0, "Use -pid xxx")
	flag.Parse()

	l, err := netlink.LinkByName(veth1Name)
	if err == nil {
		// 删除掉 已经存在的 veth pair
		netlink.LinkDel(l)
	}

	vethpeer := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{
			Name:  veth1Name,
			Flags: net.FlagUp,
			MTU:   1500,
		},
		PeerName: veth2Name,
	}
	err = netlink.LinkAdd(vethpeer)
	if err != nil {
		panic(err)
	}

	// 获取到某个容器,如11101容器对应的网络命名空间
	// 11101是容器的PID,就是容器的进程号
	// /proc/11101/ns/net
	// 如何获取到某个容器的Pid呢?
	// 假设,容器名称是 my-sw
	// docker inspect my-sw | grep -w Pid
	// 将得到的值,复制过来
	nsPath := fmt.Sprintf("/proc/%d/ns", pid)
	ns, err := netns.GetFromPath(fmt.Sprintf("%s/%s", nsPath, "net"))
	if err != nil {
		panic(err)
	}
	// 因为是打开文件的,是一个句柄,因此必须close
	defer ns.Close()

	veth2, err := netlink.LinkByName(veth2Name)
	if err != nil {
		panic(err)
	}

	// ip link set veth2 netns
	//  /proc/11101/ns/net命名空间里
	// 就是将veth2网卡,移动到容器里的网络空间里
	err = netlink.LinkSetNsFd(veth2, int(ns))
	if err != nil {
		panic(err)
	}

	// 再切换到容器网络命名空间里前,先获取当前主网络命名空间;
	// 以便能切换回来
	hostNS, err := GetCurrentNS()
	if err != nil {
		panic(err)
	}

	// 设置当前网络命名空间
	// 假设,已经将veth2移动了容器里了
	// 此时在物理机上,直接ifconfig是查看不到veth2网卡的
	// 而你的二进制文件是在物理机上的,此二进制文件想操作veth2网卡的话
	// 只能先设置网络命名空间了
	err = netns.Set(ns)
	if err != nil {
		panic(err)
	}

	// 因为网络命名空间切换了,进入到容器网络命名空间里,必须再获取一次veth2r设备
	veth2, err = netlink.LinkByName(veth2Name)
	if err != nil {
		panic(err)
	}

	// 仅仅是设置IP
	addr, _ := netlink.ParseAddr("10.244.1.2/24")
	err = netlink.AddrAdd(veth2, addr)
	if err != nil {
		panic(err)
	}

	// 可以将容器里的网卡名称,改为通用的名称,如eth0; 非必须步骤
	//netlink.LinkSetName(veth2, "eth0")

	// 将容器里的网卡eth0启动
	err = netlink.LinkSetUp(veth2)
	if err != nil {
		panic(err)
	}

	// 切换回到主网络命名空间里
	err = unix.Setns(int(hostNS.Fd()), unix.CLONE_NEWNET)
	if err != nil {
		panic(err)
	}

	addr, _ = netlink.ParseAddr("10.244.1.3/24")
	veth1, err := netlink.LinkByName(veth1Name)
	if err != nil {
		panic(err)
	}

	// 在主网络命名空间里设置veth1网卡的IP
	err = netlink.AddrAdd(veth1, addr)
	if err != nil {
		panic(err)
	}

	// 将veth1网卡设置为up状态
	netlink.LinkSetUp(veth1)
}

func GetCurrentNS() (*os.File, error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	return GetNS(getCurrentThreadNetNSPath())
}

func getCurrentThreadNetNSPath() string {
	currentNetNSPath := fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
	return currentNetNSPath
}

func GetNS(nspath string) (*os.File, error) {

	fd, err := os.Open(nspath)
	if err != nil {
		return nil, err
	}

	return fd, nil
}

4、Makefile

build:
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o createveth main.go

scp:
	scp createveth root@10.211.55.122:/root

all:
	make build && make scp

执行运行

make all

将编译后二进制文件,上传到目标服务器上

5、在服务器上,运行createveth二进制文件

在这里插入图片描述

6、总结

本篇文章最主要的几点:(仅供参考)

  • 如何获取某个网络的命名空间,

    • 就是获取 /proc/容器进程号/ns/net
  • 如何获取某个线程的网络命名空间

    • 就是获取 /proc/进程号/task/线程号/ns/net
  • 如何进入到某个网络命名空间里

  • 在cni插件中,创建网桥时,就用到了这个知识点。

这样的话,就实现了为某个网络命名空间,添加虚拟网卡的目的。

既然,可以给ip netns创建的网络命名空间,添加虚拟网卡,

那么,能不能为docker环境下的容器,添加额外的虚拟网卡呢?

实现,多网络功能?

类似于multus-cni

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“美亚杯”第三届中国电子数据取证大赛答案解析(个人赛)

试题 1 Gary的笔记本电脑已成功取证并制作成镜像 (Forensic Image),下列哪个是其MD5哈希值。 A. 0CFB3A0BB016165F1BDEB87EE9F710C9 B. 5F1BDEB87EE9F710C90CFB3A0BB01616 C. A0BB016160CFB3A0BB0161661670CFB3 D. 16160CFB3A0BB016166A0BB0161661…

独立产品灵感周刊 DecoHack #041 - 那些独立开发者是怎么养活自己的

本周刊记录有趣好玩的独立产品设计开发相关内容,每周发布,往期内容同样精彩,感兴趣的伙伴可以点击订阅我的周刊。为保证每期都能收到,建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。 💻 产品推荐 1. SOCCER STREAM…

分布式的设计思想

一、分布式设计基础 传统架构问题 ① 单机资源不足 存储:3台机器,每台机器都有2T的硬盘空间,但是现在有1个3T的文件要存储计算:3台机器,每台机器都有8核CPU和8GB内存,但是现在有1个程序需要12核CPU和24G…

启明智显分享| Sigmastar SSD212 SPI+RGB点屏示例(2.1寸 480*480圆屏,可应用于旋钮)

SSD20X 点SPIRGB屏和SSD212 类似,区别在于对应文件名不同、SSD20X没有config.ini文件。 SSD20X SPI初始化文件:vi boot/common/cmd_customer_init.c SSD20X由于没有config.ini 可以用jpeg2disp 中.h 屏参头文件的方式实现显示logo。 这里以SSD212 点屏为…

Java——AVL树

平衡二叉树 在之前的blog中讲到,平衡二叉树是一棵树,任意一个节点的左树的所有节点都小于这个节点,右树的所有节点都大于这个节点 因此,可以利用这个性质来中序遍历,就可以得到一个有序的序列,而如果我们要…

谷歌地图商家抓取工具 G-Business Extractor 7.5

G 业务提取器 | 谷歌地图抓取工具 G-Business Extractor是一款功能强大的工具,可帮助您从 Google 地图中寻找商机。它是最好的Google Maps Scraper工具,能够从最重要的企业目录中提取数据。 Google 地图是一个来源,您可以在其中找到按类别和位…

“美亚杯”第三届中国电子数据取证大赛答案解析(团体赛)

Questions Gary被逮捕后,其计算机被没收并送至计算机取证实验室。经调查后,执法机关再逮捕一名疑犯Eric,并检取其家中计算机(window 8), 并而根据其家中计算机纪录, 执法机关再于其他地方取得一台与案有关的服务器,而该服务器内含四个硬盘。该服务器是运…

跨端开发浪潮中的变与不变

自 90 年代初开启 PC 时代以来,随着移动网络的快速普及,在 2010 年左右,进入移动时代、IOT 时代,各种移动互联设备不断涌现,除了最常见的 PC、Pad、智能手机外,它还可能是小小的一块智能手表,也…

NKOJ P9492 【USACO】视频共享

题目分析 这道题其实最容易想到的方法是离线枚举,但是其时间复杂度为,很明显会超时(这题数据连离线化都救不了) 那该如何办? 并查集;因为他说有一个推荐列表,而这个推荐列表中i号视频推荐了j号视频&#…

SpringSecurity+OAuth2.0+JWT实现单点登录应用

SpringSecurityOAuth2.0JWT实现单点登录应用 gitee项目练习地址:https://gitee.com/xzq25_com/springsecurity.oauth2 OAuth2.0单点登录实践一、搭建OAuth授权服务器,采用授权码模式JWT令牌二、创建服务client:SSOA、SSOB 并进行测试一、搭建…

【云计算与大数据技术】大数据系统总体架构概述(Hadoop+MapReduce )

一、总体架构设计原则 企业级大数据应用框架需要满足业务的需求,一是要求能够满足基于数据容量大,数据类型多,数据流通快的大数据基本处理需求,能够支持大数据的采集,存储,处理和分析,二是要能…

openGauss数据库的使用

目录前言1. 启动/停止/重启数据库(1)极简版启动/停止/重启命令(2)企业版启动/停止/重启命令2. 登录数据库(1)登录数据库时的基本连接参数(2)登录数据库时的常用连接参数(…

如何使用轻量应用服务器搭建高颜值的YesPlayMusic网易云播放器

本文介绍了如何使用腾讯云的Lighthouse轻量应用服务器来搭建一个高颜值的第三方网易云播放器。 ​ 项目简介 本文使用的是YesPlayMusic项目,这是一款高颜值的第三方网易云播放器,它完全可以作为网易云官方应用的替代品。而且还拥有一些网易云官方应用没…

react-dnd 拖拽能力教程

前言 近几年来,低代码、零代码的热度在国内逐年递增。“复杂度同力一样不会消失,也不会凭空产生,它总是从一个物体转移到另一个物体或一种形式转为另一种形式”。用户在使用低零代码构建应用程序时,这些能力只是被平台研发人员提…

SQL SERVER 2019卸载和安装

卸载过程删除SQL Server2019包括sql server这个数据库和它的管理工具SQLServer Management Studio以及他们的注册表信息和安装的目录,以上,最重要的是一定要有耐心,一步一步慢慢来。 首先打开一定要把SQL的服务都关掉,这个很重要…

压缩包文件如何设置加密、删除加密?

压缩包是将文件压缩成RAR、ZIP格式文件,将文件压缩成压缩包之后,就更方便转发以及保存,而且压缩包文件可以进行加密,这样也能够起到对文件的保护作用,今天和大家分享如何对压缩包进行加密以及如何删除压缩包密码。 压…

战略,就没一本好书

战略这个词被工商业界引爆,都是1965年的事。想来到现在已经快60年了。但是实话说,战略这么重要的事,其实没几本好书,也就是说,这个领域,实在没什么有效的研究成果。(1)起点1965年是个…

Vue 进阶二 | 系统性学习 | 无知的我费曼笔记

无知的我正在复盘Vue 该笔记特点是 重新整理了涉及资料的一些语言描述、排版而使用了自己的描述对一些地方做了补充说明。比如解释专有名词、类比说明、对比说明、注意事项提升了总结归纳性。尽可能在每个知识点上都使用一句话 || 关键词概括更注重在实际上怎么应用提出并回答…

数据可视化之卡塔尔世界杯,世界杯8强全部出炉,你看好那支队伍?

2022年下半年可算是集结了众多国际赛事,前有csgo major,英雄联盟总决赛,后有斯诺克英锦赛。当然这些赛事里面最万众瞩目的就是4年一度的卡塔尔世界杯了。本届世界杯开赛前最大的看点就是世界杯的花费,卡塔尔2022年世界杯花费2290亿…

他让我看重采样

周末邓总让我帮忙看下重采样的代码,然后我就用上了自己的神器。我的神器就是Google之后总结了下代码,完整的代码可以往下看,我们平时也会用到重采样,通道转换、交织和非交织的相互转换、给音频重新map等等。这些都是做音频需要搞的…