mirror of
https://github.com/containerd/containerd.git
synced 2026-08-09 01:21:15 +00:00
Merge pull request #13838 from samuelkarp/deprecate-cri-checkpoint
cri: deprecate restore in CreateContainer
This commit is contained in:
25
RELEASES.md
25
RELEASES.md
@@ -601,18 +601,19 @@ against total impact.
|
||||
The deprecated features are shown in the following table:
|
||||
|
||||
| Component | Deprecation release | Target release for removal | Recommendation |
|
||||
|----------------------------------------------------------------------------------|---------------------|---------------------------------------|------------------------------------------|
|
||||
| Runtime V1 API and implementation (`io.containerd.runtime.v1.linux`) | containerd v1.4 | containerd v2.0 ✅ | Use `io.containerd.runc.v2` |
|
||||
| Runc V1 implementation of Runtime V2 (`io.containerd.runc.v1`) | containerd v1.4 | containerd v2.0 ✅ | Use `io.containerd.runc.v2` |
|
||||
| Built-in `aufs` snapshotter | containerd v1.5 | containerd v2.0 ✅ | Use `overlayfs` snapshotter |
|
||||
| Container label `containerd.io/restart.logpath` | containerd v1.5 | containerd v2.0 ✅ | Use `containerd.io/restart.loguri` label |
|
||||
| `cri-containerd-*.tar.gz` release bundles | containerd v1.6 | containerd v2.0 ✅ | Use `containerd-*.tar.gz` bundles |
|
||||
| Pulling Schema 1 images (`application/vnd.docker.distribution.manifest.v1+prettyjws`) | containerd v1.7 | containerd v2.1 (Disabled in v2.0) ✅ | Use Schema 2 or OCI images |
|
||||
| CRI `v1alpha2` | containerd v1.7 | containerd v2.0 ✅ | Use CRI `v1` |
|
||||
| Legacy CRI implementation of podsandbox support | containerd v2.0 | containerd v2.0 ✅ | |
|
||||
| Go-Plugin library (`*.so`) as containerd runtime plugin | containerd v2.0 | containerd v2.1 ✅ | Use external plugins (proxy or binary) |
|
||||
| NRI v0.1.0 plugin support | containerd v2.2 | containerd v2.3 | Use the v010-adapter NRI plugin, or update v0.1.0 plugins to use the current NRI API |
|
||||
| cgroup v1 support | containerd v2.2 | (May 2029) | Use cgroup v2 |
|
||||
|----------------------------------------------------------------------------------|---------------------|---------------------------------------|------------------------------------------------------------------------------------------------|
|
||||
| Runtime V1 API and implementation (`io.containerd.runtime.v1.linux`) | containerd v1.4 | containerd v2.0 ✅ | Use `io.containerd.runc.v2` |
|
||||
| Runc V1 implementation of Runtime V2 (`io.containerd.runc.v1`) | containerd v1.4 | containerd v2.0 ✅ | Use `io.containerd.runc.v2` |
|
||||
| Built-in `aufs` snapshotter | containerd v1.5 | containerd v2.0 ✅ | Use `overlayfs` snapshotter |
|
||||
| Container label `containerd.io/restart.logpath` | containerd v1.5 | containerd v2.0 ✅ | Use `containerd.io/restart.loguri` label |
|
||||
| `cri-containerd-*.tar.gz` release bundles | containerd v1.6 | containerd v2.0 ✅ | Use `containerd-*.tar.gz` bundles |
|
||||
| Pulling Schema 1 images (`application/vnd.docker.distribution.manifest.v1+prettyjws`) | containerd v1.7 | containerd v2.1 (Disabled in v2.0) ✅ | Use Schema 2 or OCI images |
|
||||
| CRI `v1alpha2` | containerd v1.7 | containerd v2.0 ✅ | Use CRI `v1` |
|
||||
| Legacy CRI implementation of podsandbox support | containerd v2.0 | containerd v2.0 ✅ | |
|
||||
| Go-Plugin library (`*.so`) as containerd runtime plugin | containerd v2.0 | containerd v2.1 ✅ | Use external plugins (proxy or binary) |
|
||||
| NRI v0.1.0 plugin support | containerd v2.2 | containerd v2.3 | Use the v010-adapter NRI plugin, or update v0.1.0 plugins to use the current NRI API |
|
||||
| cgroup v1 support | containerd v2.2 | (May 2029) | Use cgroup v2 |
|
||||
| Restoring checkpoint data during CRI `CreateContainer` | containerd v2.3 | containerd v2.4 | Follow [KEP-5823](https://github.com/kubernetes/enhancements/issues/5823) for a replacement `RestorePod` API |
|
||||
|
||||
- Pulling Schema 1 images has been disabled in containerd v2.0, but it still can be enabled by setting an environment variable `CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1`
|
||||
until containerd v2.1. `ctr` users have to specify `--local` too (e.g., `ctr images pull --local`). Users of CRI clients (such as Kubernetes and `crictl`) have to specify this environment variable on the containerd daemon (usually in the systemd unit).
|
||||
|
||||
@@ -126,6 +126,12 @@ function test_from_archive() {
|
||||
echo "error: CDI annotation was not filtered or safe annotation missing: $actual_annots"
|
||||
exit 1
|
||||
fi
|
||||
echo "--> Verifying deprecation warning via API (archive): "
|
||||
archive_ts=$(../../bin/ctr deprecations list --format=json | jq -r '.[] | select(.id == "io.containerd.deprecation/cri-create-container-checkpoint-restore") | .lastOccurrence')
|
||||
if [ -z "$archive_ts" ] || [ "$archive_ts" = "null" ]; then
|
||||
echo "error: CRICreateContainerCheckpointRestore deprecation warning not found in API introspection (archive)"
|
||||
exit 1
|
||||
fi
|
||||
# Cleanup
|
||||
echo "--> Cleanup images: "
|
||||
(crictl rmi "${TEST_IMAGE}" || true) | sed 's/^/----> \t/'
|
||||
@@ -198,6 +204,16 @@ function test_from_oci() {
|
||||
rm -f "$RESTORE_JSON" "$RESTORE_POD_JSON"
|
||||
echo -n "--> Start container from checkpoint: "
|
||||
crictl start "$ctr_id"
|
||||
echo "--> Verifying deprecation warning via API (oci): "
|
||||
oci_ts=$(../../bin/ctr deprecations list --format=json | jq -r '.[] | select(.id == "io.containerd.deprecation/cri-create-container-checkpoint-restore") | .lastOccurrence')
|
||||
if [ -z "$oci_ts" ] || [ "$oci_ts" = "null" ]; then
|
||||
echo "error: CRICreateContainerCheckpointRestore deprecation warning not found in API introspection (oci)"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$archive_ts" = "$oci_ts" ]; then
|
||||
echo "error: expected lastOccurrence to update after OCI restore (was $archive_ts, now $oci_ts)"
|
||||
exit 1
|
||||
fi
|
||||
# Cleanup
|
||||
echo "--> Cleanup images: "
|
||||
../../bin/ctr -n k8s.io images rm localhost/checkpoint-image:latest | sed 's/^/----> \t/'
|
||||
|
||||
91
internal/cri/server/container_checkpoint_warning_test.go
Normal file
91
internal/cri/server/container_checkpoint_warning_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
|
||||
"github.com/containerd/containerd/v2/core/sandbox"
|
||||
sandboxstore "github.com/containerd/containerd/v2/internal/cri/store/sandbox"
|
||||
"github.com/containerd/containerd/v2/pkg/deprecation"
|
||||
"github.com/containerd/containerd/v2/plugins/services/warning"
|
||||
)
|
||||
|
||||
type mockWarningService struct {
|
||||
emitted []deprecation.Warning
|
||||
}
|
||||
|
||||
func (m *mockWarningService) Emit(ctx context.Context, w deprecation.Warning) {
|
||||
m.emitted = append(m.emitted, w)
|
||||
}
|
||||
|
||||
func (m *mockWarningService) Warnings() []warning.Warning {
|
||||
return nil
|
||||
}
|
||||
|
||||
type testSandboxService struct {
|
||||
fakeSandboxService
|
||||
}
|
||||
|
||||
func (t *testSandboxService) SandboxStatus(ctx context.Context, sandboxer string, sandboxID string, verbose bool) (sandbox.ControllerStatus, error) {
|
||||
return sandbox.ControllerStatus{
|
||||
SandboxID: sandboxID,
|
||||
Pid: 1234,
|
||||
State: "READY",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestCreateContainerCheckpointWarning(t *testing.T) {
|
||||
c := newTestCRIService()
|
||||
mockWarn := &mockWarningService{}
|
||||
c.warningService = mockWarn
|
||||
c.sandboxService = &testSandboxService{}
|
||||
|
||||
sb := sandboxstore.NewSandbox(
|
||||
sandboxstore.Metadata{
|
||||
ID: "test-sandbox",
|
||||
Name: "test-sandbox",
|
||||
Config: &runtime.PodSandboxConfig{
|
||||
Metadata: &runtime.PodSandboxMetadata{Name: "test-sandbox", Namespace: "default"},
|
||||
},
|
||||
},
|
||||
sandboxstore.Status{
|
||||
State: sandboxstore.StateReady,
|
||||
},
|
||||
)
|
||||
require.NoError(t, c.sandboxStore.Add(sb))
|
||||
|
||||
// In newTestCRIService(), c.os is a FakeOS where Stat returns (nil, nil) (no error),
|
||||
// causing checkpointImage to evaluate as true when checked in CreateContainer.
|
||||
_, _ = c.CreateContainer(context.Background(), &runtime.CreateContainerRequest{
|
||||
PodSandboxId: "test-sandbox",
|
||||
Config: &runtime.ContainerConfig{
|
||||
Metadata: &runtime.ContainerMetadata{Name: "test-container"},
|
||||
Image: &runtime.ImageSpec{Image: "/path/to/checkpoint.tar"},
|
||||
},
|
||||
SandboxConfig: &runtime.PodSandboxConfig{
|
||||
Metadata: &runtime.PodSandboxMetadata{Name: "test-sandbox", Namespace: "default"},
|
||||
},
|
||||
})
|
||||
|
||||
assert.Contains(t, mockWarn.emitted, deprecation.CRICreateContainerCheckpointRestore, "expected CRICreateContainerCheckpointRestore deprecation warning to be emitted")
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import (
|
||||
"github.com/containerd/containerd/v2/internal/cri/util"
|
||||
"github.com/containerd/containerd/v2/internal/registrar"
|
||||
"github.com/containerd/containerd/v2/pkg/blockio"
|
||||
"github.com/containerd/containerd/v2/pkg/deprecation"
|
||||
"github.com/containerd/containerd/v2/pkg/oci"
|
||||
"github.com/containerd/containerd/v2/pkg/tracing"
|
||||
)
|
||||
@@ -153,6 +154,17 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
|
||||
// This might be a checkpoint image. Let's pass
|
||||
// it to the checkpoint code.
|
||||
|
||||
if c.warningService != nil {
|
||||
c.warningService.Emit(ctx, deprecation.CRICreateContainerCheckpointRestore)
|
||||
if msg, ok := deprecation.Message(deprecation.CRICreateContainerCheckpointRestore); ok {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"podsandboxid": sandboxID,
|
||||
"containerid": id,
|
||||
"containername": name,
|
||||
}).Warn(msg)
|
||||
}
|
||||
}
|
||||
|
||||
if sandboxConfig.GetMetadata() == nil {
|
||||
return nil, fmt.Errorf("sandboxConfig must not be empty")
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import (
|
||||
"github.com/containerd/containerd/v2/pkg/oci"
|
||||
osinterface "github.com/containerd/containerd/v2/pkg/os"
|
||||
"github.com/containerd/containerd/v2/plugins"
|
||||
"github.com/containerd/containerd/v2/plugins/services/warning"
|
||||
)
|
||||
|
||||
var kernelSupportsRRO bool
|
||||
@@ -171,6 +172,8 @@ type criService struct {
|
||||
statsCollector *StatsCollector
|
||||
// shimPath is the custom PATH environment variable value from the shim manager
|
||||
shimPath string
|
||||
// warningService is used to emit deprecation warnings.
|
||||
warningService warning.Service
|
||||
|
||||
checkCriuOnce sync.Once //nolint:nolintlint,unused // Ignore on non-Linux
|
||||
checkCriuErr error //nolint:nolintlint,unused // Ignore on non-Linux
|
||||
@@ -195,6 +198,9 @@ type CRIServiceOptions struct {
|
||||
|
||||
// ShimPath is the custom PATH environment variable value from the shim manager
|
||||
ShimPath string
|
||||
|
||||
// WarningService is used to emit deprecation warnings.
|
||||
WarningService warning.Service
|
||||
}
|
||||
|
||||
// NewCRIService returns a new instance of CRIService
|
||||
@@ -223,6 +229,7 @@ func NewCRIService(options *CRIServiceOptions) (CRIService, runtime.RuntimeServi
|
||||
runtimeHandlers: make(map[string]*runtime.RuntimeHandler),
|
||||
statsCollector: statsCollector,
|
||||
shimPath: options.ShimPath,
|
||||
warningService: options.WarningService,
|
||||
}
|
||||
|
||||
// TODO: Make discard time configurable
|
||||
|
||||
@@ -43,6 +43,8 @@ const (
|
||||
RuncOptionsTaskAPIAddress Warning = Prefix + "runc-options-task-api-address"
|
||||
// RuncOptionsTaskAPIVersion is a warning for the use of `task_api_version` in runc options
|
||||
RuncOptionsTaskAPIVersion Warning = Prefix + "runc-options-task-api-version"
|
||||
// CRICreateContainerCheckpointRestore is a warning for restoring checkpoint data from an image or archive during CRI CreateContainer
|
||||
CRICreateContainerCheckpointRestore Warning = Prefix + "cri-create-container-checkpoint-restore"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -67,8 +69,9 @@ var messages = map[Warning]string{
|
||||
CgroupV1: "The support for cgroup v1 is deprecated since containerd v2.2 and will be removed by no later than May 2029. Upgrade the host to use cgroup v2.",
|
||||
CRIEnableCDI: "The `enable_cdi` property of `[plugins.\"io.containerd.cri.v1.runtime\"]` is deprecated, will be removed in containerd v2.3, and CDI support will always be enabled.",
|
||||
|
||||
RuncOptionsTaskAPIAddress: "The `task_api_address` field in runc options is deprecated since containerd v2.3. Set `task_api_address` on CreateTaskRequest instead.",
|
||||
RuncOptionsTaskAPIVersion: "The `task_api_version` field in runc options is deprecated since containerd v2.3. Set `task_api_version` on CreateTaskRequest instead.",
|
||||
RuncOptionsTaskAPIAddress: "The `task_api_address` field in runc options is deprecated since containerd v2.3. Set `task_api_address` on CreateTaskRequest instead.",
|
||||
RuncOptionsTaskAPIVersion: "The `task_api_version` field in runc options is deprecated since containerd v2.3. Set `task_api_version` on CreateTaskRequest instead.",
|
||||
CRICreateContainerCheckpointRestore: "Restoring checkpoint data from an image or archive during CRI CreateContainer is deprecated and will be removed in containerd v2.4.",
|
||||
}
|
||||
|
||||
// Valid checks whether a given Warning is valid
|
||||
|
||||
@@ -99,14 +99,15 @@ func initCRIService(ic *plugin.InitContext) (any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
ws, err := ic.GetSingle(plugins.WarningPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
warn := ws.(warning.Service)
|
||||
|
||||
if warnings, err := criconfig.ValidateServerConfig(ic.Context, config); err != nil {
|
||||
return nil, fmt.Errorf("invalid cri image config: %w", err)
|
||||
} else if len(warnings) > 0 {
|
||||
ws, err := ic.GetSingle(plugins.WarningPlugin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
warn := ws.(warning.Service)
|
||||
for _, w := range warnings {
|
||||
warn.Emit(ic.Context, w)
|
||||
}
|
||||
@@ -157,6 +158,7 @@ func initCRIService(ic *plugin.InitContext) (any, error) {
|
||||
Client: client,
|
||||
SandboxControllers: sbControllers,
|
||||
ShimPath: shimPath,
|
||||
WarningService: warn,
|
||||
}
|
||||
is := criImagePlugin.(imageService).GRPCService()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user