管理ツール

Kubernetes Engine で動作するアプリでのロギングの使用

google cloud containers

※この投稿は米国時間 2020 年 5 月 12 日に、Google Cloud blog に投稿されたものの抄訳です。

アプリケーションのデバッグを行うデベロッパーにとっても、また複数の本番環境クラスタにわたってアプリケーションをモニタリングする DevOps チームのメンバーにとっても、ログは IT 組織の生命線といえます。Google Kubernetes Engine(GKE)を導入している場合、Cloud Logging を使用できます。これは、GKE に統合されているさまざまなサービスの一つで、有用な情報の検索に使用できます。

Cloud Logging とそれに付随するツールの Cloud Monitoring は、双方とも GKE に密接に統合されたフル機能のプロダクトです。このブログ投稿では、GKE でロギングが機能する仕組みとログ収集のベスト プラクティスをご紹介します。また、GKE と Google Cloud Platform に組み込まれている充実したロギング機能を最大限に活用するためにお役立ていただける、ロギングの一般的なユースケースについても説明します。

GKE での Cloud Logging の機能

デフォルトで、GKE クラスタは Cloud Logging(および Monitoring)とネイティブに統合されています。GKE クラスタを作成すると、Monitoring と Cloud Logging は双方ともデフォルトで有効になります。つまり、Kubernetes 専用に調整されたモニタリング ダッシュボードが利用可能になり、ログは Cloud Logging の専用の永続データストアに送信され、インデックスが付けられて Cloud ログビューアで検索、表示できるようになります。

Cloud Logging と Monitoring が無効になっている既存のクラスタを使用している場合、そのクラスタのロギングとモニタリングも有効にできます。これらを有効にしておくことは重要です。Cloud Logging が無効になっていると、GKE ベースのアプリケーションではログが一時的にワーカーノードに書き込まれますが、このログは Pod の削除時に削除されることやログファイルのローテーション時に上書きされることがあるからです。また、このログには一元的にアクセスできないため、システムやアプリケーションのトラブルシューティングが難しくなります。

クラスタ監査ログとワーカーノードのログの他に、GKE では STDOUT または STDERR に書き込まれるアプリケーション ログが自動的に収集されます。アプリケーション ログの収集は行わない場合、システムログのみを収集することを選択できるようになりました。システムログの収集は、トラブルシューティング プロセスを大きく加速させるため、本番環境クラスタには不可欠です。ログをどのように使用するかにかかわらず、GKE と Cloud Logging によってログの使用がシンプルで簡単になります。クラスタを起動し、アプリケーションをデプロイするだけで、ログが Cloud Logging に表示されます。

GKE によるログの収集方法

GKE では、コンテナログを読み取り、有用なメタデータを追加してからログをログルーターに送信するノードごとの Logging エージェントがデプロイされます。ログはログルーターから Cloud Logging と、構成されているログシンクの宛先に送信されます。Cloud Logging では、指定した期間またはデフォルトの 30 日間、ログが保存されます。Cloud Logging ではコンテナ化されたプロセス用に標準の出力ログとエラーログが自動的に収集されるため、アプリケーションのデプロイ後すぐにログの表示を開始できます。

ログがある場所

Logging では、ユースケースに応じて、さまざまな方法でログにアクセスできます。ワークスペースがすでに有効になっている場合、ログには以下の方法でアクセスできます。

  • Cloud Logging コンソール – Cloud Logging コンソールから直接ログを表示できます。このとき、必要に応じてロギング フィルタを使用して、クラスタ、ノード、名前空間、Pod、コンテナなどのログといった Kubernetes リソースを選択します。Kubernetes 関連のクエリのサンプルもご参照ください。
  • GKE コンソール – Google Cloud Console の [Kubernetes Engine] セクションで、[ワークロード] にリストされている Kubernetes リソースを選択し、コンテナログまたは監査ログのリンクを選択します。
  • Monitoring Console – Monitoring Console の [Kubernetes Engine] セクションで、関連するログを表示する適切なクラスタ、ノード、Pod、コンテナを選択します。
  • gcloud コマンドライン ツール – gcloud logging read コマンドを使用して、適切なクラスタ、ノード、Pod、コンテナのログを選択します。

カスタムログ収集、ログ分析、サードパーティ製システムとの統合を行う場合、ログシンク機能を使用して、BigQuery、Cloud Storage、Pub/Sub にログをエクスポートすることもできます。たとえば、ログを BigQuery にエクスポートし、SQL クエリを使用して 1 年間のアプリケーション ログを分析することが可能です。あるいは、Pub/Sub との統合を使用して、既存のサードパーティ製システムに特定のログをエクスポートすることもできます。ログにアクセスする最適な方法はユースケースによって異なります。

コンテナ化されたアプリケーションのロギングに関する推奨事項

GKE でのロギングの一般的なユースケースを詳しく見ていく前に、コンテナ化されたアプリケーションで Cloud Logging を使用する際のベスト プラクティスをご紹介します。

  • ログを stdout や stderr に書き込む場合は、コンテナのネイティブのロギング メカニズムを使用します。
  • ログを stdout や stderr に書き込むようにアプリケーションを構成することが簡単ではない場合は、ロギングのサイドカー パターンを使用できます。
  • 複数の異なるフィールドを指定した構造化ロギングを使用してログを直接書き込みます。このようにすれば、これらのフィールドに基づいて、より効率的にログを検索できます。
  • severity を使用すると、フィルタリング機能が向上し、ノイズが減ります。デフォルトでは、標準出力に書き込まれるログは INFO レベルであり、標準エラーに書き込まれるログは ERROR レベルです。JSON ペイロードを使用する構造化ログには、ログの重大度を定義する severity フィールドを含めることができます。
  • コンテナの場合は Cloud Console の [Kubernetes Engine] セクションからログへの直接リンクを使用すると、対象のコンテナに対応するログを迅速に見つけることができます。
  • 関連する費用を把握するには、Cloud Logging の料金割り当て、上限を把握しておくことをおすすめします。

ユースケース

GKE 環境でのログのシンプルながらも一般的なユースケースを見ていきましょう。アプリケーション エラーの診断、シンプルなログデータの分析、複雑なログデータの分析、Cloud Logging とサーパーティ製アプリケーションとの統合を紹介します。

Cloud Logging を使用したアプリケーション エラーの診断

あなたはデベロッパーで、開発クラスタ内のアプリケーション エラーを診断する必要があるとします。具体例を示すために、ここでは GKE クラスタにデプロイされているサンプルのマイクロサービス デモアプリに基づいたシナリオを使用します。このデモアプリをご自分の Google Cloud プロジェクトにデプロイすることも、サイトの信頼性のトラブルシューティングに関する Qwiklab に沿ってこのデモアプリのバージョンのうち、エラーが含まれるものをデプロイすることもできます。

デモアプリには、さまざまなマイクロサービスと、その依存関係が含まれています。

1.jpg

注文を行おうとしたらアプリで「500」の内部サーバーエラーが表示され始めたとします。

2.jpg

デバッグを開始しましょう。ログをすばやく見つける方法は 2 つあります。

1. Kubernetes Engine コンソールの使用 – Kubernetes Engine コンソールでチェックアウト サービスを開きます。ここではサービング ポッド、コンテナ、コンテナログと監査ログへのリンクに関する詳細な技術情報をすべて確認できます。

サービング ポッド、およびコンテナログと監査ログのリンクに関する詳細な技術情報を探します。

3.gif

コンテナログのリンクをクリックすると、Cloud Logging のログビューアが表示され、以下のような事前入力された検索クエリが示されます。これは自動的に作成され、checkoutservice Pod で実行されているアプリケーションの特定のコンテナログを示します。

  resource.type="k8s_container"
resource.labels.project_id="YOUR PROJECT ID"
resource.labels.location="us-west1-b"
resource.labels.cluster_name="shop-cluster"
resource.labels.namespace_name="default"
resource.labels.pod_name="checkoutservice-98f7f9d5f-7446f"
resource.labels.container_name="server"
 2. Cloud Logging コンソールからのログビューアの使用 – Cloud Logging コンソールに直接移動し、ログビューアを使用して特定のログでエラー メッセージを検索できます。

リソースタイプ、検索フィールド、期間を指定して、クエリを迅速化できます(その他のヒントはこちらをご覧ください)。ログビューアには、従来版とプレビュー版があります。プレビュー版ログビューアのクエリビルダーを使用すると、こういったフィルタ条件を迅速に指定できます。たとえば、クラスタ、名前空間、コンテナに関するリソースをプルダウン メニューで選択できます。

4.jpg

クエリビルダーでこのように選択すると、次のクエリが生成されます。

  resource.type="k8s_container"
resource.labels.cluster_name="shop-cluster"
resource.labels.namespace_name="default"
resource.labels.container_name="server"

アプリにコードベースを使用することに慣れていない場合は、問題を修正するためにログを使用したデバッグが必要になります。まずは、ログでエラー メッセージを検索し、エラーのコンテキストを理解することをおすすめします。受け取った特定のログ メッセージを検索するには、クエリに jsonPayload.error フィールドを追加します。クエリが常に効率的に実行されるように resource.type フィールドも追加しておく必要があります。

  resource.type="k8s_container"
resource.labels.cluster_name="shop-cluster"
resource.labels.namespace_name="default"
resource.labels.container_name="server"
jsonPayload.error:"Sorry, we cannot process jcb credit cards. Only VISA or MasterCard is accepted."

プレビュー版のログビューアの有用な機能の一つがヒストグラムです。これを使用すると、ログでクエリとの一致が出現する頻度を確認できます。次の例では、ヒストグラムによってログにエラーが出現する頻度を把握できます。

5.jpg

次の例では、クエリに一致する特定のログエントリを確認できます。

6.jpg

ログエントリを展開すると、支払い関連のログエントリからは、Pod、コンテナ、エラーのスタック トレースに関する詳細を確認できます。ログは、エラーが発生したコードの正確な場所を示します。

別の方法として、コマンドライン インターフェースを使用する場合は、Cloud Shell から同じコマンドを実行できます。クエリと、クエリで検索する stderr ログでは、条件が使用されていることに注意してください。

  gcloud logging read 'logName:projects/YOUR_PROJECT_ID/logs/stderr AND resource.type=k8s_container AND resource.labels.cluster_name=shop-cluster AND resource.labels.namespace_name=default AND textPayload:"Sorry, we cannot process jcb credit cards. Only VISA or MasterCard is accepted."' --limit 10 --format json

ログデータの分析

ロギングのもう一つの一般的なユースケースとして、組み込みの Logging クエリ言語を使用した複雑で強力なクエリによるログデータの分析が挙げられます。クエリビルダーを使用してクエリを作成することも、オートコンプリートを使用してカスタムクエリを作成することもできます。ログエントリを迅速に見つけるために、resource.type、logName、severity といったインデックス ログフィールドに正確な値を含めます。以下にクエリの例をいくつか示します。

次のクエリは、コンテナ内でコマンドを実行しようとしているユーザーが承認済みユーザーかどうかをチェックします。cluster_name と location を、特定のクラスタ名とゾーンの値に置き換えて使用してください。

  resource.type="k8s_cluster"
resource.labels.location="us-west1-b"
resource.labels.cluster_name="shop-cluster"
protoPayload.methodName:"io.k8s.core.v1.pods.exec"
protoPayload.authorizationInfo.granted=true

次のクエリは、コンテナ内でコマンドを実行しようとしているユーザーが特定のユーザーかどうかをチェックします。cluster_name、location、principalEmail を、特定のクラスタ名、ゾーン、メールアドレスの値に置き換えて使用してください。

  resource.type="k8s_cluster"
resource.labels.location="us-west1-b"
resource.labels.cluster_name="shop-cluster"
protoPayload.methodName:"io.k8s.core.v1.pods.exec"
protoPayload.authorizationInfo.granted=true
protoPayload.authenticationInfo.principalEmail="alice@example.com"

次のクエリは、指定した期間内の Pod 関連のログエントリをフィルタリングで抽出します。cluster_name、location、pod、timestamp を、特定のクラスタ名、ゾーン、Pod、時間の値に置き換えて使用してください。

  resource.type="k8s_pod"
resource.labels.location="us-west1-b"
resource.labels.cluster_name="shop-cluster"
jsonPayload.involvedObject.name="checkoutservice-98f7f9d5f-7446f"
timestamp>="2020-03-12T02:27:45.000-0400" timestamp<="2020-03-12T02:28:00.000-0400"

他にも Google Cloud 全体のログクエリについてプロダクト固有の例を示したサンプルクエリがありますので、ご参考になさってください。監査ログについては、GKE 監査ログの具体的なクエリ例をご覧ください。

Cloud Logging を使用した高度な分析

さらに高度な分析を行う場合は、ログを BigQuery にエクスポートします。そのうえで、標準 SQL クエリを使用して、ログの分析や他のソースからのデータとの関連付けを行い、出力を充実させることができます。たとえば、次の SQL クエリは、GKE クラスタ上の、マイクロサービス デモアプリを実行中のデフォルトの名前空間から、メールアドレス「user@example.com」に関連したログデータを返します。

  SELECT resource.type, 
       jsonpayload.message, 
       resource.labels 
FROM   `[YOUR PROJECT].gkelogging.stdout_20200312` 
WHERE  resource.labels.cluster_name = 'shop-cluster' 
       AND resource.labels.namespace_name = 'default' 
       AND jsonpayload.message LIKE "%user@example.com%" 
LIMIT  10
7.jpg

このログデータからは、価値あるビジネス分析情報も取得できます。たとえば、次のクエリを使用すると、過去 2 日間にレコメンデーション サービスが特定の商品をおすすめした回数を確認できます。

  SELECT COUNT(*) 
FROM   `[YOUR PROJECT].gkelogging.stdout_*` 
WHERE  jsonPayload.name = "recommendationservice-server" 
       AND resource.labels.cluster_name = 'shop-cluster' 
       AND jsonPayload.message LIKE 
           "[Recv ListRecommendations] product_ids=[%u'OLJCESPC7Z'%" 
              AND timestamp >= TIMESTAMP(DATE_SUB(CURRENT_DATE(), INTERVAL 2 DAY))

アクティビティ ログと監査ログも分析できます。たとえば、次のクエリは、特定の時間枠内に生じた kubelet の警告をすべて返します。

  SELECT timestamp, 
       jsonPayload.message 
FROM   `[YOU PROJECT].gkelogging.kubelet_*` 
WHERE  jsonPayload.message LIKE 'W%' 
              AND timestamp >= "2020-03-12T02:27:45.000-0400"
AND timestamp <= "2020-03-13T02:28:00.000-0400"

他のサンプルクエリもご覧になりたい場合は、Cloud Logging のエクスポートのシナリオ: セキュリティとアクセス分析の記事をご参照ください。

Cloud Logging でのサードパーティ製ツールの使用と自動化

最後に紹介するユースケースは、Pub/Sub との Cloud Logging の統合です。シンクを作成して、ログを Pub/Sub トピックにエクスポートできます。これは、ログデータの単なるエクスポート以上の機能を果たします。Pub/Sub を使用すると、イベント ドリブン アーキテクチャを作成して、リアルタイムに自動でログイベントを処理できます。このイベント ドリブン アーキテクチャを、Cloud RunCloud Functions などのサーバーレス テクノロジーと組み合わせて実装すると、自動化の費用と管理オーバーヘッドを大幅に削減できます。

Cloud Logging と GKE に関するその他の情報

ここまで、GKE のロギング機能を Cloud Logging に組み込んで、ログの保存、検索、分析、モニタリングを簡単にする方法を説明してきました。まだ開始していない場合は GKE で Cloud Logging の使用を開始して、Google のメーリング リストに基づいたディスカッションにぜひご参加ください。

- By Google Cloud ソリューション アーキテクト Charles Baer、ソリューション アーキテクト Xiang Shen