LimitRangeとResource Quotas

LimitRangeはnamespace内のPodごとのCPUやメモリなどリソースの最大値、最小値、デフォルト値を設定できる仕組みで、巨大なPodがデプロイされ、リソースが占有されてしまうことを防ぐことができます。

Resource Quotasはnamespace全体のリソースの最大値を制限するための仕組みで、主に複数のチームでクラスタを共有している場合に、リソースを食いつぶされないようにするために利用します。

LimitRangeを使ってCPUとメモリの最小値、最大値を設定してみましょう。

LimitRangeのYAML


apiVersion: v1
kind: LimitRange
metadata:
  name: limit-range-max-min
  namespace: limitrangetest
spec:
  limits:
  - max:
      cpu: 200m
      memory: 200Mi
    min:
      cpu: 100m
      memory: 100Mi
    type: Container

nginxのDeploymentのYAML


yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: limitrangetest
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources:
          limits:
            cpu: 300m
            memory: 150Mi

bash
$ kubectl create namespace limitrangetest
$ kubectl apply -f limit-range.yaml
$ kubectl apply -f nginx.yaml

上記の組み合わせでは、LimitRangeの条件を満たさないのでPodは展開されません。ReplicaSetをみると以下のようなエラーが出ていることが確認できます。


Events:
  Type     Reason        Age                   From                   Message
  ----     ------        ----                  ----                   -------
  Warning  FailedCreate  5m8s                  replicaset-controller  Error creating: pods "nginx-55fdb7d764-zxj6x" is forbidden: maximum cpu usage per Container is 200m, but limit is 300m
  Warning  FailedCreate  5m8s                  replicaset-controller  Error creating: pods "nginx-55fdb7d764-rslmt" is forbidden: maximum cpu usage per Container is 200m, but limit is 300m
  Warning  FailedCreate  5m8s                  replicaset-controller  Error creating: pods "nginx-55fdb7d764-f4xcs" is forbidden: maximum cpu usage per Container is 200m, but limit is 300m

PIDの制限

Pod内で大量のプロセスが起動され、PIDの枯渇を引き起こすような状態になるとNode全体が不安定になってしまいます。こうした事態を防ぐために、Kubernetesでは生成できるPIDの数を制限するPID Limits 機能があります。

PID Limits 機能では、ノードごとおよび Pod ごとの制限を提供し、kubelet のフラグとして設定できます。AKSではまだ正式にリリースされていませんが、以下の方法でPIDの制限を設定できます。

CustomNodeConfigPreviewを有効にします。


$ az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"

Registeredになるまで待ちます。


bash
$ az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/CustomNodeConfigPreview')].{Name:name,State:properties.state}"; date
Name                                                State


Microsoft.ContainerService/CustomNodeConfigPreview Registered Wed Feb 2 09:19:13 UTC 2022

Azure CLIでAKS Previewの機能が使えるようにします。


bash
az extension add --name aks-preview

kubeletconfig.jsonを用意します。


json
{
 "podMaxPids": 20
}

kubelet configファイルを指定してAKSクラスタを作成します。


az aks create --name kubelet-podmaxpid --resource-group aks-kubelet --kubelet-config ./kubeletconfig.json --node-count 3 --enable-addons monitoring --generate-ssh-keys --attach-acr acrkubelet --node-vm-size StandardD4v5

これでPIDが制限されたクラスタができました。

PIDの制限を行う場合に課題になるのは、以下の2点です。結果として、余裕をみて大きめの値を指定するのが落とし所になるでしょう。

  • PIDの制限はkube-systemのPodにも適用されるため、必要なPIDの数を見極めるのが難しい
  • 新しいプロセスの起動に失敗した場合のエラーメッセージは、Pod内で動いているプログラムによって異なる。