mirror of https://github.com/containers/podman.git
libpod: Allow using just one jail per container on FreeBSD
In FreeBSD-14.0, it is possible to configure a jail's network settings from outside the jail using ifconfig and route's new '-j' option. This removes the need for a separate jail to own the container's vnet. [NO NEW TESTS NEEDED] Signed-off-by: Doug Rabson <dfr@rabson.org>
This commit is contained in:
parent
06c41b614d
commit
d4ac2f3dd5
|
@ -194,15 +194,18 @@ func openDirectory(path string) (fd int, err error) {
|
||||||
|
|
||||||
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||||
if c.config.CreateNetNS {
|
if c.config.CreateNetNS {
|
||||||
if c.state.NetNS == "" {
|
// If PostConfigureNetNS is set (which is true on FreeBSD 13.3
|
||||||
// This should not happen since network setup
|
// and later), we can manage a container's network settings
|
||||||
// errors should be propagated correctly from
|
// without an extra parent jail to own the vnew.
|
||||||
// (*Runtime).createNetNS. Check for it anyway
|
//
|
||||||
// since it caused nil pointer dereferences in
|
// In this case, the OCI runtime creates a new vnet for the
|
||||||
// the past (see #16333).
|
// container jail, otherwise it creates the container jail as a
|
||||||
return fmt.Errorf("Inconsistent state: c.config.CreateNetNS is set but c.state.NetNS is nil")
|
// child of the jail owning the vnet.
|
||||||
|
if c.config.PostConfigureNetNS {
|
||||||
|
g.AddAnnotation("org.freebsd.jail.vnet", "new")
|
||||||
|
} else {
|
||||||
|
g.AddAnnotation("org.freebsd.parentJail", c.state.NetNS)
|
||||||
}
|
}
|
||||||
g.AddAnnotation("org.freebsd.parentJail", c.state.NetNS)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,10 +109,14 @@ func getSlirp4netnsIP(subnet *net.IPNet) (*net.IP, error) {
|
||||||
return nil, errors.New("not implemented GetSlirp4netnsIP")
|
return nil, errors.New("not implemented GetSlirp4netnsIP")
|
||||||
}
|
}
|
||||||
|
|
||||||
// While there is code in container_internal.go which calls this, in
|
// This is called after the container's jail is created but before its
|
||||||
// my testing network creation always seems to go through createNetNS.
|
// started. We can use this to initialise the container's vnet when we don't
|
||||||
|
// have a separate vnet jail (which is the case in FreeBSD 13.3 and later).
|
||||||
func (r *Runtime) setupNetNS(ctr *Container) error {
|
func (r *Runtime) setupNetNS(ctr *Container) error {
|
||||||
return errors.New("not implemented (*Runtime) setupNetNS")
|
networkStatus, err := r.configureNetNS(ctr, ctr.ID())
|
||||||
|
ctr.state.NetNS = ctr.ID()
|
||||||
|
ctr.state.NetworkStatus = networkStatus
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and configure a new network namespace for a container
|
// Create and configure a new network namespace for a container
|
||||||
|
@ -197,22 +201,24 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctr.state.NetNS != "" {
|
if ctr.state.NetNS != "" {
|
||||||
// Rather than destroying the jail immediately, reset the
|
// If PostConfigureNetNS is false, then we are running with a
|
||||||
// persist flag so that it will live until the container is
|
// separate vnet jail so we need to clean that up now.
|
||||||
// done.
|
if !ctr.config.PostConfigureNetNS {
|
||||||
netjail, err := jail.FindByName(ctr.state.NetNS)
|
// Rather than destroying the jail immediately, reset the
|
||||||
if err != nil {
|
// persist flag so that it will live until the container is
|
||||||
return fmt.Errorf("finding network jail %s: %w", ctr.state.NetNS, err)
|
// done.
|
||||||
|
netjail, err := jail.FindByName(ctr.state.NetNS)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("finding network jail %s: %w", ctr.state.NetNS, err)
|
||||||
|
}
|
||||||
|
jconf := jail.NewConfig()
|
||||||
|
jconf.Set("persist", false)
|
||||||
|
if err := netjail.Set(jconf); err != nil {
|
||||||
|
return fmt.Errorf("releasing network jail %s: %w", ctr.state.NetNS, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
jconf := jail.NewConfig()
|
|
||||||
jconf.Set("persist", false)
|
|
||||||
if err := netjail.Set(jconf); err != nil {
|
|
||||||
return fmt.Errorf("releasing network jail %s: %w", ctr.state.NetNS, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr.state.NetNS = ""
|
ctr.state.NetNS = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,10 +232,18 @@ func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command("jexec", ctr.state.NetNS, "netstat", "-bi", "--libxo", "json")
|
// First try running 'netstat -j' - this lets us retrieve stats from
|
||||||
|
// containers which don't have a separate vnet jail.
|
||||||
|
cmd := exec.Command("netstat", "-j", ctr.state.NetNS, "-bi", "--libxo", "json")
|
||||||
out, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// Fall back to using jexec so that this still works on 13.2
|
||||||
|
// which does not have the -j flag.
|
||||||
|
cmd := exec.Command("jexec", ctr.state.NetNS, "netstat", "-bi", "--libxo", "json")
|
||||||
|
out, err = cmd.Output()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read network stats: %v", err)
|
||||||
}
|
}
|
||||||
stats := Netstat{}
|
stats := Netstat{}
|
||||||
if err := jdec.Unmarshal(out, &stats); err != nil {
|
if err := jdec.Unmarshal(out, &stats); err != nil {
|
||||||
|
|
|
@ -296,7 +296,7 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
|
||||||
toReturn = append(toReturn, libpod.WithCgroupsMode(s.CgroupsMode))
|
toReturn = append(toReturn, libpod.WithCgroupsMode(s.CgroupsMode))
|
||||||
}
|
}
|
||||||
|
|
||||||
postConfigureNetNS := !s.UserNS.IsHost()
|
postConfigureNetNS := needPostConfigureNetNS(s)
|
||||||
|
|
||||||
switch s.NetNS.NSMode {
|
switch s.NetNS.NSMode {
|
||||||
case specgen.FromPod:
|
case specgen.FromPod:
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/buildah/pkg/jail"
|
||||||
"github.com/containers/podman/v4/libpod"
|
"github.com/containers/podman/v4/libpod"
|
||||||
"github.com/containers/podman/v4/pkg/specgen"
|
"github.com/containers/podman/v4/pkg/specgen"
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
"github.com/opencontainers/runtime-tools/generate"
|
||||||
|
@ -52,3 +53,10 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On FreeBSD 13.3 and later, we can avoid creating a separate vnet jail but
|
||||||
|
// only if we can initialise the network after the OCI container is created -
|
||||||
|
// the OCI container will own the vnet in this case.
|
||||||
|
func needPostConfigureNetNS(s *specgen.SpecGenerator) bool {
|
||||||
|
return jail.NeedVnetJail() == false
|
||||||
|
}
|
||||||
|
|
|
@ -159,3 +159,7 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func needPostConfigureNetNS(s *specgen.SpecGenerator) bool {
|
||||||
|
return !s.UserNS.IsHost()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue