零入门kubernetes网络实战-15->基于golang编程实现给ns网络命名空间添加额外的网卡

news2024/11/15 17:36:23

《零入门kubernetes网络实战》视频专栏地址
https://www.ixigua.com/7193641905282875942

本篇文章视频地址(稍后上传)


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

即,使用代码创建一对veth pair,将其中一端放入到某个网络命名空间下

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


点击 下面 返回 专栏目录

<<零入门kubernetes网络实战>>技术专栏之文章目录

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

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

相关文章

002 常见量化交易平台使用

常见的量化交易平台&#xff1a;米筐&#xff0c;BigQuant&#xff0c;优矿&#xff0c;聚宽&#xff0c;掘金。 本文简单介绍其中的米筐量化交易平台。米筐支持Python&#xff0c;Java编写交易策略进行回测。 一、平台使用 1. 注册账号 平台网址&#xff1a;米筐量化平台 平…

linux内存申请

一、基本概念 1、页&#xff1a;struct page &#xff0c;如下图所示&#xff0c;x86架构下一般为4K为大小 2、分区&#xff1a;struct zone &#xff0c;如下图所示&#xff0c;x86架构下分为三个区ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM 3、ZONE_DMA&#xff0c;一般由于内存…

代码随想录算法训练营第二天 | 977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵II、总结

打卡第二天&#xff0c;认真做了两道题目&#xff0c;顶不住了好困&#xff0c;明天早上练完车回来再重新看看。 今日任务 第一章数组 977.有序数组的平方209.长度最小的子数组59.螺旋矩阵II 977.有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每…

知识图谱构建技术综述

摘要 *知识图谱为实现语义化智能搜索以及知识互联打下了基础&#xff0c;。&#xff0c; *随着知识的发展&#xff0c;传统的基于模板和规则构建的知识图谱已经被深度学习所替代。 知识组织得原则中&#xff1a;知识的充分性、有序性和标准化规则。深度学习的效果在很大程度上…

线性神经网络(线性回归)

线性回归 目录线性回归导包生成数据集观察散点图读取数据集初始化模型参数定义模型定义损失函数定义优化算法训练简易实现(pytorch)生成数据集读取数据集定义模型初始化模型参数定义损失函数定义优化算法训练导包 import random import torch from d2l import torch as d2l生成…

微服务相关概念

一、谈谈你对微服务的理解&#xff0c;微服务有哪些优缺点&#xff1f;微服务是由Martin Fowler大师提出的。微服务是一种架构风格&#xff0c;通过将大型的单体应用划分为比较小的服务单元&#xff0c;从而降低整个系统的复杂度。优点&#xff1a;1、服务部署更灵活&#xff1…

Python pickle模块:实现Python对象的持久化存储

Python 中有个序列化过程叫作 pickle&#xff0c;它能够实现任意对象与文本之间的相互转化&#xff0c;也可以实现任意对象与二进制之间的相互转化。也就是说&#xff0c;pickle 可以实现 Python 对象的存储及恢复。值得一提的是&#xff0c;pickle 是 python 语言的一个标准模…

2023美赛A题:受旱灾影响的植物群落

文章目录背景要求服务词汇表背景 不同的植物对压力有不同的反应。例如&#xff0c;草原对干旱非常敏感。干旱以不同的频率和严重程度发生。大量的观察表明&#xff0c;不同物种的数量对植物群落如何在连续多代干旱周期中适应起到了重要作用。在一些仅有一种植物的群落中&#…

Vue基础13之浏览器本地存储、TodoList本地存储、组件自定义事件

Vue基础13浏览器本地存储localStorage 本地存储sessionStorage 会话存储总结TodoList本地存储App.vue组件自定义事件子组件给父组件传值使用props方法App.vueSchool.vue子组件给父组件传值使用组件自定义事件——绑定第一种写法&#xff1a;使用v-on或App.vueStudent.vue第二种…

idea快捷编码:生成for循环、主函数、判空非空、生成单例方法、输出;自定义快捷表达式

前言 idea可根据输入的简单表达式进行识别&#xff0c;快速生成语句 常用的快捷编码&#xff1a;生成for循环、主函数、判空非空、生成单例方法、输出 自定义快捷表达式 博客地址&#xff1a;芒果橙的个人博客 【http://mangocheng.com】 一、idea默认的快捷表达式查看 Editor…

String对象的创建和比较

String类的概述 String类&#xff1a;代表字符串。 Java 程序中的所有字符串字面值&#xff08;如 “abc” &#xff09;都作 为此类的实例实现。 String是JDK中内置的一个类&#xff1a;java.lang.string 。 String表示字符串类型&#xff0c;属于引用数据类型&#xff0c;不…

饲养员喂养动物-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-2】饲养员喂养动物 记得 关注&#xff0c;收藏&#xff0c;评论哦&#xff0c;作者将持续更新。。。。 【案例目标】 案例描述 饲养员在给动物喂食时&#xff0c;给不同的动物喂不同的食物&#xff0c;而且在每次喂食时&#xff0c;动物都会发出欢快的叫声。例如&…

Native扩展开发的一般流程(类似开发一个插件)

文章目录大致开发流程1、编写对应的java类服务2、将jar包放到对应位置3、配置文件中进行服务配置4、在代码中调用5、如何查看服务调用成功大致开发流程 1、编写服务&#xff0c;打包为jar包2、将jar包放到指定的位置3、在配置文件中进行配置&#xff0c;调用对应的服务 1、编…

linux 之 ps命令介绍

哈喽&#xff0c;大家好&#xff0c;我是有勇气的牛排&#xff08;全网同名&#xff09;&#x1f42e; 有问题的小伙伴欢迎在文末评论&#xff0c;点赞、收藏是对我最大的支持&#xff01;&#xff01;&#xff01;。 前言 如过想实现对进程监控&#xff0c;就需要使用到ps命…

macOS 13.3 Beta (22E5219e)发布

系统介绍2 月 17 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.3 开发者预览版 Beta 更新&#xff08;内部版本号&#xff1a;22E5219e&#xff09;&#xff0c;本次更新距离上次发布隔了 37 天。macOS Ventura 带来了台前调度、连续互通相机、FaceTime 通话接力…

Vue3+Lodash:2023年了,我依然在使用Lodash

目录 前言&#xff1a; 为什么选择lodash? 看看lodash的地位 如何使用lodash&#xff1f; 1.安装lodash 2.引入lodash 我们到底还需不需要lodash&#xff1f; 再举一些例子 前言&#xff1a; 前两天&#xff0c;在水群的时候&#xff0c;发现居然有人不知lodash&#…

OpenCV-PyQT项目实战(6)项目案例02:滚动条应用

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列&#xff0c;持续更新中 OpenCV-PyQT项目实战&#xff08;1&#xff09;安装与环境配置 OpenCV-PyQT项目实战&#xff08;2&#xff09;QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战&#xff08;3&#xff09;信号与槽机制 …

基于感知动作循环的层次推理用于视觉问答

title&#xff1a;Hierarchical Reasoning Based on Perception Action Cycle for Visual Question Answering 基于感知动作循环的层次推理用于视觉问答 文章目录title&#xff1a;[Hierarchical Reasoning Based on Perception Action Cycle for Visual Question Answering](…

机器学习技术:多任务学习综述!

Datawhale干货 作者&#xff1a;陈敬&#xff0c;中国移动云能力中心前言本文对多任务学习(multi-task learning, MTL)领域近期的综述文章进行整理&#xff0c;从模型结构和训练过程两个层面回顾了其发展变化&#xff0c;旨在提供一份 MTL 入门指南&#xff0c;帮助大家快速了解…

MySQL的锁机制详解

目录 一.概述 分类 锁的特性 二.MyISAM表锁 如何加表锁 读锁演示 写锁演示 三.InnoDB行锁 行锁特点 行锁模式 一.概述 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff08;避免争抢&#xff09;。 在数据库中&#xff0c;除传统的计算资源&#xff08;如…