OpenShift Logging の Loki にコマンドでアクセスしてみる

はじめに

Red Hat Advent Calendar 2023 の 12月14日の記事です。OpenShift Cluster Logging で Loki が利用できるようになってからしばらく時間が経ち、段々と利用されつつあるのではないかと思います。 本記事では、OpenShift Cluster Logging (Loki) を OpenShift Web Console からではなく、あえて CLI 経由でアクセスしてみます。

Loki について

grafana.com

Loki は Grafana Loki という名称で、Prometheus からインスパイアされたスケーラビリティ、可用性、マルチテナントに対応したログ収集システムです。 他のログシステムと異なり、ログ自身にはインデックスを持たず、メタデータのみをインデックス化して管理します。 ログはメタデータとしてラベルを持つことで管理されます。同じラベルをもつログのセットを Log Stream と呼びます。

ログデータは圧縮され、オブジェクトストレージに格納されるためログデータを効率よく保持できる仕組みとなっています。

クエリの種類

Loki の検索は LogQL を利用します。OpenShift の Web Console から呼び出すときに使います。格納されたログから特定のメッセージなどを絞り込んで見る際に利用します。LogQL は 2つの種類があり、それぞれ Log クエリと Metric クエリに別れます。

Log クエリ

ログデータを返却します。ログメッセージの絞り込みなどで目的のエラー情報などを検索するときに活躍します

grafana.com

Metric クエリ

Log クエリの拡張版でログの検索結果をベースに演算することが目的です。

grafana.com

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

パラメタの簡単な説明

  1. logging-loki という名前を使用してください。
  2. Loki の展開サイズを選択してください。
  3. ログストレージに使用するシークレットを指定してください。
  4. 対応するストレージタイプを指定してください。
  5. 一時的なストレージに既存のストレージクラスの名前を入力してください。最適なパフォーマンスを得るためには、ブロックストレージを割り当てるストレージクラスを指定してください。クラスタで利用可能なストレージクラスは、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

docs.openshift.com

簡単なアクセス確認

Web Console からのアクセス

ここまでで、Loki が利用できるようになっているはずなので、Web Console からも簡単に確認してみます。 Web Console の Administrator の画面から、 Observe > Logs を選択すると画面が表示されます。

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}infrastructureapplicationaudit となります。

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

grafana.com

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 でのアクセスを試します。 コマンドは、以下のページを参考に予め準備してください。

grafana.com

環境変数で接続先と認証情報を設定します。呼び出したいテナント毎に呼び出し先は変えてください。

$ 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 クエリの結果を取得できることが試せました。 まだ発展途上のコンポーネントではありますが、こういった形でログの解析ができるようになっていくとログを利用した運用や調査などが進みそうです。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。