summaryrefslogtreecommitdiff
path: root/libpod/networking_linux.go
diff options
context:
space:
mode:
authorGabi Beyer <gabrielle.n.beyer@intel.com>2019-06-12 17:31:18 +0000
committerMarco Vedovati <mvedovati@suse.com>2019-09-24 11:01:28 +0200
commit5813c8246eb32205cc3e68a293c6cf3eb2ba291d (patch)
tree1e497c09fbe9cb762fd1f0c8ee0554f2fd060e9e /libpod/networking_linux.go
parent6ce8d05a5b06d97a2897411fcbd4da6a3abb4d65 (diff)
downloadpodman-5813c8246eb32205cc3e68a293c6cf3eb2ba291d.tar.gz
podman-5813c8246eb32205cc3e68a293c6cf3eb2ba291d.tar.bz2
podman-5813c8246eb32205cc3e68a293c6cf3eb2ba291d.zip
rootless: Rearrange setup of rootless containers
In order to run Podman with VM-based runtimes unprivileged, the network must be set up prior to the container creation. Therefore this commit modifies Podman to run rootless containers by: 1. create a network namespace 2. pass the netns persistent mount path to the slirp4netns to create the tap inferface 3. pass the netns path to the OCI spec, so the runtime can enter the netns Closes #2897 Signed-off-by: Gabi Beyer <gabrielle.n.beyer@intel.com>
Diffstat (limited to 'libpod/networking_linux.go')
-rw-r--r--libpod/networking_linux.go62
1 files changed, 40 insertions, 22 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 67dd0150b..d854a2de6 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -90,9 +90,6 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
// Create and configure a new network namespace for a container
func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q []*cnitypes.Result, err error) {
- if rootless.IsRootless() {
- return nil, nil, errors.New("cannot configure a new network namespace in rootless mode, only --network=slirp4netns is supported")
- }
ctrNS, err := netns.NewNS()
if err != nil {
return nil, nil, errors.Wrapf(err, "error creating network namespace for container %s", ctr.ID())
@@ -110,7 +107,10 @@ func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q []*cnitypes.Result,
logrus.Debugf("Made network namespace at %s for container %s", ctrNS.Path(), ctr.ID())
- networkStatus, err := r.configureNetNS(ctr, ctrNS)
+ networkStatus := []*cnitypes.Result{}
+ if !rootless.IsRootless() {
+ networkStatus, err = r.configureNetNS(ctr, ctrNS)
+ }
return ctrNS, networkStatus, err
}
@@ -138,9 +138,6 @@ func checkSlirpFlags(path string) (bool, bool, bool, error) {
// Configure the network namespace for a rootless container
func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
- defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)
- defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncW)
-
path := r.config.NetworkCmdPath
if path == "" {
@@ -164,7 +161,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
cmdArgs := []string{}
if havePortMapping {
- cmdArgs = append(cmdArgs, "--api-socket", apiSocket, fmt.Sprintf("%d", ctr.state.PID))
+ cmdArgs = append(cmdArgs, "--api-socket", apiSocket)
}
dhp, mtu, sandbox, err := checkSlirpFlags(path)
if err != nil {
@@ -179,13 +176,32 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
if sandbox {
cmdArgs = append(cmdArgs, "--enable-sandbox")
}
- cmdArgs = append(cmdArgs, "-c", "-e", "3", "-r", "4", fmt.Sprintf("%d", ctr.state.PID), "tap0")
- cmd := exec.Command(path, cmdArgs...)
+ // the slirp4netns arguments being passed are describes as follows:
+ // from the slirp4netns documentation: https://github.com/rootless-containers/slirp4netns
+ // -c, --configure Brings up the tap interface
+ // -e, --exit-fd=FD specify the FD for terminating slirp4netns
+ // -r, --ready-fd=FD specify the FD to write to when the initialization steps are finished
+ cmdArgs = append(cmdArgs, "-c", "-e", "3", "-r", "4")
+ if !ctr.config.PostConfigureNetNS {
+ ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe()
+ if err != nil {
+ return errors.Wrapf(err, "failed to create rootless network sync pipe")
+ }
+ cmdArgs = append(cmdArgs, "--netns-type=path", ctr.state.NetNS.Path(), "tap0")
+ } else {
+ defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)
+ defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncW)
+ cmdArgs = append(cmdArgs, fmt.Sprintf("%d", ctr.state.PID), "tap0")
+ }
+ cmd := exec.Command(path, cmdArgs...)
+ logrus.Debugf("slirp4netns command: %s", strings.Join(cmd.Args, " "))
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
+
+ // Leak one end of the pipe in slirp4netns, the other will be sent to conmon
cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncR, syncW)
if err := cmd.Start(); err != nil {
@@ -388,20 +404,22 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID())
- var requestedIP net.IP
- if ctr.requestedIP != nil {
- requestedIP = ctr.requestedIP
- // cancel request for a specific IP in case the container is reused later
- ctr.requestedIP = nil
- } else {
- requestedIP = ctr.config.StaticIP
- }
+ // rootless containers do not use the CNI plugin
+ if !rootless.IsRootless() {
+ var requestedIP net.IP
+ if ctr.requestedIP != nil {
+ requestedIP = ctr.requestedIP
+ // cancel request for a specific IP in case the container is reused later
+ ctr.requestedIP = nil
+ } else {
+ requestedIP = ctr.config.StaticIP
+ }
- podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
+ podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
- // The network may have already been torn down, so don't fail here, just log
- if err := r.netPlugin.TearDownPod(podNetwork); err != nil {
- return errors.Wrapf(err, "error tearing down CNI namespace configuration for container %s", ctr.ID())
+ if err := r.netPlugin.TearDownPod(podNetwork); err != nil {
+ return errors.Wrapf(err, "error tearing down CNI namespace configuration for container %s", ctr.ID())
+ }
}
// First unmount the namespace