Podへのリソース制限
Pod内の各コンテナは、以下のパラメータを指定することでCPUやメモリなどのリソースを管理することができる。
- spec.containers[].resources.limits.cpu
- spec.containers[].resources.limits.memory
- spec.containers[].resources.limits.hugepages-
- spec.containers[].resources.requests.cpu
- spec.containers[].resources.requests.memory
- spec.containers[].resources.requests.hugepages-
その中で、resources.limits.memoryについては、メモリーに関する制限を制御することができるが、下記の記載があり、ファイルシステムもスコープとなるとのことなので、動作を確認する。
https://kubernetes.io/ja/docs/concepts/storage/volumes/#emptydir
emptyDir.mediumフィールドを"Memory"に設定すると、Kubernetesは代わりにtmpfs(RAMベースのファイルシステム)をマウントします。 tmpfsは非常に高速ですが、ディスクと違ってノードのリブート時にクリアされ、書き込んだファイルはコンテナのメモリー制限にカウントされることに注意してください。
動作確認
事前準備 - k8s clusterの構築
minikubeを使用した。インストールは下記を参照。
事前準備 - minikubeの起動
minikubeを起動する。
実行結果
$ minikube start --cpus=4 --memory='4g'
$ alias kubectl="minikube kubectl --"
テスト1 - メモリ
- リソース制限
- resources.limit=1024MiBを指定
- テスト内容
- stressコマンドで2GB分のメモリを確保
- テスト結果
- OOMが発生した
実行結果
ubuntu@ubuntu:~$ kubectl apply -f test1.yaml
pod/test created
ubuntu@ubuntu:~$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
test 0/1 ContainerCreating 0 4s
test 1/1 Running 0 5s
test 0/1 OOMKilled 0 21s
test 1/1 Running 1 (3s ago) 24s
test 0/1 OOMKilled 1 (17s ago) 38s
^C
ubuntu@ubuntu:~$
test1.yaml
test1.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: ubuntu:latest
resources:
limits:
memory: "1024Mi"
command: ["sh"]
args:
- "-c"
- "apt-get update && apt-get install stress -y && stress --vm 1 --vm-bytes 2048M --vm-hang 0"
テスト2 - emptyDir
- リソース制限
- resources.limit=1024MiBを指定
- テスト内容
- emptyDirの領域に2GBのファイルを作成
- テスト結果
- ファイルの作成に成功
実行結果
ubuntu@ubuntu:~$ kubectl apply -f test2.yaml
pod/test created
ubuntu@ubuntu:~$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
test 0/1 ContainerCreating 0 3s
test 1/1 Running 0 5s
test 0/1 Completed 0 6s
test 1/1 Running 1 (4s ago) 9s
test 0/1 Completed 1 (21s ago) 26s
^C
ubuntu@ubuntu:~$
test2.yaml
test2.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: ubuntu:latest
command: ["sh"]
args:
- "-c"
- "dd if=/dev/zero of=/tmpdir/2Gfile bs=1024K count=2048"
resources:
limits:
memory: "1024Mi"
volumeMounts:
- name: tmpdir
mountPath: "/tmpdir"
volumes:
- name: tmpdir
emptyDir: {}
テスト3 - emptyDir (medium: Memory)
- リソース制限
- resources.limit=1024MiBを指定
- テスト内容
- emptyDirのmediumにMemoryを指定
- emptyDirの領域に2GB分のファイルを作成
- テスト結果
- OOMが発生
実行結果
ubuntu@ubuntu:~$ kubectl apply -f test3.yaml
pod/test created
ubuntu@ubuntu:~$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
test 0/1 ContainerCreating 0 3s
test 1/1 Running 0 7s
test 0/1 OOMKilled 0 14s
test 0/1 RunContainerError 1 (13s ago) 29s
test 1/1 Running 2 (17s ago) 33s
test 0/1 OOMKilled 2 (22s ago) 38s
test 0/1 CrashLoopBackOff 2 (2s ago) 39s
^C
ubuntu@ubuntu:~$
test3.yaml
test3.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: ubuntu:latest
command: ["sh"]
args:
- "-c"
- "sleep 5 && dd if=/dev/zero of=/tmpdir/2Gfile bs=1024K count=2048"
resources:
limits:
memory: "1024Mi"
volumeMounts:
- name: tmpdir
mountPath: "/tmpdir"
volumes:
- name: tmpdir
emptyDir:
medium: Memory
テスト4 - hostPath
- リソース制限
- resources.limit=1024MiBを指定
- テスト内容
- hostPathの領域に2GBのファイルを作成
- テスト結果
- ファイル作成に成功
実行結果
ubuntu@ubuntu:~$ kubectl apply -f test4.yaml
pod/test created
ubuntu@ubuntu:~/$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
test 0/1 ContainerCreating 0 4s
test 1/1 Running 0 5s
test 0/1 Completed 0 10s
test 1/1 Running 1 (4s ago) 13s
test 0/1 Completed 1 (14s ago) 23s
^C
ubuntu@ubuntu:~$
実行結果(別端末)
ubuntu@ubuntu:~$ minikube ssh
docker@minikube:~$ sudo mkdir -p /mnt/tmpdir
docker@minikube:~$
docker@minikube:~$ ls /mnt/tmpdir/ -l
total 214456
-rw-r--r-- 1 root root 219602944 Dec 8 12:13 2Gfile
docker@minikube:~$
test4.yaml
test4.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: ubuntu:latest
command: ["sh"]
args:
- "-c"
- "ls /tmpdir && mount && dd if=/dev/zero of=/tmpdir/2Gfile bs=1024K count=2048"
resources:
limits:
memory: "1024Mi"
volumeMounts:
- name: tmpdir
mountPath: "/tmpdir"
volumes:
- name: tmpdir
hostPath:
path: /mnt/tmpdir
テスト5 - hostPath (tmpfs)
- リソース制限
- resources.limit=1024MiBを指定
- テスト内容
- hostPath領域をtmpfsに設定
- hostPathの領域に2GBのファイルを作成
- テスト結果
- OOMが発生
- 1GB分のファイルしか作成されなかった
実行結果
ubuntu@ubuntu:~$ kubectl apply -f test5.yaml
pod/test created
ubuntu@ubuntu:~$ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
test 0/1 ContainerCreating 0 3s
test 1/1 Running 0 4s
test 0/1 OOMKilled 0 6s
test 0/1 RunContainerError 1 (16s ago) 24s
test 0/1 RunContainerError 2 (16s ago) 42s
^C
ubuntu@ubuntu:~$
実行結果(別端末)
ubuntu@ubuntu:~$ minikube ssh
docker@minikube:~$ sudo mkdir -p /mnt/tmpdir
docker@minikube:~$ sudo mount -t tmpfs tmpfs /mnt/tmpdir
docker@minikube:~$ mount |grep tmpdir
tmpfs on /mnt/tmpdir type tmpfs (rw,relatime,inode64)
docker@minikube:~$
docker@minikube:~$ ls /mnt/tmpdir/ -l
total 1044352
-rw-r--r-- 1 root root 1069416448 Dec 8 12:21 2Gfile ## ファイルサイズが約1GB
docker@minikube:~$
test5.yaml
test5.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: ubuntu:latest
command: ["sh"]
args:
- "-c"
- "ls /tmpdir && mount && dd if=/dev/zero of=/tmpdir/2Gfile bs=1024K count=2048"
resources:
limits:
memory: "1024Mi"
volumeMounts:
- name: tmpdir
mountPath: "/tmpdir"
volumes:
- name: tmpdir
hostPath:
path: /mnt/tmpdir
テスト結果
今回確認した一覧は以下。
# | resources.limit | 操作を実施した対象 | 結果 |
---|---|---|---|
1 | 1024MiB | Memory | OOMが発生 |
2 | 1024MiB | emptyDir | ファイル作成成功 |
3 | 1024MiB | emptyDir(medium: Memory) | OOMが発生 |
4 | 1024MiB | hostPath | ファイル作成成功 |
5 | 1024MiB | hostPath(tmpfs) | OOMが発生 |
- emptyDirにおいて、medium: Memoryを使用した場合はOOMが発生したため、ドキュメントに記載された通り、emptyDir領域への書き込みもメモリー制限の対象となっていた
- hostPathにおいて、tmpfsをmountした場合についても、同様にメモリー制限の対象となっている模様