Merge pull request #24179 from aveshagarwal/master-downward-api-resources-limits-requests-implementation
Automatic merge from submit-queue Downward API implementation for resources limits and requests This is an implementation of Downward API for resources limits and requests, and it works with environment variables and volume plugin. This is based on proposal https://github.com/kubernetes/kubernetes/pull/24051. This implementation follows API with magic keys approach as discussed in the proposal. @kubernetes/rh-cluster-infra <!-- Reviewable:start --> --- This change is [<img src="http://reviewable.k8s.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](http://reviewable.k8s.io/reviews/kubernetes/kubernetes/24179) <!-- Reviewable:end -->
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
@@ -80,6 +81,53 @@ var _ = framework.KubeDescribe("Downward API", func() {
|
||||
|
||||
testDownwardAPI(f, podName, env, expectations)
|
||||
})
|
||||
|
||||
It("should provide container's limits.cpu/memory and requests.cpu/memory as env vars", func() {
|
||||
podName := "downward-api-" + string(util.NewUUID())
|
||||
env := []api.EnvVar{
|
||||
{
|
||||
Name: "CPU_LIMIT",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
Resource: "limits.cpu",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "MEMORY_LIMIT",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
Resource: "limits.memory",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "CPU_REQUEST",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
Resource: "requests.cpu",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "MEMORY_REQUEST",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
Resource: "requests.memory",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
expectations := []string{
|
||||
fmt.Sprintf("CPU_LIMIT=2"),
|
||||
fmt.Sprintf("MEMORY_LIMIT=67108864"),
|
||||
fmt.Sprintf("CPU_REQUEST=1"),
|
||||
fmt.Sprintf("MEMORY_REQUEST=33554432"),
|
||||
}
|
||||
|
||||
testDownwardAPI(f, podName, env, expectations)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, expectations []string) {
|
||||
@@ -94,7 +142,17 @@ func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, e
|
||||
Name: "dapi-container",
|
||||
Image: "gcr.io/google_containers/busybox:1.24",
|
||||
Command: []string{"sh", "-c", "env"},
|
||||
Env: env,
|
||||
Resources: api.ResourceRequirements{
|
||||
Requests: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("250m"),
|
||||
api.ResourceMemory: resource.MustParse("32Mi"),
|
||||
},
|
||||
Limits: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("1250m"),
|
||||
api.ResourceMemory: resource.MustParse("64Mi"),
|
||||
},
|
||||
},
|
||||
Env: env,
|
||||
},
|
||||
},
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
@@ -131,6 +132,43 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
|
||||
podLogTimeout, framework.Poll).Should(ContainSubstring("builder=\"foo\"\n"))
|
||||
|
||||
})
|
||||
|
||||
It("should provide container's cpu limit", func() {
|
||||
podName := "downwardapi-volume-" + string(util.NewUUID())
|
||||
pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_limit")
|
||||
|
||||
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
|
||||
fmt.Sprintf("2\n"),
|
||||
}, f.Namespace.Name)
|
||||
})
|
||||
|
||||
It("should provide container's memory limit", func() {
|
||||
podName := "downwardapi-volume-" + string(util.NewUUID())
|
||||
pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_limit")
|
||||
|
||||
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
|
||||
fmt.Sprintf("67108864\n"),
|
||||
}, f.Namespace.Name)
|
||||
})
|
||||
|
||||
It("should provide container's cpu request", func() {
|
||||
podName := "downwardapi-volume-" + string(util.NewUUID())
|
||||
pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_request")
|
||||
|
||||
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
|
||||
fmt.Sprintf("1\n"),
|
||||
}, f.Namespace.Name)
|
||||
})
|
||||
|
||||
It("should provide container's memory request", func() {
|
||||
podName := "downwardapi-volume-" + string(util.NewUUID())
|
||||
pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_request")
|
||||
|
||||
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
|
||||
fmt.Sprintf("33554432\n"),
|
||||
}, f.Namespace.Name)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func downwardAPIVolumePodForSimpleTest(name string, filePath string) *api.Pod {
|
||||
@@ -154,6 +192,40 @@ func downwardAPIVolumePodForSimpleTest(name string, filePath string) *api.Pod {
|
||||
return pod
|
||||
}
|
||||
|
||||
func downwardAPIVolumeForContainerResources(name string, filePath string) *api.Pod {
|
||||
pod := downwardAPIVolumeBasePod(name, nil, nil)
|
||||
pod.Spec.Containers = downwardAPIVolumeBaseContainers("client-container", filePath)
|
||||
return pod
|
||||
}
|
||||
|
||||
func downwardAPIVolumeBaseContainers(name, filePath string) []api.Container {
|
||||
return []api.Container{
|
||||
{
|
||||
Name: name,
|
||||
Image: "gcr.io/google_containers/mounttest:0.6",
|
||||
Command: []string{"/mt", "--file_content=" + filePath},
|
||||
Resources: api.ResourceRequirements{
|
||||
Requests: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("250m"),
|
||||
api.ResourceMemory: resource.MustParse("32Mi"),
|
||||
},
|
||||
Limits: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("1250m"),
|
||||
api.ResourceMemory: resource.MustParse("64Mi"),
|
||||
},
|
||||
},
|
||||
VolumeMounts: []api.VolumeMount{
|
||||
{
|
||||
Name: "podinfo",
|
||||
MountPath: "/etc",
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func downwardAPIVolumePodForUpdateTest(name string, labels, annotations map[string]string, filePath string) *api.Pod {
|
||||
pod := downwardAPIVolumeBasePod(name, labels, annotations)
|
||||
|
||||
@@ -192,11 +264,39 @@ func downwardAPIVolumeBasePod(name string, labels, annotations map[string]string
|
||||
Items: []api.DownwardAPIVolumeFile{
|
||||
{
|
||||
Path: "podname",
|
||||
FieldRef: api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
},
|
||||
{
|
||||
Path: "cpu_limit",
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
ContainerName: "client-container",
|
||||
Resource: "limits.cpu",
|
||||
},
|
||||
},
|
||||
{
|
||||
Path: "cpu_request",
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
ContainerName: "client-container",
|
||||
Resource: "requests.cpu",
|
||||
},
|
||||
},
|
||||
{
|
||||
Path: "memory_limit",
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
ContainerName: "client-container",
|
||||
Resource: "limits.memory",
|
||||
},
|
||||
},
|
||||
{
|
||||
Path: "memory_request",
|
||||
ResourceFieldRef: &api.ResourceFieldSelector{
|
||||
ContainerName: "client-container",
|
||||
Resource: "requests.memory",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -213,7 +313,7 @@ func applyLabelsAndAnnotationsToDownwardAPIPod(labels, annotations map[string]st
|
||||
if len(labels) > 0 {
|
||||
pod.Spec.Volumes[0].DownwardAPI.Items = append(pod.Spec.Volumes[0].DownwardAPI.Items, api.DownwardAPIVolumeFile{
|
||||
Path: "labels",
|
||||
FieldRef: api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1",
|
||||
FieldPath: "metadata.labels",
|
||||
},
|
||||
@@ -223,7 +323,7 @@ func applyLabelsAndAnnotationsToDownwardAPIPod(labels, annotations map[string]st
|
||||
if len(annotations) > 0 {
|
||||
pod.Spec.Volumes[0].DownwardAPI.Items = append(pod.Spec.Volumes[0].DownwardAPI.Items, api.DownwardAPIVolumeFile{
|
||||
Path: "annotations",
|
||||
FieldRef: api.ObjectFieldSelector{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1",
|
||||
FieldPath: "metadata.annotations",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user