diff --git a/cluster/vagrant/provision-master.sh b/cluster/vagrant/provision-master.sh index c7f5a6fab9e..cfeefd8e6bc 100755 --- a/cluster/vagrant/provision-master.sh +++ b/cluster/vagrant/provision-master.sh @@ -75,7 +75,7 @@ grains: cloud_provider: vagrant roles: - kubernetes-master - admission_control: AlwaysAdmit + admission_control: ResourceDefaults,AlwaysAdmit EOF mkdir -p /srv/salt-overlay/pillar diff --git a/cmd/kube-apiserver/plugins.go b/cmd/kube-apiserver/plugins.go index a1ed1d13480..366b211ecf6 100644 --- a/cmd/kube-apiserver/plugins.go +++ b/cmd/kube-apiserver/plugins.go @@ -28,4 +28,5 @@ import ( _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/deny" + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/resourcedefaults" ) diff --git a/plugin/pkg/admission/resourcedefaults/admission.go b/plugin/pkg/admission/resourcedefaults/admission.go new file mode 100644 index 00000000000..e17feb1ccb0 --- /dev/null +++ b/plugin/pkg/admission/resourcedefaults/admission.go @@ -0,0 +1,70 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resourcedefaults + +import ( + "io" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client" +) + +func init() { + admission.RegisterPlugin("ResourceDefaults", func(client client.Interface, config io.Reader) (admission.Interface, error) { + return NewResourceDefaults(), nil + }) +} + +const ( + defaultMemory string = "512Mi" + defaultCPU string = "1" +) + +// resourceDefaults is an implementation of admission.Interface which applies default resource limits (cpu/memory) +// It is useful for clusters that do not want to support unlimited usage constraints, but instead supply sensible defaults +type resourceDefaults struct{} + +func (resourceDefaults) Admit(a admission.Attributes) (err error) { + // ignore deletes, only process create and update + if a.GetOperation() == "DELETE" { + return nil + } + + // we only care about pods + if a.GetKind() != "pods" { + return nil + } + + // get the pod, so we can validate each of the containers within have default mem / cpu constraints + obj := a.GetObject() + pod := obj.(*api.Pod) + for index := range pod.Spec.Containers { + if pod.Spec.Containers[index].Memory.Value() == 0 { + pod.Spec.Containers[index].Memory = resource.MustParse(defaultMemory) + } + if pod.Spec.Containers[index].CPU.Value() == 0 { + pod.Spec.Containers[index].CPU = resource.MustParse(defaultCPU) + } + } + return nil +} + +func NewResourceDefaults() admission.Interface { + return new(resourceDefaults) +} diff --git a/plugin/pkg/admission/resourcedefaults/admission_test.go b/plugin/pkg/admission/resourcedefaults/admission_test.go new file mode 100644 index 00000000000..c901232864e --- /dev/null +++ b/plugin/pkg/admission/resourcedefaults/admission_test.go @@ -0,0 +1,51 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resourcedefaults + +import ( + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +func TestAdmission(t *testing.T) { + namespace := "default" + + handler := NewResourceDefaults() + pod := api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "123", Namespace: "ns"}, + Spec: api.PodSpec{ + Volumes: []api.Volume{{Name: "vol"}}, + Containers: []api.Container{{Name: "ctr", Image: "image"}}, + }, + } + + err := handler.Admit(admission.NewAttributesRecord(&pod, namespace, "pods", "CREATE")) + if err != nil { + t.Errorf("Unexpected error returned from admission handler") + } + + for i := range pod.Spec.Containers { + if pod.Spec.Containers[i].Memory.String() != "512Mi" { + t.Errorf("Unexpected memory value %s", pod.Spec.Containers[i].Memory.String()) + } + if pod.Spec.Containers[i].CPU.String() != "1" { + t.Errorf("Unexpected cpu value %s", pod.Spec.Containers[i].CPU.String()) + } + } +} diff --git a/plugin/pkg/admission/resourcedefaults/doc.go b/plugin/pkg/admission/resourcedefaults/doc.go new file mode 100644 index 00000000000..38f10213b6f --- /dev/null +++ b/plugin/pkg/admission/resourcedefaults/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package resourcedefaults contains an example plug-in that +// cluster operators can use to prevent unlimited CPU and +// Memory usage for a container. It intercepts all pod +// create and update requests and applies a default +// Memory and CPU quantity if none is supplied. +// This plug-in can be enhanced in the future to make the default value +// configurable via the admission control configuration file. +package resourcedefaults