mirror of
https://github.com/containers/podman.git
synced 2025-10-19 20:23:08 +08:00
Merge pull request #17379 from umohnani8/ulimit
Add ulimit annotation to kube gen & play
This commit is contained in:
@ -140,6 +140,10 @@ const (
|
|||||||
// of the init container.
|
// of the init container.
|
||||||
InitContainerType = "io.podman.annotations.init.container.type"
|
InitContainerType = "io.podman.annotations.init.container.type"
|
||||||
|
|
||||||
|
// UlimitAnnotation is used by kube play when playing a kube yaml to specify the ulimits
|
||||||
|
// of the container
|
||||||
|
UlimitAnnotation = "io.podman.annotations.ulimit"
|
||||||
|
|
||||||
// MaxKubeAnnotation is the max length of annotations allowed by Kubernetes.
|
// MaxKubeAnnotation is the max length of annotations allowed by Kubernetes.
|
||||||
MaxKubeAnnotation = 63
|
MaxKubeAnnotation = 63
|
||||||
)
|
)
|
||||||
|
@ -531,6 +531,24 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctr.config.Spec.Process != nil {
|
||||||
|
var ulimitArr []string
|
||||||
|
defaultUlimits := util.DefaultContainerConfig().Ulimits()
|
||||||
|
for _, ulimit := range ctr.config.Spec.Process.Rlimits {
|
||||||
|
finalUlimit := strings.ToLower(strings.ReplaceAll(ulimit.Type, "RLIMIT_", "")) + "=" + strconv.Itoa(int(ulimit.Soft)) + ":" + strconv.Itoa(int(ulimit.Hard))
|
||||||
|
// compare ulimit with default list so we don't add it twice
|
||||||
|
if cutil.StringInSlice(finalUlimit, defaultUlimits) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ulimitArr = append(ulimitArr, finalUlimit)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ulimitArr) > 0 {
|
||||||
|
kubeAnnotations[define.UlimitAnnotation] = strings.Join(ulimitArr, ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !ctr.HostNetwork() {
|
if !ctr.HostNetwork() {
|
||||||
hostNetwork = false
|
hostNetwork = false
|
||||||
}
|
}
|
||||||
|
@ -273,6 +273,18 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
|
|||||||
s.ResourceLimits.Memory.Reservation = &memoryRes
|
s.ResourceLimits.Memory.Reservation = &memoryRes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ulimitVal, ok := opts.Annotations[define.UlimitAnnotation]
|
||||||
|
if ok {
|
||||||
|
ulimits := strings.Split(ulimitVal, ",")
|
||||||
|
for _, ul := range ulimits {
|
||||||
|
parsed, err := units.ParseUlimit(ul)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.Rlimits = append(s.Rlimits, spec.POSIXRlimit{Type: parsed.Name, Soft: uint64(parsed.Soft), Hard: uint64(parsed.Hard)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: We don't understand why specgen does not take of this, but
|
// TODO: We don't understand why specgen does not take of this, but
|
||||||
// integration tests clearly pointed out that it was required.
|
// integration tests clearly pointed out that it was required.
|
||||||
imageData, err := opts.Image.Inspect(ctx, nil)
|
imageData, err := opts.Image.Inspect(ctx, nil)
|
||||||
|
@ -72,7 +72,6 @@ var _ = Describe("Podman kube generate", func() {
|
|||||||
Expect(pod.Spec.Containers[0].SecurityContext).To(BeNil())
|
Expect(pod.Spec.Containers[0].SecurityContext).To(BeNil())
|
||||||
Expect(pod.Spec.Containers[0].Env).To(BeNil())
|
Expect(pod.Spec.Containers[0].Env).To(BeNil())
|
||||||
Expect(pod).To(HaveField("Name", "top-pod"))
|
Expect(pod).To(HaveField("Name", "top-pod"))
|
||||||
Expect(pod.Annotations).To(HaveLen(0))
|
|
||||||
|
|
||||||
numContainers := 0
|
numContainers := 0
|
||||||
for range pod.Spec.Containers {
|
for range pod.Spec.Containers {
|
||||||
@ -1330,4 +1329,40 @@ USER test1`
|
|||||||
|
|
||||||
Expect(pod.Spec.Volumes[0].Secret).To(BeNil())
|
Expect(pod.Spec.Volumes[0].Secret).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman generate & play kube with --ulimit set", func() {
|
||||||
|
ctrName := "ulimit-ctr"
|
||||||
|
ctrNameInKubePod := ctrName + "-pod-" + ctrName
|
||||||
|
session1 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--ulimit", "nofile=1231:3123", ALPINE, "sleep", "1000"})
|
||||||
|
session1.WaitWithDefaultTimeout()
|
||||||
|
Expect(session1).Should(Exit(0))
|
||||||
|
|
||||||
|
outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml")
|
||||||
|
kube := podmanTest.Podman([]string{"kube", "generate", ctrName, "-f", outputFile})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube).Should(Exit(0))
|
||||||
|
|
||||||
|
b, err := os.ReadFile(outputFile)
|
||||||
|
Expect(err).ShouldNot(HaveOccurred())
|
||||||
|
pod := new(v1.Pod)
|
||||||
|
err = yaml.Unmarshal(b, pod)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(pod.Annotations).To(HaveKey(define.UlimitAnnotation))
|
||||||
|
Expect(pod.Annotations[define.UlimitAnnotation]).To(ContainSubstring("nofile=1231:3123"))
|
||||||
|
|
||||||
|
rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", ctrName})
|
||||||
|
rm.WaitWithDefaultTimeout()
|
||||||
|
Expect(rm).Should(Exit(0))
|
||||||
|
|
||||||
|
play := podmanTest.Podman([]string{"kube", "play", outputFile})
|
||||||
|
play.WaitWithDefaultTimeout()
|
||||||
|
Expect(play).Should(Exit(0))
|
||||||
|
|
||||||
|
inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
Expect(inspect).Should(Exit(0))
|
||||||
|
Expect(inspect.OutputToString()).To(ContainSubstring("RLIMIT_NOFILE"))
|
||||||
|
Expect(inspect.OutputToString()).To(ContainSubstring("1231"))
|
||||||
|
Expect(inspect.OutputToString()).To(ContainSubstring("3123"))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user