Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
16 changes: 16 additions & 0 deletions contrib/checkpoint/checkpoint-restore-cri-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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/'
Expand Down Expand Up @@ -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/'
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ require (
github.com/google/uuid v1.6.0
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0
github.com/intel/goresctrl v0.13.0
github.com/klauspost/compress v1.19.0
github.com/klauspost/compress v1.19.1
github.com/mdlayher/vsock v1.3.0
github.com/moby/locker v1.0.1
github.com/moby/sys/mountinfo v0.7.2
Expand All @@ -58,7 +58,7 @@ require (
github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116
github.com/opencontainers/selinux v1.13.1
github.com/pelletier/go-toml/v2 v2.4.3
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_golang v1.24.0
github.com/prometheus/client_model v0.6.2
github.com/sirupsen/logrus v1.9.4
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -131,8 +131,8 @@ require (
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/prometheus/common v0.70.0 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.5 // indirect
github.com/smallstep/pkcs7 v0.1.1 // indirect
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI=
github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -284,22 +284,22 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI=
github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/common v0.70.0 h1:bcpru3tWPVnxGnETLgOV5jbp/JRXgYEyv65CuBLAMMI=
github.com/prometheus/common v0.70.0/go.mod h1:S/SFasQmgGiYH6C81LKCtYa8QACgthGg5zxL2udV7SY=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
Expand Down
91 changes: 91 additions & 0 deletions internal/cri/server/container_checkpoint_warning_test.go
Original file line number Diff line number Diff line change
@@ -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")
}
12 changes: 12 additions & 0 deletions internal/cri/server/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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")
}
Expand Down
7 changes: 7 additions & 0 deletions internal/cri/server/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions internal/oom/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ func (ows *oomWatchers) Add(cid string, pid int, fn EventFunc) (retErr error) {

func (ows *oomWatchers) Stop(cid string) error {
ows.mu.Lock()
w, exist := ows.watchers[cid]
w := ows.watchers[cid]
delete(ows.watchers, cid)
ows.mu.Unlock()

if !exist {
if w == nil {
return nil
}
return w.stop()
Expand Down
32 changes: 32 additions & 0 deletions internal/oom/watcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,35 @@ func skipIfBinaryUnavailable(t *testing.T, binaryName string) {
func toPtr[T comparable](v T) *T {
return &v
}

func TestWatcherStopRemovesFromMap(t *testing.T) {
testutil.RequiresRoot(t)

skipIfCgroupUnavailable(t)

group := fmt.Sprintf("/%s", t.Name())
mgr, err := cgroupsv2.NewManager(defaultCgroup2Path, group, &cgroupsv2.Resources{})
require.NoError(t, err)

// A dummy process to get a valid pid and cgroup
cmd := exec.Command("sleep", "10000")
require.NoError(t, cmd.Start())
defer func() {
cmd.Process.Kill()
cmd.Wait()
}()

require.NoError(t, mgr.AddProc(uint64(cmd.Process.Pid)))

watchers := New()
containerID := "test-stop-removes"

fn := func(cid string) {}

require.NoError(t, watchers.Add(containerID, cmd.Process.Pid, fn))
require.NoError(t, watchers.Stop(containerID))

// Should be able to add again with the same containerID
require.NoError(t, watchers.Add(containerID, cmd.Process.Pid, fn))
require.NoError(t, watchers.Stop(containerID))
}
Loading
Loading