mirror of
https://github.com/containers/podman.git
synced 2025-10-19 12:12:36 +08:00
network: add support for rootless network with slirp4netns
slirp4netns is required to setup the network namespace: https://github.com/rootless-containers/slirp4netns Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> Closes: #1156 Approved by: rhatdan
This commit is contained in:

committed by
Atomic Bot

parent
5b9c60cc10
commit
cfcd928476
@ -3,6 +3,7 @@ package libpod
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -106,6 +107,9 @@ type Container struct {
|
|||||||
valid bool
|
valid bool
|
||||||
lock storage.Locker
|
lock storage.Locker
|
||||||
runtime *Runtime
|
runtime *Runtime
|
||||||
|
|
||||||
|
rootlessSlirpSyncR *os.File
|
||||||
|
rootlessSlirpSyncW *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
// containerState contains the current state of the container
|
// containerState contains the current state of the container
|
||||||
|
@ -524,12 +524,12 @@ func (c *Container) completeNetworkSetup() error {
|
|||||||
if !c.config.PostConfigureNetNS {
|
if !c.config.PostConfigureNetNS {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if rootless.IsRootless() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err := c.syncContainer(); err != nil {
|
if err := c.syncContainer(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
return c.runtime.setupRootlessNetNS(c)
|
||||||
|
}
|
||||||
return c.runtime.setupNetNS(c)
|
return c.runtime.setupNetNS(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,11 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
cnitypes "github.com/containernetworking/cni/pkg/types/current"
|
cnitypes "github.com/containernetworking/cni/pkg/types/current"
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
@ -93,6 +95,42 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) {
|
|||||||
return r.configureNetNS(ctr, ctrNS)
|
return r.configureNetNS(ctr, ctrNS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure the network namespace for a rootless container
|
||||||
|
func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
|
||||||
|
defer ctr.rootlessSlirpSyncR.Close()
|
||||||
|
defer ctr.rootlessSlirpSyncW.Close()
|
||||||
|
|
||||||
|
path, err := exec.LookPath("slirp4netns")
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("could not find slirp4netns, the network namespace won't be configured: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
syncR, syncW, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to open pipe")
|
||||||
|
}
|
||||||
|
defer syncR.Close()
|
||||||
|
defer syncW.Close()
|
||||||
|
|
||||||
|
cmd := exec.Command(path, "-c", "-e", "3", "-r", "4", fmt.Sprintf("%d", ctr.state.PID), "tap0")
|
||||||
|
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Setpgid: true,
|
||||||
|
}
|
||||||
|
cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncR, syncW)
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to start process")
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, 16)
|
||||||
|
if _, err := syncR.Read(b); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to read from sync pipe")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the network namespace using the container process
|
// Configure the network namespace using the container process
|
||||||
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
|
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
|
||||||
nsProcess := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID)
|
nsProcess := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID)
|
||||||
|
@ -6,6 +6,10 @@ import (
|
|||||||
"github.com/projectatomic/libpod/pkg/inspect"
|
"github.com/projectatomic/libpod/pkg/inspect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
|
||||||
|
return ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
|
func (r *Runtime) setupNetNS(ctr *Container) (err error) {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
"github.com/opencontainers/selinux/go-selinux/label"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/projectatomic/libpod/pkg/ctime"
|
"github.com/projectatomic/libpod/pkg/ctime"
|
||||||
|
"github.com/projectatomic/libpod/pkg/rootless"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
kwait "k8s.io/apimachinery/pkg/util/wait"
|
kwait "k8s.io/apimachinery/pkg/util/wait"
|
||||||
@ -317,6 +318,15 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (er
|
|||||||
// process cannot use them.
|
// process cannot use them.
|
||||||
cmd.ExtraFiles = append(cmd.ExtraFiles, ports...)
|
cmd.ExtraFiles = append(cmd.ExtraFiles, ports...)
|
||||||
|
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to create rootless network sync pipe")
|
||||||
|
}
|
||||||
|
// Leak one end in conmon, the other one will be leaked into slirp4netns
|
||||||
|
cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncW)
|
||||||
|
}
|
||||||
|
|
||||||
if notify, ok := os.LookupEnv("NOTIFY_SOCKET"); ok {
|
if notify, ok := os.LookupEnv("NOTIFY_SOCKET"); ok {
|
||||||
cmd.Env = append(cmd.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notify))
|
cmd.Env = append(cmd.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notify))
|
||||||
}
|
}
|
||||||
|
@ -381,8 +381,12 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||||||
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
|
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
|
||||||
}
|
}
|
||||||
options = append(options, libpod.WithNetNSFrom(connectedCtr))
|
options = append(options, libpod.WithNetNSFrom(connectedCtr))
|
||||||
} else if !rootless.IsRootless() && !c.NetMode.IsHost() && !c.NetMode.IsNone() {
|
} else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
|
||||||
postConfigureNetNS := (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
|
isRootless := rootless.IsRootless()
|
||||||
|
postConfigureNetNS := isRootless || (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
|
||||||
|
if isRootless && len(portBindings) > 0 {
|
||||||
|
return nil, errors.New("port bindings are not yet supported by rootless containers")
|
||||||
|
}
|
||||||
options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, networks))
|
options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, networks))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user