1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

k8sノードのスケールアップ検証

Last updated at Posted at 2021-11-05

モチベーション

webアプリの運用であればk8sクラスタをスケールアウトするが、HPCジョブやAI学習等の高負荷なワークロードを実行する際はノードをスケールアップしたい要件があると思われるため、検証してみた。

検証内容

  1. ノードのスペックを超えるPodを作成

    このとき、Podはpending状態になる想定
  2. ノードをスケールアップ

手順2の実施後、pending状態であったPodが、スケールアップしたノード上で起動するか確認する。

環境

  • kubernetes
    • バージョン:v1.21.6
    • デプロイツール:kubespray v2.17.1
    • ノード構成:controlplane × 1, worker × 2
    • 各ノードのスペック
      • 仮想CPU数:2
      • RAMサイズ:4GB
  • ノード
    • OS:Ubuntu 20.04.3
    • ノードの種類:OpenStackのVM

検証結果

k8sから見えているスケールアップ前のノードのスペックは以下の通り。

$ k describe nodes kube-worker02
Name:               kube-worker02

... snip ...

Capacity:
  cpu:                2
  ephemeral-storage:  50633164Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             4030532Ki
  pods:               110

... snip ...

ノードのスペックを超えるリクエストをもつPodをつくる。

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      requests:
        memory: "5Gi"
        cpu: "3"
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
$ k get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   0/1     Pending   0          4s
$ k describe pod nginx

... snip ...

Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  22s (x2 over 24s)  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 Insufficient cpu, 2 Insufficient memory.

Podのリクエストがノードのスペックを超えるため、Podはpending状態となった。

つづいて、workerノード1台を以下のようにスケールアップする。

  • vCPU数:2 => 8
  • RAMサイズ:4GB => 12GB
# openstack flavor list
+--------------------------------------+--------------------------------------+-------+------+-----------+-------+-----------+
| ID                                   | Name                                 |   RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+--------------------------------------+-------+------+-----------+-------+-----------+

... snip ...

| 8937a33f-7cbd-491d-9b9a-0e5170cc6274 | m1.large                             | 12288 |    0 |         0 |     8 | True      |

... snip ...

+--------------------------------------+--------------------------------------+-------+------+-----------+-------+-----------+
# openstack server resize --flavor 8937a33f-7cbd-491d-9b9a-0e5170cc6274 f127a4db-03b3-4baa-b0e2-b90219370c42
# openstack server show f127a4db-03b3-4baa-b0e2-b90219370c42
+-------------------------------------+----------------------------------------------------------+
| Field                               | Value                                                    |
+-------------------------------------+----------------------------------------------------------+

... snip ...

| OS-EXT-STS:vm_state                 | resized                                                  |

... snip ...

| flavor                              | m1.large (8937a33f-7cbd-491d-9b9a-0e5170cc6274)          |

... snip ...

+-------------------------------------+----------------------------------------------------------+
# openstack server resize --confirm f127a4db-03b3-4baa-b0e2-b90219370c42
# openstack server show f127a4db-03b3-4baa-b0e2-b90219370c42
+-------------------------------------+----------------------------------------------------------+
| Field                               | Value                                                    |
+-------------------------------------+----------------------------------------------------------+

... snip ...

| OS-EXT-STS:vm_state                 | active                                                   |

... snip ...

| flavor                              | m1.large (8937a33f-7cbd-491d-9b9a-0e5170cc6274)          |

... snip ...

+-------------------------------------+----------------------------------------------------------+

先程デプロイしたPodを確認する。

$ k get pod nginx -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          38m   10.233.71.3   kube-worker02   <none>           <none>

スケールアップしたノード上でPodが稼働していることを確認できた。

スケールアップしたノードを確認する。

$ k describe nodes kube-worker02
Name:               kube-worker02

... snip ...

Capacity:
  cpu:                8
  ephemeral-storage:  50633164Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             12268324Ki
  pods:               110

... snip ...

Non-terminated Pods:          (6 in total)
  Namespace                   Name                         CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                         ------------  ----------  ---------------  -------------  ---
  default                     nginx                        3 (37%)       0 (0%)      5Gi (44%)        0 (0%)         39m
  kube-system                 calico-node-tptkn            150m (1%)     300m (3%)   64M (0%)         500M (4%)      20h
  kube-system                 coredns-8474476ff8-g2g7f     100m (1%)     0 (0%)      70Mi (0%)        170Mi (1%)     126m
  kube-system                 kube-proxy-fq6wt             0 (0%)        0 (0%)      0 (0%)           0 (0%)         20h
  kube-system                 nginx-proxy-kube-worker02    25m (0%)      0 (0%)      32M (0%)         0 (0%)         20h
  kube-system                 nodelocaldns-j4x7b           100m (1%)     0 (0%)      70Mi (0%)        170Mi (1%)     20h

... snip ...

ノードのスペックはスケールアップにあわせて変更されていることを確認できた。
OpenStackでVMをリサイズすると、裏でVMが再起動される。
VMを再起動せずにスケールアップした場合のk8sの挙動も確認したいので、次にオンラインスケールアップの検証を実施してみる。

オンラインスケールアップ時の検証

OpenStackではオンラインスケールアップができない(多分)ので、VMが動作するコンピュートノードからvirshコマンドを実行することでオンラインスケールアップを実施する。

最初に、検証に使ったnginxのPodを削除する。

kube-controlplane01:~$ k get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          5d
kube-controlplane01:~$ k delete pod nginx 
pod "nginx" deleted
kube-controlplane01:~$ k get pod
No resources found in default namespace.

現状のworkerノードkube-worker02のスペックを確認。

kube-worker02:~$ fgrep 'physical id' /proc/cpuinfo | sort -u | wc -l
8
kube-worker02:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           11Gi       570Mi       8.5Gi       2.0Mi       2.6Gi        10Gi
Swap:            0B          0B          0B

workerノードkube-worker02を超えるリソース量を要求するPodを作成する。

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx-large
  name: nginx-large
spec:
  containers:
  - image: nginx
    name: nginx-large
    resources:
      requests:
        memory: "13Gi"
        cpu: "9"
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
kube-controlplane01:~$ k apply -f nginx-large.yaml 
pod/nginx-large created
kube-controlplane01:~$ k get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-large   0/1     Pending   0          110s
kube-controlplane01:~$ k describe pod nginx-large 

... snip ...

Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  10s (x2 over 11s)  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 Insufficient cpu, 2 Insufficient memory.

Podのリソース要求を満たすノードが存在しないためPending状態となった。

kube-worker02が動作するコンピュートノードに乗り込み、kube-worker02をスケールアップする。

まずは、kube-worker02が動作するコンピュートノードとKVMにおける仮想マシン名を特定する。

ctl01:~# openstack server show f127a4db-03b3-4baa-b0e2-b90219370c42
+-------------------------------------+----------------------------------------------------------+
| Field                               | Value                                                    |
+-------------------------------------+----------------------------------------------------------+

... snip ...

| OS-EXT-SRV-ATTR:host                | cmp001                                                   |
| OS-EXT-SRV-ATTR:hypervisor_hostname | cmp001.xxxxxx.local                          |
| OS-EXT-SRV-ATTR:instance_name       | instance-0000335c                                        |

... snip ...

+-------------------------------------+----------------------------------------------------------+

コンピュートノードに乗り込む。

@cmp001:~# virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     instance-00002b0e              running
 2     instance-0000335c              running

cmp001:~#  virsh dominfo instance-0000335c 
Id:             2
Name:           instance-0000335c
UUID:           f127a4db-03b3-4baa-b0e2-b90219370c42
OS Type:        hvm
State:          running
CPU(s):         8
CPU time:       98780.1s
Max memory:     12582912 KiB
Used memory:    12582912 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: apparmor
Security DOI:   0
Security label: libvirt-f127a4db-03b3-4baa-b0e2-b90219370c42 (enforcing)

以下を参考にスケールアップする。
https://www.eastforest.jp/centos6/3694

まずはvCPU数を追加する。

cmp001:~# virsh vcpucount instance-0000335c
maximum      config         8
maximum      live           8
current      config         8
current      live           8

virsh setvcpusコマンドで仮想マシンに割り当てるCPU数を変更できます。ただし最大CPU数を超えることはできません。
--configを指定すると次回起動時から有効になります。--maximumの指定で最大CPU数を変更できますが、動作中の仮想マシンには適用されません。

まずはVMのvCPU数の上限を増やす必要がある。

cmp001:~# virsh setvcpus instance-0000335c 12 --config --maximum
error: invalid argument: CPU topology doesn't match the desired vcpu count

失敗した。
virsh editで以下のようにCPUトポロジーとvCPU数を変更することで、vCPU数を変更することができた。

  <vcpu placement='static' current='8'>12</vcpu>
  <cpu mode='host-passthrough' check='none'>
    <topology sockets='12' cores='1' threads='1'/>
  </cpu>
cmp001:~# virsh edit instance-0000335c
Domain instance-0000335c XML configuration edited.

root@cmp001:~# virsh vcpucount instance-0000335c
maximum      config        12
current      config        8

VM再起動後に反映されるため、この時点ではまだ反映さいない。

続いて、メモリの上限を変更する。

root@cmp001:~# virsh dominfo instance-0000335c

... snip ...

Max memory:     12582912 KiB
Used memory:    12582912 KiB

... snip ...

現在のメモリサイズの上限は12GiBなので、16GiBに変更する。

root@cmp001:~# virsh setmaxmem instance-0000335c 16G --config

vCPU数、メモリサイズの上限変更を反映させるためにVMを再起動する。

root@ctl01:~# openstack server reboot --soft f127a4db-03b3-4baa-b0e2-b90219370c42

virshコマンドでVMを再起動すると以下の問題があったため、ここではわざわざOpenStackからVMを再起動した。

  • VMを起動すると、vCPU, メモリサイズの上限が反映されずフレーバーと同じになってしまう
  • VM起動後、しばらくするとVMが勝手に停止されてしまう
root@cmp001:~# virsh vcpucount instance-0000335c
maximum      config        12
maximum      live          12
current      config         8
current      live           8

root@cmp001:~# virsh dominfo instance-0000335c

... snip ...

Max memory:     16777216 KiB
Used memory:    12582912 KiB

... snip ...

vCPU数、メモリサイズの上限値が反映された。

続いて、VMをオンラインスケールアップする。

root@cmp001:~# virsh setvcpus instance-0000335c 12

root@cmp001:~# virsh vcpucount instance-0000335c
maximum      config        12
maximum      live          12
current      config         8
current      live          12

root@cmp001:~# virsh setmem instance-0000335c 16G

root@cmp001:~# virsh dominfo instance-0000335c

... snip ...

Max memory:     16777216 KiB
Used memory:    16777216 KiB

... snip ...

スケールアップできた!

次にVMに乗り込み、スケールアップされているか確認する。

ubuntu@kube-worker02:~$ fgrep 'physical id' /proc/cpuinfo | sort -u | wc -l
8
ubuntu@kube-worker02:~$ lscpu |grep "CPU(s)"
CPU(s):                          12
On-line CPU(s) list:             0-7
Off-line CPU(s) list:            8-11
NUMA node0 CPU(s):               0-7
ubuntu@kube-worker02:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       453Mi        14Gi       1.0Mi       1.0Gi        14Gi
Swap:            0B          0B          0B

メモリサイズは反映されているが、追加したCPUはオフラインになっているので、オンラインにする。

ubuntu@kube-worker02:~$ for i in {8..11}; do echo 1 | sudo tee /sys/devices/system/cpu/cpu${i}/online; done
1
1
1
1
ubuntu@kube-worker02:~$ fgrep 'physical id' /proc/cpuinfo | sort -u | wc -l
12

vCPU数も反映された。

次にPodを確認

ubuntu@kube-controlplane01:~$ k get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-large   0/1     Pending   0          8d

Pendingのまま。
ノードのリソースを確認。

ubuntu@kube-controlplane01:~$ k describe nodes kube-worker02

... snip ...

Capacity:
  cpu:                8
  ephemeral-storage:  50633164Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             12201896Ki
  pods:               110

... snip ...

ノードのスケールアップは反映されていない。
対象ノードのkubeletを再起動してみる。

ubuntu@kube-worker02:~$ sudo systemctl restart kubelet.service
ubuntu@kube-controlplane01:~$ k describe nodes kube-worker02

... snip ...

Capacity:
  cpu:                12
  ephemeral-storage:  50633164Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             16396200Ki
  pods:               110

... snip ...

ubuntu@kube-controlplane01:~$ k get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-large   1/1     Running   0          8d

ノードのスケールアップが反映され、Podがrunningとなった!

結論

kubeletは起動時に、ノードのスペックを見に行くようである。
そのため、ノードのスペックを変更した際は、kubeletを再起動する必要がある。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?