VPA Admission controller e2e tests for boundary cases.
This commit is contained in:
parent
a68c20ee49
commit
4e7f5612e3
|
|
@ -45,7 +45,7 @@ var _ = actuationSuiteE2eDescribe("Actuation", func() {
|
|||
cpuQuantity := parseQuantityOrDie("100m")
|
||||
memoryQuantity := parseQuantityOrDie("100Mi")
|
||||
|
||||
d := hamsterDeployment(f, cpuQuantity, memoryQuantity)
|
||||
d := newHamsterDeploymentWithResources(f, cpuQuantity, memoryQuantity)
|
||||
d, err := c.ExtensionsV1beta1().Deployments(ns).Create(d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err = framework.WaitForDeploymentComplete(c, d)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package autoscaling
|
|||
|
||||
import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
vpa_types "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/poc.autoscaling.k8s.io/v1alpha1"
|
||||
vpa_clientset "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/client/clientset/versioned"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
|
|
@ -30,49 +30,26 @@ import (
|
|||
var _ = admissionControllerE2eDescribe("Admission-controller", func() {
|
||||
f := framework.NewDefaultFramework("vertical-pod-autoscaling")
|
||||
|
||||
ginkgo.It("starts pods with new request", func() {
|
||||
c := f.ClientSet
|
||||
ns := f.Namespace.Name
|
||||
ginkgo.It("starts pods with new recommended request", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
config, err := framework.LoadConfig()
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"app": "hamster",
|
||||
},
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
newCPUQuantity := parseQuantityOrDie("250m")
|
||||
newMemoryQuantity := parseQuantityOrDie("200Mi")
|
||||
vpaCRD.Status.Recommendation.ContainerRecommendations = []vpa_types.RecommendedContainerResources{
|
||||
{
|
||||
Name: "hamster",
|
||||
Target: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: newCPUQuantity,
|
||||
apiv1.ResourceMemory: newMemoryQuantity,
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("250m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("200Mi"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vpaClientSet := vpa_clientset.NewForConfigOrDie(config)
|
||||
vpaClient := vpaClientSet.PocV1alpha1()
|
||||
_, err = vpaClient.VerticalPodAutoscalers(ns).Create(vpaCRD)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
|
||||
cpuQuantity := parseQuantityOrDie("100m")
|
||||
memoryQuantity := parseQuantityOrDie("100Mi")
|
||||
|
||||
d := hamsterDeployment(f, cpuQuantity, memoryQuantity)
|
||||
d, err = c.ExtensionsV1beta1().Deployments(ns).Create(d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err = framework.WaitForDeploymentComplete(c, d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
podList, err := framework.GetPodsForDeployment(c, d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// Originally Pods had 100m CPU, 100Mi of memory, but admission controller
|
||||
// should change it to recommended 250m CPU and 200Mi of memory.
|
||||
|
|
@ -80,6 +57,185 @@ var _ = admissionControllerE2eDescribe("Admission-controller", func() {
|
|||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("250m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("200Mi")))
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("caps request to limit set by the user", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
d.Spec.Template.Spec.Containers[0].Resources.Limits = apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("222m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("123Mi"),
|
||||
}
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
vpaCRD.Status.Recommendation.ContainerRecommendations = []vpa_types.RecommendedContainerResources{
|
||||
{
|
||||
Name: "hamster",
|
||||
Target: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("250m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("200Mi"),
|
||||
},
|
||||
},
|
||||
}
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// Originally Pods had 100m CPU, 100Mi of memory, but admission controller
|
||||
// should change it to 222m CPU and 123Mi of memory (as this is the recommendation
|
||||
// capped to the limit set by the user)
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("222m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("123Mi")))
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("caps request to max set in VPA", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
vpaCRD.Status.Recommendation.ContainerRecommendations = []vpa_types.RecommendedContainerResources{
|
||||
{
|
||||
Name: "hamster",
|
||||
Target: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("250m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("200Mi"),
|
||||
},
|
||||
MaxRecommended: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("233m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("150Mi"),
|
||||
},
|
||||
},
|
||||
}
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// Originally Pods had 100m CPU, 100Mi of memory, but admission controller
|
||||
// should change it to 233m CPU and 150Mi of memory (as this is the recommendation
|
||||
// capped to max specified in VPA)
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("233m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("150Mi")))
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("raises request to min set in VPA", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
vpaCRD.Status.Recommendation.ContainerRecommendations = []vpa_types.RecommendedContainerResources{
|
||||
{
|
||||
Name: "hamster",
|
||||
Target: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("50m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("60Mi"),
|
||||
},
|
||||
MinRecommended: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("90m"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("80Mi"),
|
||||
},
|
||||
},
|
||||
}
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// Originally Pods had 100m CPU, 100Mi of memory, but admission controller
|
||||
// should change it to recommended 90m CPU and 800Mi of memory (as this the
|
||||
// recommendation raised to min specified in VPA)
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("90m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("80Mi")))
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("leaves users request when no recommendation", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// VPA has no recommendation, so user's request is passed through
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("100m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("100Mi")))
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("leaves user's request when target recommendation is zero", func() {
|
||||
d := newHamsterDeploymentWithResources(f, parseQuantityOrDie("100m") /*cpu*/, parseQuantityOrDie("100Mi") /*memory*/)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
vpaCRD.Status.Recommendation.ContainerRecommendations = []vpa_types.RecommendedContainerResources{
|
||||
{
|
||||
Name: "hamster",
|
||||
Target: apiv1.ResourceList{
|
||||
apiv1.ResourceCPU: parseQuantityOrDie("0"),
|
||||
apiv1.ResourceMemory: parseQuantityOrDie("0"),
|
||||
},
|
||||
},
|
||||
}
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// VPA has no recommendation, so user's request is passed through
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceCPU]).To(gomega.Equal(parseQuantityOrDie("100m")))
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests[apiv1.ResourceMemory]).To(gomega.Equal(parseQuantityOrDie("100Mi")))
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("passes empty request when no recommendation and no user-specified request", func() {
|
||||
d := newHamsterDeployment(f)
|
||||
|
||||
ginkgo.By("Setting up a VPA CRD")
|
||||
vpaCRD := newVPA(f, "hamster-vpa", &metav1.LabelSelector{
|
||||
MatchLabels: d.Spec.Template.Labels,
|
||||
})
|
||||
installVPA(f, vpaCRD)
|
||||
|
||||
ginkgo.By("Setting up a hamster deployment")
|
||||
podList := startDeploymentPods(f, d)
|
||||
|
||||
// VPA has no recommendation, deployment has no request specified
|
||||
for _, pod := range podList.Items {
|
||||
gomega.Expect(pod.Spec.Containers[0].Resources.Requests).To(gomega.BeEmpty())
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func startDeploymentPods(f *framework.Framework, deployment *extensions.Deployment) *apiv1.PodList {
|
||||
c, ns := f.ClientSet, f.Namespace.Name
|
||||
deployment, err := c.ExtensionsV1beta1().Deployments(ns).Create(deployment)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err = framework.WaitForDeploymentComplete(c, deployment)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
podList, err := framework.GetPodsForDeployment(c, deployment)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
return podList
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
vpa_types "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/poc.autoscaling.k8s.io/v1alpha1"
|
||||
vpa_clientset "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/client/clientset/versioned"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
)
|
||||
|
||||
|
|
@ -64,15 +65,20 @@ func actuationSuiteE2eDescribe(name string, body func()) bool {
|
|||
return e2eDescribe(actuationSuite, name, body)
|
||||
}
|
||||
|
||||
func hamsterDeployment(f *framework.Framework, cpuQuantity, memoryQuantity resource.Quantity) *extensions.Deployment {
|
||||
func newHamsterDeployment(f *framework.Framework) *extensions.Deployment {
|
||||
d := framework.NewDeployment("hamster-deployment", 3, map[string]string{"app": "hamster"}, "hamster", "gcr.io/google_containers/ubuntu-slim:0.1", extensions.RollingUpdateDeploymentStrategyType)
|
||||
d.ObjectMeta.Namespace = f.Namespace.Name
|
||||
d.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh"}
|
||||
d.Spec.Template.Spec.Containers[0].Args = []string{"-c", "/usr/bin/yes >/dev/null"}
|
||||
return d
|
||||
}
|
||||
|
||||
func newHamsterDeploymentWithResources(f *framework.Framework, cpuQuantity, memoryQuantity resource.Quantity) *extensions.Deployment {
|
||||
d := newHamsterDeployment(f)
|
||||
d.Spec.Template.Spec.Containers[0].Resources.Requests = v1.ResourceList{
|
||||
v1.ResourceCPU: cpuQuantity,
|
||||
v1.ResourceMemory: memoryQuantity,
|
||||
}
|
||||
d.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh"}
|
||||
d.Spec.Template.Spec.Containers[0].Args = []string{"-c", "/usr/bin/yes >/dev/null"}
|
||||
return d
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +101,16 @@ func newVPA(f *framework.Framework, name string, selector *metav1.LabelSelector)
|
|||
return &vpa
|
||||
}
|
||||
|
||||
func installVPA(f *framework.Framework, vpa *vpa_types.VerticalPodAutoscaler) {
|
||||
ns := f.Namespace.Name
|
||||
config, err := framework.LoadConfig()
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
vpaClientSet := vpa_clientset.NewForConfigOrDie(config)
|
||||
vpaClient := vpaClientSet.PocV1alpha1()
|
||||
_, err = vpaClient.VerticalPodAutoscalers(ns).Create(vpa)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
}
|
||||
|
||||
func parseQuantityOrDie(text string) resource.Quantity {
|
||||
quantity, err := resource.ParseQuantity(text)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ var _ = recommenderE2eDescribe("VPA CRD object", func() {
|
|||
cpuQuantity := parseQuantityOrDie("100m")
|
||||
memoryQuantity := parseQuantityOrDie("100Mi")
|
||||
|
||||
d := hamsterDeployment(f, cpuQuantity, memoryQuantity)
|
||||
d := newHamsterDeploymentWithResources(f, cpuQuantity, memoryQuantity)
|
||||
_, err := c.ExtensionsV1beta1().Deployments(ns).Create(d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err = framework.WaitForDeploymentComplete(c, d)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ var _ = updaterE2eDescribe("Updater", func() {
|
|||
cpuQuantity := parseQuantityOrDie("100m")
|
||||
memoryQuantity := parseQuantityOrDie("100Mi")
|
||||
|
||||
d := hamsterDeployment(f, cpuQuantity, memoryQuantity)
|
||||
d := newHamsterDeploymentWithResources(f, cpuQuantity, memoryQuantity)
|
||||
d, err := c.ExtensionsV1beta1().Deployments(ns).Create(d)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
err = framework.WaitForDeploymentComplete(c, d)
|
||||
|
|
|
|||
Loading…
Reference in New Issue