Skip to content

Commit 6670695

Browse files
committed
Revert "cri: make read-only mounts recursively read-only"
Revert PR 9713, as it appeared to break the compatibility too much kubernetes/enhancements#3858 (comment) This reverts commit b2f254f. > Conflicts: > internal/cri/opts/spec_linux_opts.go Signed-off-by: Akihiro Suda <[email protected]>
1 parent 96bf529 commit 6670695

File tree

11 files changed

+8
-387
lines changed

11 files changed

+8
-387
lines changed

RELEASES.md

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -461,25 +461,6 @@ version = 2
461461

462462
</p></details>
463463

464-
## Other breaking changes
465-
### containerd v2.0
466-
#### CRI plugin treats read-only mounts recursively read-only
467-
Starting with containerd v2.0, the CRI plugin treats read-only mounts
468-
as recursively read-only mounts when running on Linux kernel v5.12 or later.
469-
470-
To rollback to the legacy behavior that corresponds to containerd v1.x,
471-
set the following config:
472-
```toml
473-
version = 2
474-
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
475-
# treat_ro_mounts_as_rro ("Enabled"|"IfPossible"|"Disabled")
476-
# treats read-only mounts as recursive read-only mounts.
477-
# An empty string means "IfPossible".
478-
# "Enabled" requires Linux kernel v5.12 or later.
479-
# This configuration does not apply to non-volume mounts such as "/sys/fs/cgroup".
480-
treat_ro_mounts_as_rro = "Disabled"
481-
```
482-
483464
## Experimental features
484465

485466
Experimental features are new features added to containerd which do not have the

docs/cri/config.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -369,14 +369,6 @@ version = 2
369369
# See https://github.com/containerd/containerd/issues/6657 for context.
370370
snapshotter = ""
371371

372-
# treat_ro_mounts_as_rro ("Enabled"|"IfPossible"|"Disabled")
373-
# treats read-only mounts as recursive read-only mounts.
374-
# An empty string means "IfPossible".
375-
# "Enabled" requires Linux kernel v5.12 or later.
376-
# Introduced in containerd v2.0.
377-
# This configuration does not apply to non-volume mounts such as "/sys/fs/cgroup".
378-
treat_ro_mounts_as_rro = ""
379-
380372
# 'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options' is options specific to
381373
# "io.containerd.runc.v1" and "io.containerd.runc.v2". Its corresponding options type is:
382374
# https://github.com/containerd/containerd/blob/v1.3.2/runtime/v2/runc/options/oci.pb.go#L26 .

integration/container_volume_linux_test.go

Lines changed: 0 additions & 149 deletions
This file was deleted.

internal/cri/config/config.go

Lines changed: 2 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,9 @@ import (
2121
"errors"
2222
"fmt"
2323
"net/url"
24-
goruntime "runtime"
25-
"strconv"
2624
"time"
2725

28-
introspectionapi "github.com/containerd/containerd/v2/api/services/introspection/v1"
29-
apitypes "github.com/containerd/containerd/v2/api/types"
30-
"github.com/containerd/containerd/v2/protobuf"
3126
"github.com/containerd/log"
32-
"github.com/containerd/typeurl/v2"
3327
"github.com/pelletier/go-toml/v2"
3428
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
3529
"k8s.io/kubelet/pkg/cri/streaming"
@@ -40,16 +34,8 @@ import (
4034
"github.com/containerd/containerd/v2/pkg/deprecation"
4135
runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
4236
"github.com/containerd/containerd/v2/plugins"
43-
"github.com/opencontainers/image-spec/specs-go"
44-
"github.com/opencontainers/runtime-spec/specs-go/features"
4537
)
4638

47-
func init() {
48-
const prefix = "types.containerd.io"
49-
major := strconv.Itoa(specs.VersionMajor)
50-
typeurl.Register(&features.Features{}, prefix, "opencontainers/runtime-spec", major, "features", "Features")
51-
}
52-
5339
const (
5440
// defaultImagePullProgressTimeoutDuration is the default value of imagePullProgressTimeout.
5541
//
@@ -87,17 +73,6 @@ const (
8773
DefaultSandboxImage = "registry.k8s.io/pause:3.9"
8874
)
8975

90-
// Ternary represents a ternary value.
91-
// Ternary is needed because TOML does not accept "null" for boolean values.
92-
type Ternary = string
93-
94-
const (
95-
TernaryEmpty Ternary = "" // alias for IfPossible
96-
TernaryEnabled Ternary = "Enabled"
97-
TernaryIfPossible Ternary = "IfPossible"
98-
TernaryDisabled Ternary = "Disabled"
99-
)
100-
10176
// Runtime struct to contain the type(ID), engine, and root variables for a default runtime
10277
// and a runtime for untrusted workload.
10378
type Runtime struct {
@@ -141,15 +116,6 @@ type Runtime struct {
141116
// shim - means use whatever Controller implementation provided by shim (e.g. use RemoteController).
142117
// podsandbox - means use Controller implementation from sbserver podsandbox package.
143118
Sandboxer string `toml:"sandboxer" json:"sandboxer"`
144-
145-
// TreatRoMountsAsRro ("Enabled"|"IfPossible"|"Disabled")
146-
// treats read-only mounts as recursive read-only mounts.
147-
// An empty string means "IfPossible".
148-
// "Enabled" requires Linux kernel v5.12 or later.
149-
// Introduced in containerd v2.0.
150-
// This configuration does not apply to non-volume mounts such as "/sys/fs/cgroup".
151-
TreatRoMountsAsRro Ternary `toml:"treat_ro_mount_as_rro" json:"treatRoMountsAsRro"`
152-
TreatRoMountsAsRroResolved bool `toml:"-" json:"-"` // Do not set manually
153119
}
154120

155121
// ContainerdConfig contains toml config related to containerd
@@ -533,120 +499,8 @@ func ValidateImageConfig(ctx context.Context, c *ImageConfig) ([]deprecation.War
533499
return warnings, nil
534500
}
535501

536-
func introspectRuntimeFeatures(ctx context.Context, introspectionClient introspectionapi.IntrospectionClient, r Runtime) (*features.Features, error) {
537-
if introspectionClient == nil { // happens for unit tests
538-
return nil, errors.New("introspectionClient is nil")
539-
}
540-
infoReq := &introspectionapi.PluginInfoRequest{
541-
Type: string(plugins.RuntimePluginV2),
542-
ID: "task",
543-
}
544-
rr := &apitypes.RuntimeRequest{
545-
RuntimePath: r.Type,
546-
}
547-
if r.Path != "" {
548-
rr.RuntimePath = r.Path
549-
}
550-
options, err := GenerateRuntimeOptions(r)
551-
if err != nil {
552-
return nil, err
553-
}
554-
rr.Options, err = protobuf.MarshalAnyToProto(options)
555-
if err != nil {
556-
return nil, fmt.Errorf("failed to marshal %T: %w", options, err)
557-
}
558-
infoReq.Options, err = protobuf.MarshalAnyToProto(rr)
559-
if err != nil {
560-
return nil, fmt.Errorf("failed to marshal %T: %w", rr, err)
561-
}
562-
infoResp, err := introspectionClient.PluginInfo(ctx, infoReq)
563-
if err != nil {
564-
return nil, fmt.Errorf("failed to call PluginInfo: %w", err)
565-
}
566-
var info apitypes.RuntimeInfo
567-
if err := typeurl.UnmarshalTo(infoResp.Extra, &info); err != nil {
568-
return nil, fmt.Errorf("failed to get runtime info from plugin info: %w", err)
569-
}
570-
featuresX, err := typeurl.UnmarshalAny(info.Features)
571-
if err != nil {
572-
return nil, fmt.Errorf("failed to unmarshal Features (%T): %w", info.Features, err)
573-
}
574-
features, ok := featuresX.(*features.Features)
575-
if !ok {
576-
return nil, fmt.Errorf("unknown features type %T", featuresX)
577-
}
578-
return features, nil
579-
}
580-
581-
// resolveTreatRoMountsAsRro resolves r.TreatRoMountsAsRro string into a boolean.
582-
func resolveTreatRoMountsAsRro(ctx context.Context, introspectionClient introspectionapi.IntrospectionClient, r Runtime) (bool, error) {
583-
debugPrefix := "treat_ro_mounts_as_rro"
584-
if r.Type != "" {
585-
debugPrefix += fmt.Sprintf("[%s]", r.Type)
586-
}
587-
if binaryName := r.Options["BinaryName"]; binaryName != "" {
588-
debugPrefix += fmt.Sprintf("[%v]", binaryName)
589-
}
590-
debugPrefix += ": "
591-
592-
var runtimeSupportsRro bool
593-
if r.Type == plugins.RuntimeRuncV2 {
594-
features, err := introspectRuntimeFeatures(ctx, introspectionClient, r)
595-
if err != nil {
596-
log.G(ctx).WithError(err).Warnf(debugPrefix + "failed to introspect runtime features (binary is not compatible with runc v1.1?)")
597-
} else {
598-
log.G(ctx).Debugf(debugPrefix+"Features: %+v", features)
599-
for _, s := range features.MountOptions {
600-
if s == "rro" {
601-
runtimeSupportsRro = true
602-
break
603-
}
604-
}
605-
}
606-
}
607-
608-
switch r.TreatRoMountsAsRro {
609-
case TernaryDisabled:
610-
log.G(ctx).Debug(debugPrefix + "rro mounts are explicitly disabled")
611-
return false, nil
612-
case TernaryEnabled:
613-
log.G(ctx).Debug(debugPrefix + "rro mounts are explicitly enabled")
614-
if !kernelSupportsRro {
615-
return true, fmt.Errorf("invalid `treat_ro_mounts_as_rro`: %q: needs Linux kernel v5.12 or later", TernaryEnabled)
616-
}
617-
if !runtimeSupportsRro {
618-
return true, fmt.Errorf("invalid `treat_ro_mounts_as_rro`: %q: needs a runtime that is compatible with runc v1.1", TernaryEnabled)
619-
}
620-
return true, nil
621-
case TernaryEmpty, TernaryIfPossible:
622-
if r.Type != plugins.RuntimeRuncV2 {
623-
log.G(ctx).Debugf(debugPrefix+"rro mounts are not supported by runtime %q, disabling rro mounts", r.Type)
624-
return false, nil
625-
}
626-
if !kernelSupportsRro {
627-
msg := debugPrefix + "rro mounts are not supported by kernel, disabling rro mounts"
628-
if goruntime.GOOS == "linux" {
629-
msg += " (Hint: upgrade the kernel to v5.12 or later)"
630-
log.G(ctx).Warn(msg)
631-
} else {
632-
log.G(ctx).Debug(msg)
633-
}
634-
return false, nil
635-
}
636-
if !runtimeSupportsRro {
637-
log.G(ctx).Warn(debugPrefix + "rro mounts are not supported by runtime, disabling rro mounts (Hint: use a runtime that is compatible with runc v1.1)")
638-
return false, nil
639-
}
640-
log.G(ctx).Debug(debugPrefix + "rro mounts are implicitly enabled")
641-
return true, nil
642-
default:
643-
return false, fmt.Errorf("invalid `treat_ro_mounts_as_rro`: %q (must be %q, %q, or %q)",
644-
r.TreatRoMountsAsRro, TernaryDisabled, TernaryEnabled, TernaryIfPossible)
645-
}
646-
}
647-
648502
// ValidateRuntimeConfig validates the given runtime configuration.
649-
func ValidateRuntimeConfig(ctx context.Context, c *RuntimeConfig, introspectionClient introspectionapi.IntrospectionClient) ([]deprecation.Warning, error) {
503+
func ValidateRuntimeConfig(ctx context.Context, c *RuntimeConfig) ([]deprecation.Warning, error) {
650504
var warnings []deprecation.Warning
651505
if c.ContainerdConfig.Runtimes == nil {
652506
c.ContainerdConfig.Runtimes = make(map[string]Runtime)
@@ -667,15 +521,8 @@ func ValidateRuntimeConfig(ctx context.Context, c *RuntimeConfig, introspectionC
667521
// If empty, use default podSandbox mode
668522
if len(r.Sandboxer) == 0 {
669523
r.Sandboxer = string(ModePodSandbox)
524+
c.ContainerdConfig.Runtimes[k] = r
670525
}
671-
672-
// Resolve r.TreatRoMountsAsRro (string; empty value must not be ignored) into r.TreatRoMountsAsRroResolved (bool)
673-
var err error
674-
r.TreatRoMountsAsRroResolved, err = resolveTreatRoMountsAsRro(ctx, introspectionClient, r)
675-
if err != nil {
676-
return warnings, err
677-
}
678-
c.ContainerdConfig.Runtimes[k] = r
679526
}
680527

681528
// Validation for drain_exec_sync_io_timeout

0 commit comments

Comments
 (0)