Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

第26章 Node Problem Detector

26.1. 概要

Node Problem Detector (ノード問題検出機能) は特定の問題を検出し、それらの問題を API サーバーに報告することで、ノードの正常性をモニターします。Node Problem Detector は、各ノードで daemonSet として実行されます。

重要

Node Problem Detector はテクノロジープレビュー機能です。テクノロジープレビュー機能は Red Hat の実稼働環境でのサービスレベルアグリーメント (SLA) ではサポートされていないため、Red Hat では実稼働環境での使用を推奨していません。これらの機能は、近々発表予定の製品機能をリリースに先駆けてご提供することにより、お客様は機能性をテストし、開発プロセス中にフィードバックをお寄せいただくことができます。

Red Hat のテクノロジープレビュー機能のサポートについての詳細は、https://access.redhat.com/support/offerings/techpreview/ を参照してください。

Node Problem Detector はシステムログを読み取り、特定のエントリーの有無を監視し、コントロールプレーンにそれらの問題を表示します。これらの問題は、oc get node および oc get event などの OpenShift Container Platform コマンドを使用して表示できます。これらの問題については、適宜修正するようアクションを実行するか、または OpenShift Container Platform ログモニタリングなどの選択可能なツールを使用してメッセージをキャプチャーすることができます。検出される問題は以下のいずれかのカテゴリーに分類できます。

  • NodeCondition: ノードを Pod に対して利用不可にする永続的な問題です。ノードの状態は、ホストが再起動されるまでクリアされません。
  • Event: ノードに制限的な影響を与える一時的な問題で、情報を提供します。

Node Problem Detector は以下を検出できます。

  • コンテナーランタイムの問題:

    • 反応しないランタイムデーモン
  • ハードウェアの問題:

    • 正常でない CPU
    • 正常でないメモリー
    • 正常でないディスク
  • カーネルの問題:

    • カーネルのデッドロック状態
    • 破損したファイルシステム
    • 反応しないランタイムデーモン
  • インフラストラクチャーデーモンの問題:

    • NTP サービスの停止

26.2. Node Problem Detector の出力サンプル

以下の例では、特定のノードでカーネルのデッドロックを監視する Node Problem Detector の出力を示しています。コマンドでは oc get node を使用し、ログで KernelDeadlock エントリーについてフィルターし、特定のノードを監視します。

# oc get node <node> -o yaml | grep -B5 KernelDeadlock

Node Problem Detector の出力サンプル (問題がない場合)

message: kernel has no deadlock
reason: KernelHasNoDeadlock
status: false
type: KernelDeadLock

KernelDeadLock 状態の出力サンプル

message: task docker:1234 blocked for more than 120 seconds
reason: DockerHung
status: true
type: KernelDeadLock

この例は、ノードでイベントの有無を監視する Node Problem Detector からの出力を示しています。以下のコマンドでは、default プロジェクトに対して oc get event を使用し、Node Problem Detector 設定マップkernel-monitor.json セクションに一覧表示されているイベントの有無を監視します。

# oc get event -n default --field-selector=source=kernel-monitor --watch

ノードのイベントを表示する出力サンプル

LAST SEEN                       FIRST SEEN                    COUNT NAME     KIND  SUBOBJECT TYPE    REASON      SOURCE                   MESSAGE
2018-06-27 09:08:27 -0400 EDT   2018-06-27 09:08:27 -0400 EDT 1     my-node1 node            Warning TaskHunk    kernel-monitor.my-node1  docker:1234 blocked for more than 300 seconds
2018-06-27 09:08:27 -0400 EDT   2018-06-27 09:08:27 -0400 EDT 3     my-node2 node            Warning KernelOops  kernel-monitor.my-node2  BUG: unable to handle kernel NULL pointer deference at nowhere
2018-06-27 09:08:27 -0400 EDT   2018-06-27 09:08:27 -0400 EDT 1     my-node1 node            Warning KernelOops  kernel-monitor.my-node2  divide error 0000 [#0] SMP

注記

Node Problem Detector はリソースを消費するため、Node Problem Detector を使用する場合は、クラスターのパフォーマンスのバランスを保つために十分なノードがあることを確認してください。

26.3. Node Problem Detector のインストール

openshift_node_problem_detector_install/etc/ansible/hosts インベントリーファイルで true に設定される場合、インストールではデフォルトで Node Problem Detector の Deamonset を作成し、openshift-node-problem-detector という検出プログラムのプロジェクトを作成します。

注記

Node Problem Detector はテクノロジープレビューとして提供されているため、openshift_node_problem_detector_install はデフォルトで false に設定されています。Node Problem Detector のインストール時には、パラメーターを true に手動で設定する必要があります。

Node Problem Detector がインストールされていない場合、Playbook ディレクトリーに切り替え、openshift-node-problem-detector/config.yml Playbook を実行して Node Problem Detector をインストールします。

$ cd /usr/share/ansible/openshift-ansible
$ ansible-playbook playbooks/openshift-node-problem-detector/config.yml

26.4. 検出された条件のカスタマイズ

Node Problem Detector 設定マップを編集し、Node Problem Detector をログの文字列を監視するように設定できます。

Node Problem Detector 設定マップのサンプル

apiVersion: v1
kind: ConfigMap
metadata:
  name: node-problem-detector
data:
  docker-monitor.json: |  1
    {
        "plugin": "journald", 2
        "pluginConfig": {
                "source": "docker"
        },
        "logPath": "/host/log/journal", 3
        "lookback": "5m",
        "bufferSize": 10,
        "source": "docker-monitor",
        "conditions": [],
        "rules": [              4
                {
                        "type": "temporary", 5
                        "reason": "CorruptDockerImage", 6
                        "pattern": "Error trying v2 registry: failed to register layer: rename /var/lib/docker/image/(.+) /var/lib/docker/image/(.+): directory not empty.*" 7
                }
        ]
    }
  kernel-monitor.json: |  8
    {
        "plugin": "journald", 9
        "pluginConfig": {
                "source": "kernel"
        },
        "logPath": "/host/log/journal", 10
        "lookback": "5m",
        "bufferSize": 10,
        "source": "kernel-monitor",
        "conditions": [                 11
                {
                        "type": "KernelDeadlock", 12
                        "reason": "KernelHasNoDeadlock", 13
                        "message": "kernel has no deadlock"  14
                }
        ],
        "rules": [
                {
                        "type": "temporary",
                        "reason": "OOMKilling",
                        "pattern": "Kill process \\d+ (.+) score \\d+ or sacrifice child\\nKilled process \\d+ (.+) total-vm:\\d+kB, anon-rss:\\d+kB, file-rss:\\d+kB"
                },
                {
                        "type": "temporary",
                        "reason": "TaskHung",
                        "pattern": "task \\S+:\\w+ blocked for more than \\w+ seconds\\."
                },
                {
                        "type": "temporary",
                        "reason": "UnregisterNetDevice",
                        "pattern": "unregister_netdevice: waiting for \\w+ to become free. Usage count = \\d+"
                },
                {
                        "type": "temporary",
                        "reason": "KernelOops",
                        "pattern": "BUG: unable to handle kernel NULL pointer dereference at .*"
                },
                {
                        "type": "temporary",
                        "reason": "KernelOops",
                        "pattern": "divide error: 0000 \\[#\\d+\\] SMP"
                },
                {
                        "type": "permanent",
                        "condition": "KernelDeadlock",
                        "reason": "AUFSUmountHung",
                        "pattern": "task umount\\.aufs:\\w+ blocked for more than \\w+ seconds\\."
                },
                {
                        "type": "permanent",
                        "condition": "KernelDeadlock",
                        "reason": "DockerHung",
                        "pattern": "task docker:\\w+ blocked for more than \\w+ seconds\\."
                }
        ]
    }

1
コンテナーイメージに適用されるルールおよび条件。
2 9
カンマ区切りの一覧のモニタリングサービス
3 10
モニタリングサービスログのパス。
4 11
モニターされるイベントの一覧。
5 12
エラーがイベント (temporary) または NodeCondition (permanent) であることを示すラベル。
6 13
エラーを記述するテキストメッセージ。
7 14
Node Problem Detector が監視するエラーメッセージ。
8
カーネルに適用されるルールおよび条件。

Node Problem Detector を設定するには、問題の状態およびイベントを追加するか、またはこれらを削除します。

  1. テキストエディターで Node Problem Detector 設定マップを編集します。

    $ oc edit configmap -n openshift-node-problem-detector node-problem-detector
  2. ノードの状態またはイベントを必要に応じて削除、追加、または編集します。

    {
           "type": <`temporary` or `permanent`>,
           "reason": <free-form text describing the error>,
           "pattern": <log message to watch for>
    },

    例:

    {
           "type": "temporary",
           "reason": "UnregisterNetDevice",
           "pattern": "unregister_netdevice: waiting for \\w+ to become free. Usage count = \\d+"
    },
  3. 変更を適用するために実行中の Pod を再起動します。Pod を再起動するために、すべての既存 Pod を削除できます。

    # oc delete pods -n openshift-node-problem-detector -l name=node-problem-detector
  4. Node Problem Detector 出力を標準出力 (stdout) および標準エラー出力 (stderr) に表示するには、以下を Node Problem Detector の DaemonSet に追加します。

    spec:
      template:
        spec:
          containers:
          - name: node-problem-detector
            command:
            - node-problem-detector
            - --alsologtostderr=true 1
            - --log_dir="/tmp" 2
            - --system-log-monitors=/etc/npd/kernel-monitor.json,/etc/npd/docker-monitor.json 3
    1
    出力を標準出力 (stdout) に送信します。
    2
    エラーログへのパス。
    3
    プラグイン設定ファイルへのカンマ区切りのパス。

26.5. Node Problem Detector が実行中であることの確認

Node Problem Detector が有効であることを確認するには、以下を実行します。

  • 以下のコマンドを実行し、Problem Node Detector Pod の名前を取得します。

    # oc get pods -n openshift-node-problem-detector
    
    NAME                          READY     STATUS    RESTARTS   AGE
    node-problem-detector-8z8r8   1/1       Running   0          1h
    node-problem-detector-nggjv   1/1       Running   0          1h
  • 以下のコマンドを実行し、Problem Node Detector Pod のログ情報を表示します。

    # oc logs -n openshift-node-problem-detector <pod_name>

    出力は以下のようになります。

    # oc logs -n openshift-node-problem-detector node-problem-detector-c6kng
    I0416 23:22:00.641354       1 log_monitor.go:63] Finish parsing log monitor config file: {WatcherConfig:{Plugin:journald PluginConfig:map[source:kernel] LogPath:/host/log/journal Lookback:5m} BufferSize:10 Source:kernel-monitor DefaultConditions:[{Type:KernelDeadlock Status:false Transition:0001-01-01 00:00:00 +0000 UTC Reason:KernelHasNoDeadlock Message:kernel has no deadlock}]
  • ノードのイベントをシミュレーションして Node Problem Detector をテストします。

    # echo "kernel: divide error: 0000 [#0] SMP." >> /dev/kmsg
  • ノードの状態をシミュレーションして Node Problem Detector をテストします。

    # echo "kernel: task docker:7 blocked for more than 300 seconds." >> /dev/kmsg

26.6. Node Problem Detector のアンインストール

Node Problem Detector をアンインストールするには、以下を実行します。

  1. Ansible インベントリーファイルに以下のオプションを追加します。

    [OSEv3:vars]
    openshift_node_problem_detector_state=absent
  2. Playbook ディレクトリーに切り替え、config.yml Ansible Playbook を実行します。

    $ cd /usr/share/ansible/openshift-ansible
    $ ansible-playbook playbooks/openshift-node-problem-detector/config.yml