はじめに
今回はリソース制御の一種のLimitRangeの動作を確認します。
LimitRangeはNamespaceごとに設定をして、そのNamespaceに属するPodのデフォルトの上限下限を設定します。
LimitRangeを設定できるリソースは、Container/Pod/PVCで、それぞれに設定できる項目は以下のようになります。
設定項目 | 概要 | Container | Pod | PVC |
---|---|---|---|---|
max | 最大リソース | レ | レ | レ |
min | 最小リソース | レ | レ | レ |
default | defaultのLimits | レ | ||
defaultRequest | defaultのRequests | レ | ||
maxLimitRequestRatio | Limits / Requestsの割合 | レ | レ |
クラウドサービスによっては、デフォルトでLimitRangeが設定されているものもあります。
Container
動作を確認していきます。まずはContainerの動作を確認します。
max/min
CPUとメモリを設定できるのですが、CPUだけ設定します。
以下のマニフェストのLimitRangeを作成します。
apiVersion: v1
kind: LimitRange
metadata:
name: limit-range-max-min-con
namespace: stg
spec:
limits:
- max:
cpu: "500m"
min:
cpu: "200m"
type: Container
namespaceを作成してからapplyします。
$ kubectl create namespace stg
namespace/stg created
$ kubectl apply -f limitrange-max_min-con.yaml
limitrange/limit-range-max-min-con created
確認します。
$ kubectl -n stg get limitranges
NAME CREATED AT
limit-range-max-min-con 2020-05-17T12:59:35Z
$ kubectl -n stg describe limitranges
Name: limit-range-max-min-con
Namespace: stg
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 200m 500m 500m 500m -
設定したのは、max/minですが、Default Request/Default Limitも設定されていますね。どちらもmaxの値になっています。
マニュアルには以下のように記載されていて、これは正常な動作のようです。
The output shows the minimum and maximum CPU constraints as expected. But notice that even though you didn’t specify default values in the configuration file for the LimitRange, they were created automatically.
Configure Minimum and Maximum CPU Constraints for a Namespace
以下のマニフェストのPod(Deployment)を作成します。
ここでは特にリソース制御の設定はしていません。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
namespace: stg
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: nginx
image: nginx:latest
applyして確認します。
$ kubectl apply -f nginx1.yaml
deployment.apps/nginx1 created
$ kubectl get pod -o wide
No resources found in default namespace.
$ kubectl -n stg get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-5589d85476-5mtq7 1/1 Running 0 28s 192.168.69.194 k8s-worker02 <none> <none>
nginx1-5589d85476-rvkdr 1/1 Running 0 28s 192.168.79.65 k8s-worker01 <none> <none>
$ kubectl -n stg describe pod nginx1-5589d85476-rvkdr
Name: nginx1-5589d85476-rvkdr
Namespace: stg
・・・
Containers:
nginx:
・・・
Limits:
cpu: 500m
Requests:
cpu: 500m
・・・
LimitsとRequestsの値だけ設定されていますね。max/minの値は設定値としては設定されていないようです。
default/defaultRequest
max/minを設定したら、Default Request/Default Limitも設定されていました。
max/minとdefault/defaultRequestの違いがわからなくなってしまったのですが、ひとまずdefault/defaultRequestの動作を確認してから考えたいと思います。
以下のマニフェストのLimitRangeを作成します。namespaceは分けておきました。
apiVersion: v1
kind: LimitRange
metadata:
name: limitrange-default-con
namespace: dev
spec:
limits:
- default:
cpu: 500m
defaultRequest:
cpu: 300m
type: Container
namespaceを作成してからapplyします。
$ kubectl create namespace dev
namespace/dev created
$ kubectl apply -f limitrange-default-con.yaml
limitrange/limitrange-default-con created
確認します。
$ kubectl describe limitranges -A
Name: limitrange-default-con
Namespace: dev
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - - 300m 500m -
Name: limit-range-max-min-con
Namespace: stg
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 200m 500m 500m 500m -
Default Request/Default Limitのみ設定されていますね。
念のため、Podを作成して確認してみます。マニフェストは、nginx1.yamlのnamespaceとnameを変えただけです。
kubectl apply -f nginx2.yaml
deployment.apps/nginx2 created
$ kubectl -n dev describe pod nginx2-5589d85476-fjdz7
Name: nginx2-5589d85476-fjdz7
・・・
Containers:
nginx:
・・・
Limits:
cpu: 500m
Requests:
cpu: 300m
・・・
想定通り、作成できますね。
max/minとdefault/defaultRequestの違いを確認する。
ここまでの検証では、max/minとdefault/defaultRequestの違いがよくわかりませんでした。
もう少し詳細に確認します。
設定値を一度整理しておきます。
Pod | namespace | max | min | default | defaultRequest |
---|---|---|---|---|---|
nginx1 | stg | 500m | 200m | 500m* | 500m* |
nginx2 | dev | - | - | 500m | 300m |
* 自動で設定された |
minの値を下回るrequestsの値をPodに指定してデプロイしてみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx3
namespace: stg
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 100m
$ kubectl apply -f nginx3.yaml
deployment.apps/nginx3 created
$ kubectl -n stg get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx1 2/2 2 2 24h
nginx3 0/2 0 0 26s
Deploymentはデプロイされているのですが、Podが作成されていません。
詳細を確認します。
$ kubectl -n stg describe deployments.apps nginx3
Name: nginx3
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 55s deployment-controller Scaled up replica set nginx3-785d4ccb57 to 2
Deploymentは問題なさそうです。
ReplicaSetを確認します。
$ kubectl -n stg get replicasets.apps
NAME DESIRED CURRENT READY AGE
nginx1-5589d85476 2 2 2 24h
nginx3-785d4ccb57 2 0 0 109s
$ kubectl -n stg describe replicasets.apps nginx3-785d4ccb57
Name: nginx3-785d4ccb57
Namespace: stg
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreate 2m18s replicaset-controller Error creating: pods "nginx3-785d4ccb57-469gj" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m18s replicaset-controller Error creating: pods "nginx3-785d4ccb57-9cgnn" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m18s replicaset-controller Error creating: pods "nginx3-785d4ccb57-rlwsm" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m18s replicaset-controller Error creating: pods "nginx3-785d4ccb57-b2ntn" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m17s replicaset-controller Error creating: pods "nginx3-785d4ccb57-xk8wp" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m17s replicaset-controller Error creating: pods "nginx3-785d4ccb57-8h7p5" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m17s replicaset-controller Error creating: pods "nginx3-785d4ccb57-mkwn4" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m17s replicaset-controller Error creating: pods "nginx3-785d4ccb57-x7fx6" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 2m16s replicaset-controller Error creating: pods "nginx3-785d4ccb57-v9jt8" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
Warning FailedCreate 56s (x6 over 2m15s) replicaset-controller (combined from similar events): Error creating: pods "nginx3-785d4ccb57-xqwcc" is forbidden: minimum cpu usage per Container is 200m, but request is 100m
requestsとしてminで設定した200mを下回る100mを指定したため、Podの起動に失敗していますね。
ちなみに、requestsを200m以上にするとPodまで起動します。
念のためminが設定されていないnamaspace:devで、defaultRequestを下回る値に設定してデプロイできるか確認します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx4
namespace: dev
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 200m
$ kubectl apply -f nginx4.yaml
deployment.apps/nginx4 created
$ kubectl -n dev get pod
NAME READY STATUS RESTARTS AGE
nginx2-5589d85476-fjdz7 1/1 Running 0 48m
nginx2-5589d85476-m6n9r 1/1 Running 0 48m
nginx4-5544cfc499-466jb 1/1 Running 0 18s
nginx4-5544cfc499-x2cxd 1/1 Running 0 18s
$ kubectl -n dev describe pod nginx4-5544cfc499-466jb
Name: nginx4-5544cfc499-466jb
Namespace: dev
・・・
Containers:
nginx:
・・・
Limits:
cpu: 500m
Requests:
cpu: 200m
・・・
defaultRequestは300mで設定していますが、Requestsでそれ以下に設定することも可能です。
まとめると、max/minとdefault/defaultRequestの動作は以下のようになるようです。
- Pod作成時にLimits/Requestsを指定していなかったら、LimitRangeのdefault/defaultRequestの値がコンテナに設定される。
- Pod作成時にLimits/Requestsを指定したら、その値が優先される。
- LimitRangeのmax/minを設定していたら、Pod作成時にmax以上のLimits/min以下のRequestsを指定するとPodの起動に失敗する。
maxLimitRequestRatio
最後にmaxLimitRequestRatioの動作を確認します。
以下のマニフェストのLimitRangeを作成します。
apiVersion: v1
kind: LimitRange
metadata:
name: limitlange-ratio-con
namespace: prd
spec:
limits:
- maxLimitRequestRatio:
cpu: 2
type: Container
namespaceを作成してから、applyします。
$ kubectl create namespace prd
namespace/prd created
$ kubectl apply -f limitrange-ratio-con.yaml
limitrange/limitlange-ratio-con created
確認します。
$ kubectl describe limitranges -n prd
Name: limitlange-ratio-con
Namespace: prd
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - - - - 2
Max Limit/Request Ratioだけが設定されていますね。
Podをデプロイして確認します。まずはlimits/requestsどちらも設定しないPodをデプロイしてみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx5
namespace: prd
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: nginx
image: nginx:latest
$ kubectl apply -f nginx5.yaml
deployment.apps/nginx5 created
$ kubectl -n prd get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx5 0/2 0 0 31s
$ kubectl -n prd describe replicasets.apps nginx5-5589d85476
Name: nginx5-5589d85476
Namespace: prd
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-cx82p" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-66bj2" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-qhwcd" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-8znms" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-xnqcr" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 47s replicaset-controller Error creating: pods "nginx5-5589d85476-d9v2z" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 46s replicaset-controller Error creating: pods "nginx5-5589d85476-t5x45" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 46s replicaset-controller Error creating: pods "nginx5-5589d85476-4xbnv" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 46s replicaset-controller Error creating: pods "nginx5-5589d85476-zlk62" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Warning FailedCreate 6s (x5 over 44s) replicaset-controller (combined from similar events): Error creating: pods "nginx5-5589d85476-gh4x5" is forbidden: cpu max limit to request ratio per Container is 2, but no request is specified or request is 0
Podのデプロイに失敗しています。limits/requestsを設定しないといけないようです。
色々なパターンで試しましたが、以下のような動作になりました。
limits | requests | Podデプロイ可否 | 備考 |
---|---|---|---|
設定しない | 設定しない | 失敗 | |
設定しない | 設定する | 失敗 | |
設定する | 設定しない | 成功 | 「requestsの値=limitsの値」になる |
設定する | 設定する | 成功 | limits/requestsの割合がmaxLimitRequestRatio以内である必要がある。maxLimitRequestRatioを超えると、Podのデプロイに失敗する。 |
まとめ
マニュアルや本を読んだだけではわからないことも、実際にやってみることで理解が深まりますね。
リソース制限をかけないと、コンテナはあるだけリソースを使いますので、環境やシステムごとにデフォルトの制限を設定するLimitRangeは大切ですね。
今回はコンテナしか検証できませんでしたので、PodとPVCは次回検証したいと思います。