0
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?

Kubernetes Metrics Server を導入して kubectl top でノードのリソース使用状況を確認してみる

0
Last updated at Posted at 2026-08-04

1 メトリクスサーバーとは?

メトリクスサーバーは、Kubernetes クラスタ内のノードや Pod のリソース使用状況(CPU・メモリ使用率など)を収集するサーバです。収集したメトリクス(システムの状態や性能を数値で表したデータ)は、主に HPA(Horizontal Pod Autoscaler) や VPA(Vertical Pod Autoscaler) などのオートスケーリング機能で利用され、Pod の数やリソース量を自動的に調整するために使われます。

2 検証環境

2.1 ネットワーク構成

検証環境は、VMware Workstation Pro上に構築した3台の仮想マシンでKubernetesクラスタを構成しています。各仮想マシンはブリッジ接続により、PCと同じネットワーク(192.168.1.0/24)に接続されています。

一方、10.244.0.0/16 は、CalicoのCNIプラグインによってクラスタ内に作成されるPodネットワークです。各Podにはこのアドレス帯からIPアドレスが割り当てられ、異なるノード上のPod同士が相互に通信する際に使用されます。Calicoは各ノードに経路を設定することで、Pod間通信を透過的に実現しています。

+--- control ---+    +--- worker1 ---+   +--- worker2 ---+
|AlmaLinux 10.2 |    |AlmaLinux 10.2 |   |AlmaLinux 10.2 |
|               |    |               |   |               |
|      Pod      |    |      Pod      |   |      Pod      |
|       |       |    |       |       |   |       |       |
| 10.244.x.0/24 |    | 10.244.y.0/24 |   | 10.244.z.0/24 |
| ------------- |    | ------------- |   | ------------- |
|               |    |               |   |               |
+-------+-------+    +-------+-------+   +-------+-------+
        |.19                 |.20                |.22
        |                    |                   |
        |   192.168.1.0/24   |                   |
+--------------------------------------------------------+
|        VMware Workstation Pro(Bridged networking)    |
+--------------------------------------------------------+
                             |
                    +---------------+
                    |               |
                    |       PC      |
                    |               |
                    +---------------+

それぞれの役割は以下のとおりです。
1台をコントロールノード、2台をワーカーノードとして使用します。

ホスト名 名称 役割
control コントロールノード クラスタ(control、worker1、worker2)の状態を管理し、Pod をどのノードで実行するかを決定するノード
worker1 ワーカーノード Pod を実行するノード
worker2 ワーカーノード Pod を実行するノード

2.2 ソフトウェアのバージョン

各ノードのAlmaLinuxバージョンは以下のとおりです。

[root@control ~]# cat /etc/redhat-release
AlmaLinux release 10.2 (Lavender Lion)

各ノードのカーネルバージョンは以下のとおりです。

[root@control ~]# uname -r
6.12.0-211.7.3.el10_2.x86_64

Kubernetesのバージョンは以下のとおりです。

[root@contol ~]# kubectl version
Client Version: v1.36.3
Kustomize Version: v5.8.1
Server Version: v1.36.3

2.3 ノードのリソース

各ノードには4GBのメモリを割り当てています。

[root@control ~]#  free -h
               total        used        free      shared  buff/cache   available
Mem:           3.6Gi       1.3Gi       1.0Gi       5.8Mi       1.5Gi       2.3Gi
Swap:             0B          0B          0B

各ノードは 4コアのCPU(4 vCPU) を搭載しています。

[root@control ~]# lscpu -xe
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
  0    0      0    0 0:0:0:0          yes
  1    0      1    1 1:1:1:1          yes
  2    0      2    2 2:2:2:2          yes
  3    0      3    3 3:3:3:3          yes

lscpuコマンドの詳しい使い方は、以下のページをご覧ください。

3 事前準備

3.1 検証ツールのインストール

CPU負荷をあげる検証をするため、stress-ngパッケージをインストールします。

[root@control ~]# dnf -y install stress-ng

stress-ngコマンドのバージョンを確認します。

[root@contol ~]# stress-ng --version
stress-ng, version 0.19.03 (gcc 14.3.1, x86_64 Linux 6.12.0-211.7.3.el10_2.x86_64) ??

stress-ngコマンドの使い方は、以下を参照してください。

3.2 Kubelet のサーバ証明書の再作成

Metrics Server は、メトリクスを取得するために、各ノード上で動作している Kubelet に対して HTTPS 接続を行います。

このとき、Kubelet が使用するサーバ証明書には、デフォルトでは自身のノード IP アドレスが Subject Alternative Name(SAN)として設定されていません。

一方、Metrics Server は Kubelet から送信されたサーバ証明書を検証する際、接続先として指定した IP アドレスが証明書の SAN に含まれているかを確認します。しかし、Kubelet のサーバ証明書の SAN にノード IP アドレスが設定されていないため、証明書検証に失敗します。

この問題を解決するため、Kubelet のサーバ証明書を再発行します。再発行することで、サーバ証明書の SAN に各ノードの IP アドレスが設定され、Metrics Server は Kubelet の証明書を正しく検証できるようになります。

3.2.1 全てのノードで実施

まず、設定変更に備えて Kubelet の設定ファイルをバックアップします。

[root@control ~]# cp /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.org

kubeletの設定ファイルを編集します。

[root@control ~]# vi /var/lib/kubelet/config.yaml

設定ファイルの末尾に serverTLSBootstrap: true を追加します。この設定を有効にすると、Kubelet はサーバ証明書の Certificate Signing Request(CSR)を Kubernetes API Server に送信し、Kubernetes CA からサーバ証明書を取得できるようになります。

[root@control ~]# diff -Nur /var/lib/kubelet/config.yaml.org /var/lib/kubelet/config.yaml
--- /var/lib/kubelet/config.yaml.org    2026-08-03 20:20:36.010789515 +0900
+++ /var/lib/kubelet/config.yaml        2026-08-03 20:25:53.212588088 +0900
@@ -46,3 +46,4 @@
 streamingConnectionIdleTimeout: 0s
 syncFrequency: 0s
 volumeStatsAggPeriod: 0s
+serverTLSBootstrap: true

設定を反映するため、Kubelet を再起動します。

[root@control ~]# systemctl restart kubelet

3.2.2 コントロールノードで実施

Kubelet を再起動すると、各ノードの Kubelet は CSR(Certificate Signing Request)を Kubernetes API Server に送信します。CSR の状態を確認すると、CONDITION 列が Pending なので、CSR がまだ承認されておらず、サーバ証明書が発行されていない状態を示しています。

[root@control ~]# kubectl get csr
NAME        AGE   SIGNERNAME                      REQUESTOR             REQUESTEDDURATION   CONDITION
csr-bdgn5   6s    kubernetes.io/kubelet-serving   system:node:worker2   <none>              Pending
csr-ds5zx   8s    kubernetes.io/kubelet-serving   system:node:control   <none>              Pending
csr-n8k2p   12s   kubernetes.io/kubelet-serving   system:node:worker1   <none>              Pending

kubectl certificate approve コマンドを実行して CSR を承認します。承認されると、Kubernetes CA の秘密鍵を使用して CSR に署名し、Kubelet のサーバ証明書を発行します。

[root@control ~]# kubectl certificate approve csr-bdgn5
certificatesigningrequest.certificates.k8s.io/csr-bdgn5 approved
[root@control ~]# kubectl certificate approve csr-ds5zx
certificatesigningrequest.certificates.k8s.io/csr-ds5zx approved
[root@control ~]# kubectl certificate approve csr-n8k2p
certificatesigningrequest.certificates.k8s.io/csr-n8k2p approved

承認後、CSR の状態を確認します。Approved,Issued と表示されれば、Kubernetes CA によってサーバ証明書が発行され、各ノードの Kubelet が新しいサーバ証明書を取得したことを示しています。

[root@control ~]# kubectl get csr
NAME        AGE     SIGNERNAME                      REQUESTOR             REQUESTEDDURATION   CONDITION
csr-bdgn5   4m9s    kubernetes.io/kubelet-serving   system:node:worker2   <none>              Approved,Issued
csr-ds5zx   4m11s   kubernetes.io/kubelet-serving   system:node:control   <none>              Approved,Issued
csr-n8k2p   4m15s   kubernetes.io/kubelet-serving   system:node:worker1   <none>              Approved,Issued

3.2.3 Kubelet サーバ証明書の確認

Kubelet のサーバ証明書に、各ノードの IP アドレスが Subject Alternative Name(SAN)として設定されていることを確認します。serverTLSBootstrap を有効化し、CSR を承認すると、Kubelet は Kubernetes CA によって署名されたサーバ証明書を取得します。この証明書には、Kubelet が待ち受けるノードの DNS 名および IP アドレスが SAN として設定されます。

まず、コントロールノードで Kubelet のサーバ証明書を確認します。

[root@control ~]# openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text -noout | grep -A5 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                DNS:control, IP Address:192.168.1.15
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        8c:ad:a9:af:7e:16:0b:21:91:69:94:0f:fd:40:ea:49:57:4b:
        75:d5:94:fe:28:89:e0:bf:a6:b2:96:f9:a1:fb:4d:5e:0f:7c:

出力結果から、コントロールノードのホスト名である control と IP アドレス 192.168.1.15 が SAN に設定されていることを確認できます。

次に、ワーカノード(worker1)で Kubelet のサーバ証明書を確認します。

[root@worker1 ~]# openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text -noout | grep -A5 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                DNS:worker1, IP Address:192.168.1.16
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        7e:f1:47:49:8c:fe:b0:b2:05:3b:5f:2d:12:60:97:48:d5:93:
        61:f9:58:92:72:00:e1:8b:f4:3a:73:74:17:7b:fc:c4:90:48:

同様に、ワーカノード(worker2)でも Kubelet のサーバ証明書を確認します。

[root@worker2 ~]# openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text -noout | grep -A5 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                DNS:worker2, IP Address:192.168.1.17
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        8c:e3:f8:57:e3:7b:0c:0d:45:89:47:0b:79:1f:bf:02:d5:e5:
        28:4b:90:db:5a:76:92:4c:f7:9d:b4:bc:79:5b:72:99:50:83:

4 メトリクスサーバのインストール

(1) リポジトリの追加
メトリクスサーバーのチャートが公開されているリポジトリを、Helmで利用できるように追加します。

[root@control ~]# helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server
"metrics-server" has been added to your repositories

helm コマンドの詳しい使い方は、以下のページをご覧ください。

追加したリポジトリの一覧を確認します。

[root@control ~]# helm repo list
NAME            URL
metrics-server  https://kubernetes-sigs.github.io/metrics-serve

ローカルにキャッシュされているチャート情報を最新の状態に更新します。この操作を行わないと、最新のチャート情報がローカルに反映されず、最新バージョンの検索や取得ができない場合があるため、事前に実行します。

[root@contol ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "metrics-server" chart repository
Update Complete. ?Happy Helming!?

(2) チャートのインストール
メトリクスサーバーのHelmチャートをクラスタにインストールします。このとき、kube-system 名前空間にデプロイするよう指定します。

[root@control ~]# helm install metrics-server metrics-server/metrics-server --namespace kube-system
NAME: metrics-server
LAST DEPLOYED: Tue Aug  4 14:13:06 2026
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
***********************************************************************
* Metrics Server                                                      *
***********************************************************************
  Chart version: 3.13.1
  App version:   0.8.1
  Image tag:     registry.k8s.io/metrics-server/metrics-server:v0.8.1
***********************************************************************

Podの状態を確認します。コマンドを実行すると、出力結果の一覧に metrics-server のPodが表示され、正常に動作していることを確認できます(この実行例では、一番下の行)。

[root@control ~]# kubectl get pods -n kube-system -o wide
NAME                                       READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
calico-kube-controllers-58f68d56d9-7mh9c   1/1     Running   0          3h47m   10.244.42.194    control   <none>           <none>
calico-node-bw49k                          1/1     Running   0          3h38m   192.168.1.16     worker1   <none>           <none>
calico-node-pmt6s                          1/1     Running   0          3h38m   192.168.1.17     worker2   <none>           <none>
calico-node-x9gmw                          1/1     Running   0          3h47m   192.168.1.15     control   <none>           <none>
coredns-589f44dc88-bm7dp                   1/1     Running   0          3h50m   10.244.42.193    control   <none>           <none>
coredns-589f44dc88-pgrks                   1/1     Running   0          3h50m   10.244.42.195    control   <none>           <none>
etcd-control                               1/1     Running   0          3h50m   192.168.1.15     control   <none>           <none>
kube-apiserver-control                     1/1     Running   0          3h50m   192.168.1.15     control   <none>           <none>
kube-controller-manager-control            1/1     Running   0          3h50m   192.168.1.15     control   <none>           <none>
kube-proxy-hqvsc                           1/1     Running   0          3h38m   192.168.1.16     worker1   <none>           <none>
kube-proxy-nnnl6                           1/1     Running   0          3h38m   192.168.1.17     worker2   <none>           <none>
kube-proxy-wrgcs                           1/1     Running   0          3h50m   192.168.1.15     control   <none>           <none>
kube-scheduler-control                     1/1     Running   0          3h50m   192.168.1.15     control   <none>           <none>
metrics-server-5846d89996-lf78z            1/1     Running   0          36s     10.244.235.129   worker1   <none>           <none>

5 動作確認

(1) 初期状態の確認
ノードのリソース使用状況を確認します。

[root@control ~]# kubectl top node
NAME      CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
control   159m         3%       1949Mi          55%
worker1   46m          1%       1029Mi          29%
worker2   46m          1%       972Mi           27%

(2) CPU0 に負荷をかける
CPU0 に対して、CPU 使用率を高める負荷(CPU 負荷)をかけます。

[root@control ~]# stress-ng -c 1 --taskset 0 -q &
[1] 75755

CPU使用率を確認すると、CPU0(PSR列が 0)の CPU使用率が96%になっていることが分かります。

[root@control ~]# ps -C stress-ng,stress-ng-cpu -o comm,pid,ppid,%cpu,psr,wchan
COMMAND             PID    PPID %CPU PSR WCHAN
stress-ng         75755    3885  0.0   0 do_wait
stress-ng-cpu     75756   75755 96.0   0 -

control ノードの CPU 使用率を確認すると、28% に増加していることが分かります。

[root@control ~]# kubectl top node
NAME      CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
control   1138m        28%      1989Mi          56%
worker1   54m          1%       1045Mi          29%
worker2   52m          1%       987Mi           28%

(3) CPU1 に負荷をかける
CPU1 に対して、CPU 使用率を高める負荷(CPU 負荷)をかけます。

[root@control ~]# stress-ng -c 1 --taskset 1 -q &
[2] 76990

CPU使用率を確認すると、CPU1(PSR列が 0)の CPU使用率が102%になっていることが分かります。

[root@control ~]# ps -C stress-ng,stress-ng-cpu -o comm,pid,ppid,%cpu,psr,wchan
COMMAND             PID    PPID %CPU PSR WCHAN
stress-ng         75755    3885  0.0   0 do_wait
stress-ng-cpu     75756   75755 98.9   0 -
stress-ng         76990    3885  0.0   1 do_wait
stress-ng-cpu     76991   76990  102   1 -

control ノードの CPU 使用率を確認すると、53% に増加していることが分かります。

[root@control ~]# kubectl top node
NAME      CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
control   2137m        53%      2005Mi          56%
worker1   57m          1%       1045Mi          29%
worker2   63m          1%       987Mi           28%

(4) CPU2 に負荷をかける
CPU2 に対して、CPU 使用率を高める負荷(CPU 負荷)をかけます。

[root@control ~]# stress-ng -c 1 --taskset 2 -q &
[3] 77977

CPU使用率を確認すると、CPU2(PSR列が 0)の CPU使用率が102%になっていることが分かります。

[root@control ~]# ps -C stress-ng,stress-ng-cpu -o comm,pid,ppid,%cpu,psr,wchan
COMMAND             PID    PPID %CPU PSR WCHAN
stress-ng         75755    3885  0.0   0 do_wait
stress-ng-cpu     75756   75755 99.0   0 -
stress-ng         76990    3885  0.0   1 do_wait
stress-ng-cpu     76991   76990 99.6   1 -
stress-ng         77977    3885  0.0   2 do_wait
stress-ng-cpu     77978   77977  102   2 -

control ノードの CPU 使用率を確認すると、78% に増加していることが分かります。

[root@control ~]# kubectl top node
NAME      CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
control   3140m        78%      2021Mi          57%
worker1   81m          2%       1044Mi          29%
worker2   75m          1%       987Mi           28%

(5) CPU3 に負荷をかける
CPU3 に対して、CPU 使用率を高める負荷(CPU 負荷)をかけます。

[root@control ~]# stress-ng -c 1 --taskset 3 -q &
[4] 78856

CPU 使用率を確認すると、すべての CPU コアがほぼ 100% の状態で動作していることが分かります。

[root@control ~]# ps -C stress-ng,stress-ng-cpu -o comm,pid,ppid,%cpu,psr,wchan
COMMAND             PID    PPID %CPU PSR WCHAN
stress-ng         75755    3885  0.0   0 do_wait
stress-ng-cpu     75756   75755 98.8   0 -
stress-ng         76990    3885  0.0   1 do_wait
stress-ng-cpu     76991   76990 99.0   1 -
stress-ng         77977    3885  0.0   2 do_wait
stress-ng-cpu     77978   77977 98.9   2 -
stress-ng         78856    3885  0.1   3 do_wait
stress-ng-cpu     78857   78856 90.5   3 -

control ノードの CPU 使用率を確認すると、99% に増加していることが分かります。

[root@control ~]# kubectl top node
NAME      CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
control   3998m        99%      2037Mi          57%
worker1   92m          2%       1045Mi          29%
worker2   84m          2%       987Mi           28%

(6) あと始末
起動した stress-ng のプロセスを終了します。

[root@control ~]# jobs
[1]   実行中               stress-ng -c 1 --taskset 0 -q &
[2]   実行中               stress-ng -c 1 --taskset 1 -q &
[3]-  実行中               stress-ng -c 1 --taskset 2 -q &
[4]+  実行中               stress-ng -c 1 --taskset 3 -q &
[root@control ~]# kill %1
[root@control ~]# kill %2
[root@control ~]# kill %3
[root@control ~]# kill %4

6 まとめ

kubectl top node で表示される CPU(cores) は、CPU 使用量をコア数換算で表した値です。1000m が CPU 1コア分に相当します。

本環境は 4 コア構成のため、CPU(cores) が 3998m の場合は、約 4 コアすべてを使用している状態を示します。

CPU(%) は、ノードが持つ CPU 全体に対する使用率を示します。4 コアすべてに負荷をかけた結果、CPU(%) は約 99% となり、ノード全体の CPU がほぼ使い切られていることを確認できました。

今回の実験では、stress-ng を使用して CPU 0~3 に対して段階的に負荷をかけ、その変化を kubectl top node で確認しました。負荷の増加に合わせて CPU 使用量(CPU(cores)、CPU(%))が増加したことから、Metrics Server が Kubelet からメトリクスを正常に取得できていることを確認できました。

また、負荷をかけた control ノードのみ CPU 使用率が上昇し、worker ノードの CPU 使用率には大きな変化がないことも確認できました。

0
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
0
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?