5.9. コンプライアンス Operator のトラブルシューティング

このセクションでは、コンプライアンス Operator のトラブルシューティングの方法について説明します。この情報は、問題を診断したり、バグレポートに情報を提供したりする際に役立ちます。一般的なヒントには、以下が含まれます。

  • コンプライアンス Operator は、重要なことが発生すると Kubernetes イベントを生成します。コマンドを使用して、クラスター内のすべてのイベントを表示できます。

     $ oc get events -n openshift-compliance

    または、コマンドを使用してスキャンなどのオブジェクトのイベントを表示します。

    $ oc describe compliancescan/<scan_name>
  • コンプライアンス Operator は複数のコントローラーで構成されており、API オブジェクトごとに約 1 つのコントローラーで構成されます。問題のある API オブジェクトに対応するコントローラーのみをフィルターすることが役に立つ場合があります。ComplianceRemediation を適用できない場合、remediationctrl コントローラーのメッセージを表示します。jq で解析することにより、単一のコントローラーからのメッセージをフィルターできます。

    $ oc logs compliance-operator-775d7bddbd-gj58f | jq -c 'select(.logger == "profilebundlectrl")'
  • タイムスタンプについては、UTC の UNIX エポックからの経過時間で秒単位でログに記録されます。人間が判読可能な日付に変換するには、date -d @timestamp --utc を使用します。以下は例になります。

    $ date -d @1596184628.955853 --utc
  • 数多くのカスタムリソースで、最も重要な ComplianceSuite および ScanSettingdebug オプションを設定できます。このオプションを有効にすると、OpenSCAP スキャナー Pod や他のヘルパー Pod の詳細度が上がります。
  • 単一ルールの合否が予期せずに出される場合、そのルールのみを使用して単一スキャンまたはスイートを実行し、対応する ComplianceCheckResult オブジェクトからルール ID を見つけ、それを Scan CR の rule 属性として使用することが役に立つ場合があります。次に、debug オプションが有効になると、スキャナー Pod の scanner コンテナーログに未加工の OpenSCAP ログが表示されます。

5.9.1. スキャンの仕組み

以下のセクションでは、コンプライアンス Operator スキャンのコンポーネントおよびステージについて説明します。

5.9.1.1. コンプライアンスのソース

コンプライアンスコンテンツは、ProfileBundle オブジェクトから生成される Profile オブジェクトに保存されます。コンプライアンス Operator は、ProfileBundle をクラスター用とクラスターノード用に作成します。

$ oc get profilebundle.compliance
$ oc get profile.compliance

ProfileBundle オブジェクトは、 Bundle の名前でラベルが付けられたデプロイメントで処理されます。Bundle で問題のトラブルシューティングを行うには、デプロイメントを見つけ、デプロイメントで Pod のログを表示できます。

$ oc logs -lprofile-bundle=ocp4 -c profileparser
$ oc get deployments,pods -lprofile-bundle=ocp4
$ oc logs pods/<pod-name>
$ oc describe pod/<pod-name> -c profileparser

5.9.1.2. ScanSetting および ScanSettingBinding のライフサイクルおよびデバッグ

有効なコンプライアンスコンテンツソースを使用して、高レベルの ScanSetting および ScanSettingBinding オブジェクトを、ComplianceSuite および ComplianceScan オブジェクトを生成するために使用できます。

apiVersion: compliance.openshift.io/v1alpha1
kind: ScanSetting
metadata:
  name: my-companys-constraints
debug: true
# For each role, a separate scan will be created pointing
# to a node-role specified in roles
roles:
  - worker
---
apiVersion: compliance.openshift.io/v1alpha1
kind: ScanSettingBinding
metadata:
  name: my-companys-compliance-requirements
profiles:
  # Node checks
  - name: rhcos4-e8
    kind: Profile
    apiGroup: compliance.openshift.io/v1alpha1
  # Cluster checks
  - name: ocp4-e8
    kind: Profile
    apiGroup: compliance.openshift.io/v1alpha1
settingsRef:
  name: my-companys-constraints
  kind: ScanSetting
  apiGroup: compliance.openshift.io/v1alpha1

ScanSetting および ScanSettingBinding オブジェクトはどちらも、 logger=scansettingbindingctrl のタグの付けられた同じコントローラーで処理されます。これらのオブジェクトにはステータスがありません。問題はイベントの形式で通信されます。

Events:
  Type     Reason        Age    From                    Message
  ----     ------        ----   ----                    -------
  Normal   SuiteCreated  9m52s  scansettingbindingctrl  ComplianceSuite openshift-compliance/my-companys-compliance-requirements created

今回のリリースにより、ComplianceSuite オブジェクトが作成されました。フローは新規に作成された ComplianceSuite を継続して調整します。

5.9.1.3. ComplianceSuite カスタムリソースのライフサイクルおよびデバッグ

ComplianceSuite CR は ComplianceScan CR に関連したラッパーです。ComplianceSuite CR は、 logger=suitectrl のタグが付けられたコントローラーによって処理されます。このコントローラーは、スイートからのスキャンの作成を処理し、個別のスキャンのステータスを調整し、これを単一の Suite ステータスに集約します。スイートが定期的に実行するよう設定されている場合、suitectrl は、初回の実行後にスキャンをスイートで再実行する CronJob CR の作成にも対応します。

$ oc get cronjobs

出力例

NAME                                           SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
<cron_name>                                    0 1 * * *   False     0        <none>          151m

最も重要な問題について、イベントが生成されます。oc describe compliancesuites/<name> を使用してそれらを表示します。Suite オブジェクトには、 Status サブリソースも含まれており、これはこのスイートに属する Scan オブジェクトが Status サブリソースを更新すると更新されます。予想されるすべてのスキャンが作成されると、コントローラーがスキャンコントローラーに渡されます。

5.9.1.4. ComplianceScan カスタムリソースのライフサイクルおよびデバッグ

ComplianceScan CR は scanctrl コントローラーによって処理されます。これは、実際のスキャンとスキャン結果が作成される場所でもあります。それぞれのスキャンは複数のフェーズを経由します。

5.9.1.4.1. Pending (保留) フェーズ

このフェーズでは、スキャンがその正確性について検証されます。ストレージサイズなどの一部のパラメーターが無効な場合、スキャンは ERROR 結果と共に DONE に移行します。それ以外の場合は、Launching (起動) フェーズに進みます。

5.9.1.4.2. Launching (起動) フェーズ

このフェーズでは、いくつかの設定マップにスキャナー Pod の環境またはスキャナー Pod が評価するスクリプトが直接含まれます。設定マップを一覧表示します。

$ oc get cm -lcompliance.openshift.io/scan-name=rhcos4-e8-worker,complianceoperator.openshift.io/scan-script=

これらの設定マップはスキャナー Pod によって使用されます。スキャナーの動作を変更したり、スキャナーのデバッグレベルを変更したり、未加工の結果を出力したりする必要がある場合は、1 つの方法として設定マップを変更することができます。その後、未加工の ARF の結果を保存するために永続ボリューム要求 (PVC) がスキャンごとに作成されます。

$ oc get pvc -lcompliance.openshift.io/scan-name=<scan_name>

PVC はスキャンごとの ResultServer デプロイメントでマウントされます。ResultServer は、個別のスキャナー Pod が完全な ARF 結果をアップロードする単純な HTTP サーバーです。各サーバーは、異なるノードで実行できます。完全な ARF の結果のサイズは非常に大きくなる可能性があり、複数のノードから同時にマウントできるボリュームを作成することができると想定することはできません。スキャンが終了した後に、ResultServer デプロイメントはスケールダウンされます。未加工の結果のある PVC は別のカスタム Pod からマウントでき、結果はフェッチしたり、検査したりできます。スキャナー Pod と ResultServer 間のトラフィックは相互 TLS プロトコルで保護されます。

最後に、スキャナー Pod はこのフェーズで起動します。Platform スキャンインスタンスの 1 つのスキャナー Pod と、node スキャンインスタンスの一致するノードごとに 1 つのスキャナー Pod です。ノードごとの Pod にはノード名のラベルが付けられます。それぞれの Pod には、常に ComplianceScan という名前のラベルが付けられます。

$ oc get pods -lcompliance.openshift.io/scan-name=rhcos4-e8-worker,workload=scanner --show-labels

出力例

NAME                                                              READY   STATUS      RESTARTS   AGE   LABELS
rhcos4-e8-worker-ip-10-0-169-90.eu-north-1.compute.internal-pod   0/2     Completed   0          39m   compliance.openshift.io/scan-name=rhcos4-e8-worker,targetNode=ip-10-0-169-90.eu-north-1.compute.internal,workload=scanner
At this point, the scan proceeds to the Running phase.

5.9.1.4.3. Running (実行) フェーズ

実行フェーズは、スキャナー Pod の完了後に開始します。以下の用語およびプロセスは実行フェーズで使用されます。

  • init container: content-container という 1 つの init コンテナーがあります。これは、contentImage コンテナーを実行し、contentFile を、この Pod の他のコンテナーで共有される /content ディレクトリーにコピーします。
  • scanner: このコンテナーはスキャンを実行します。ノードのスキャンの場合には、コンテナーはノードファイルシステムを /host としてマウントし、init コンテナーによって配信されるコンテンツをマウントします。また、コンテナーは Launching (起動) フェーズで作成される entrypoint ConfigMap をマウントし、これを実行します。エントリーポイント ConfigMap のデフォルトスクリプトは OpenSCAP を実行し、結果ファイルを Pod のコンテナー間で共有される /results ディレクトリーに保存します。この Pod のログを表示して、OpenSCAP スキャナーがチェックした内容を判別できます。より詳細な出力は、debug フラグを使用して表示できます。
  • logcollector: logcollector コンテナーは、スキャナーコンテナーが終了するまで待機します。その後、これは ConfigMap として完全な ARF 結果を ResultServer にアップロードし、スキャン結果および OpenSCAP 結果コードと共に XCCDF 結果を個別にアップロードします。これらの結果の設定マップには、スキャン名 (compliance.openshift.io/scan-name=<scan_name>) のラベルが付けられます。

    $ oc describe cm/rhcos4-e8-worker-ip-10-0-169-90.eu-north-1.compute.internal-pod

    出力例

          Name:         rhcos4-e8-worker-ip-10-0-169-90.eu-north-1.compute.internal-pod
          Namespace:    openshift-compliance
          Labels:       compliance.openshift.io/scan-name-scan=rhcos4-e8-worker
                        complianceoperator.openshift.io/scan-result=
          Annotations:  compliance-remediations/processed:
                        compliance.openshift.io/scan-error-msg:
                        compliance.openshift.io/scan-result: NON-COMPLIANT
                        OpenSCAP-scan-result/node: ip-10-0-169-90.eu-north-1.compute.internal
    
          Data
          ====
          exit-code:
          ----
          2
          results:
          ----
          <?xml version="1.0" encoding="UTF-8"?>
          ...

Platform スキャンのスキャナー Pod も同様ですが、以下の点で異なります。

  • api-resource-collector という追加の init コンテナーがあります。これは content-container init、コンテナーで提供される OpenSCAP コンテンツを読み取り、コンテンツで確認する必要のある API リソースを判別し、それらの API リソースを scanner コンテナーが読み取りを行う共有ディレクトリーに保存します。
  • scanner コンテナーは、ホストファイルシステムをマウントする必要はありません。

スキャナー Pod が実行されると、スキャンは Aggregating (集計) フェーズに移行します。

5.9.1.4.4. Aggregating (集計) フェーズ

Aggregating (集計) フェーズでは、スキャンコントローラーがアグリゲーター Pod と呼ばれる別の Pod を起動します。その目的は、結果の ConfigMap オブジェクトを取り、結果を読み取り、それぞれのチェックの結果について対応する Kubernetes オブジェクトを作成することにあります。チェックの失敗を自動的に修復できる場合は、 ComplianceRemediation オブジェクトが作成されます。チェックと修復についての人間が判読できるメタデータを提供するために、アグリゲーター Pod は init コンテナーを使用して OpenSCAP コンテンツもマウントします。

設定マップがアグリゲーター Pod によって処理される場合、これには compliance-remediations/processed ラベルでラベルが付けられます。このフェーズの結果は ComplianceCheckResult オブジェクトになります。

$ oc get compliancecheckresults -lcompliance.openshift.io/scan-name=rhcos4-e8-worker

出力例

NAME                                                       STATUS   SEVERITY
rhcos4-e8-worker-accounts-no-uid-except-zero               PASS     high
rhcos4-e8-worker-audit-rules-dac-modification-chmod        FAIL     medium

ComplianceRemediation オブジェクト:

$ oc get complianceremediations -lcompliance.openshift.io/scan-name=rhcos4-e8-worker

出力例

NAME                                                       STATE
rhcos4-e8-worker-audit-rules-dac-modification-chmod        NotApplied
rhcos4-e8-worker-audit-rules-dac-modification-chown        NotApplied
rhcos4-e8-worker-audit-rules-execution-chcon               NotApplied
rhcos4-e8-worker-audit-rules-execution-restorecon          NotApplied
rhcos4-e8-worker-audit-rules-execution-semanage            NotApplied
rhcos4-e8-worker-audit-rules-execution-setfiles            NotApplied

これらの CR が作成されると、アグリゲーター Pod は終了し、スキャンは Done (終了) フェーズに移行します。

5.9.1.4.5. Done (終了) フェーズ

最終のスキャンフェーズでは、必要な場合にスキャンリソースがクリーンアップされ、ResultServer デプロイメントは (スキャンが 1 回限りの場合) スケールダウンされるか、または (スキャンが継続される場合) 削除されます。次回のスキャンインスタンスではデプロイメントを再作成します。

また、Done (終了) フェーズでは、スキャンにアノテーションを付けてスキャンの再実行をトリガーすることもできます。

$ oc annotate compliancescans/<scan_name> compliance.openshift.io/rescan=

スキャンが Done (終了) フェーズに到達した後に、修復が autoApplyRemediations: true を指定して自動的に適用されるように設定されていない限り、自動的に実行されることは何もありません。OpenShift Container Platform 管理者は、修復を確認し、必要に応じてそれらを適用できるようになりました。修復が自動的に適用されるように設定されている場合、ComplianceSuite コントローラーが Done (終了) フェーズで引き継ぎ、マシン設定プールをスキャンがマップされるポイントで一時停止し、すべての修復を 1 回で適用します。修復が適用されると、ComplianceRemediation コントローラーが引き継ぎます。

5.9.1.5. ComplianceRemediation コントローラーのライフサイクルおよびデバッグ

サンプルスキャンは特定の結果を報告します。修復の 1 つを有効にするには、apply 属性を true に切り替えます。

$ oc patch complianceremediations/rhcos4-e8-worker-audit-rules-dac-modification-chmod --patch '{"spec":{"apply":true}}' --type=merge

ComplianceRemediation コントローラー (logger=remediationctrl) は変更されたオブジェクトを調整します。調整の結果として、調整される修復オブジェクトのステータスが変更されますが、適用されたすべての修復が含まれる、レンダリングされるスイートごとの MachineConfig オブジェクトも変更されます。

MachineConfig オブジェトは常に 75- で開始し、スキャンとスィートに基づいて名前が付けられます。

$ oc get mc | grep 75-

出力例

75-rhcos4-e8-worker-my-companys-compliance-requirements                                                2.2.0             2m46s

mc を現在構成している修復はマシン設定のアノテーションに一覧表示されます。

$ oc describe mc/75-rhcos4-e8-worker-my-companys-compliance-requirements

出力例

Name:         75-rhcos4-e8-worker-my-companys-compliance-requirements
Labels:       machineconfiguration.openshift.io/role=worker
Annotations:  remediation/rhcos4-e8-worker-audit-rules-dac-modification-chmod:

ComplianceRemediation コントローラーのアルゴリズムは以下のようになります。

  • 現在適用されているすべての修復は初期の修復セットに読み込まれます。
  • 調整された修復が適用されることが予想される場合、それはセットに追加されます。
  • MachineConfig オブジェクトはセットからレンダリングされ、セット内の修復の名前でアノテーションが付けられます。セットが空の場合 (最後の修復は適用されない)、レンダリングされる MachineConfig オブジェクトは削除されます。
  • レンダリングされたマシン設定がクラスターにすでに適用されているものとは異なる場合にのみ、適用される MC は更新されます (または作成されるか、削除されます)。
  • MachineConfig オブジェクトの作成または変更により、machineconfiguration.openshift.io/role ラベルに一致するノードの再起動がトリガーされます。詳細は、Machine Config Operator のドキュメントを参照してください。

修復ループは、レンダリングされたマシン設定が更新され (必要な場合)、調整された修復オブジェクトのステータスが更新されると終了します。この場合、修復を適用すると再起動がトリガーされます。再起動後、スキャンにアノテーションを付け、再度実行します。

$ oc annotate compliancescans/<scan_name> compliance.openshift.io/rescan=

スキャンが実行され、終了します。渡される修復の有無を確認します。

$ oc get compliancecheckresults/rhcos4-e8-worker-audit-rules-dac-modification-chmod

出力例

NAME                                                  STATUS   SEVERITY
rhcos4-e8-worker-audit-rules-dac-modification-chmod   PASS     medium

5.9.1.6. 役に立つラベル

コンプライアンス Operator によって起動する各 Pod には、それが属するスキャンおよびその機能にとくに関連するラベルが付けられます。スキャン ID には compliance.openshift.io/scan-name ラベルが付けられます。ワークロード ID には、workload ラベルでラベルが付けられます。

コンプライアンス Operator は以下のワークロードをスケジュールします。

  • scanner: コンプライアンススキャンを実行します。
  • resultserver: コンプライアンススキャンの未加工の結果を保存します。
  • aggregator: 結果を集計し、不整合を検出し、結果オブジェクト (チェックの結果と修復) を出力します。
  • suitererunner: 再実行するスイートにタグを付けます (スケジュールが設定されている場合)。
  • profileparser: データストリームを解析し、適切なプロファイル、ルールおよび変数を作成します。

デバッグおよびログが特定のワークロードに必要な場合は、以下を実行します。

$ oc logs -l workload=<workload_name> -c <container_name>