From f15b0887c7fe0fc722a24fa3b2a8ed188f136707 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Fri, 21 Mar 2025 12:26:33 +0100 Subject: [PATCH] Add support for pids-limit annotation for 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: #24418 Signed-off-by: Jan Kaluza --- docs/source/markdown/podman-kube-play.1.md.in | 2 ++ libpod/define/annotations.go | 3 +++ pkg/specgen/generate/kube/kube.go | 14 ++++++++++++++ pkg/specgenutil/specgen.go | 4 ++++ test/e2e/play_kube_test.go | 14 ++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/docs/source/markdown/podman-kube-play.1.md.in b/docs/source/markdown/podman-kube-play.1.md.in index 5ed9a4b766..18dd1e5650 100644 --- a/docs/source/markdown/podman-kube-play.1.md.in +++ b/docs/source/markdown/podman-kube-play.1.md.in @@ -55,6 +55,8 @@ by `podman kube play` to create them. 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. +Note: Use the **io.podman.annotations.pids-limit/$ctrname** annotation to configure the pod's pids limit. + `Kubernetes PersistentVolumeClaims` 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. diff --git a/libpod/define/annotations.go b/libpod/define/annotations.go index e1da8a157e..e2e562902c 100644 --- a/libpod/define/annotations.go +++ b/libpod/define/annotations.go @@ -169,6 +169,9 @@ const ( // KubeImageAutomountAnnotation KubeImageAutomountAnnotation = "io.podman.annotations.kube.image.volumes.mount" + // PIDsLimitAnnotation is used to limit the number of PIDs + PIDsLimitAnnotation = "io.podman.annotations.pids-limit" + // TotalAnnotationSizeLimitB is the max length of annotations allowed by Kubernetes. TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB ) diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 6c5782a202..8ec71a7317 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -375,6 +375,20 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener s.Annotations[define.InspectAnnotationApparmor] = apparmor } + if pidslimit, ok := annotations[define.PIDsLimitAnnotation+"/"+opts.Container.Name]; ok { + s.Annotations[define.PIDsLimitAnnotation] = pidslimit + pidslimitAsInt, err := strconv.ParseInt(pidslimit, 10, 0) + if err != nil { + return nil, err + } + if s.ResourceLimits == nil { + s.ResourceLimits = &spec.LinuxResources{} + } + s.ResourceLimits.Pids = &spec.LinuxPids{ + Limit: pidslimitAsInt, + } + } + if label, ok := opts.Annotations[define.InspectAnnotationLabel+"/"+opts.Container.Name]; ok { if label == "nested" { s.ContainerSecurityConfig.LabelNested = &localTrue diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 6163f47a0e..bd42622f4f 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -527,6 +527,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions s.Annotations[define.UserNsAnnotation] = c.UserNS } + if c.PIDsLimit != nil { + s.Annotations[define.PIDsLimitAnnotation] = strconv.FormatInt(*c.PIDsLimit, 10) + } + if len(c.StorageOpts) > 0 { opts := make(map[string]string, len(c.StorageOpts)) for _, opt := range c.StorageOpts { diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 078bad5533..f182f138f8 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -6180,4 +6180,18 @@ spec: Expect(execArr[len(execArr)-1]).To(Not(ContainSubstring(arr[len(arr)-1]))) }) + It("test pids-limit annotation", func() { + ctrAnnotation := "io.podman.annotations.pids-limit/" + defaultCtrName + 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"})))) + err := generateKubeYaml("pod", pod, kubeYaml) + Expect(err).ToNot(HaveOccurred()) + + kube := podmanTest.Podman([]string{"kube", "play", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(ExitCleanly()) + + exec := podmanTest.PodmanExitCleanly("exec", "testPod-"+defaultCtrName, "cat", "/sys/fs/cgroup/pids.max") + Expect(exec.OutputToString()).To(Equal("10")) + }) + })