Brandwatchのエンジニアリングチームが、EKS、GKE、自社クラスタで構成されるマルチクラスタKuberenetsを管理した自らの経験について記事を書いた。Brandwatchでは、AWS EKS、GKE、およびロンドンにある自社管理のデータセンタで動作する、6つの独立したKubernetesクラスタにわたる、約150の実稼働サービスを運用している。2016年初め、同社はまずGKE上での運用を開始して、自社サービスの多くに適しているという評価を下した。その後、ConcourseCIといくつかの自社開発ツールを使ってデプロイメントを自動化し、HTTPリクエスト/レスポンスのコントロール性向上のためにnginx ingressコントローラを導入した。
InfoQは今回、同社でエンジニアリングとアプリケーションインフラストラクチャのディレクタを務めるAndy Hume氏に、詳しい話を聞くことができた。
GKEとEKSはKubernetesコントロールプレーンの管理に関する頭痛の種を取り除いてくれるが、自社管理のKuberenetsクラスタの管理とアップグレードは依然として自分で行わなくてはならない。これに使用するツールについて、Hume氏は次のように語った。
自社DCのKuberenets管理にはRancherを使用しています。Kubernetes導入以前の2015/2016年にRahcher 1を運用した経験があったので、Rancher 2がKubernetesに移行した時、当社に導入するスタートポイントとして妥当だと思ったのです。ただし当社では、Kubernetesを既存のベアメタルインフラストラクチャ以外にも拡張する予定なので、あまり複雑ではない、それでいて既存のネットワークデザインへの統合においてフレキシブルなソリューションを探すことになるでしょう。
BrandwatchチームはK8Sを広範に採用している。チーム全体に対して特定のツールを指定していないことについて、Hume氏は次のように説明している。
当社の開発チームは開発ワークフローのアプローチが非常に多様なので、アプリケーションプラットフォームがローカル開発に特定のツールやワークフローを課すようなことはしていません。開発をスムーズに進めるために、SkaffoldやTelepresence、Docker Composeなど、さまざまなツールを使っています。
ただし、CI/CDワークフローは標準化されていて、"すべてのチームがコンテナイメージとメタデータを中央システムにパブリッシュして、デプロイメントと変更管理に使用されています"、と述べている。
CI/CDはConcourseCIで管理されている。これ自体がKubernetes上で動作し、デプロイメントを自動化するためのカスタムツールを備える。また、kubectlを囲む宣言的なラッパ — YAMLとして編集可能 — を記述して、サービスのメタデータのキャプチャを行っている。クラスタレベルの全サービスの管理にはKustomizeを採用して、Helmをテンプレート生成に用いている(本番ロールアウトは除く)。"変更のロールアウト方法のメカニズムを単純にする"ため、Kubernetesのマニフェストはすべて、アプリケーションのソースコードとは別のリポジトリで管理している。アプリを旧バージョンにロールバックするには、単に古いマニフェストをデプロイすればよい。Hume氏が詳しく説明する。
ソースコードの新しいバージョン(のイメージ)をデプロイする時は、GitにあるKubernetesマニフェストのイメージ参照を更新すればよいのです。この自動化によって、開発者のデプロイ作業はこの上なく単純になっていますが、実際にアプリケーションのソースコードとKubernetesのマニフェストの間に個別のマッピングがある訳ではありません。Git内のマニフェストが"Single Source of Truth"なので、旧バージョンにリバートすれば、イメージタグやバージョンもロールバックされるのです。
Kubernetesクラスタがインターネットからのトラフィックを受け入れるためにはIngressが必要になる。マネージドKubernetesを提供しているクラウドベンダは、自社のIngress実装の一部としてロードバランサを組み入れているが、自身でロードバランサを用意したり、あるいはKubernetesクラスタを自分自身で管理することも可能だ。Brandwatchのエンジニアチームでは、EKSやGKE上のものを含むすべてのクラスタ上でnginx-ingress-controllerを実行することで、マネージドサービスのロードバランサをバイパスしている。この方法により、HTTPレスポンスのヘッダを操作して、セキュリティ関連のヘッダを追加したり、内部的なヘッダを削除したりすることが可能になった。Hume氏はさらに、次のように述べている。
これらのヘッダの追加をアプリケーション自体に依存するのはなく、中央のひとつの場所で行うということは、セキュリティチームが監査したり、あるいは必要に応じて調整することが可能になるという意味で、よい方法です。クラウドのHTTP LBには制限もいくつかあります。例えばGCP LBは、受信するリクエストのHTTPヘッダのサイズを制限しているため、当社がKubernetesに移行したかった古いアプリケーションのいくつかで問題が発生していました。
Brandwatchでは、各クラスタ上でPrometheusを稼働させて、監視と警告にPrometheusオペレータを使用している。警告機能のおもな目標は"アプリケーションを実際に使用するユーザの可用性と正確性に関する懸念と、それらの確立と対応について個々の開発チームが、各クラスタのprometheus/alartmanagerスタックを使って基本的に責任を負うこと"だ、とHume氏は述べている。これとは別に、Kubernetesワークロードの動作状況についても、クラスタ全体の健全性の指標として監視されている。Hume氏は次のように付け加える。
一般論として、GKEやEKSのマネージドノードはレジリエントで、障害時の管理も容易であるということは分かっています。あるノードのワークロードに障害が発生した場合、最初の対応はそれを停止して、クラスタのオートスケールに改めて立ち上げてもらう、というものです。管理はノードレベルで行っていますが、ノードレベルのメトリクスを元に予備的な警告を発行する、ということは行っていません。
Brandwatchは必要時のノード立ち上げにCluster Autoscalerを使用しているが、動作の遅い場合が少なくない。これに対しては、ノード(およびpod)の立ち上がるまで処理のキューイングやリトライを行うアプリケーションロジックを使用し、既知のワークロードスパイクに対しては想定値による事前スケーリングを行っている。