@@ -23,6 +23,7 @@ import (
23
23
"fmt"
24
24
"net/url"
25
25
"os"
26
+ "path"
26
27
"path/filepath"
27
28
"strings"
28
29
@@ -48,6 +49,7 @@ import (
48
49
"github.com/containerd/nerdctl/pkg/netutil"
49
50
"github.com/containerd/nerdctl/pkg/netutil/nettype"
50
51
"github.com/containerd/nerdctl/pkg/portutil"
52
+ "github.com/containerd/nerdctl/pkg/rootlessutil"
51
53
"github.com/containerd/nerdctl/pkg/strutil"
52
54
"github.com/containerd/nerdctl/pkg/taskutil"
53
55
"github.com/docker/cli/opts"
@@ -495,6 +497,9 @@ func runAction(clicontext *cli.Context) error {
495
497
return fmt .Errorf ("Invalid pid namespace. Set --pid=host to enable host pid namespace." )
496
498
} else {
497
499
opts = append (opts , oci .WithHostNamespace (specs .PIDNamespace ))
500
+ if rootlessutil .IsRootless () {
501
+ opts = append (opts , withBindMountHostProcfs )
502
+ }
498
503
}
499
504
}
500
505
@@ -669,6 +674,36 @@ func generateRootfsOpts(ctx context.Context, client *containerd.Client, cliconte
669
674
return opts , cOpts , ensured , nil
670
675
}
671
676
677
+ // withBindMountHostProcfs replaces procfs mount with rbind.
678
+ // Required for --pid=host on rootless.
679
+ //
680
+ // https://github.com/moby/moby/pull/41893/files
681
+ // https://github.com/containers/podman/blob/v3.0.0-rc1/pkg/specgen/generate/oci.go#L248-L257
682
+ func withBindMountHostProcfs (_ context.Context , _ oci.Client , _ * containers.Container , s * oci.Spec ) error {
683
+ for i , m := range s .Mounts {
684
+ if path .Clean (m .Destination ) == "/proc" {
685
+ newM := specs.Mount {
686
+ Destination : "/proc" ,
687
+ Type : "bind" ,
688
+ Source : "/proc" ,
689
+ Options : []string {"rbind" , "nosuid" , "noexec" , "nodev" },
690
+ }
691
+ s .Mounts [i ] = newM
692
+ }
693
+ }
694
+
695
+ // Remove ReadonlyPaths for /proc/*
696
+ newROP := s .Linux .ReadonlyPaths [:0 ]
697
+ for _ , x := range s .Linux .ReadonlyPaths {
698
+ x = path .Clean (x )
699
+ if ! strings .HasPrefix (x , "/proc/" ) {
700
+ newROP = append (newROP , x )
701
+ }
702
+ }
703
+ s .Linux .ReadonlyPaths = newROP
704
+ return nil
705
+ }
706
+
672
707
func withCustomResolvConf (src string ) func (context.Context , oci.Client , * containers.Container , * oci.Spec ) error {
673
708
return func (_ context.Context , _ oci.Client , _ * containers.Container , s * oci.Spec ) error {
674
709
s .Mounts = append (s .Mounts , specs.Mount {
0 commit comments