Page:
Agent Network
No results
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Le reseaux entre les vms
+--------------------------------------------------------------+ +----------------------------------------------------+
| HOST A | | HOST B |
| | | |
| [ netns-1 (VPC 1) ] | | |
| | | |
| br-subnet-1 (10.0.1.1/32) ---- veth1 <----------------+ | | |
| (dans netns) | | |
| | | |
| br-subnet-2 (10.0.2.1/32) ---- veth2 <----------------+ | | |
| (dans netns) | | |
| | | |
| | | |
| [ netns-2 (VPC 2) ] | | [ netns-2 (VPC 2) ] |
| | | |
| br-subnet-3 (10.0.3.1/32) ---- veth3 <------+ | | br-subnet-3 (10.0.3.1/32) ---- veth4 <------+ |
| (dans netns) | | | (dans netns) | |
| | | | | |
+-------------------------------------------------+------------+ +-------------------+--------------------------------+
| |
| |
+----------v-----------+ +-----------v----------+
| br-vx-1 (host) | | br-vx-1 (host) |
| (infra bridge) | | (infra bridge) |
+----------------------+ +----------------------+
| |
+-----------v-----------+ +----------v------------+
| vxlan1001 | | vxlan1001 |
| (Tunnel inter-host) | | (Tunnel inter-host) |
+-----------------------+ +-----------------------+
package netutils
import (
"fmt"
"net"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
"golang.org/x/sys/unix"
)
// CreateNetns crée un nouveau namespace nommé
func CreateNetns(name string) error {
path := fmt.Sprintf("/var/run/netns/%s", name)
return unix.Mount("/proc/self/ns/net", path, "none", unix.MS_BIND, "")
}
// CreateBridge crée un bridge dans le namespace donné (ou root si nsPath == "")
func CreateBridge(name, nsPath string) error {
link := &netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{Name: name},
}
if nsPath != "" {
newNs, err := netns.GetFromPath(nsPath)
if err != nil {
return err
}
defer newNs.Close()
return netns.Do(newNs, func(_ netns.NsHandle) error {
return netlink.LinkAdd(link)
})
}
return netlink.LinkAdd(link)
}
// LinkBridgeNetns connecte deux bridges via un veth pair (br1 dans root, br2 dans netns)
func LinkBridgeNetns(vethName, peerName, netnsPath, bridgeRoot, bridgeInNs string) error {
peer := netlink.Veth{
LinkAttrs: netlink.LinkAttrs{Name: vethName},
PeerName: peerName,
}
if err := netlink.LinkAdd(&peer); err != nil {
return err
}
// Set peer into target netns
ns, err := netns.GetFromPath(netnsPath)
if err != nil {
return err
}
defer ns.Close()
linkPeer, err := netlink.LinkByName(peerName)
if err != nil {
return err
}
if err := netlink.LinkSetNsFd(linkPeer, int(ns)); err != nil {
return err
}
// Attach veth to host bridge
br, err := netlink.LinkByName(bridgeRoot)
if err != nil {
return err
}
veth, _ := netlink.LinkByName(vethName)
if err := netlink.LinkSetMaster(veth, br); err != nil {
return err
}
if err := netlink.LinkSetUp(veth); err != nil {
return err
}
// Attach peer to bridge in netns
return netns.Do(ns, func(_ netns.NsHandle) error {
peerLink, err := netlink.LinkByName(peerName)
if err != nil {
return err
}
brInNs, err := netlink.LinkByName(bridgeInNs)
if err != nil {
return err
}
if err := netlink.LinkSetMaster(peerLink, brInNs); err != nil {
return err
}
return netlink.LinkSetUp(peerLink)
})
}
// AddIPToBridge ajoute une IP en /32 à un bridge dans un namespace
func AddIPToBridge(nsPath, bridgeName, ipCidr string) error {
ns, err := netns.GetFromPath(nsPath)
if err != nil {
return err
}
defer ns.Close()
return netns.Do(ns, func(_ netns.NsHandle) error {
br, err := netlink.LinkByName(bridgeName)
if err != nil {
return err
}
addr, err := netlink.ParseAddr(ipCidr)
if err != nil {
return err
}
return netlink.AddrAdd(br, addr)
})
}
// AddLinkLocalRoute ajoute une route link-local dans un netns
func AddLinkLocalRoute(nsPath string) error {
ns, err := netns.GetFromPath(nsPath)
if err != nil {
return err
}
defer ns.Close()
return netns.Do(ns, func(_ netns.NsHandle) error {
_, dst, _ := net.ParseCIDR("fe80::/64")
route := &netlink.Route{
Dst: dst,
Scope: netlink.SCOPE_LINK,
}
return netlink.RouteAdd(route)
})
}
// CleanupNetns démonte et supprime un netns (utilise iproute2 fs)
func CleanupNetns(name string) error {
path := fmt.Sprintf("/var/run/netns/%s", name)
if err := unix.Unmount(path, 0); err != nil {
return err
}
return unix.Unlink(path)
}
// DeleteLink supprime un lien réseau (bridge, veth, etc.)
func DeleteLink(name string) error {
link, err := netlink.LinkByName(name)
if err != nil {
return err
}
return netlink.LinkDel(link)
}
CreateNetns("netns-1")
CreateBridge("br-subnet-1", "/var/run/netns/netns-1")
CreateBridge("br-vx-1", "") // root
LinkBridgeNetns("veth1", "veth1-peer", "/var/run/netns/netns-1", "br-vx-1", "br-subnet-1")
AddIPToBridge("/var/run/netns/netns-1", "br-subnet-1", "10.0.1.1/32")
AddLinkLocalRoute("/var/run/netns/netns-1")
systemd pour dnsmasq et metadata
Oui, c’est tout à fait possible avec la bibliothèque go-systemd, en particulier via le module dbus, qui permet de démarrer, arrêter et interroger l'état des unités systemd.
Voici un exemple minimal de code Go pour démarrer et arrêter une unité comme dnsmasq@vpc-00003_br-00000.service :
✅ Exemple de code pour start/stop via go-systemd:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/coreos/go-systemd/v22/dbus"
)
func main() {
conn, err := dbus.NewSystemdConnectionContext(context.Background())
if err != nil {
log.Fatalf("Erreur de connexion à systemd: %v", err)
}
defer conn.Close()
unitName := "dnsmasq@vpc-00003_br-00000.service"
// Démarrer l'unité
jobID, err := conn.StartUnitContext(context.Background(), unitName, "replace", nil)
if err != nil {
log.Fatalf("Erreur au démarrage de l'unité: %v", err)
}
fmt.Printf("Service démarré (job ID: %s)\n", jobID)
time.Sleep(3 * time.Second) // attendre un peu
// Arrêter l'unité
jobID, err = conn.StopUnitContext(context.Background(), unitName, "replace", nil)
if err != nil {
log.Fatalf("Erreur à l'arrêt de l'unité: %v", err)
}
fmt.Printf("Service arrêté (job ID: %s)\n", jobID)
}
🔐 Privilèges requis :
- Il faut que votre programme Go soit exécuté avec des droits suffisants (souvent
sudo) pour interagir avec systemd au niveau système.
Exemple d'exécution :
sudo ./mon-binaire-go
📦 Dépendance :
Ajoutez ce module dans votre go.mod :
go get github.com/coreos/go-systemd/v22
Souhaitez-vous aussi vérifier l’état de l’unité (Active, Failed, etc.) ou juste la gestion start/stop ?
Belong to
This project belong to Nicolas Boufidjeline (nicolas.boufidjeline@g3e.fr)