🐈

Kubernetes nodeの電源を落とすとどうなるのか?の実験

に公開

この記事について

こんにちは、東京大学鈴村研究室で、インフラエンジニアとしてお手伝いさせていただいています、福田と申します。

https://sites.google.com/view/toyolab/鈴村研究室概要

これまで、クラウド基盤mdxの上でKubernetes環境を構築し、サーバレスWebアプリケーションを開発するための手順や、分散学習を行うための手順について説明してきました。

https://zenn.dev/suzumura_lab/articles/627b5063d6884d

はじめに

  • Kubernetesは、nodeと呼ばれる物理的なサーバと、その上で稼動するPodやServiceの独立性が高くなっており、サービスの稼働中にnodeを停止させても、問題なく稼動ができる、素晴らしい仕組みを備えています。
  • この仕組みによって、例えば夜間はアクセスが少ないので、node(mdx仮想マシン)の電源を数台落としてコストを削減したり、アクセスが増える日中帯は電源を入れると言ったことが可能です。
  • nodeが増えると、アクセス数に応じて勝手にPodが増えますし、nodeが減ると、自動的にPodが減ります。
  • 今回の記事では、試しにnodeの電源を落としたときに、稼働中のPodなどがどう変化するのか、その時にデプロイされているWebサービスは問題なく使えるのか?などを実験して試してみたいと思います

前提環境

  • mdxの管理画面に入れる状態であること
  • mdx仮想マシンを使って、Kubernetesが構築されていること
  • 少なくとも3台以上のWorker nodeが存在すること
    • Worker nodeが2台だけの場合、そのうち1台を落とすと、冗長性が保証されていない状態となり、サービスによっては動作が不安定になります。
  • KNativeの上で、何かしらのWebサービスが稼動していること
  • Lensがインストールされていること

踏み台サーバへの接続

いつもの通り、mdx踏み台サーバに接続します。
PCにインストールされたLENSからもアクセスできるように、kube masterへのssh portfowardを有効にします。

eval `ssh-agent`
ssh-add ~/.ssh/(ssh公開秘密鍵のファイル名)
ssh -L 6443:(master nodeのPrivate IPアドレス):6443 -A mdxuser@(踏み台サーバのGlobal IPアドレス)

nodeの確認

Lens上で、Nodesのメニューを選び、稼働中のノードを確認します。
私の環境では合計4台のノードが稼働していることが確認できます。

稼働中のサービスの確認

Lens上で、稼働中のサービスを1つ選んで、Podの稼動状況などを確認します。
左側のメニューからDeploymentsを選んで、その中から、自分でデプロイしたKNative Webサービスの1つを選択します。


稼働中のPodの状況が以下の通りに確認できます

Podは、Podsのメニューからも確認できます。
私の環境では、合計、16個のPodが稼動していることが分かります。


参考までに、私のこのサービスのDeployment yamlの定義は以下の通りです。
私の場合、LLMのWebサービスを稼動させており、このLLM Webサービスは1処理当たりの時間が非常に長いため、予め4台のnodeのリソースで動作可能な最大Pod数を全て立ち上げています。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: llm-jp-31-13b-instruct4-v2
  namespace: default
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/minScale: "16" # Podの最小数は16個
        autoscaling.knative.dev/maxScale: "16" # Podの最大数は16個
    spec:
      containerConcurrency: 1
      timeoutSeconds: 1800
      containers:
        - image: ghcr.io/ggml-org/llama.cpp:server
          args:
            - "--model"
            - "/models/llm-jp-3.1-13b-instruct4-Q4_K_M.gguf"
            - "--host"
            - "0.0.0.0"
            - "--port"
            - "8000"
            - "--api-key"
            - "xxxxxxxxxxxxxxxxxxxx"
            - "--n_gpu_layers"
            - "0"
            - "--threads"
            - "32"
          ports:
            - containerPort: 8000
          resources:
            requests:
              cpu: "32"
              memory: "16Gi"
            limits:
              cpu: "32"
              memory: "16Gi"
          volumeMounts:
            - mountPath: /models
              name: pvc-large-volume
      volumes:
        - name: pvc-large-volume
          persistentVolumeClaim:
            claimName: hostpath-pvc-large

試しに合計16個のリクエストを同時に投げてみましたが、これらのリクエストが問題なく処理できていることがわかります。
GIF動画で、画像が小さく分かりにくくて恐縮です。

nodeを停止する実験

停止操作

ここで、kube-node3とkube-node4を停止させてみます。
nodeの停止の方法は簡単で、対象のnodeにsshログインし、いつもの通りのshutdownコマンドでOKです。

ssh (対象のnodeのIPアドレス or ホスト名)
sudo shutdown -h now

Lens上でもnodeが停止されることを確認します。

DeploymentやPodの状態の確認

この状態で対象のWebサービスの、PodやDeploymentがどうなっているか確認します。
まずDeploymentの状態はScalingとなっており、kube-node3とkube-node4にアサインされたPodには警告マークが付いており、稼動できていないことを表しています。

一方で、kube-node1とkube-node2にアサインされたPodは警告マークが付いておらず、問題なく動作できていることが確認できます。

なお、ここでのScalingの意味は、nodeの電源を落とした結果、 現在動作しているPodは8個であり、このDeploymentのPodの最小数である16個を下回っているので、最小数を満たしてないので、今増やそうとしているよ、でも今ある8個のPodでサービスは問題なく使えるよということを表しています。

稼働中のサービスへのアクセス

この状態で並列に8個以上のリクエストを投げて、想定通り8つのリクエストが処理できることを確認します。
ちょっと分かりにくいですが、今回12リクエストを投げて、8リクエストが問題なく動いていることを確認出来ました。
なお、この時点で待機している4つのリクエストについては、今処理している8つのリクエストを処理した後、問題なく動作します。

nodeを復活する実験

停止したnodeの電源の再投入

さて、2つのnodeの電源を突然落としても、Webサービスには問題なくアクセスできることを確認できました。

ここで、再度、2つのノードの電源を入れて、また16同時アクセスが可能なのかどうかを確認します。

mdx管理画面で、nodeの電源をONにします。
電源ONの操作は、問題なくできると思いますが、念のため操作動画を載せておきます。
この操作では、SELECT MULTIPLE VMSというボタンを押して、同時に2つのノードの電源をONにする操作を行っています。

しばらく経つとLens上で、合計4つのノードが起動できていることが確認できます。

PodやDeploymentの確認

合計16個のPodが立ち上がり、DeploymentのStatusもRunningとなり、最小Pod数である16個が全て起動し、問題なく稼動できていることが分かります。

稼働中のサービスへのアクセス

この状態で並列に16個以上のリクエストを投げて、想定通り16つのリクエストが処理できることを確認します。
問題なく16個のアクセスが処理できていることが確認できました。

まとめ

今回の記事では、Kubernetesのノードの数を減らしたときに、稼動しているPodがどういった振る舞いをするのかを確認してみました。
ノードの数を減らすと、受け入れ可能な同時アクセス数は減るものの、サービスとしては問題なく利用できることが分かりました。
また、電源を落としたノードの電源を再度ONにすると、Podが自動的に復活し、元の状態に自動的に復活することが分かりました。

この実験を通して、Kubernetesは、nodeと呼ばれる物理的なサーバと、その上で稼動するPodやServiceの独立性が高く、サービスの稼働中にnodeを停止させても、問題なく稼動ができることが分かりました。

東京大学鈴村研究室について

https://sites.google.com/view/toyolab/鈴村研究室概要

Discussion