kubernetes(k8s)でコンテナのCPUとメモリの割り当て

kubernetes

説明

kubernetes(k8s)では、コンテナおよびPodにCPUとメモリのリソースをマニフェストで管理することができます。Linuxのstressコマンドを使用しながら簡単にしてみましょう。

環境

・ubuntu(k8sを入れているメインサーバ(ホスト):2CPU以上でないと以下の一部内容を確認できません。)
・minikube
・CentOS7コンテナ(k8sで作成する)

イメージの作成

CentOS7ベースにstressコマンドを入れたイメージを作成します。

Dokcerfileの作成

$ vi Dockerfile
FROM  centos:centos7
RUN  yum update -y && \
     yum install -y epel-release && \
     yum -y install stress

イメージの作成

$ docker build --tag codemogu/centosstress:0.1 .

$ $ docker images
codemogu/centosstress      0.1     55075d4f5713    35 seconds ago      408MB

マニフェストの作成

マニフェストにresourcesでrequest(要求)とlimit(制限)でそれぞれ書くことで、cpuとmemoryを管理することができます。requestは、コンテナ作成時に指定したリソースの容量が確保されます。limitは、言葉通り、リソース容量がそれ以上にならないように制限がかかります。

以下のマニフェストを作成します。

$ vi cpu-memory-check.yml
apiVersion: v1
kind: Pod
metadata:
  name: cpu-memory-check
spec:
  restartPolicy: OnFailure
  containers:
  - name: ctr1
    image: codemogu/centosstress:0.1
    command: ["/bin/sh"]
    args: ["-c", "while :; do sleep 10; done"]
    resources:
      limits:
        cpu: "2"
        memory: "150Mi"
      requests:
        cpu: "1"
        memory: "100Mi"

ポッドを作成します。

$ kubectl apply -f cpu-memory-check.yml 
pod/cpu-memory-check created

確認してステータスがRunningになってればOKです。

$ kubectl get po
NAME               READY   STATUS      RESTARTS   AGE
cpu-memory-check   1/1     Running   0          62s

終了

$ kubectl delete -f cpu-memory-check.yml

CPUのリソース要求の値を上げてみる

minikubeを動かしている、サーバ(ホスト)のCPUを確認してみます。

$ cat /proc/cpuinfo |grep processor
processor       : 0
processor       : 1

以上の結果からサーバのコア数は2つです。

先ほどのマニフェストを一部を編集します。(cpuを4に変更

    resources:
      limits:
        cpu: "4"
        memory: "150Mi"
      requests:
        cpu: "4"
        memory: "100Mi"

実行してみます。

$ kubectl apply -f cpu-memory-check.yml 
pod/cpu-memory-check created

確認してみます。

$ kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
cpu-memory-check   0/1     Pending   0          44s

ずっとステータスがPendingのままで作成できません。

このことから、Podはサーバ(ホスト)のノード上で動作するうえで、CPU要求に対してノードに十分利用可能なCPUリソースがない場合は動いてくれないのが確認できました。

ちなみに、CPUに上限を設定しなかった場合は、
・コンテナは実行中のノードで利用可能なすべてのCPUを使用できる
・CPU制限を与えられたnamespaceでコンテナを実行された場合は、LimitRangeの指定した値になる

らしいです。

メモリに負荷をくわえてみる

cpuの次はメモリに負荷をくわえて、実験してみます。マニフェストを以下にしてみます。
(stressコマンドで、1プロセスを使って、メモリに50Mの負荷を3分くわえ続けます。)

$ vi cpu-memory-check.yml
apiVersion: v1
kind: Pod
metadata:
  name: cpu-memory-check
spec:
  restartPolicy: OnFailure
  containers:
  - name: ctr1
    image: codemogu/centosstress:0.1
    command: ["/bin/sh"]
    args: ["-c", "stress --vm 1 --vm-bytes 50M --timeout 3m"]
    resources:
      limits:
        cpu: "2"
        memory: "150Mi"
      requests:
        cpu: "1"
        memory: "100Mi"

実行します。

$ kubectl apply -f cpu-memory-check.yml 
pod/cpu-memory-check created

確認します。

$ kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
cpu-memory-check   1/1     Running   0          5s

正常に動いているのが確認できます。

次に上限越えの300Miの負荷をくわえてみます。マニフェストの一部を以下に変更します。

command: ["/bin/sh"]
args: ["-c", "stress --vm 1 --vm-bytes 300M --timeout 3m"]

実行します

$ kubectl apply -f cpu-memory-check.yml 
pod/cpu-memory-check created

確認します

$ kubectl get pod
NAME               READY   STATUS      RESTARTS   AGE
cpu-memory-check   0/1     OOMKilled   0          3s

OOMKilledが発生して、メモリの上限設定を越えた時にポッドが作成できないことが確認できました。

ちなみに、メモリの上限設定をしなかった場合は、
・コンテナは実行中のノードで利用可能なすべてのメモリーを使用できるが、メモリが少なくなるとOOM Killerが呼び出され強制終了する可能性がある。
・メモリー制限を与えられたnamespaceでコンテナを実行された場合は、LimitRangeの指定した値になる

らしいです。

コメント

タイトルとURLをコピーしました