Necoのサーバー再起動の仕組みの改善

この記事は、CYBOZU SUMMER BLOG FES '24 (クラウド基盤本部 stage) DAY 11の記事です。

こんにちは、CloudPlatformの三村です。 サイボウズでは、Kubernetesを用いた新たなインフラ基盤「Neco」の開発・運用をしています。

現在我々は、Kuberneteノードで使用しているサーバーの再起動の仕組みの改善に取り組んでいます。サーバー再起動の仕組みに関してはCybozu Inside Outの以下の記事で紹介していますので、ぜひご覧ください。 blog.cybozu.io

この記事では、上記の再起動の仕組みを運用する上で出てきた課題と改善の取り組みについて紹介します。

Necoの再起動の仕組み

Necoでは、オンプレミスでKubernetesクラスタを運用しているため、ファームウェアの更新やセキュリティ対応などでクラスタの全てのサーバーを再起動したいことがあります。

Necoでは、CKE(Cybozu Kubernetes Engine)と呼ばれるKubernetes管理ツールを用いてKubernetesクラスタの管理を行なっています。このCKEには、サーバーの再起動を宣言的に行うことができる機能を実装しており、再起動のキューが用意されています。キューに追加されたサーバーはCKEが適切に再起動を行います。コマンドを実行することでこのキューにKubernetesノードで使っているサーバーを追加することができるようになっています。

詳しくは前述した記事で紹介されているので、そちらもご覧ください。

既存の仕組みの課題

Kubernetesクラスタの活用が進み規模が大きくなるにつれて、既存の仕組みの課題が明らかになってきました。ここでは、大きな課題となっていた2つの問題を紹介します。

再起動の時間を指定できない

既存の再起動の仕組みでは、再起動キューに入っているサーバーの再起動を順番に実行し続けるようになっており、特定の時間での再起動が行えませんでした。 サーバー再起動によるアプリケーションへの影響が少ない時間帯に再起動を実施したいという要望があり、再起動の時間を指定できる仕組みが必要でした。

再起動に時間がかかる

既存の再起動の仕組みではサーバーを1台ずつ再起動しているため、クラスタの規模と比例して再起動にかかる時間が長くなってしまう問題がありました。 また、1個目の課題の解決で再起動の時間指定を行うと、さらに長期化する懸念がありました。 現状でも規模の大きいクラスタでは、再起動が数週間に及ぶこともあり、これを高速化するために並列して再起動を行えるような仕組みが必要でした。

課題解決のための新しい仕組み

上記の問題を解決するために、CKEの再起動機能を使用し再起動を制御するソフトウェアを開発しました。neco-rebooterという名前をつけています。

以下にneco-rebotoerの構成図を示します。

neco-rebooterの構成図

今まで再起動する予定のサーバーをCKEの再起動キューに入れていたところを、neco-rebooterが持つ再起動キュー(reboot list)に入れるようになっています。neco-rebooterがこのreboot listからCKEの再起動キューに適切に入れることで、時間指定の機能と並列再起動を実現します。

再起動の時間指定に関しては、neco-rebooterのConfigでノードのラベルと再起動可能な時間の組み合わせを設定し、neco-rebooterは再起動可能な時間になるとCKEの再起動キューに入れることで実現しています。 再起動可能な時間の設定に関しては、cron式で再起動をしない時間・再起動をする時間がそれぞれ複数指定できるようになっており、柔軟な設定ができるようになっています。 例えばhoge/type=type1というラベルが付いたノードを

  • 平日21時〜翌朝9時までの間で再起動する
  • 毎月1日は再起動しない

と設定したい場合、以下のように記述することで実現できます。

rebootTimes:
  - name: type1
    labelSelector:
      matchLabels:
        hoge/type: type1
    times:
      deny:
        - "* 0-23 1 * *"
      allow:
        - "* 0-8 * * 1-5"
        - "* 21-23 * * 1-5"
timeZone: Asia/Tokyo


並列再起動に関しては、CKEの並列再起動機能を用いることで実現しています。

サイボウズではラックごとにfailure domainを区切っており、1ラックの機材すべてが落ちてもサービスの提供が止まらないようにサービスをデプロイしています。 そのため、サービスを停止することなく、ラック内の機材であれば同時に再起動することが可能になっています。 CKEには元々、再起動キューに積まれているサーバーを指定された並列度で再起動する機能を実装していましたが、これを単に利用するだけでは、異なるラックのノードを同時に再起動してしまう可能性があるので、failure domain単位で再起動するような機能が必要でした。

neco-rebooterがfailure domain単位でCKEの再起動キューに入れるようにし、異なるfailure domainのサーバーが同時にキューに入らないように制御しています。

実装

neco-rebooterはPublicリポジトリであるcybozu-go/necoの下で実装されています。 ドキュメントがありますので、実装の詳細はこちらをご覧ください。

github.com

成果

neco-rebooterを用いて並列再起動を行なった際の進捗具合を示すグラフを以下に示します。

つい最近に実装が完了したため、まだ全てのサーバーの再起動が完了した際の計測はできていませんが、並列再起動を行うことで以前の通常の再起動に比べて早く再起動が進んでいることがわかります。

今後、再起動にかかる時間をさらに短くするために再起動の仕組みの改善は引き続き行っていく予定です。