Sign In
Free Sign Up
  • English
  • Español
  • 简体中文
  • Deutsch
  • 日本語
Sign In
Free Sign Up
  • English
  • Español
  • 简体中文
  • Deutsch
  • 日本語

レプリケートされたMyScaleクラスターにおけるゼロダウンタイムのKubernetesアップグレードを実現する方法

このブログでは、MyScaleがレプリケートされたクラスターにおいてKubernetes(k8s)のアップグレード中にゼロダウンタイムを実現する方法について詳しく説明します。AWSクラウド上にホストされ、Amazon EKSを利用しているMyScaleは、堅牢かつスケーラブルなDatabase-as-a-Service(DBaaS)を提供しています。MyScaleのアーキテクチャのグローバルおよびリージョナルな側面を探り、オートスケーリングとKubernetesのアップグレードの課題に取り組み、シームレスなユーザークラスターの移行戦略を概説します。すべてのサービスが中断することなく、サービスを確実に提供します。

# MyScaleのアーキテクチャの探索

MyScale (opens new window)は、AWSクラウドプラットフォーム上に構築されたDatabase-as-a-Service(DBaaS)です。すべてのサービスはAWSのマネージドKubernetesサービスであるAmazon EKS (opens new window)上に展開されており、Kubernetesの強力な機能(サービスディスカバリ、ロードバランシング、自動スケーリング、セキュリティ分離など)をフルに活用することができます。

以下の図に示すように、グローバルプレーンとWebサービス (opens new window)、ユーザー管理、請求支払いなどが配置されたリージョナルサービスなど、非常に弾力性のあるスケーラブルなアーキテクチャを設計しています。また、各リージョンのサービスは、異なる地理的な場所に配置されており、各リージョンのサービスは、ユーザークラスターの作成、管理、アップグレード、破棄、使用状況の監視、アプリケーションインターフェースなどといった同じ機能を提供しています。

MyScaleクラウドのアーキテクチャ

さらに、各リージョンのサービスは、単一のコントロールプレーンと複数のデータプレーンで構成されています。

各リージョンのコントロールプレーンは、タスクまたはリクエストの管理とスケジューリングを担当しています。また、データプレーンとグローバルプレーンの間のリンクとして機能し、グローバルプレーンから発行された管理リクエストを受け入れ、適切なデータプレーンで実行するために渡します。さらに、このコントロールプレーンは、データプレーンの状態と詳細な使用状況メトリックスを収集し、ユーザークラスターが正しくデータプレーン上で実行されることを確認する責任も担っています。

各プレーンは独立したK8sクラスターに対応しており、通常の状況では、これらのクラスターの作成と維持には多数のクラウドリソースが必要となります。特にKubernetesクラスターの作成と構成には多くのクラウドリソースが必要です。私たちは、Crossplane (opens new window)を使用して、Kubernetesパターンを使ってインフラストラクチャ、アプリケーション、およびユーザークラスターを効率的に統合的に管理しています。

異なるユーザークラスターの仕様に応じて、個々のユーザークラスターの仕様とワークロードに対応するために、異なるNodeGroup (opens new window)を作成し、データプレーン上のリソース利用率を最大化しています。Cluster Autoscaler (opens new window)の助けを借りて、Kubernetesクラスターの自動スケーリングを実現しています。

apiVersion: eks.aws.crossplane.io/v1alpha1
kind: NodeGroup
metadata:
  name: <eks-nodegroup-name>
spec:
  forProvider:
    region: us-east-1
    clusterNameRef:
      name: <eks-cluster-name>
    subnets:
      - subnet-for-us-east-1a
      - subnet-for-us-east-1b
      - subnet-for-us-east-1c
    labels:
      myscale.com/workload: db
      myscale.com/instance-type: <myscale-instance-type>
    taints:
      - key: myscale.com/workload
        value: db
        effect: NO_EXECUTE
    instanceTypes:
      - <instance-type>
      - <instance-type>
    scalingConfig:
      maxSize: 100
      minSize: 3

# Kubernetesにおけるオートスケーリングの課題への対応

最初はNodeGroupを使用することでうまく機能していましたが、ユーザークラスターの仕様が拡大するにつれて、次の2つの問題に直面しました。

  1. NodeGroupは、期待どおりに利用可能なゾーン全体に均等に分散されず、ユーザークラスターの作成、削除、開始、停止が行われると徐々に利用可能なゾーンの1つにユーザークラスターが集中してしまいます。
  2. 各NodeGroupの最小サイズ(minSize)要素は常にゼロ以外である必要があります。一部の場合、既存のPVCを使用する場合など、ゼロに設定されると自動拡張がトリガされず、ポッドは永久にペンディングのままになります。

これらの問題の解決策を見つけるために、Cluster Autoscalerのログや以下のドキュメントを調査したところ、この現象に関する参照情報を見つけました。

ログ:

Found multiple availability zones for ASG "eks-nodegroup-xxxxxxx-90c4246a-215b-da2a-0ce8-c871017528ab"; using us-east-1a for failure-domain.beta.kubernetes.io/zone label

ドキュメント:

参考ドキュメントのベストプラクティスに従い、NodeGroupの元々のマルチアベイラビリティゾーンを複数のシングルアベイラビリティゾーンのNodeGroupを表すように変更しました。さらに、ゼロからのスケーリングをASGタグの設定によって実装しました。

以下のYAMLスクリプトによる設定を行いました。

apiVersion: eks.aws.crossplane.io/v1alpha1
kind: NodeGroup
metadata:
  name: <eks-nodegroup-name-for-az1>
spec:
  forProvider:
    region: us-east-1
    clusterNameRef:
      name: <eks-cluster-name>
    subnets:
      - subnet-for-us-east-1a
    labels:
      myscale.com/workload: db
      myscale.com/instance-type: <myscale-instance-type>
    tags:
      k8s.io/cluster-autoscaler/node-template/label/topology.kubernetes.io/region: us-east-1
      k8s.io/cluster-autoscaler/node-template/label/topology.kubernetes.io/zone: us-east-1a
      k8s.io/cluster-autoscaler/node-template/label/topology.ebs.csi.aws.com/zone: us-east-1a
      k8s.io/cluster-autoscaler/node-template/taint/myscale.com/workload: db:NO_EXECUTE
      k8s.io/cluster-autoscaler/node-template/label/myscale.com/workload: db
      k8s.io/cluster-autoscaler/node-template/label/myscale.com/instance-type: <myscale-instance-type>
    taints:
      - key: myscale.com/workload
        value: db
        effect: NO_EXECUTE
    instanceTypes:
      - <instance-type>
      - <instance-type>
    scalingConfig:
      maxSize: 100
      minSize: 0
Boost Your AI App Efficiency now
Sign up for free to benefit from 150+ QPS with 5,000,000 vectors
Free Trial
Explore our product

# Kubernetesのアップグレードに対する取り組み

AWSはEKS 1.24の廃止通知を受けて、Kubernetesクラスターのアップグレードを行うように指示されました。そのため、サポート期限前に最新バージョンにアップグレードすることが課題となりました。

リリースカレンダー (opens new window)によると、AWSはリリース日から14ヶ月以内にこれらの新しいバージョンに対してサポートを提供します。

AWSが提供するドキュメントに基づいて、AWSのアップグレードプロセスをテストしました。

テスト中に、次の問題に遭遇しました。

  • 複数のバージョンを同時にアップグレードすることはできません。一度に1つのバージョンのみをアップグレードし、1年間に最大3つのバージョンをアップグレードすることができます。
  • NodeGroupのアップグレードには比較的長い時間がかかります。1つのNodeGroupにつき、ポッドの移行または強制的な移行が行われるまで数十分かかります。

頻繁なバージョンのアップグレードと長いアップグレード時間、および強制的なポッドの移行は、既存のネットワーク接続の異常な中断を引き起こす可能性があり、データプレーンのユーザークラスターに大きな影響を与え、ユーザーがシステムの状態 (opens new window)に注意を払って問題に対処する必要があります。

これらの課題に対する解決策を見つけるために、関連するAWS EKSのドキュメントを調査し、次の有益な情報を見つけました。

  • EKSのコントロールプレーンとNodeGroupは1つのバージョンの差異があっても問題ありません。EKS 1.28以降、2つのバージョンの差異が許容されます。
  • EKSのコントロールプレーンがアップグレードされた後、コントロールプレーンのバージョンと同じNodeGroupを作成し、アップグレードされていない古いNodeGroupと共存させることができます。

これらのポイントに基づいて、次の変更を行いました。

  • 既存のNodeGroupの設定にinstance-versionラベルを追加しました。
labels:
  myscale.com/instance-version: v1.24
  • 次に、EKSのコントロールプレーンをアップグレードしました。
apiVersion: eks.aws.crossplane.io/v1beta1
kind: Cluster
metadata:
  name: <eks-cluster-name>
spec:
  forProvider:
    version: "1.25"

EKSのコントロールプレーンのアップグレードが完了した後、古い/既存のNodeGroupをアップグレードしないでおきます。代わりに、アップグレードされたEKSのコントロールプレーンバージョンに基づいて新しいNodeGroupを作成し、バージョンを示すラベルを追加します。

labels:
  myscale.com/instance-version: v1.25

その後、クラスターコントローラに以下の設定を追加して、バージョンのアップグレード期間中にユーザークラスターのスケジューリングをサポートしました。

node_group:
  default: v1.25
  allowed:
    - "v1.25"
    - "v1.24"

これにより、新しく作成されたユーザークラスター、またはユーザーがアクティブにバージョンのアップグレードや再起動などをトリガーした場合、デフォルトでv1.25とマークされたNodeGroupにスケジュールされます。他のクラスターは変更されません。EKSのアップグレード中のポッドの移行の問題を解決し、ユーザーには透過的なものとなりました。

なお、EKS 1.28では2つのバージョンの偏差が許容されます。1.26以上の場合、EKS 1.26から始まり、2つの連続したバージョンでEKSのコントロールプレーンをアップグレードすることができます。これにより、アップグレード回数を半分に減らすことができます。

Join Our Newsletter

# ユーザークラスターのアップグレードの戦略

ただし、一部のユーザークラスターはまだ古いv1.24のNodeGroupで実行されています。

これらのクラスターはいつ移行されるのでしょうか?

この問題を議論する前に、まずユーザークラスターを以下のように分類しましょう。

  • マルチレプリカユーザークラスター
  • シングルレプリカユーザークラスター

マルチレプリカクラスターのレプリカは、異なるアベイラビリティゾーンの複数のノードに配置されています。新しいユーザーリクエストはロードバランサーによって他のポッドにスケジュールされるため、移行対象のポッドは新しいユーザーリクエストを処理しなくなります。既存のリクエストが処理された後、ポッドを移行することができます。このプロセスを繰り返すことで、マルチレプリカユーザークラスターのすべてのポッドを移行することができます。

ただし、シングルレプリカユーザークラスターには単一のポッドしか含まれていません。マルチレプリカユーザークラスターのロジックは適用できません。

したがって、この移行をどのように処理するのでしょうか?マルチレプリカユーザークラスターの方法を参照して再利用することはできるでしょうか?

MyScaleのレプリカメカニズムがクラスターを拡張し(レプリカを増やす)ると、新しく作成されたレプリカは既存のレプリカからデータを自動的に同期し、データの同期が完了した後、複数のレプリカが同時にサービスを提供します。

したがって、私たちが行う必要があるのは、ユーザークラスターを移行するように設定することだけです。

apiVersion: db.myscale.com/v1alpha1
kind: Cluster
metadata:
  name: <cluster-name>
spec:
  replicas: 1
  shards: 1
  ......

シングルレプリカからダブルレプリカへの移行前に拡張します。

apiVersion: db.myscale.com/v1alpha1
kind: Cluster
metadata:
  name: <cluster-name>
spec:
  replicas: 2
  shards: 1
  ......

その後、マルチレプリカユーザークラスターの移行ロジックを再利用して移行を実行します。移行が完了したら、余分なポッドをスケールダウンして削除します。

最終的に、すべてのユーザークラスターが移行されます。古いNodeGroupのノード上のポッドはすべて移行されます。Cluster Autoscalerは古いNodeGroupの空のノードを自動的に削除します。ノードサイズがゼロのNodeGroupを確認して削除するだけです。このプロセスはユーザーには影響を与えず、EKSも新しいバージョンに完全にアップグレードされます。

# まとめ

これらのアーキテクチャの課題とアップグレードに関する取り組みにより、MyScaleの堅牢性と効率性が向上し、重要なKubernetesのアップグレード中にゼロダウンタイムを確保することができました。最後に、この取り組みは、私たちのユーザーにシームレスで高性能なDBaaS体験を提供するという私たちの取り組みを反映しています。

Keep Reading

Start building your Al projects with MyScale today

Free Trial
Contact Us