プライベートクラウドに作る Kubernetes サービスの設計

はじめに

KADOKAWA Connected KCS 部の nokamoto です。

KCS 部は KADOKAWA グループ向けプライベートクラウド (KCS) を提供しており、その中の一つに私がアーキテクトとして参加している Kubernetes クラスタを提供するサービス (DKS) があります。

今回は DKS の紹介として Kubernetes サービスの設計について投稿します。

サービスの背景

f:id:kdx_writer:20200521155716p:plain

KCS はベアメタルから仮想サーバーに移行を果たし、次のステップとしてコンテナ技術へのキャッチアップが必要な状態でした。 また、グループ社内にも Docker や Kubernetes を立てて利用するユーザーがいたりと、プライベートクラウド上でのコンテナ管理に需要があると見込める状態でした。

これらの状況から、Kubernetes の小規模な利用・管理の経験を持った数名のメンバーが集まって、DKS の開発がスタートしました。

DKS をスタートする上で自動化が一つのトピックとしてありました。 KCS では自動化に課題1があり、例えばロードバランサーの設定変更は SRE チームへ依頼する形で行われています。 この状態では、ユーザーが Kubernetes のサービス公開だけを柔軟に操作できても、外部に公開するためには人への依頼をはさむ必要があり、十分なアジリティを発揮できる状態にはならないと考えられます。 こういったギャップを解消するために、DKS では出来る限り自動化された操作をインターフェースとしてユーザーに提供することを意識しています。 このロードバランサーの例では、ユーザーがサービスの公開をアジリティ高く行うことができるように DKS がロードバランサーの操作をラップして提供することで、人への依頼なく実現できるようにしています。

サービスの設計

DKS は周辺の KCS サービスとの連携も含めて Kubernetes の導入を自動化して提供することを意識して設計しています。

DKS は次の操作を利用者に提供しています。

  • クラスタの作成
  • クラスタの削除
  • クラスタのリサイズ
  • サービス公開のためのロードバランサー設定変更

それぞれの操作は gRPC で行い、gRPC サーバーとクライアントの CLI は Go 言語で実装しています。

$ dkscli cluster get-credentials your-cluster-id > ~/.kube/config
$ kubectl cluster-info

これらの操作で構築されたクラスタに対して、各ユーザーは CLI アプリケーションのコマンド実行により kubeconfig を取得して操作できます。

f:id:kdx_writer:20200512101323p:plain

DKS は IaaS として仮想マシンをホストする NicoSphere というサービス上にクラスタを構築して提供しています。 また、構築されたクラスタの Kubernetes API や実行するアプリケーションの API に対するロードバランサーの設定を自動化しています。

構築された Kubernetes クラスタ自身のメトリクスやログは DKS が MaaS (DataDog) や ESaaS (Elastic) に送信して管理しています。 これらの情報はクラスタの健全性を確認したり SLO を設定するために利用しています。

クラスタのメトリクスとは別に Kubernetes 上で実行されるアプリケーションのログやメトリクスの管理も必要となります。 これらはユーザーが管理するマニフェストによる設定で MaaS や ESaaS に送信できる形になっています。

その他、Kubernetes 上で実行されるアプリケーションは基本的にステートレスなものをサポートしており、永続化は DBaaS と連携することで実現しています。

次に DKS の設計で経験した Kubernetes に関する課題と方針について紹介します。

課題と方針:シングルクラスタとマルチクラスタ

f:id:kdx_writer:20200521171222p:plain

ここでは、単一のクラスタのみを管理し namespace などでユーザーを分けて提供するサービス形態をシングルクラスタと定義し、ユーザー毎に任意のクラスタを払い出すサービス形態をマルチクラスタと定義して呼んでいます。

DKS のサービスを考えた時に、どういったサービス形態を目指すかという議論がありました。

シングルクラスタを目指した場合は、DKS はクラスタの管理というよりは DevOps やチームビルディングの領域により焦点を当てたサービスになると想像されました。 例えば、組織を横断するプロダクトチームとクラスタ管理チームを定義し、それぞれの責務範囲を設計するなどです。

また、全体最適化の視点では、シングルクラスタはマルチクラスタの場合に発生するマスターノードのオーバーヘッドを抑えられたり、標準化された Kubernetes の利用によるユーザーの導入コストや管理コストの削減も考えられました。

一方で DKS はグループ社内のユーザーを対象に Kubernetes を広く提供するという役割を持ちます。 会社的・組織的にも異なるプロダクト、サービス全てを単一のクラスタで管理するのは難しく、どこかで複数のクラスタを管理する必要性は出てきそうです。 そのため、純粋にクラスタをアジリティ高く提供できるという仕組みはいずれにせよ必要になると考えました。

結論として DKS はマルチクラスタを選択していますが、全体最適化という視点は KCS でサービスを提供する上で必要なものと考えています。

DKS ではマルチクラスタを選択した上で、単純にクラスタを提供するだけではなく提供したクラスタの利用を標準化することもサービスの役割ととらえています。 例えば、他 KCS サービスとの連携のガイドラインを作成することで、ユーザーに DKS が提供するクラスタの事情にあった利用の指標を示すといった活動も行なっています。

課題と方針: クラスタのバージョン

Kuberentes は約三ヶ月ごとにマイナーリリースが行われ、最新の三つのリリースブランチがメンテナンスされています2。 このリリースサイクルにどのようにキャッチアップするかというのが設計上の課題でした。

バージョンに関わる設計の関心事として、 DKS 上で一つのバージョンのみ扱うか、複数のバージョンのクラスタを扱うかの選択肢がありました。 前者は DKS が決定するバージョンに強制的に全クラスタをアップグレードさせるというやり方で、後者はユーザーがクラスタのバージョンを選択できるやり方です。

DKS では前者の一斉更新に利用者提供者共に対応できるのか不安があったため、管理コストが増すことを許容して後者を選択しました。

二つ目の関心事としてバージョン追従ポリシーの決定がありました。 毎月三つのパッチバージョンがリリースされたり、三ヶ月毎にマイナーバージョンがリリースされたりする中で、 DKS にどのバージョンを取り込むかという選択です。

これは主にバージョン追従に関してどの程度の定常的なコストを掛けられるかという話になり、 DKS では初期のポリシーとしてはある程度遅れたバージョンに追従することで運用コストを出来るだけ下げることを選択しました。

三つ目の関心事としてアップグレード戦略がありました。

クラスタのアップグレードは大きく分けて in place のアップグレードと、マイグレーションによる入れ替えが考えられます。

in place のアップグレードはユーザーの実行コストが低い一方で、失敗時の対処を提供する難しさがありました。 また、ユーザーのユースケースとしても in place アップグレードを行うことに対してはまだ不安があるという意見がグループ社内にありました。

マイグレーションによる入れ替えでは、マニフェスト管理がされていれば Kubernetes ではマイグレーション自体は比較的楽であるとはいえ、サーバーへのリクエストやアプリケーションのデプロイを切り替えるための実行コストが掛かります。 特に自動化に難のあるロードバランサーへの変更をどのように行うかが課題としてありました。

  • in place
    • コマンド実行
    • 失敗時の対処
      • ダウングレードの不透明さ
  • マイグレーション
    • クラスタレベルの blue/green
      • クラスタの複製
      • ロードバランサーの切り替え
    • 失敗時の対処
      • 切り戻し

これらに対して DKS では in place のアップグレード操作より優先してリプレイスによるアップグレードの実行コストを下げるため、ロードバランサー操作の自動化実装にコストを割り当てる選択をしました。

これらの方針については Kubernetes クラスタの社内運用知見が足りていないこともあり、今後の運用も踏まえてより望ましい状態を考えていく必要があると考えています。

今後のサービス

DKS は次のリリースで一通りの自動化と、継続した SLO の達成による安定稼働した Kubernetes クラスタの提供が開始されます。

今後は SLO を維持しつつ、Kubernetes のバージョンにキャッチアップすることが運用目標になります。

開発としては本格化するであろうユーザー利用からフィードバックを受けて機能追加や、KCS の自動化 ( API 提供 ) が進んだ時には Kubernetes クラスタ自体を CRD で管理するといった目論見もあります。

今後の投稿について

DKS の今後の投稿は以下のようなトピックを考えています。

  1. Kubernetes クラスタ構築を自動化する話
  2. DataDog で Kubernetes のメトリクスを監視する話
  3. Kubernetes の機能テストを作る話

DKS はリリースされたばかりの新しいサービスです。 今後チームで経験する Kubernetes に関わる投稿をできればと考えています。

今回ご紹介したような Kubernetes や gRPC Go 言語などを利用した開発に興味がある方は、オープンポジション採用ページ からご応募ください(専用の採用ページは準備中です)。


  1. 自動化の達成は DKS とは別に KCS が取り組んでいるプロジェクトの一つになっています

  2. https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions