func NewNS() (NetNS, error) {
	const nsRunDir = "/var/run/netns"
	b := make([]byte, 16)
	_, err := rand.Reader.Read(b)
	if err != nil {
		return nil, fmt.Errorf("failed to generate random netns name: %v", err)
	}
	err = os.MkdirAll(nsRunDir, 0755)
	if err != nil {
		return nil, err
	}
	nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
	nsPath := path.Join(nsRunDir, nsName)
	mountPointFd, err := os.Create(nsPath)
	if err != nil {
		return nil, err
	}
	mountPointFd.Close()
	defer os.RemoveAll(nsPath)
	var wg sync.WaitGroup
	wg.Add(1)
	var fd *os.File
	go (func() {
		defer wg.Done()
		runtime.LockOSThread()
		var origNS NetNS
		origNS, err = GetNS(getCurrentThreadNetNSPath())
		if err != nil {
			return
		}
		defer origNS.Close()
		err = unix.Unshare(unix.CLONE_NEWNET)
		if err != nil {
			return
		}
		defer origNS.Set()
		err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
		if err != nil {
			return
		}
		fd, err = os.Open(nsPath)
		if err != nil {
			return
		}
	})()
	wg.Wait()
	if err != nil {
		unix.Unmount(nsPath, unix.MNT_DETACH)
		return nil, fmt.Errorf("failed to create namespace: %v", err)
	}
	return &netNS{file: fd, mounted: true}, nil
}
Creates a new persistent network namespace and returns an object
representing that namespace, without switching to it
package ns
import (
	"crypto/rand"
	"fmt"
	"os"
	"path"
	"runtime"
	"sync"
	"golang.org/x/sys/unix"
)
func GetCurrentNS() (NetNS, error) {
	return GetNS(getCurrentThreadNetNSPath())
}
func getCurrentThreadNetNSPath() string {
	return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
}