Skip to content

Commit 0c7b2e2

Browse files
author
Jan Kaluza
committed
Add support for --pids-limit in podman kube play.
This commit adds new annotation called: io.podman.annotations.pids-limit/$ctrname This annotation is used to define the PIDsLimit for a particular pod. It is also automatically defined when newly added --pids-limit option is used. Fixes: containers#24418 Signed-off-by: Jan Kaluza <[email protected]>
1 parent 3e247db commit 0c7b2e2

File tree

14 files changed

+97
-1
lines changed

14 files changed

+97
-1
lines changed

cmd/podman/kube/play.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type playKubeOptionsWrapper struct {
4040
BuildCLI bool
4141
annotations []string
4242
macs []string
43+
pidsLimit int64
4344
}
4445

4546
var (
@@ -176,6 +177,13 @@ func playFlags(cmd *cobra.Command) {
176177
flags.BoolVar(&playOptions.UseLongAnnotations, noTruncFlagName, false, "Use annotations that are not truncated to the Kubernetes maximum length of 63 characters")
177178
_ = flags.MarkHidden(noTruncFlagName)
178179

180+
pidsLimitFlagName := "pids-limit"
181+
flags.Int64Var(
182+
&playOptions.pidsLimit, pidsLimitFlagName, 0,
183+
"Tune pods pids limit (set -1 for unlimited)",
184+
)
185+
_ = cmd.RegisterFlagCompletionFunc(pidsLimitFlagName, completion.AutocompleteNone)
186+
179187
if !registry.IsRemote() {
180188
certDirFlagName := "cert-dir"
181189
flags.StringVar(&playOptions.CertDir, certDirFlagName, "", "`Pathname` of a directory containing TLS certificates and keys")
@@ -237,6 +245,9 @@ func play(cmd *cobra.Command, args []string) error {
237245
return err
238246
}
239247
}
248+
if cmd.Flags().Changed("pids-limit") {
249+
playOptions.PIDsLimit = &playOptions.pidsLimit
250+
}
240251
if playOptions.ContextDir != "" && playOptions.Build != types.OptionalBoolTrue {
241252
return errors.New("--build must be specified when using --context-dir option")
242253
}

docs/source/markdown/options/pids-limit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
####> This option file is used in:
2-
####> podman create, run, update
2+
####> podman create, kube play, run, update
33
####> If file is edited, make sure the changes
44
####> are applicable to all of those.
55
#### **--pids-limit**=*limit*

docs/source/markdown/podman-kube-play.1.md.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ by `podman kube play` to create them.
5555

5656
Note: To customize the name of the infra container created during `podman kube play`, use the **io.podman.annotations.infra.name** annotation in the pod definition. This annotation is automatically set when generating a kube yaml from a pod that was created with the `--infra-name` flag set.
5757

58+
Note: Use the **io.podman.annotations.pids-limit/$ctrname** annotation to configure the pod's pids limit.
59+
5860
`Kubernetes PersistentVolumeClaims`
5961

6062
A Kubernetes PersistentVolumeClaim represents a Podman named volume. Only the PersistentVolumeClaim name is required by Podman to create a volume. Kubernetes annotations can be used to make use of the available options for Podman volumes.
@@ -252,6 +254,8 @@ When no network option is specified and *host* network mode is not configured in
252254

253255
This option conflicts with host added in the Kubernetes YAML.
254256

257+
@@option pids-limit
258+
255259
#### **--publish**=*[[ip:][hostPort]:]containerPort[/protocol]*
256260

257261
Define or override a port definition in the YAML file.

libpod/define/annotations.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ const (
169169
// KubeImageAutomountAnnotation
170170
KubeImageAutomountAnnotation = "io.podman.annotations.kube.image.volumes.mount"
171171

172+
// PIDsLimitAnnotation is used to limit the number of PIDs
173+
PIDsLimitAnnotation = "io.podman.annotations.pids-limit"
174+
172175
// TotalAnnotationSizeLimitB is the max length of annotations allowed by Kubernetes.
173176
TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
174177
)

pkg/api/handlers/libpod/kube.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
123123
Userns string `schema:"userns"`
124124
Wait bool `schema:"wait"`
125125
Build bool `schema:"build"`
126+
PIDsLimit int64 `schema:"PIDsLimit"`
126127
}{
127128
TLSVerify: true,
128129
Start: true,
@@ -208,6 +209,9 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
208209
if _, found := r.URL.Query()["start"]; found {
209210
options.Start = types.NewOptionalBool(query.Start)
210211
}
212+
if _, found := r.URL.Query()["PIDsLimit"]; found {
213+
options.PIDsLimit = &query.PIDsLimit
214+
}
211215
report, err := containerEngine.PlayKube(r.Context(), reader, options)
212216
if err != nil {
213217
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("playing YAML file: %w", err))

pkg/bindings/kube/kube.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func PlayWithBody(ctx context.Context, body io.Reader, options *PlayOptions) (*e
4949
if options.Start != nil {
5050
params.Set("start", strconv.FormatBool(options.GetStart()))
5151
}
52+
if options.PIDsLimit != nil {
53+
params.Set("PIDsLimit", strconv.FormatInt(*options.PIDsLimit, 10))
54+
}
5255

5356
// For the remote case, read any configMaps passed and append it to the main yaml content
5457
if options.ConfigMaps != nil {

pkg/bindings/kube/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type PlayOptions struct {
6363
// Wait - indicates whether to return after having created the pods
6464
Wait *bool
6565
ServiceContainer *bool
66+
PIDsLimit *int64
6667
}
6768

6869
// ApplyOptions are optional options for applying kube YAML files to a k8s cluster

pkg/bindings/kube/types_play_options.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/domain/entities/play.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ type PlayKubeOptions struct {
8181
Wait bool
8282
// SystemContext - used when building the image
8383
SystemContext *types.SystemContext
84+
// Pids Limit
85+
PIDsLimit *int64
8486
}
8587

8688
// PlayKubePod represents a single pod and associated containers created by play kube

pkg/domain/infra/abi/play.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
996996
VolumesFrom: volumesFrom,
997997
ImageVolumes: automountImages,
998998
UtsNSIsHost: p.UtsNs.IsHost(),
999+
PIDsLimit: options.PIDsLimit,
9991000
}
10001001
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
10011002
if err != nil {
@@ -1087,6 +1088,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
10871088
VolumesFrom: volumesFrom,
10881089
ImageVolumes: automountImages,
10891090
UtsNSIsHost: p.UtsNs.IsHost(),
1091+
PIDsLimit: options.PIDsLimit,
10901092
}
10911093

10921094
if podYAML.Spec.TerminationGracePeriodSeconds != nil {

pkg/domain/infra/tunnel/kube.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en
7575
options.WithPublishPorts(opts.PublishPorts)
7676
options.WithPublishAllPorts(opts.PublishAllPorts)
7777
options.WithNoTrunc(opts.UseLongAnnotations)
78+
options.PIDsLimit = opts.PIDsLimit
7879
return play.KubeWithBody(ic.ClientCtx, body, options)
7980
}
8081

pkg/specgen/generate/kube/kube.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ type CtrSpecGenOptions struct {
184184
PodSecurityContext *v1.PodSecurityContext
185185
// TerminationGracePeriodSeconds is the grace period given to a container to stop before being forcefully killed
186186
TerminationGracePeriodSeconds *int64
187+
// PIDsLimit
188+
PIDsLimit *int64
187189
}
188190

189191
func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
@@ -361,6 +363,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
361363
if opts.PodInfraID != "" {
362364
annotations[ann.SandboxID] = opts.PodInfraID
363365
}
366+
if opts.PIDsLimit != nil {
367+
annotations[define.PIDsLimitAnnotation+"/"+opts.Container.Name] = strconv.FormatInt(*opts.PIDsLimit, 10)
368+
}
364369
s.Annotations = annotations
365370

366371
if containerCIDFile, ok := opts.Annotations[define.InspectAnnotationCIDFile+"/"+opts.Container.Name]; ok {
@@ -375,6 +380,20 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
375380
s.Annotations[define.InspectAnnotationApparmor] = apparmor
376381
}
377382

383+
if pidslimit, ok := annotations[define.PIDsLimitAnnotation+"/"+opts.Container.Name]; ok {
384+
s.Annotations[define.PIDsLimitAnnotation] = pidslimit
385+
pidslimitAsInt, err := strconv.ParseInt(pidslimit, 10, 0)
386+
if err != nil {
387+
return nil, err
388+
}
389+
if s.ResourceLimits == nil {
390+
s.ResourceLimits = &spec.LinuxResources{}
391+
}
392+
s.ResourceLimits.Pids = &spec.LinuxPids{
393+
Limit: pidslimitAsInt,
394+
}
395+
}
396+
378397
if label, ok := opts.Annotations[define.InspectAnnotationLabel+"/"+opts.Container.Name]; ok {
379398
if label == "nested" {
380399
s.ContainerSecurityConfig.LabelNested = &localTrue

pkg/specgenutil/specgen.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
527527
s.Annotations[define.UserNsAnnotation] = c.UserNS
528528
}
529529

530+
if c.PIDsLimit != nil {
531+
s.Annotations[define.PIDsLimitAnnotation] = strconv.FormatInt(*c.PIDsLimit, 10)
532+
}
533+
530534
if len(c.StorageOpts) > 0 {
531535
opts := make(map[string]string, len(c.StorageOpts))
532536
for _, opt := range c.StorageOpts {

test/e2e/play_kube_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6180,4 +6180,31 @@ spec:
61806180
Expect(execArr[len(execArr)-1]).To(Not(ContainSubstring(arr[len(arr)-1])))
61816181
})
61826182

6183+
It("test pids-limit annotation", func() {
6184+
ctrAnnotation := "io.podman.annotations.pids-limit/" + defaultCtrName
6185+
pod := getPod(withAnnotation(ctrAnnotation, "10"), withPodInitCtr(getCtr(withImage(CITEST_IMAGE), withCmd([]string{"printenv", "container"}), withInitCtr(), withName("init-test"))), withCtr(getCtr(withImage(CITEST_IMAGE), withCmd([]string{"top"}))))
6186+
err := generateKubeYaml("pod", pod, kubeYaml)
6187+
Expect(err).ToNot(HaveOccurred())
6188+
6189+
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
6190+
kube.WaitWithDefaultTimeout()
6191+
Expect(kube).Should(ExitCleanly())
6192+
6193+
exec := podmanTest.PodmanExitCleanly("exec", "testPod-"+defaultCtrName, "cat", "/sys/fs/cgroup/pids.max")
6194+
Expect(exec.OutputToString()).To(Equal("10"))
6195+
})
6196+
6197+
It("test --pids-limit command line option", func() {
6198+
pod := getPod(withPodInitCtr(getCtr(withImage(CITEST_IMAGE), withCmd([]string{"printenv", "container"}), withInitCtr(), withName("init-test"))), withCtr(getCtr(withImage(CITEST_IMAGE), withCmd([]string{"top"}))))
6199+
err := generateKubeYaml("pod", pod, kubeYaml)
6200+
Expect(err).ToNot(HaveOccurred())
6201+
6202+
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml, "--pids-limit", "10"})
6203+
kube.WaitWithDefaultTimeout()
6204+
Expect(kube).Should(ExitCleanly())
6205+
6206+
exec := podmanTest.PodmanExitCleanly("exec", "testPod-"+defaultCtrName, "cat", "/sys/fs/cgroup/pids.max")
6207+
Expect(exec.OutputToString()).To(Equal("10"))
6208+
})
6209+
61836210
})

0 commit comments

Comments
 (0)