Merge pull request #7973 from mxpv/backport

Backport changes to sandboxed CRI
This commit is contained in:
Phil Estes 2023-01-18 11:52:44 -05:00 committed by GitHub
commit dadd203c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 186 additions and 18 deletions

View File

@ -804,6 +804,182 @@ func TestPidNamespace(t *testing.T) {
} }
} }
func TestUserNamespace(t *testing.T) {
testID := "test-id"
testPid := uint32(1234)
testSandboxID := "sandbox-id"
testContainerName := "container-name"
idMap := runtime.IDMapping{
HostId: 1000,
ContainerId: 1000,
Length: 10,
}
otherIDMap := runtime.IDMapping{
HostId: 2000,
ContainerId: 2000,
Length: 10,
}
expIDMap := runtimespec.LinuxIDMapping{
HostID: 1000,
ContainerID: 1000,
Size: 10,
}
containerConfig, sandboxConfig, imageConfig, _ := getCreateContainerTestData()
ociRuntime := config.Runtime{}
c := newTestCRIService()
for desc, test := range map[string]struct {
userNS *runtime.UserNamespace
sandboxUserNS *runtime.UserNamespace
expNS *runtimespec.LinuxNamespace
expNotNS *runtimespec.LinuxNamespace // Does NOT contain this namespace
expUIDMapping []runtimespec.LinuxIDMapping
expGIDMapping []runtimespec.LinuxIDMapping
err bool
}{
"node namespace mode": {
userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_NODE},
// Expect userns to NOT be present.
expNotNS: &runtimespec.LinuxNamespace{
Type: runtimespec.UserNamespace,
Path: opts.GetUserNamespace(testPid),
},
},
"node namespace mode with mappings": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_NODE,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
err: true,
},
"container namespace mode": {
userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_CONTAINER},
err: true,
},
"target namespace mode": {
userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_TARGET},
err: true,
},
"unknown namespace mode": {
userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode(100)},
err: true,
},
"pod namespace mode": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
expNS: &runtimespec.LinuxNamespace{
Type: runtimespec.UserNamespace,
Path: opts.GetUserNamespace(testPid),
},
expUIDMapping: []runtimespec.LinuxIDMapping{expIDMap},
expGIDMapping: []runtimespec.LinuxIDMapping{expIDMap},
},
"pod namespace mode with inconsistent sandbox config (different GIDs)": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
sandboxUserNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&otherIDMap},
},
err: true,
},
"pod namespace mode with inconsistent sandbox config (different UIDs)": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
sandboxUserNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&otherIDMap},
Gids: []*runtime.IDMapping{&idMap},
},
err: true,
},
"pod namespace mode with inconsistent sandbox config (different len)": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
sandboxUserNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap, &idMap},
Gids: []*runtime.IDMapping{&idMap, &idMap},
},
err: true,
},
"pod namespace mode with inconsistent sandbox config (different mode)": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
sandboxUserNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_NODE,
Uids: []*runtime.IDMapping{&idMap},
Gids: []*runtime.IDMapping{&idMap},
},
err: true,
},
"pod namespace mode with several mappings": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap, &idMap},
Gids: []*runtime.IDMapping{&idMap, &idMap},
},
err: true,
},
"pod namespace mode with uneven mappings": {
userNS: &runtime.UserNamespace{
Mode: runtime.NamespaceMode_POD,
Uids: []*runtime.IDMapping{&idMap, &idMap},
Gids: []*runtime.IDMapping{&idMap},
},
err: true,
},
} {
desc := desc
test := test
t.Run(desc, func(t *testing.T) {
containerConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{UsernsOptions: test.userNS}
// By default, set sandbox and container config to the same (this is
// required by containerSpec). However, if the test wants to test for what
// happens when they don't match, the test.sandboxUserNS should be set and
// we just use that.
sandboxUserns := test.userNS
if test.sandboxUserNS != nil {
sandboxUserns = test.sandboxUserNS
}
sandboxConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{UsernsOptions: sandboxUserns}
spec, err := c.buildContainerSpec(currentPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
if test.err {
require.Error(t, err)
assert.Nil(t, spec)
return
}
require.NoError(t, err)
assert.Equal(t, spec.Linux.UIDMappings, test.expUIDMapping)
assert.Equal(t, spec.Linux.GIDMappings, test.expGIDMapping)
if test.expNS != nil {
assert.Contains(t, spec.Linux.Namespaces, *test.expNS)
}
if test.expNotNS != nil {
assert.NotContains(t, spec.Linux.Namespaces, *test.expNotNS)
}
})
}
}
func TestNoDefaultRunMount(t *testing.T) { func TestNoDefaultRunMount(t *testing.T) {
testID := "test-id" testID := "test-id"
testPid := uint32(1234) testPid := uint32(1234)

View File

@ -478,7 +478,7 @@ func copyResourcesToStatus(spec *runtimespec.Spec, status containerstore.Status)
} }
if spec.Linux.Resources.HugepageLimits != nil { if spec.Linux.Resources.HugepageLimits != nil {
hugepageLimits := make([]*runtime.HugepageLimit, len(spec.Linux.Resources.HugepageLimits)) hugepageLimits := make([]*runtime.HugepageLimit, 0)
for _, l := range spec.Linux.Resources.HugepageLimits { for _, l := range spec.Linux.Resources.HugepageLimits {
hugepageLimits = append(hugepageLimits, &runtime.HugepageLimit{ hugepageLimits = append(hugepageLimits, &runtime.HugepageLimit{
PageSize: l.Pagesize, PageSize: l.Pagesize,

View File

@ -425,7 +425,7 @@ func (c *criService) registryHosts(ctx context.Context, auth *runtime.AuthConfig
if err != nil { if err != nil {
return nil, fmt.Errorf("get TLSConfig for registry %q: %w", e, err) return nil, fmt.Errorf("get TLSConfig for registry %q: %w", e, err)
} }
} else if isLocalHost(host) && u.Scheme == "http" { } else if docker.IsLocalhost(host) && u.Scheme == "http" {
// Skipping TLS verification for localhost // Skipping TLS verification for localhost
transport.TLSClientConfig = &tls.Config{ transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
@ -470,26 +470,12 @@ func (c *criService) registryHosts(ctx context.Context, auth *runtime.AuthConfig
// defaultScheme returns the default scheme for a registry host. // defaultScheme returns the default scheme for a registry host.
func defaultScheme(host string) string { func defaultScheme(host string) string {
if isLocalHost(host) { if docker.IsLocalhost(host) {
return "http" return "http"
} }
return "https" return "https"
} }
// isLocalHost checks if the registry host is local.
func isLocalHost(host string) bool {
if h, _, err := net.SplitHostPort(host); err == nil {
host = h
}
if host == "localhost" {
return true
}
ip := net.ParseIP(host)
return ip.IsLoopback()
}
// addDefaultScheme returns the endpoint with default scheme // addDefaultScheme returns the endpoint with default scheme
func addDefaultScheme(endpoint string) (string, error) { func addDefaultScheme(endpoint string) (string, error) {
if strings.Contains(endpoint, "://") { if strings.Contains(endpoint, "://") {

View File

@ -330,6 +330,8 @@ func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.
config = sandbox.Config config = sandbox.Config
path = sandbox.NetNSPath path = sandbox.NetNSPath
netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler) netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler)
err error
result *cni.Result
) )
if netPlugin == nil { if netPlugin == nil {
return errors.New("cni config not initialized") return errors.New("cni config not initialized")
@ -341,7 +343,11 @@ func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.
} }
log.G(ctx).WithField("podsandboxid", id).Debugf("begin cni setup") log.G(ctx).WithField("podsandboxid", id).Debugf("begin cni setup")
netStart := time.Now() netStart := time.Now()
result, err := netPlugin.Setup(ctx, id, path, opts...) if c.config.CniConfig.NetworkPluginSetupSerially {
result, err = netPlugin.SetupSerially(ctx, id, path, opts...)
} else {
result, err = netPlugin.Setup(ctx, id, path, opts...)
}
networkPluginOperations.WithValues(networkSetUpOp).Inc() networkPluginOperations.WithValues(networkSetUpOp).Inc()
networkPluginOperationsLatency.WithValues(networkSetUpOp).UpdateSince(netStart) networkPluginOperationsLatency.WithValues(networkSetUpOp).UpdateSince(netStart)
if err != nil { if err != nil {