AKS で Pod に必要なメモリ / CPU を明示的に割り当てる

前回の AKS 記事からの続きです。今回は、Pod ごとに必要なメモリ/CPU を明示的に割り当てる方法を見ていきます。

#動いている Node を確認する
まずは、動いている Node の詳細を確認します。コマンドは `kubectl describe node aks-XXXXXXXX`

```
$ kubectl describe node aks-XXXXXXXX
~前略~
Allocatable:
 attachable-volumes-azure-disk:  4
 cpu:                            940m
 ephemeral-storage:              93619943269
 hugepages-1Gi:                  0
 hugepages-2Mi:                  0
 memory:                         1815424Ki
 pods:                           110
~省略~
```

実行結果のうち、`[Allocatable] - [cpu]` を確認します。これが Pod が利用可能な CPU です。また、`[Allocatable] - [memory]` がメモリを示します。上記の例場合は、CPU = 940m, Memory=1815424Ki となります。

#メモリ/CPU を明示的に設定する
設定する場合は、Pod を作成するマニュフェストファイルを変更します。以下の様に変更します。

```cpumemosetting.yaml
apiVersion: v1
kind: Pod
metadata:
  name: requests-pod
  
spec:
  containers:
  - image: busybox
    command: ["dd", "if=/dev/zero", "of=/dev/null"]
    name: main
    resources:
      requests:
        cpu: 400m
        memory: 1Gi
```


`kubectl create -f cpumemosetting.yaml` を実行すると、Pod が起動されます。作成が完了したら、`kubectl get pods --output wide` で動いている Pods の詳細を確認します。

```
$ kubectl get pods --output wide
NAME           READY   STATUS    RESTARTS   AGE   IP           NODE                                NOMINATED NODE   READINESS GATES
requests-pod   1/1     Running   0          20s   XX.XXX.X.X   aks-nodepool1-XXXXXXXX-vmss000000   <none>           <none>
```

また、Node がどのようになっているか `kubectl describe node aks-XXXXXXXX` で確認します。

```
Non-terminated Pods:         (3 in total)
  Namespace                  Name                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                        ------------  ----------  ---------------  -------------  ---
  default                    requests-pod                400m (42%)    0 (0%)      1Gi (57%)        0 (0%)         2m3s
  kube-system                coredns-XXXXXXXXXX-9289q    100m (10%)    0 (0%)      70Mi (3%)        170Mi (9%)     20m
  kube-system                kube-proxy-gwwt2            100m (10%)    0 (0%)      0 (0%)           0 (0%)         21m
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource                       Requests      Limits
  --------                       --------      ------
  cpu                            600m (63%)    0 (0%)
  memory                         1094Mi (61%)  170Mi (9%)
  ephemeral-storage              0 (0%)        0 (0%)
  attachable-volumes-azure-disk  0             0
```


上記の出力結果で CPU が全体の 63%、メモリが全体の 61% 使用されていることが分かります。

#オーバーさせて割り当ててみる
次に、あえてオーバーさせてメモリを割り当ててみます。マニュフェストファイルの `memory` の部分を変更します。

```cpumemosetting.yaml
apiVersion: v1
kind: Pod
metadata:
  name: requests-pod
  
spec:
  containers:
  - image: busybox
    command: ["dd", "if=/dev/zero", "of=/dev/null"]
    name: main
    resources:
      requests:
        cpu: 400m
        memory: 4Gi
```

`kubectl apply -f cpumemosetting.yaml` で Pods を作成します。`kubectl get pod --output=wide` で確認すると、Status が Pending になっていることが分かります。

```
$ kubectl get pod --output wide
NAME           READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
requests-pod   0/1     Pending   0          3s    <none>   <none>   <none>           <none>
```

また Node の詳細情報を `kubectl describe pod requests-pod` で確認すると、以下になっています。

```
$ kubectl describe pod requests-pod
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  49s (x6 over 2m57s)  default-scheduler  0/3 nodes are available: 3 Insufficient memory.
```
メモリがオーバーしているため、Pod が作成できたなかった、ということです。

#Pod のメモリ/CPU の上限を設定する
上限を設定する場合、以下のマニュフェストファイルを使います。

```cpumemosetting.yaml
apiVersion: v1
kind: Pod
metadata:
  name: limits-pod

spec:
  containers:
  - name: main
    image: polinux/stress
    resources:
      limits:
        cpu: 400m
        memory: 1Gi
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "500M", "--vm-hang", "1"]
```

マニュフェストファイルの　`args: ["--vm", "1", "--vm-bytes", "500M", "--vm-hang", "1"]`　の部分で、上限を設定しています。500m を 2G に設定してみることで、上限を増やすことができます。

```cpumemosetting.yaml
apiVersion: v1
kind: Pod
metadata:
  name: limits-pod

spec:
  containers:
  - name: main
    image: polinux/stress
    resources:
      limits:
        cpu: 400m
        memory: 4Gi
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "2G", "--vm-hang", "1"]
```

#参考情報
Assign CPU Resources to Containers and Pods
https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/