Merge pull request #7973 from mxpv/backport
Backport changes to sandboxed CRI
This commit is contained in:
commit
dadd203c25
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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, "://") {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user