Red Hat Insightsの説明 (Part 2)

投稿者: | 2019年10月7日

第二部:Red Hat Insightsの少し突っ込んだ話

前回は、Red Hat Insightsの概略を説明しました。今回と次回は、Red Hat Insightsを更にソースコードを読みながら詳細に解説していきます。今回は特にInsights Clientの詳細な動作を解説します。

5. Red Hat Insightsの構成

Red Hat InsightsはRed Hat社が提供している、Red Hat製品の問題を自動的に見つけたり修復するための、Red Hat社の商用のソフトウェアです。内部でinsights-coreが使用されています。以下のコンポーネントから構成されています。

  • insights-client

    insights-core内のClient APIに対するClient API Wrapperです。実際に情報を収集し、HTTPSを用いてInsights Engineに情報を送信します。

  • Insights Engine(insights-core)

    OSSで提供されているコンポーネントで、データ収集と解析のインフラ部分を担っています。これは他のプロジェクトでも転用が可能とのことです(転用の実例は未だ見てませんが・・・)。

  • Insights Customer Interface

    実際に情報をわかりやすく見るGUIです。Red Hatの提供するinsightsのサイト(https://cloud.redhat.com/insights/overview)がこれに該当します。

(参照:https://insights-core.readthedocs.io/en/latest/intro.html)

Red Hat Insightsのフレームワーク(主要なコンポーネント部分)はOSSで公開されています(https://github.com/RedHatInsights)。次章以降はソースを見ながら説明します。

6. insights-clientの説明

insights-clientはGitHubで公開されています。ので、そちらの説明を補足する形で解説します。

6.1 insights-clientのソースコードの取得とインストール

insights-clientの動作を追いかけるために、まずはinsights-clientのソースをgitで取得しインストールしてみます(RHEL8では既にパッケージがありますので、そちらを使うのがベストですが、ソースコードの確認のため入れてみます)。
インストールの際には、適当なworkingディレクトリの中にinsights-clientとinsights-coreの両方のソース2つ

を同階層で置いておく(gitで取得しておく)必要があります。ここでは仮に、/home/sios/insights-client以下に2つのディレクトリが取得されているとします。

  1. インストールする際のユーザをsudoに登録して下さい(後でinsights-client/lay-the-egg.shスクリプトからsudoが呼び出されます)。
  2. 事前に以下のパッケージをインストールしておきます。

    rpmbuild, make, python, python2-setuptools, python2-devel

  3. insights-clientに移動し、インストールスクリプト(lay-the-eggs.sh)を実行します。
    $ cd insights-client
    $ sh lay-the-eggs.sh
    

    このシェルスクリプトは、

    etc/rpm.egg
    etc/rpm.egg.ac,
    /etc/insights-client/rpm.egg
    

    を削除し、insights-coreディレクトリのbuild_client_egg.shを実行した後に、yumで入っていたinsights-clientを削除して、insights.zipファイルを/etc/rpm.eggとしてコピー/クライアントのファイルをインストール(make install)します。

    呼び出されるbuild_client_egg.shですが、ソースコード中の情報(rpm.eggとなるinsights/以下のファイル一覧等の情報)を作成しています。

  4. eggはGPGでサインされていないので、GPGによるチェックを迂回するために無効化します。
    $ sudo BYPASS_GPG=True EGG=/etc/insights-client/rpm.egg insights-client --no-gpg 
    

InsightsのClientは、2つの主要なコンポーネント(ラッパー(Wrapper)と、更新可能なコアモジュール(EGG))から出来ています。直接コマンドで実行する場合の実体がWrapperで、RHELにRPMパッケージなどでインストールされているものになります。

Wrapper

wrapperはInsight Clientが実行される場合に経由されるメインのものになります。このwrapper経由でEggのモジュールを呼び出して情報を収集したりアップロードを行います。EGGは次の順番で実行され、Eggが失敗した時には順に次のEggを呼び出すことになります。

  • ENV_EGG – 環境変数により指定されたEGG
  • NEW_EGG – 更新が実施された場合、最新にんる新しいEGG
  • STABLE_EGG – 前回最後に収集/アップロードが成功したEGG
  • RPM_EGG – RPMで提供されているデフォルトのEGG

前章でも説明しましたが、これはRPMベースでインストールされているもので

  • 設定ファイル、及びrpm.EGGと鍵など関連ファイル
    • /etc/insights-client/ 以下
  • 実行するバイナリ
    • /usr/bin/insights-client
    • /usr/bin/insights-client-run
    • /usr/bin/redhat-access-insights
  • 参照されるEGGの情報
    • /usr/lib/python3.6/site-packages/insights_client-3.0.5-py3.6.egg-info/ 以下

で構成されています。


Egg

EggはInsight Clientのコアモジュールになります。オプション/設定等はWrapperを通して与えられます。

このEgg本体は、RPMでインストールしている場合にはinsights-clientのRPMファイルに同梱されている

/etc/insights-client/rpm.egg

になります(前述のRPM_EGG)。

このRPM_EGG(rpm.egg)自体は

[root@rhel8test work]# file  rpm.egg
rpm.egg: Zip archive data, at least v1.0 to extract

のようにZipアーカイブになっているので、リネームして中身を見てみます。

[root@rhel8test work]# mv rpm.egg rpm.egg.zip
[root@rhel8test work]# unzip rpm.egg.zip
Archive:  rpm.egg.zip
 extracting: EGG-INFO/dependency_links.txt  
  inflating: EGG-INFO/entry_points.txt  
  inflating: EGG-INFO/PKG-INFO       
  inflating: EGG-INFO/requires.txt   
  inflating: EGG-INFO/SOURCES.txt    
 extracting: EGG-INFO/top_level.txt  
  inflating: insights/client/archive.py  
  inflating: insights/client/auto_config.py  
  inflating: insights/client/cert_auth.py  
  inflating: insights/client/client.py  
  inflating: insights/client/collection_rules.py  
  inflating: insights/client/compressed_file.py  
  inflating: insights/client/config.py  
  inflating: insights/client/connection.py  
  inflating: insights/client/constants.py  
  inflating: insights/client/containers.py  
  inflating: insights/client/data_collector.py  
  inflating: insights/client/dmsetupWrap.py  
  inflating: insights/client/docker_wrap.py  
  inflating: insights/client/__init__.py  
  inflating: insights/client/insights_spec.py

このように、RPM_EGGは、実は前述のinsights-core

https://github.com/RedHatInsights/insights-core

のクライアントとして動作するパーツの主要部分として、不要な部分(後述するParserやその他クライアントには必要ない部分、テストユーティリティなど)を削除したものが固められているものになっています。実際にどの部分が入っているかは、insights-coreに含まれている”build_client_egg.sh”スクリプトで

#!/bin/bash
PYTHON=${1:-python}

rm -f insights.zip
rm -rf insights_core.egg-info
cp MANIFEST.in.client MANIFEST.in
$PYTHON setup.py egg_info
mkdir -p tmp/EGG-INFO
cp insights_core.egg-info/* tmp/EGG-INFO
cp -r insights tmp
cd tmp
# remove unneeded bits to save on space
rm -rf insights/archive
find insights -path '*tests/*' -delete
find insights -name '*.pyc' -delete

git rev-parse --short HEAD > insights/COMMIT

find . -type f -exec touch -c -t 201801010000.00 {} \;
find . -type f -exec chmod 0444 {} \;
find . -type f -print | sort -df | xargs zip -X --no-dir-entries -r ../insights.zip
cd ..
rm -rf tmp
git checkout MANIFEST.in

のように作られています。

という事で、実際のCore部分は、実はinsights-core内のclientを固めたEgg(insights-core/insights/client)により構成されていて、そのEggをWrapperが叩きに行くことになっています。

6.2 Insights-clientの動作

insights-clientの動作を知るには、ソースコードを参照するのが簡単です。insights-clientの主な動作は

insights-client/insights_client/__init__.py

に書かれています(参照しているオブジェクトはinsights-core/insights/client以下に置かれています(所謂Eggです)。そのため、インストールにはclientとcoreの両方が必要になります)。insights_client/__init__.py中のmain()を少し見て、動きを見てみましょう。

  1. まずrootアカウントで動作しているかを確認します。
  2. EGGファイルを探して参照します。EGGファイルが見つからない場合には”No GPG-verified eggs can be found”を表示して終了します。
  3. insights/clientからInsightsClient()をインポートします。
    1. 設定ファイルを読み込みます。無い場合にはデフォルト値を使います。
    2. Insights-serverへの接続を初期化します。
  4. insights/client/phase/v1.pyからget_phases()をインポートします。
  5. confファイルをロードし、logに出力できるようにします。
  6. for p in get_phases():
    run_phase(p, client, validated_eggs)
    

    の所で、それぞれの”phase”に従って処理が進められます。

6.2.1 Insights-clientの”Phase”

insights-clientは次の4つの”Phase”毎にモジュール化されて実行されます。そのため、EGGに問題が有り処理が中断されたとしても、その次の候補のEGGを用いて現在の状態がレジュームされる事になっています。

  1. pre_update

    “すぐに実行する(–statusと–unregisterを除く)指定されたスイッチ”を実行し、必要ならExitします。この箇所で接続前の設定確認・疎通確認を行います。

  2. update

    Insightsサーバと接続を行い、アップストリームのEGGが新しいバージョンの場合にはEGGの更新を行います。情報収集のための新しい”uploader.json”をダウンロードします。

    uploader.jsonはこちらから参照できますが、このファイルの記述に従ってファイルに記述されている情報や、コマンドの出力結果を”collect_and_output” Phaseで収集します。こちらに関しては、次の項で説明します。

  3. post_update

    登録されているかの確認です。システムが未登録で、登録が必要な操作をしている場合にはExitします。

  4. collect_and_output

    uploader.jsonファイルや/etc/insights-client以下の設定ファイルに従って情報収集を実行し、望まれた形式で出力します。デフォルトではInsightsにアップロードされるアーカイブ形式です。

6.2.2 情報収集

insights-clientはシステムの情報を収集するために2つの”モード”(設定ファイル等からの出力結果と、コマンドによる出力結果)を使用しています。

それぞれ定義どおりの話と注意事項はこちらのREADMEにも記載されていますが、実際にどうなっているかを理解するためにuploader.jsonファイルを参照しながら説明しましょう。それぞれファイル/コマンドを実行する部分はinsights-core/insights/client/insights_spec.pyになります。

  1. ファイル(file)

    ファイルの箇所でファイルに含まれるパターンを指定し、そのパターンに対する値を抽出します。

    例として、ssh(/etc/ssh/sshd_config)の設定ですが、下記のようなパターンを用いて/etc/ssh/sshd_configファイルから設定を抽出しています。

    {
                "file": "/etc/ssh/sshd_config",
                "pattern": [
                    "ALLOWUSERS",
                    "AllowUsers",
                    "CIPHERS",
                    "CLIENTALIVECOUNTMAX",
                    "CLIENTALIVEINTERVAL",
    --snip--
                    "PermitRootLogin",
                    "Permitemptypasswords",
                    "Permitrootlogin",
                    "Port",
                    "Protocol",
    --snip--
                    "usepam"
                ],
                "symbolic_name": "sshd_config"
    },
    

    ここで、/etc/insights-client/remove.confファイル(場所の指定は/etc/insishgt-client/insights-client.confファイルに従います)にファイル名を列記することで、情報を収集するファイルから除外することが可能です。

  2. コマンド(command)

    コマンドの出力結果から含まれるパターンを指定し、そのパターンに対する値を抽出します。

    例として、lsofの設定ですが、下記のようなパターンを用いてlsofコマンドから設定を抽出しています。

      {     
                "command": "/usr/sbin/lsof",
                "pattern": [
    --snip--
                    "(deleted)",
                    "/var/log/journal",
                    "libcrypto",
                    "libssl",
                    "libssl.so",
    --snip--
                ],
                "symbolic_name": "lsof"
    },
    

    ここで、/etc/insights-client/remove.confファイル(場所の指定は/etc/insishgt-client/insights-client.confファイルに従います)にコマンド名を列記することで、情報を収集するコマンドから除外することが可能です。

  3. remove.confファイルの例

    remove.confファイルの記述例は、Red Hat Supportから見る事ができます。正規表現を用いてパターンで除外したり、キーワードを列挙することが可能です。

    [remove]
    files=/etc/cluster/cluster.conf,/etc/hosts
    commands=/bin/dmesg
    patterns=password,username
    keywords=super$ecret,ultra$ecret
    

6.2.3 Insights-clientが収集する情報

収集されたデータがどのような形式になっているかは、実際にオフラインで(Insightsサーバに接続しないで)データを収集して出力するモードを使用すると理解しやすいでしょう。

insights-clientをオフラインオプションを付けて実行してみます。

[root@fc30 ~]# insights-client --offline
Starting to collect Insights data for fc30.localdomain
Archive saved at /var/tmp/qybk6le2/insights-fc30.localdomain-20190812050718.tar.gz

デフォルトでは、/var/tmp/[ランダムパターン]/insights-[ホスト名]-[日付と時刻].tar.gz として保存されます。こちらの中身を見てみましょう。

[root@fc30 insights-fc30.localdomain-20190812050718]# pwd
/var/tmp/qybk6le2/insights-fc30.localdomain-20190812050718
[root@fc30 insights-fc30.localdomain-20190812050718]# ls -F
boot/        display_name  insights_commands/  run/  usr/
branch_info  etc/          proc/               sys/  version_info

収集された情報がそれぞれのディレクトリに集まっていることがわかります。例えば下記のように、etc/以下に色々な”file”で指定したパターンで出力された設定情報が集められています。

[root@fc30 insights-fc30.localdomain-20190812050718]# cd etc
[root@fc30 etc]# ls -F
NetworkManager/   krb5.conf.d/    rc.d/                    ssh/
audit/            libvirt/        rdma/                    sysconfig/
chrony.conf       logrotate.conf  redhat-access-insights/  sysctl.conf
crypto-policies/  logrotate.d/    redhat-release           systemd/
dnf/              lvm/            resolv.conf              yum/
fstab             machine-id      rhsm/                    yum.conf
hosts             modprobe.d/     rsyslog.conf             yum.repos.d/
insights-client/  nsswitch.conf   samba/
kdump.conf        os-release      security/
krb5.conf         pam.d/          selinux/
[root@fc30 etc]# cat ssh/sshd_config
#Port 22
# Ciphers and keying
# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any
#LoginGraceTime 2m
PermitRootLogin yes
#MaxAuthTries 6
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
--snip--
#MaxStartups 10:30:100
#Match User anoncvs

また、commandによる実行結果はinsights-commands/以下に集められており

[root@fc30 insights_commands]# cat getenforce
Enforcing

のようにコマンドと出力結果が残っています。これらの情報をinsights-clientはinsightsサーバに送信しています。

6.2.4 Insights-clientのネットワーク接続

insights-clientはinsightsサーバとHTTPSを利用して情報を送ります。この接続部分は、insights-core/insights/client/connection.pyに記載されています。

ここでの注意点としては、Proxyの設定がきちんとされているかを確認するために、”hhttps://cert-api.access.redhat.com/r/insights”>https://cert-api.access.redhat.com/r/insights” にアクセスを行うことです。このサイトに接続できない場合には、insights-clientは正常に動作しません。

また、疎通テストを行う際には、タイムアウト値を10秒として、ステータスコード200(OK)か201(Created)が帰ってきた場合には、疎通確認が取れたということにしています。

このタイムアウト値は、/etc/insights-client/insights-clinet.confファイル内に

---略---
# Timeout for HTTP calls, in seconds
#http_timeout=10

として設定されているため、変更が可能です。

先の章で記したシステム情報(アーカイブ)をアップロードする際には、HTTPSを用いて暗号化し平文では流れないようにしてあります。

6.2.5 その他

Insights-Clientのソースコードは少し入り組んでいますが、難しいものではないので一度ソースコードを読んだほうが良いでしょう。

次回予告

今回はここまでです。次回はInsights Engine(insights-core)のそれぞれのコンポーネントに関して突っ込んだ解説を行います。