×

本节介绍如何对合规性操作符进行故障排除。这些信息可用于诊断问题或在错误报告中提供信息。一些常规技巧

  • 合规性操作符在发生重要事件时会发出 Kubernetes 事件。您可以使用以下命令查看集群中的所有事件:

     $ oc get events -n openshift-compliance

    或者使用以下命令查看某个对象的事件(例如扫描):

    $ oc describe -n openshift-compliance compliancescan/cis-compliance
  • 合规性操作符由多个控制器组成,每个 API 对象大约对应一个控制器。仅过滤与出现问题的 API 对象对应的控制器可能很有用。如果无法应用 `ComplianceRemediation`,请查看 `remediationctrl` 控制器的消息。您可以使用 `jq` 解析来过滤单个控制器的消息:

    $ oc -n openshift-compliance logs compliance-operator-775d7bddbd-gj58f \
        | jq -c 'select(.logger == "profilebundlectrl")'
  • 时间戳以自 UNIX 纪元以来的秒数(UTC)记录。要将其转换为人类可读的日期,请使用 `date -d @timestamp --utc`,例如:

    $ date -d @1596184628.955853 --utc
  • 许多自定义资源(最重要的是 `ComplianceSuite` 和 `ScanSetting`)允许设置 `debug` 选项。启用此选项会增加 OpenSCAP 扫描程序 Pod 以及其他一些辅助 Pod 的详细程度。

  • 如果单个规则意外通过或失败,则运行仅包含该规则的单个扫描或套件可能会有所帮助,以从相应的 `ComplianceCheckResult` 对象中查找规则 ID 并将其用作 `Scan` CR 中的 `rule` 属性值。然后,结合启用的 `debug` 选项,扫描程序 Pod 中的 `scanner` 容器日志将显示原始 OpenSCAP 日志。

扫描剖析

以下各节概述了合规性操作符扫描的组件和阶段。

合规性来源

合规性内容存储在从 `ProfileBundle` 对象生成的 `Profile` 对象中。合规性操作符为集群创建 `ProfileBundle` 对象,为集群节点创建另一个对象。

$ oc get -n openshift-compliance profilebundle.compliance
$ oc get -n openshift-compliance profile.compliance

`ProfileBundle` 对象由标有 `Bundle` 名称的部署处理。要对 `Bundle` 问题进行故障排除,您可以找到部署并查看部署中 Pod 的日志:

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

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`。

ComplianceSuite 自定义资源的生命周期和调试

`ComplianceSuite` CR 是 `ComplianceScan` CR 的包装器。`ComplianceSuite` CR 由标记为 `logger=suitectrl` 的控制器处理。此控制器负责从套件中创建扫描、协调和将单个扫描状态聚合到单个套件状态。如果套件设置为定期执行,则 `suitectrl` 还负责创建一个 `CronJob` CR,该 CR 在初始运行完成后重新运行套件中的扫描。

$ oc get cronjobs
示例输出
NAME                                           SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
<cron_name>                                    0 1 * * *   False     0        <none>          151m

对于最重要的问题,会发出事件。可以使用oc describe compliancesuites/查看它们。当属于此套件的任何Scan对象的Status子资源更新时,Suite对象也会更新其Status子资源。创建所有预期的扫描后,控制权将传递给扫描控制器。

合规性扫描自定义资源生命周期和调试

ComplianceScan CR 由scanctrl控制器处理。这也是实际扫描发生和创建扫描结果的地方。每次扫描都经过几个阶段

待处理阶段

在此阶段会验证扫描的正确性。如果某些参数(如存储大小)无效,则扫描将转换为DONE状态并返回ERROR结果,否则将继续执行启动阶段。

启动阶段

在此阶段,将创建多个包含扫描程序 Pod 环境或扫描程序 Pod 将评估的脚本的 ConfigMap。列出 ConfigMap

$ oc -n openshift-compliance get cm \
-l compliance.openshift.io/scan-name=rhcos4-e8-worker,complianceoperator.openshift.io/scan-script=

这些 ConfigMap 将由扫描程序 Pod 使用。如果您需要修改扫描程序行为、更改扫描程序调试级别或打印原始结果,修改 ConfigMap 是可行的方法。之后,将为每个扫描创建持久卷声明 (PVC) 以存储原始 ARF 结果。

$ oc get pvc -n openshift-compliance -lcompliance.openshift.io/scan-name=rhcos4-e8-worker

PVC 由每个扫描的ResultServer部署挂载。ResultServer是一个简单的HTTP服务器,各个扫描程序Pod将完整的ARF结果上传到该服务器。每个服务器可以在不同的节点上运行。完整的ARF结果可能非常大,您不能假设可以创建可以在同一时间从多个节点挂载的卷。扫描完成后,ResultServer部署将缩减规模。可以从另一个自定义 Pod 挂载包含原始结果的 PVC,并可以获取或检查结果。扫描程序 Pod 和ResultServer之间的流量受互通 TLS 协议保护。

最后,在此阶段启动扫描程序 Pod;对于Platform扫描实例,一个扫描程序 Pod;对于node扫描实例,每个匹配节点一个扫描程序 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

+ 然后扫描进入运行阶段。

运行阶段

运行阶段将等待扫描程序 Pod 完成。运行阶段使用以下术语和流程

  • init 容器:有一个名为content-container的 init 容器。它运行contentImage容器并执行单个命令,该命令将contentFile复制到与此 Pod 中的其他容器共享的/content目录。

  • 扫描程序:此容器运行扫描。对于节点扫描,容器将节点文件系统安装为/host,并安装由 init 容器提供的 content。容器还安装在启动阶段创建的entrypoint ConfigMap并执行它。entrypoint ConfigMap中的默认脚本执行 OpenSCAP 并将结果文件存储在 Pod 容器之间共享的/results目录中。可以查看此 Pod 的日志以确定 OpenSCAP 扫描程序检查的内容。可以使用debug标志查看更详细的输出。

  • 日志收集器:日志收集器容器将等待扫描程序容器完成。然后,它将完整的 ARF 结果上传到ResultServer,并分别上传 XCCDF 结果以及扫描结果和 OpenSCAP 结果代码作为ConfigMap。这些结果 ConfigMap 用扫描名称标记(compliance.openshift.io/scan-name=rhcos4-e8-worker

    $ 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 完成后,扫描将继续进行聚合阶段。

聚合阶段

在聚合阶段,扫描控制器将生成另一个名为聚合器 Pod 的 Pod。其目的是获取结果ConfigMap对象,读取结果,并为每个检查结果创建相应的 Kubernetes 对象。如果可以自动修复检查失败,则会创建一个ComplianceRemediation对象。为了提供检查和修复的人类可读元数据,聚合器 Pod 还使用 init 容器安装 OpenSCAP 内容。

当聚合器 Pod 处理 ConfigMap 时,它将被标记为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 将退出,扫描将继续进行完成阶段。

完成阶段

在最终扫描阶段,如果需要,将清理扫描资源,并且ResultServer部署将缩减规模(如果扫描是一次性的)或删除(如果扫描是连续的);下一个扫描实例将再次重新创建部署。

也可以通过添加注释来触发完成阶段扫描的重新运行。

$ oc -n openshift-compliance \
annotate compliancescans/rhcos4-e8-worker compliance.openshift.io/rescan=

扫描到达完成阶段后,除非修复设置为使用autoApplyRemediations: true自动应用,否则不会自行发生其他任何事情。OpenShift Container Platform 管理员现在将审查修复并根据需要应用它们。如果修复设置为自动应用,则ComplianceSuite控制器将在完成阶段接管,暂停扫描映射到的机器配置池,并一次性应用所有修复。如果应用了修复,则ComplianceRemediation控制器将接管。

ComplianceRemediation 控制器生命周期和调试

示例扫描已报告一些发现。可以通过将其中一个修复的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                                                3.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标签匹配的节点重启 - 详情请参见机器配置操作员文档。

如果需要,一旦更新了渲染的机器配置并更新了协调的修复对象状态,则修复循环结束。在我们的案例中,应用修复将触发重启。重启后,注释扫描以重新运行它。

$ oc -n openshift-compliance \
annotate compliancescans/rhcos4-e8-worker compliance.openshift.io/rescan=

扫描将运行并完成。检查修复是否通过。

$ oc -n openshift-compliance \
get compliancecheckresults/rhcos4-e8-worker-audit-rules-dac-modification-chmod
示例输出
NAME                                                  STATUS   SEVERITY
rhcos4-e8-worker-audit-rules-dac-modification-chmod   PASS     medium

有用的标签

遵从性操作员生成的每个 Pod 都用其所属的扫描和执行的工作进行特别标记。扫描标识符用compliance.openshift.io/scan-name标签标记。工作负载标识符用workload标签标记。

遵从性操作员调度以下工作负载

  • scanner:执行遵从性扫描。

  • resultserver:存储遵从性扫描的原始结果。

  • aggregator:聚合结果,检测不一致性并输出结果对象(checkresults 和修复措施)。

  • suitererunner:(设置计划时)将标记一个要重新运行的套件。

  • profileparser:解析数据流并创建相应的配置文件、规则和变量。

当需要调试和日志记录特定工作负载时,请运行

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

增加遵从性操作员资源限制

在某些情况下,遵从性操作员可能需要比默认限制允许的更多内存。缓解此问题的最佳方法是设置自定义资源限制。

要增加扫描程序 Pod 的默认内存和 CPU 限制,请参见`ScanSetting`自定义资源

步骤
  1. 要将操作员的内存限制增加到 500 Mi,请创建以下名为co-memlimit-patch.yaml的补丁文件。

    spec:
      config:
        resources:
          limits:
            memory: 500Mi
  2. 应用补丁文件。

    $ oc patch sub compliance-operator -nopenshift-compliance --patch-file co-memlimit-patch.yaml --type=merge

配置操作员资源约束

resources字段定义了操作员生命周期管理器 (OLM) 创建的 Pod 中所有容器的资源约束。

在此过程中应用的资源约束会覆盖现有的资源约束。

步骤
  • 通过编辑Subscription对象,在每个容器中注入 0.25 cpu 和 64 Mi 内存的请求,以及 0.5 cpu 和 128 Mi 内存的限制。

    kind: Subscription
    metadata:
      name: compliance-operator
      namespace: openshift-compliance
    spec:
      package: package-name
      channel: stable
      config:
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

配置 ScanSetting 资源

在包含超过 500 个 MachineConfig 的集群中使用遵从性操作员时,ocp4-pci-dss-api-checks-pod Pod 在执行Platform扫描时可能会在init阶段暂停。

在此过程中应用的资源约束会覆盖现有的资源约束。

步骤
  1. 确认ocp4-pci-dss-api-checks-pod Pod 是否卡在Init:OOMKilled状态。

    $ oc get pod ocp4-pci-dss-api-checks-pod -w
    示例输出
    NAME                          READY   STATUS     RESTARTS        AGE
    ocp4-pci-dss-api-checks-pod   0/2     Init:1/2   8 (5m56s ago)   25m
    ocp4-pci-dss-api-checks-pod   0/2     Init:OOMKilled   8 (6m19s ago)   26m
  2. 编辑ScanSetting CR 中的scanLimits属性,以增加ocp4-pci-dss-api-checks-pod Pod 可用的内存。

    timeout: 30m
    strictNodeScan: true
    metadata:
      name: default
      namespace: openshift-compliance
    kind: ScanSetting
    showNotApplicable: false
    rawResultStorage:
      nodeSelector:
        node-role.kubernetes.io/master: ''
      pvAccessModes:
        - ReadWriteOnce
      rotation: 3
      size: 1Gi
      tolerations:
        - effect: NoSchedule
          key: node-role.kubernetes.io/master
          operator: Exists
        - effect: NoExecute
          key: node.kubernetes.io/not-ready
          operator: Exists
          tolerationSeconds: 300
        - effect: NoExecute
          key: node.kubernetes.io/unreachable
          operator: Exists
          tolerationSeconds: 300
        - effect: NoSchedule
          key: node.kubernetes.io/memory-pressure
          operator: Exists
    schedule: 0 1 * * *
    roles:
      - master
      - worker
    apiVersion: compliance.openshift.io/v1alpha1
    maxRetryOnTimeout: 3
    scanTolerations:
      - operator: Exists
    scanLimits:
      memory: 1024Mi (1)
    1 默认设置为500Mi
  3. ScanSetting CR 应用到您的集群。

    $ oc apply -f scansetting.yaml

配置 ScanSetting 超时

ScanSetting对象有一个超时选项,可以在ComplianceScanSetting对象中指定为持续时间字符串,例如1h30m。如果扫描在指定的超时时间内未完成,则扫描会重新尝试,直到达到maxRetryOnTimeout限制。

步骤
  • 要在 ScanSetting 中设置timeoutmaxRetryOnTimeout,请修改现有的ScanSetting对象。

    apiVersion: compliance.openshift.io/v1alpha1
    kind: ScanSetting
    metadata:
      name: default
      namespace: openshift-compliance
    rawResultStorage:
      rotation: 3
      size: 1Gi
    roles:
    - worker
    - master
    scanTolerations:
    - effect: NoSchedule
      key: node-role.kubernetes.io/master
      operator: Exists
    schedule: '0 1 * * *'
    timeout: '10m0s' (1)
    maxRetryOnTimeout: 3 (2)
    1 timeout变量定义为持续时间字符串,例如1h30m。默认值为30m。要禁用超时,请将值设置为0s
    2 maxRetryOnTimeout变量定义重试尝试的次数。默认值为3

获取支持

如果您在使用本文档中描述的步骤或 OpenShift Container Platform 时遇到困难,请访问Red Hat 客户门户

在客户门户中,您可以

  • 搜索或浏览 Red Hat 知识库中与 Red Hat 产品相关的文章和解决方案。

  • 向 Red Hat 支持提交支持案例。

  • 访问其他产品文档。

要识别集群中的问题,您可以在OpenShift 集群管理器中使用 Insights。Insights 提供有关问题的详细信息,以及(如果可用)如何解决问题的相关信息。

如果您有改进此文档的建议或发现错误,请针对最相关的文档组件提交Jira 问题。请提供具体的详细信息,例如章节名称和 OpenShift Container Platform 版本。