はじめに
Red Hat Advent Calendar 2023 の 12月14日の記事です。OpenShift Cluster Logging で Loki が利用できるようになってからしばらく時間が経ち、段々と利用されつつあるのではないかと思います。 本記事では、OpenShift Cluster Logging (Loki) を OpenShift Web Console からではなく、あえて CLI 経由でアクセスしてみます。
Loki について
Loki は Grafana Loki という名称で、Prometheus からインスパイアされたスケーラビリティ、可用性、マルチテナントに対応したログ収集システムです。 他のログシステムと異なり、ログ自身にはインデックスを持たず、メタデータのみをインデックス化して管理します。 ログはメタデータとしてラベルを持つことで管理されます。同じラベルをもつログのセットを Log Stream と呼びます。
ログデータは圧縮され、オブジェクトストレージに格納されるためログデータを効率よく保持できる仕組みとなっています。
クエリの種類
Loki の検索は LogQL を利用します。OpenShift の Web Console から呼び出すときに使います。格納されたログから特定のメッセージなどを絞り込んで見る際に利用します。LogQL は 2つの種類があり、それぞれ Log クエリと Metric クエリに別れます。
Log クエリ
ログデータを返却します。ログメッセージの絞り込みなどで目的のエラー情報などを検索するときに活躍します
Metric クエリ
Log クエリの拡張版でログの検索結果をベースに演算することが目的です。
OpenShift Logging としての構築
まずは製品ドキュメントに従いながら、Loki を利用した Logging を構築していきます。
まずは Operator の導入から。Operator は Loki Operator と OpenShift Cluster Logging Operator の 2 つが必要となります。それぞれをインストールします。
Operator の導入
Loki Operator をインストールする Namespace の作成
$ cat << EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-operators-redhat annotations: openshift.io/node-selector: "" labels: openshift.io/cluster-monitoring: "true" EOF
Cluster Logging Operator をインストールする Namespace の作成
$ cat <<EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-logging annotations: openshift.io/node-selector: "" labels: openshift.io/cluster-monitoring: "true" EOF
OpenShift Cluster Logging 用の OperatorGroup と Subscription を作成する
OperatorGroup の作成
$ cat <<EOF | oc create -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: cluster-logging namespace: openshift-logging spec: targetNamespaces: - openshift-logging EOF
続いて、Subscription を作成します。
$ cat <<EOF | oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: cluster-logging namespace: openshift-logging spec: spec: channel: stable-5.8 installPlanApproval: Automatic name: cluster-logging source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: cluster-logging.v5.8.0 EOF
次に、Loki Operator をインストールします。Cluster Logging Operator 同様に Subscription を作成します。
$ cat << EOF | oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: loki-operator namespace: openshift-operators-redhat spec: channel: stable-5.8 installPlanApproval: Automatic name: loki-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF
Loki のデプロイ
Loki は Object Storage を必要とします。今回の構築環境は AWS を利用しているので、適当に AWS S3 のバケットを作成して利用します。 Object Storage へのアクセス情報は Secret を利用して指定するため、接続情報を以下のように用意します。
$ cat <<EOF | oc create -f - apiVersion: v1 kind: Secret metadata: name: logging-loki-s3 namespace: openshift-logging stringData: access_key_id: <ACCESS KEY> access_key_secret: <ACCESS_KEY_SECRET> bucketnames: <BUCKET_NAME> endpoint: https://s3.ap-southeast-2.amazonaws.com region: ap-southeast-2 EOF
次に、LokiStack Custom Resource を作成します。今回作成する LokiStack のサイズは 1x.small
とします。
$ cat <<EOF | oc create -f - apiVersion: loki.grafana.com/v1 kind: LokiStack metadata: name: logging-loki # 1 namespace: openshift-logging spec: size: 1x.small #2 storage: schemas: - version: v12 effectiveDate: '2022-06-01' secret: name: logging-loki-s3 #3 type: s3 #4 storageClassName: gp3-csi #5 tenants: mode: openshift-logging EOF
パラメタの簡単な説明
- logging-loki という名前を使用してください。
- Loki の展開サイズを選択してください。
- ログストレージに使用するシークレットを指定してください。
- 対応するストレージタイプを指定してください。
- 一時的なストレージに既存のストレージクラスの名前を入力してください。最適なパフォーマンスを得るためには、ブロックストレージを割り当てるストレージクラスを指定してください。クラスタで利用可能なストレージクラスは、oc get storageclasses コマンドを使用してリストアップできます。
Cluster Logging として利用する
デプロイした Loki を OpenShift Cluster Logging として利用します。
$ cat << EOF | oc create -f - apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: name: instance namespace: openshift-logging spec: logStore: type: lokistack lokistack: name: logging-loki collection: type: vector EOF
簡単なアクセス確認
Web Console からのアクセス
ここまでで、Loki が利用できるようになっているはずなので、Web Console からも簡単に確認してみます。 Web Console の Administrator の画面から、 Observe > Logs を選択すると画面が表示されます。
CLI からのアクセス
ここで本題です。今回 CLI アクセスを試すきっかけとなったのは、実は OpenShift Web Console からはまだ Metric クエリを実行することができません。そのため、Metric クエリを実行するにはどうしても CLI 経由での呼び出しが必要となります。
アクセス方法の確認
Loki へのアクセスは Route 経由で行います。
$ oc get route -n openshift-logging NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD logging-loki logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com logging-loki-gateway-http public reencrypt None
呼び出し方を確認するため、試しに Route にアクセスしてみます。Loki は OpenShift による認証を利用しているため、OpenShift のユーザーのトークンを利用してアクセスしてみます。
$ curl -k -s -H 'Authorization: Bearer <TOKEN>' https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com { "paths": [ "/api/logs/v1/{tenant}/*" ] }
{tenant}
を指定する必要がありそうです。テナントとは何でしょうか。実は、OpenShift Cluster Logging では Loki のマルチテナント機能を利用して、infrastracture ログ、application ログ、audit ログを分けて格納しています。
そのため、ここでいう {tenant}
は infrastructure
、application
、audit
となります。
Loki の API のパスは製品ドキュメントに記載があり以下のようになっています。パスの最後にある query_range
は呼び出すAPIにより代わりますが、今回は Metric クエリを呼び出すのでこちらを利用します。
GET /loki/api/v1/query_range
これを合わせると次のようなURLを呼び出すことで、curl
でアクセスできることがわかります。
https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/{tenant}/loki/api/v1/query_range
Metric クエリを呼び出してみる
LogQL は空白やシングルクォートなども含むため、URLエンコードした形で指定します。curl コマンドではパラメタ指定によりURLエンコードを行うことはできますが、予めエンコードしておきます。
今回テストするのは次の Metric クエリです。 Namespace 毎に log_type=infrastructure のログ数をカウントするというものです。
sum by (kubernetes_namespace_name) (count_over_time({ log_type="infrastructure" } [5m]) )
curl コマンドにすると以下のような感じです。
$ curl -G -k -s -H 'Authorization: Bearer sha256~_hJqP4Ksy5Opcs1_37s2fC2_XFXWigO6iXJEDBpM_nA' https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/infrastructure/loki/api/v1/query_range --data 'query=sum%20by%20(kubernetes_namespace_name)%20(count_over_time(%7B%20log_type%3D%22infrastructure%22%20%7D%20%5B5m%5D)%20)' --data-urlencode step=2m --data-urlencode start=1702467769 --data-urlencode end=1702471369
呼び出し結果
{ "status": "success", "data": { "resultType": "matrix", "result": [ { "metric": { "kubernetes_namespace_name": "openshift-apiserver" }, "values": [ [ 1702469160, "1" ], [ 1702469280, "1" ], [ 1702469400, "5" ], [ 1702469520, "4" ], [ 1702469640, "4" ], [ ...
うまく取得できたようです。
LogCLI
次に、Loki の CLI LogCLI でのアクセスを試します。 コマンドは、以下のページを参考に予め準備してください。
環境変数で接続先と認証情報を設定します。呼び出したいテナント毎に呼び出し先は変えてください。
$ export LOKI_BEARER_TOKEN="<TOKEN>" $ export LOKI_ADDR=https://logging-loki-openshift-logging.apps.samplecluster.sandboxABCDE.opentlc.com/api/logs/v1/infrastructure
コマンドを実行します。OpenShift の証明書は自己署名証明書を利用しているため、TLSのチェックはスキップするようにします。
$ logcli query --tls-skip-verify 'sum by (kubernetes_namespace_name) (count_over_time({ log_type="infrastructure" } [5m]) )'
出力結果が取得できました。 curl で取得したときと異なり、result が抽出されてます。
[ { "metric": { "kubernetes_namespace_name": "openshift-apiserver" }, "values": [ [ 1702470154, "4" ], [ 1702470168, "4" ], [ 1702470182, "4" ], [ 1702470196, "4" ], [ 1702470210, ...
おわりに
今回は、CLI を用いて Loki へのアクセスをしてみました。これにより現在は Web Console から利用できない Metric クエリの結果を取得できることが試せました。 まだ発展途上のコンポーネントではありますが、こういった形でログの解析ができるようになっていくとログを利用した運用や調査などが進みそうです。