Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
620af168
Commit
620af168
authored
Apr 02, 2015
by
Prashanth B
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6097 from derekwaynecarr/limit_range_default_value
Limit range supporting a default resource limits value
parents
e0cbe385
dbe4d429
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
265 additions
and
179 deletions
+265
-179
admission_control_limit_range.md
docs/design/admission_control_limit_range.md
+16
-6
invalid-pod.json
examples/limitrange/invalid-pod.json
+3
-1
limit-range.json
examples/limitrange/limit-range.json
+5
-1
invalid-pod.json
examples/limitrange/v1beta3/invalid-pod.json
+9
-3
limit-range.json
examples/limitrange/v1beta3/limit-range.json
+5
-1
types.go
pkg/api/types.go
+2
-0
conversion.go
pkg/api/v1beta1/conversion.go
+6
-0
types.go
pkg/api/v1beta1/types.go
+2
-0
conversion.go
pkg/api/v1beta2/conversion.go
+6
-0
types.go
pkg/api/v1beta2/types.go
+2
-0
types.go
pkg/api/v1beta3/types.go
+2
-0
describe.go
pkg/kubectl/describe.go
+14
-4
admission.go
plugin/pkg/admission/limitranger/admission.go
+62
-8
admission_test.go
plugin/pkg/admission/limitranger/admission_test.go
+131
-155
No files found.
docs/design/admission_control_limit_range.md
View file @
620af168
...
@@ -25,6 +25,8 @@ type LimitRangeItem struct {
...
@@ -25,6 +25,8 @@ type LimitRangeItem struct {
Max
ResourceList
`json:"max,omitempty"`
Max
ResourceList
`json:"max,omitempty"`
// Min usage constraints on this kind by resource name
// Min usage constraints on this kind by resource name
Min
ResourceList
`json:"min,omitempty"`
Min
ResourceList
`json:"min,omitempty"`
// Default usage constraints on this kind by resource name
Default
ResourceList
`json:"default,omitempty"`
}
}
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
...
@@ -74,6 +76,14 @@ The following min/max limits are imposed:
...
@@ -74,6 +76,14 @@ The following min/max limits are imposed:
| cpu | Min/Max amount of cpu per pod |
| cpu | Min/Max amount of cpu per pod |
| memory | Min/Max amount of memory per pod |
| memory | Min/Max amount of memory per pod |
If a resource specifies a default value, it may get applied on the incoming resource. For example, if a default
value is provided for container cpu, it is set on the incoming container if and only if the incoming container
does not specify a resource requirements limit field.
If a resource specifies a min value, it may get applied on the incoming resource. For example, if a min
value is provided for container cpu, it is set on the incoming container if and only if the incoming container does
not specify a resource requirements requests field.
If the incoming object would cause a violation of the enumerated constraints, the request is denied with a set of
If the incoming object would cause a violation of the enumerated constraints, the request is denied with a set of
messages explaining what constraints were the source of the denial.
messages explaining what constraints were the source of the denial.
...
@@ -105,12 +115,12 @@ NAME
...
@@ -105,12 +115,12 @@ NAME
limits
limits
$ kubectl describe limits limits
$ kubectl describe limits limits
Name: limits
Name: limits
Type Resource Min Max
Type Resource Min Max
Default
---- -------- --- ---
---- -------- --- ---
---
Pod memory 1Mi 1Gi
Pod memory 1Mi 1Gi
-
Pod cpu 250m 2
Pod cpu 250m 2
-
Container memory 1Mi 1Gi
Container memory 1Mi 1Gi
1Mi
Container cpu 250m 2
Container cpu 250m 2
50m 250m
```
```
## Future Enhancements: Define limits for a particular pod or container.
## Future Enhancements: Define limits for a particular pod or container.
...
...
examples/limitrange/invalid-pod.json
View file @
620af168
...
@@ -11,7 +11,9 @@
...
@@ -11,7 +11,9 @@
"id"
:
"invalid-pod"
,
"id"
:
"invalid-pod"
,
"containers"
:
[{
"containers"
:
[{
"name"
:
"kubernetes-serve-hostname"
,
"name"
:
"kubernetes-serve-hostname"
,
"image"
:
"gcr.io/google_containers/serve_hostname"
"image"
:
"gcr.io/google_containers/serve_hostname"
,
"cpu"
:
10
,
"memory"
:
1048576
}]
}]
}
}
}
}
...
...
examples/limitrange/limit-range.json
View file @
620af168
...
@@ -24,7 +24,11 @@
...
@@ -24,7 +24,11 @@
"min"
:
{
"min"
:
{
"memory"
:
"1048576"
,
"memory"
:
"1048576"
,
"cpu"
:
"0.25"
"cpu"
:
"0.25"
}
},
"default"
:
{
"memory"
:
"1048576"
,
"cpu"
:
"0.25"
}
}
}
]
]
}
}
...
...
examples/limitrange/v1beta3/invalid-pod.json
View file @
620af168
...
@@ -10,7 +10,13 @@
...
@@ -10,7 +10,13 @@
"spec"
:
{
"spec"
:
{
"containers"
:
[{
"containers"
:
[{
"name"
:
"kubernetes-serve-hostname"
,
"name"
:
"kubernetes-serve-hostname"
,
"image"
:
"gcr.io/google_containers/serve_hostname"
"image"
:
"gcr.io/google_containers/serve_hostname"
,
}]
"resources"
:
{
}
"limits"
:
{
"cpu"
:
"10m"
,
"memory"
:
"1Mi"
}
}
}]
}
}
}
examples/limitrange/v1beta3/limit-range.json
View file @
620af168
...
@@ -26,7 +26,11 @@
...
@@ -26,7 +26,11 @@
"min"
:
{
"min"
:
{
"memory"
:
"1Mi"
,
"memory"
:
"1Mi"
,
"cpu"
:
"250m"
"cpu"
:
"250m"
}
},
"default"
:
{
"memory"
:
"1Mi"
,
"cpu"
:
"250m"
}
}
}
]
]
}
}
...
...
pkg/api/types.go
View file @
620af168
...
@@ -1554,6 +1554,8 @@ type LimitRangeItem struct {
...
@@ -1554,6 +1554,8 @@ type LimitRangeItem struct {
Max
ResourceList
`json:"max,omitempty"`
Max
ResourceList
`json:"max,omitempty"`
// Min usage constraints on this kind by resource name
// Min usage constraints on this kind by resource name
Min
ResourceList
`json:"min,omitempty"`
Min
ResourceList
`json:"min,omitempty"`
// Default usage constraints on this kind by resource name
Default
ResourceList
`json:"default,omitempty"`
}
}
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
...
...
pkg/api/v1beta1/conversion.go
View file @
620af168
...
@@ -922,6 +922,9 @@ func init() {
...
@@ -922,6 +922,9 @@ func init() {
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
s
.
Convert
(
&
in
.
Default
,
&
out
.
Default
,
0
);
err
!=
nil
{
return
err
}
return
nil
return
nil
},
},
func
(
in
*
LimitRangeItem
,
out
*
newer
.
LimitRangeItem
,
s
conversion
.
Scope
)
error
{
func
(
in
*
LimitRangeItem
,
out
*
newer
.
LimitRangeItem
,
s
conversion
.
Scope
)
error
{
...
@@ -933,6 +936,9 @@ func init() {
...
@@ -933,6 +936,9 @@ func init() {
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
s
.
Convert
(
&
in
.
Default
,
&
out
.
Default
,
0
);
err
!=
nil
{
return
err
}
return
nil
return
nil
},
},
...
...
pkg/api/v1beta1/types.go
View file @
620af168
...
@@ -1358,6 +1358,8 @@ type LimitRangeItem struct {
...
@@ -1358,6 +1358,8 @@ type LimitRangeItem struct {
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
// Min usage constraints on this kind by resource name
// Min usage constraints on this kind by resource name
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
// Default usage constraints on this kind by resource name
Default
ResourceList
`json:"default,omitempty" description:"default values on this kind by resource name if omitted"`
}
}
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
...
...
pkg/api/v1beta2/conversion.go
View file @
620af168
...
@@ -853,6 +853,9 @@ func init() {
...
@@ -853,6 +853,9 @@ func init() {
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
s
.
Convert
(
&
in
.
Default
,
&
out
.
Default
,
0
);
err
!=
nil
{
return
err
}
return
nil
return
nil
},
},
func
(
in
*
LimitRangeItem
,
out
*
newer
.
LimitRangeItem
,
s
conversion
.
Scope
)
error
{
func
(
in
*
LimitRangeItem
,
out
*
newer
.
LimitRangeItem
,
s
conversion
.
Scope
)
error
{
...
@@ -864,6 +867,9 @@ func init() {
...
@@ -864,6 +867,9 @@ func init() {
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
if
err
:=
s
.
Convert
(
&
in
.
Min
,
&
out
.
Min
,
0
);
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
s
.
Convert
(
&
in
.
Default
,
&
out
.
Default
,
0
);
err
!=
nil
{
return
err
}
return
nil
return
nil
},
},
...
...
pkg/api/v1beta2/types.go
View file @
620af168
...
@@ -1420,6 +1420,8 @@ type LimitRangeItem struct {
...
@@ -1420,6 +1420,8 @@ type LimitRangeItem struct {
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
// Min usage constraints on this kind by resource name
// Min usage constraints on this kind by resource name
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
// Default usage constraints on this kind by resource name
Default
ResourceList
`json:"default,omitempty" description:"default values on this kind by resource name if omitted"`
}
}
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
...
...
pkg/api/v1beta3/types.go
View file @
620af168
...
@@ -1459,6 +1459,8 @@ type LimitRangeItem struct {
...
@@ -1459,6 +1459,8 @@ type LimitRangeItem struct {
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
Max
ResourceList
`json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
// Min usage constraints on this kind by resource name
// Min usage constraints on this kind by resource name
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
Min
ResourceList
`json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
// Default usage constraints on this kind by resource name
Default
ResourceList
`json:"default,omitempty" description:"default values on this kind by resource name if omitted"`
}
}
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
...
...
pkg/kubectl/describe.go
View file @
620af168
...
@@ -115,12 +115,13 @@ func (d *LimitRangeDescriber) Describe(namespace, name string) (string, error) {
...
@@ -115,12 +115,13 @@ func (d *LimitRangeDescriber) Describe(namespace, name string) (string, error) {
func
describeLimitRange
(
limitRange
*
api
.
LimitRange
)
(
string
,
error
)
{
func
describeLimitRange
(
limitRange
*
api
.
LimitRange
)
(
string
,
error
)
{
return
tabbedString
(
func
(
out
io
.
Writer
)
error
{
return
tabbedString
(
func
(
out
io
.
Writer
)
error
{
fmt
.
Fprintf
(
out
,
"Name:
\t
%s
\n
"
,
limitRange
.
Name
)
fmt
.
Fprintf
(
out
,
"Name:
\t
%s
\n
"
,
limitRange
.
Name
)
fmt
.
Fprintf
(
out
,
"Type
\t
Resource
\t
Min
\t
Max
\n
"
)
fmt
.
Fprintf
(
out
,
"Type
\t
Resource
\t
Min
\t
Max
\
t
Default
\
n
"
)
fmt
.
Fprintf
(
out
,
"----
\t
--------
\t
---
\t
---
\n
"
)
fmt
.
Fprintf
(
out
,
"----
\t
--------
\t
---
\t
---
\
t
---
\
n
"
)
for
i
:=
range
limitRange
.
Spec
.
Limits
{
for
i
:=
range
limitRange
.
Spec
.
Limits
{
item
:=
limitRange
.
Spec
.
Limits
[
i
]
item
:=
limitRange
.
Spec
.
Limits
[
i
]
maxResources
:=
item
.
Max
maxResources
:=
item
.
Max
minResources
:=
item
.
Min
minResources
:=
item
.
Min
defaultResources
:=
item
.
Default
set
:=
map
[
api
.
ResourceName
]
bool
{}
set
:=
map
[
api
.
ResourceName
]
bool
{}
for
k
:=
range
maxResources
{
for
k
:=
range
maxResources
{
...
@@ -129,11 +130,15 @@ func describeLimitRange(limitRange *api.LimitRange) (string, error) {
...
@@ -129,11 +130,15 @@ func describeLimitRange(limitRange *api.LimitRange) (string, error) {
for
k
:=
range
minResources
{
for
k
:=
range
minResources
{
set
[
k
]
=
true
set
[
k
]
=
true
}
}
for
k
:=
range
defaultResources
{
set
[
k
]
=
true
}
for
k
:=
range
set
{
for
k
:=
range
set
{
// if no value is set, we output -
// if no value is set, we output -
maxValue
:=
"-"
maxValue
:=
"-"
minValue
:=
"-"
minValue
:=
"-"
defaultValue
:=
"-"
maxQuantity
,
maxQuantityFound
:=
maxResources
[
k
]
maxQuantity
,
maxQuantityFound
:=
maxResources
[
k
]
if
maxQuantityFound
{
if
maxQuantityFound
{
...
@@ -145,8 +150,13 @@ func describeLimitRange(limitRange *api.LimitRange) (string, error) {
...
@@ -145,8 +150,13 @@ func describeLimitRange(limitRange *api.LimitRange) (string, error) {
minValue
=
minQuantity
.
String
()
minValue
=
minQuantity
.
String
()
}
}
msg
:=
"%v
\t
%v
\t
%v
\t
%v
\n
"
defaultQuantity
,
defaultQuantityFound
:=
defaultResources
[
k
]
fmt
.
Fprintf
(
out
,
msg
,
item
.
Type
,
k
,
minValue
,
maxValue
)
if
defaultQuantityFound
{
defaultValue
=
defaultQuantity
.
String
()
}
msg
:=
"%v
\t
%v
\t
%v
\t
%v
\t
%v
\n
"
fmt
.
Fprintf
(
out
,
msg
,
item
.
Type
,
k
,
minValue
,
maxValue
,
defaultValue
)
}
}
}
}
return
nil
return
nil
...
...
plugin/pkg/admission/limitranger/admission.go
View file @
620af168
...
@@ -35,7 +35,7 @@ import (
...
@@ -35,7 +35,7 @@ import (
func
init
()
{
func
init
()
{
admission
.
RegisterPlugin
(
"LimitRanger"
,
func
(
client
client
.
Interface
,
config
io
.
Reader
)
(
admission
.
Interface
,
error
)
{
admission
.
RegisterPlugin
(
"LimitRanger"
,
func
(
client
client
.
Interface
,
config
io
.
Reader
)
(
admission
.
Interface
,
error
)
{
return
NewLimitRanger
(
client
,
PodLimitFunc
),
nil
return
NewLimitRanger
(
client
,
Limit
),
nil
})
})
}
}
...
@@ -114,13 +114,67 @@ func Max(a int64, b int64) int64 {
...
@@ -114,13 +114,67 @@ func Max(a int64, b int64) int64 {
return
b
return
b
}
}
// PodLimitFunc enforces that a pod spec does not exceed any limits specified on the supplied limit range
// Limit enforces resource requirements of incoming resources against enumerated constraints
func
PodLimitFunc
(
limitRange
*
api
.
LimitRange
,
resourceName
string
,
obj
runtime
.
Object
)
error
{
// on the LimitRange. It may modify the incoming object to apply default resource requirements
if
resourceName
!=
"pods"
{
// if not specified, and enumerated on the LimitRange
return
nil
func
Limit
(
limitRange
*
api
.
LimitRange
,
resourceName
string
,
obj
runtime
.
Object
)
error
{
switch
resourceName
{
case
"pods"
:
return
PodLimitFunc
(
limitRange
,
obj
.
(
*
api
.
Pod
))
}
return
nil
}
// defaultContainerResourceRequirements returns the default requirements for a container
// the requirement.Limits are taken from the LimitRange defaults (if specified)
// the requirement.Requests are taken from the LimitRange min (if specified)
func
defaultContainerResourceRequirements
(
limitRange
*
api
.
LimitRange
)
api
.
ResourceRequirements
{
requirements
:=
api
.
ResourceRequirements
{}
requirements
.
Limits
=
api
.
ResourceList
{}
requirements
.
Requests
=
api
.
ResourceList
{}
for
i
:=
range
limitRange
.
Spec
.
Limits
{
limit
:=
limitRange
.
Spec
.
Limits
[
i
]
if
limit
.
Type
==
api
.
LimitTypeContainer
{
for
k
,
v
:=
range
limit
.
Default
{
value
:=
v
.
Copy
()
requirements
.
Limits
[
k
]
=
*
value
}
for
k
,
v
:=
range
limit
.
Min
{
value
:=
v
.
Copy
()
requirements
.
Requests
[
k
]
=
*
value
}
}
}
}
return
requirements
}
// mergePodResourceRequirements merges enumerated requirements with default requirements
func
mergePodResourceRequirements
(
pod
*
api
.
Pod
,
defaultRequirements
*
api
.
ResourceRequirements
)
{
for
i
:=
range
pod
.
Spec
.
Containers
{
container
:=
pod
.
Spec
.
Containers
[
i
]
for
k
,
v
:=
range
defaultRequirements
.
Limits
{
_
,
found
:=
container
.
Resources
.
Limits
[
k
]
if
!
found
{
container
.
Resources
.
Limits
[
k
]
=
*
v
.
Copy
()
}
}
for
k
,
v
:=
range
defaultRequirements
.
Requests
{
_
,
found
:=
container
.
Resources
.
Requests
[
k
]
if
!
found
{
container
.
Resources
.
Requests
[
k
]
=
*
v
.
Copy
()
}
}
}
}
// PodLimitFunc enforces resource requirements enumerated by the pod against
// the specified LimitRange. The pod may be modified to apply default resource
// requirements if not specified, and enumerated on the LimitRange
func
PodLimitFunc
(
limitRange
*
api
.
LimitRange
,
pod
*
api
.
Pod
)
error
{
pod
:=
obj
.
(
*
api
.
Pod
)
defaultResources
:=
defaultContainerResourceRequirements
(
limitRange
)
mergePodResourceRequirements
(
pod
,
&
defaultResources
)
podCPU
:=
int64
(
0
)
podCPU
:=
int64
(
0
)
podMem
:=
int64
(
0
)
podMem
:=
int64
(
0
)
...
@@ -190,11 +244,11 @@ func PodLimitFunc(limitRange *api.LimitRange, resourceName string, obj runtime.O
...
@@ -190,11 +244,11 @@ func PodLimitFunc(limitRange *api.LimitRange, resourceName string, obj runtime.O
switch
minOrMax
{
switch
minOrMax
{
case
"Min"
:
case
"Min"
:
if
observed
<
enforced
{
if
observed
<
enforced
{
return
apierrors
.
NewForbidden
(
resourceName
,
pod
.
Name
,
err
)
return
apierrors
.
NewForbidden
(
"pods"
,
pod
.
Name
,
err
)
}
}
case
"Max"
:
case
"Max"
:
if
observed
>
enforced
{
if
observed
>
enforced
{
return
apierrors
.
NewForbidden
(
resourceName
,
pod
.
Name
,
err
)
return
apierrors
.
NewForbidden
(
"pods"
,
pod
.
Name
,
err
)
}
}
}
}
}
}
...
...
plugin/pkg/admission/limitranger/admission_test.go
View file @
620af168
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment