朝から昼寝

(ブログ準備中) IT技術、健康、日常

1回のGet-VMで色々なVMプロパティを取得(PowerCLI)

概要

PowerCLIでvCenterから仮想マシン情報を取得可能ですが、目的のプロパティ群がGet-VMやGet-VMGuestなど複数のコマンドレットの出力にまたがる場合、各コマンドレットを実行しそれらの出力をマージするというのは煩雑です。
本記事は、シンプルに1回のGet-VMコマンドレット実行から、Get-VMの出力に含まれないプロパティ情報も合わせて取得し、CSVファイルに保存する方法をまとめたものです。

本記事の目的

  • 1回のGet-VMコマンドレット実行で仮想マシンの各プロパティを取得する。

目次

基本

環境設定

既に以下の環境設定は完了しているものとします。

  • PowerCLIのインストール
  • PowerCLIからvCenterへの接続確認(Connect-VIServer)

仮想マシンの各プロパティを取得するスクリプト

Connect-VIServerにてvCenterに接続後、以下の例のようにスクリプトを実行すると、各プロパティを取得できます。取得するプロパティは変更可能です。

vmlist.ps1

# 複数NICを持つVMのVLAN/NetworkAdapterプロパティは複数値になるので":"で結合する関数を用意
function concatNetworkAdapters {
    Param($VM)
    $var = @()
    $Adapters = @(Get-NetworkAdapter -VM $VM | Select Name, NetworkName)

    ForEach ($Adapter in  $Adapters) {
        $var += $Adapter.NetworkName + "(" + $Adapter.Name + ")"
    }

    Return [String]::join(":", $var)
}

$date = Get-Date

# Get-VMにて全VMのオブジェクトを取得し、目的のプロパティをハッシュテーブルに格納
$out = Get-VM | Select Name, 
    @{N="PowerState"; E={[String] $_.PowerState}},
    @{N="Host"; E={$_.VMHost.name}},
    NumCpu,
    MemoryGB,
    @{N="ProvisionedSpaceGB"; E={[Math]::Round(($_.ProvisionedSpaceGB),0)}},
    @{N="UsedSpaceGB"; E={[Math]::Round(($_.UsedSpaceGB),0)}},
    @{N="GuestOS"; E={$_.Guest.OSFullName}},
    HardwareVersion,
    @{N="IPAddress"; E={[string]::Join(':',$_.Guest.IPAddress)}},
    @{N="VLAN"; E={concatNetworkAdapters $_.Name}},
    @{N="VmxPath"; E={$_.ExtensionData.Summary.Config.VmPathName}},
    CreateDate,
    @{N="UptimeDays";E={(New-TimeSpan -Start $_.Extensiondata.Runtime.BootTime.ToLocalTime() -End $date).Days}},
    @{N="ToolsInstallType"; E={$_.ExtensionData.Guest.ToolsInstallType}},
    @{N="ToolsVersion"; E={$_.ExtensionData.Guest.ToolsVersion}},
    @{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsStatus}},
    Notes

# CSVファイルに出力
$out | Export-CSV -NoTypeInformation -encoding UTF8 "C:\vmlist\vmlist.csv"

CSV出力例

出力されたCSVファイルの例です。(列が多いので画像2枚に分けてあります。また例なので1行分のみですが実際には全VM分の行が出力されます)

CSV出力例CSV出力例
CSV出力例

スクリプトの注意点

以下、注意点です。

  • スクリプトの中でファイルパス等にマルチバイト文字(非Ascii文字)を使用する場合、PowerShellの環境の都合上、スクリプト文字コードUTF-8(BOM付)で保存する等の対応が必要(参考情報はこちら)

  • 上記の例では、型指定([String]等)の有無等は統一しきれていません。

詳細

スクリプトの説明

このスクリプトは、後述の参考URL等にあるVMwareのコミュニティ情報を元にしたものです。内容を簡単に説明します。

  • function concatNetworkAdapters
    複数NICを持つVMのVLAN(ポートグループ)やNetworkAdapterの情報は、複数値になるので、各値を":"で結合し、CSVの1フィールドに収まるよう整形する関数(適切なプロパティが別途あるかもしれないが、この関数の中ではGet-NetworkAdapterを使用)
  • $out = Get-VM |
    Get-VMにて全VMのオブジェクトを取得し、パイプラインに渡す。
  • | select以降
    VMのオブジェクトを渡された後は、Select経由でハッシュテーブル(@{Name=xxx, Expression=xxx})に格納する。
    Get-VMの出力に含まれるプロパティのままで良いものは、ハッシュテーブルの記載(@{})を省略可。
    逆に、Get-VMの出力に含まれないプロパティを参照するときは、$_.ExtensionData.xxxのように、オブジェクトのメンバ情報から目的のプロパティを指定する(目的のプロパティ名の探し方は後述)。
    • Name : 仮想マシン
    • @{N="PowerState"; E={[String] $_.PowerState}} : 電源状態
    • @{N="Host"; E={$_.VMHost.name}} : 稼働ホスト
    • NumCpu : 仮想CPU数(総コア数)
    • MemoryGB : メモリ量[GB]
    • @{N="ProvisionedSpaceGB"; E={[Math]::Round(($_.ProvisionedSpaceGB),0)}}, @{N="UsedSpaceGB"; E={[Math]::Round(($_.UsedSpaceGB),0)}} : それぞれ、プロビジョニングした容量[GB]、使用容量[GB] ※小数点以下はRound()で四捨五入
    • @{N="GuestOS"; E={$_.Guest.OSFullName}} : ゲストOS名
    • HardwareVersion : 仮想マシンバージョン
    • @{N="IPAddress"; E={[string]::Join(':',$_.Guest.IPAddress)}} : IPアドレス ※複数のIPアドレスがある場合、Join()にて":"で結合
    • @{N="VLAN"; E={concatNetworkAdapters $_.Name}} : 前述の concatNetworkAdapters関数にて取得したVLAN(ポートグループ)情報
    • @{N="VmxPath"; E={$_.ExtensionData.Summary.Config.VmPathName}} : 格納先データストア(vmxファイルのパス)
    • CreateDate : 仮想マシンの作成日時 ※Cross vCenter VMotionされると、その日時にリセットされるようです
    • @{N="UptimeDays";E={(New-TimeSpan -Start $_.Extensiondata.Runtime.BootTime.ToLocalTime() -End $date).Days}} :稼働日数(Uptimeから日数だけを取り出したもの)
    • @{N="ToolsInstallType"; E={$_.ExtensionData.Guest.ToolsInstallType}},@{N="ToolsVersion"; E={$_.ExtensionData.Guest.ToolsVersion}},@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsStatus}} : VMwareTools関連の情報
    • Notes : vCenter上の"注"

目的のプロパティ名の探し方

  • Get-Member
    適当な仮想マシンのオブジェクトをGet-VM等で取得し、Get-Memberで辿りながら地道に探す方法があります。ExtensionDataExtensionData.Guest仮想マシン管理に使えるプロパティがあると思います。
> $vm = Get-VM -name vm01
> $vm | Get-Member
> $vm.ExtensionData | Get-Member
> $vm.ExtensionData.Guest | Get-Member
  • VMware社公式ドキュメント (例:Get-VM RelatedObject)
    2022/5現在、Beta版のようですが、VMware Developer Documentation等でコマンドレットのRelatedObjectを参照すると、各プロパティを参照できます。ただ、Get-VM で取得したオブジェクトから全プロパティを簡単にリンクで辿れる訳ではなさそうです。
    その他、vSphere Web Services APIでもプロパティの説明など参考になりそうな記載があります。

あとは、後述のVMwareコミュニティのやり取りを参考にするのが一番実用的のように思います。

参考URL等

VMwareコミュニティのやり取りから、目的のプロパティの記載が見つかる場合もあります。PowerCLI関連の話題は、詳細に回答されて方がいるようで、非常に参考になります。

VSCode v1.61以降のテレメトリー無効化(自動データ送信)

概要

VSCode v1.61以降、自動データ送信(テレメトリー)の設定パラメタが変更になったようです。
本記事は、VSCodeテレメトリー設定の無効化についてまとめたものです。

本記事の目的

目次

基本

VSCodeテレメトリー無効化設定(設定画面)

VSCodeの設定画面にてTelemetry LevelをOffに設定すると、すべてのテレメトリー機能を無効化できます。

Setting: Telemetry Level
Setting: Telemetry Level

VSCodeテレメトリー無効化設定(settings.json)

VSCodesettings.jsonを直接編集して設定する場合は、以下の行を追加すると、すべてのテレメトリー機能を無効化できます。

"telemetry.telemetryLevel": "off"

従来のテレメトリー設定パラメタ

新たな設定パラメタtelemetry.telemetryLevelが実装されたため、従来のパラメタであるtelemetry.enableTelemetrytelemetry.enableCrashReporterは非推奨(deprecation)となりました。
ただし、これら従来のパラメタも今のところは(v1.67時点)、引き続き使用できるようです(リリースノートに「but will continue to be respected」の記載あり )。

以下のように、新パラメタ(telemetry.telemetryLevel)は、従来パラメタ(telemetry.enableTelemetrytelemetry.enableCrashReporter)より優先されます。

  • 新パラメタがoffの場合、従来パラメタに関係なくテレメトリは無効化される
  • 新パラメタがoff以外に設定され、かつ従来パラメタでテレメトリが無効になっている場合、テレメトリは無効化される

詳細

defaultSettings.jsonの記載(日本語)

日本語環境のVSCodedefaultSettings.jsonを参照すると、日本語訳を確認できます。

  // 
  // Visual Studio Code テレメトリ、ファースト パーティ拡張テレメトリ機能、および参加しているサード パーティの拡張機能テレメトリを制御します。一部のサード パーティの拡張機能では、この設定が考慮されない場合があります。確認するには、特定の拡張機能のドキュメントを参照してください。テレメトリにより、Visual Studio Code のパフォーマンス、改善が必要な場所、および機能の使用方法について理解しやすくなります。 [収集するデータ](https://aka.ms/vscode-telemetry) と[プライバシーに関する声明](https://go.microsoft.com/fwlink/?LinkId=786907) を参照してください。 クラッシュ レポートの変更を有効にするには、アプリケーションを完全に再起動する必要があります。
  // 
  //  
  // 
  // 次の表は、各設定で送信されるデータの概要を示しています。
  // 
  // |       | クラッシュ レポート | エラー テレメトリ | 使用状況データ |
  // |:------|:---------------------:|:---------------:|:--------------:|
  // | all   |            ✓          |        ✓        |        ✓       |
  // | error |            ✓          |        ✓        |        -       |
  // | crash |            ✓          |        -        |        -       |
  // | off   |            -          |        -        |        -       |
  // 
  // 
  //  
  // 
  // ****注:*** この設定が 'off' の場合、他のテレメトリ設定に関係なくテレメトリは送信されません。この設定が 'off' 以外に設定されていて、非推奨の設定でテレメトリが無効になっている場合、テレメトリは送信されません。*
  // 
  //  - all: 使用状況データ、エラー、クラッシュ レポートを送信します。
  //  - error: 一般的なエラー テレメトリとクラッシュ レポートを送信します。
  //  - crash: OS レベルのクラッシュ レポートを送信します。
  //  - off: すべての製品テレメトリを無効にします。
  "telemetry.telemetryLevel": "all",
  // この設定が false の場合、新しい設定の値に関係なくテレメトリは送信されません。`telemetry.telemetryLevel`設定を優先して非推奨になりました。
  // 診断データの収集を有効にします。これにより、Visual Studio Code の実行状況と改善が必要な箇所について理解を深めることができます。収集する情報とプライバシーに関する声明についての [Read more] (https://go.microsoft.com/fwlink/?LinkId=786907) をご覧ください。
  "telemetry.enableTelemetry": true,
  // この設定が false の場合、新しい設定の値に関係なくテレメトリは送信されません。`telemetry.telemetryLevel`設定に結合されているため、非推奨になりました。
  // クラッシュ レポートの収取を有効にします。これにより、安定性が向上します。
  // このオプションを有効にするには、再起動が必要です。
  "telemetry.enableCrashReporter": true,

参考URL等

Systemdのネットワーク関連ユニット解説(After=network.target等)

概要

Systemdのユニットファイルの中にAfter=network.targetといった記述をよく見かけますが、ややこしい仕様なので、誤解の無いようネットワーク関連ユニットの概要を抑えておくことが大事です。
本記事は、Systemdのネットワーク関連ユニットの概要をまとめたものです。対象は主にRHEL7、CentOS7以降です。
なお、Systemdの基本的なサービス管理については、こちらの記事にまとめてあります。

本記事の目的

  • After=network.targetの意味を把握する。
  • ネットワークを待ってサービス起動する設定(network-online.target)を把握する。
  • ネットワーク関連ユニットの概要を把握する。

目次

基本

After=network.target ≠ ネットワーク疎通可

サービスのユニットファイルにAfter=network.targetが記載されていても、それは「ネットワーク疎通できるようになった後にそのサービスを起動する」ということを保証するものではありません。
例えば、httpdはユニットファイルにAfter=network.targetが記載されていますが、httpd.confにて特定IPアドレスのみをListen指定していると、OS起動時に、そのIPアドレスが使用可能になる前にhttpdサービスを起動し始めてしまい、Cannot assign requested address: AH00072: make_sock: could not bind to address x.x.x.x:443といったエラーで起動失敗することがあります。postfixのinet_interfacesの指定でも同様の事象が起きることがあると思います。

ネットワーク疎通できるようになった後にそのサービスを起動したい場合は、 network-online.targetというユニットとの順序関係を指定します。

順に説明していきます。

ネットワークを待ってサービス起動する設定(network-online.target)

ネットワーク疎通(※)ができるようになってからサービスを起動する設定について説明します。
(※)本記事では、ネットワークインタフェースの設定(IPアドレス割り当てなど)が完了した状態を指します。そのIPアドレスに対するソケット割り当て(バインド)ができる状態です。

元のユニットファイルを直接編集せず、以下のようにdrop-in(別の設定ファイルを追加)を利用します。例としてhttpdの場合の手順を記載しますが、他のサービスでも同様です。drop-inの詳細はman systemd.unitで確認できます。

# systemctl edit httpd にて、以下を記載します。

[Unit]
After=network-online.target
Wants=network-online.target

その後、
# systemctl daemon-reload
を実行してsystemdに読み込ませると、設定完了です。
httpdはネットワーク疎通できるようになってからサービス起動するようになります。

詳細は、後述します。

詳細

drop-inの管理TIPS

drop-inを設定すると、以下のようにdrop-inファイルが作成されます。インストール時に配置された元のユニットファイルを変更せず、別ファイルに設定を追加する形です。
$ cat /etc/systemd/system/httpd.service.d/override.conf

[Unit]
After=network-online.target
Wants=network-online.target

drop-inが存在していることは、以下のようにsystemctl statusの結果にDrop-In:行が表示されることでも確認できます。 $ systemctl status httpd

● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └override.conf

drop-inを修正したいときは、systemctl editで可能です。
なお、drop-inを削除したいときは、編集画面で中身を空にして保存してもキャンセルされてしまい削除できないので注意が必要です。
# systemctl edit httpd

(drop-inファイルを空にして保存しようとした場合)
Editing "/etc/systemd/system/httpd.service.d/override.conf" canceled: temporary file is empty.

drop-inを削除したいときは、以下のようにsystemctl revertを利用可能です。ただし、必要なファイルも削除されないか注意が必要です。
# systemctl revert httpd

Removed /etc/systemd/system/httpd.service.d/override.conf.
Removed /etc/systemd/system/httpd.service.d.

systemctl revertにより、指定したユニットのdrop-inファイルが削除されますが、他に手動で修正したユニットファイルも削除(※)されるようですので注意が必要です。systemctl revertではどうしても支障がある場合は、手動でdrop-inファイルを削除する方が無難でしょう。
(※)詳細な動作は確認していませんが、/usr/lib/配下のオリジナルのユニットファイル(vendor-supplied)を/etc/system/system配下等にコピーしてから修正した同名のユニットファイルがあればそれが削除され、オリジナルのユニットファイルのみが存在する状態に戻るようです。なお、オリジナルのユニットファイルが無く、自作したユニットファイルが1つあるだけであれば、それは削除されずに残るはずです。

drop-inで追加した設定が反映されていることは、systemctl showでも確認できます。 $ systemctl show httpd

…
After=remote-fs.target nss-lookup.target system.slice systemd-tmpfiles-setup.service httpd-init.service tmp.mount systemd-journald.socket basic.target sysinit.target -.mount network-online.target network.target
(改行されず見切れるので続きを見る場合は → キーで最後まで見られます)
…

ネットワーク関連ユニット

では、After=network.targetの意味や、関連する特殊ユニットについて説明します。

概要

システム起動時、以下のnetwork-pre.targetから順にユニットが起動されます。

  1. network-pre.target
    ↑After
  2. NetworkManager.service
    ↓Before(,Wants)
  3. network.target (After=network-pre.target含む)
    ↑ Requires
  4. NetworkManager-wait-online.service (After=NetworkManager.service含む)
    ↓ Before(,WantedBy)
  5. network-online.target (After=network.target含む)

※NetworkManager-dispatcher.serviceについては省略

グレーの矢印 (↑、↓) や補記は、矢印の元のユニットファイルにおいてBefore,After等の順序関係が矢印の先のユニットに対して指定されていることのメモです。依存関係(Wants,Requires等)も補記してあります。

「network~」はsystemdにおけるネットワーク関連の特殊ユニット(詳細はman systemd.special)、「NetworkManager~」はOS標準のネットワーク管理サービスであるNetworkManager関連のユニットです。

systemctl list-dependenciesでユニットの依存関係を確認してみると、システム起動時には、NetworkManager.serviceが起動するよう指定されていることが分かります(NetworkManager.serviceのユニットファイルでは、WantedBy=multi-user.targetが指定されています)。

$ systemctl list-dependencies

default.target
…
● ├NetworkManager.service
…

また参考までに、各ユニットは以下のように有効化(enabled)、もしくは特殊ユニットの場合はstaticになっていることが分かります。

# systemctl list-unit-files | grep NetworkManager

NetworkManager-dispatcher.service                                      enabled
NetworkManager-wait-online.service                                     enabled
NetworkManager.service                                                 enabled

# systemctl list-unit-files | grep network

network-online.target                                                  static
network-pre.target                                                     static
network.target                                                         static

次に、各ユニットの説明をします。

1. network-pre.target

特殊ユニットの1つで、サービスの起動順序の制御等に使用されます。
ネットワークインタフェースの設定前に実行されるユニットです。

なお、network-online.targetは、network.targetと同様にパッシブユニットです。パッシブユニットについては後述のnetwork.targetの箇所で説明します。

2. NetworkManager.service

特殊ユニットではなく、通常のユニットです。
NetworkManagerのメインのユニットです。ネットワークインタフェースの設定処理等を実行します。

3. network.target (重要)

特殊ユニットの1つで、サービスの起動順序の制御等に使用されます。

After=network.targetが指定されたユニット(サービス)の起動は、ネットワーク疎通可能になるまで遅延される訳ではありません。
systemdがnetwork.targetを起動すると、ネットワークの設定を行うサービスが開始した状態にはなりますが、それはネットワークデバイスの設定(IPアドレス設定等)までが完了した状態ではありません。
そのため、After=network.targetが指定されたユニットは、OS起動時にはnetwork.targetの起動後に自身のサービスを起動し始めるのですが、まだその時点ではIPアドレスが使用可能になっていないこともあるので、その場合にはソケット割り当て(バインド)が失敗してしまいます。

では、何のためにAfter=network.targetが指定されているサービスがあるのかと言うと、それは起動時でなく停止時の順序制御のためのようです。
After=network.targetが指定されたユニットが停止するまで、network.targetの停止処理が開始されることはありません。
つまり、自身が停止するまでネットワークが起動していないといけないサービスには、After=network.targetを指定しておくべきということになります。
このように、停止時の順序の話になると、「After」という単語の意味とは逆の働きをするので、ややこしいです。

なお、network.targetはパッシブユニットなので、通常のサービス(consumer)において、After=network.targetのように順序関係を指定しても良いですが、Wants=network.targetRequires=network.targetのように依存関係を指定してはいけません。
パッシブユニットに関する詳細な記述が見つけられませんでしたが、パッシブユニットのユニットファイルには、RefuseManualStart=yesが記載されているようです。

4. NetworkManager-wait-online.service

特殊ユニットではなく、通常のユニットです。
これもNetworkManager関連のユニットです。

NetworkManager-wait-online.serviceは、後述のnetwork-online.targetより先に起動します。After=network-online.targetを設定したときに実質的なネットワーク起動完了を判定するのが、このNetworkManager-wait-online.serviceであると思われます。

NetworkManager-wait-online.serviceのユニットファイルには、Before=network-online.targetが記載されています。
NetworkManager-wait-online.serviceが起動完了(=ネットワーク起動完了)してから、network-online.targetの起動が開始されるということです。

5. network-online.target (重要)

特殊ユニットの1つで、サービスの起動順序の制御等に使用されます。

network.targetの場合とは異なり、After=network-online.targetが指定されたユニットの起動は、ネットワーク疎通可能になるまで遅延されます。
前述のNetworkManager-wait-online.serviceがネットワーク起動(IPアドレス設定等)が完了したことを判定後、network-online.targetが起動完了となります。その後にAfter=network-online.targetが指定されたユニットが起動開始されますので、確かにネットワーク疎通可になってから起動できます。
network-online.target自体のタイムアウトは90秒のようです。

なお、補足事項として、systemd開発プロジェクトをホストしているらしいfreedesktop.orgの説明ページによると、ネットワークを利用するサーバソフトウェアのサービスにおいてAfter=network-online.targetを多用しないことが強く推奨されているようです。これは、例えばサーバソフトウェアはネットワーク起動前であってもローカルコネクションを受け付ける方が一般的には望ましく、そもそもAfter=network-online.targetの主目的がネットワーク無しでは動作できないクライアントソフトウェアのためにあると説明されています。
また、開発者向けに、ネットワーク設定が動的に変わっても動作するようプログラムを修正することを勧めています。
ただ、実際には例えばhttpd自動起動失敗を回避するためAfter=network-online.targetを指定したいケースもあるので、システム管理者からすると、なかなかこの思想の通りに運用するのは難しいところです。

以下、freedesktop.orgの説明ページより引用。

It is strongly recommended not to pull in this target too liberally: for example network server software should generally not pull this in (since server software generally is happy to accept local connections even before any routable network interface is up), its primary purpose is network client software that cannot operate without network.

If you are a developer, instead of wondering what to do about network.target, please just fix your program to be friendly to dynamically changing network configuration.
https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

ちなみに、network-online.targetは、network.targetとは異なりパッシブユニットではありません。通常のサービス(consumer)において、After=network.targetのように順序関係を指定する以外に、Wants=network.targetRequires=network.targetのように依存関係を指定できます。
前述の設定例では、After=network.targetWants=network.targetの両方を指定しています(freedesktop.orgの説明ページの設定例と同等)。

(参考)NetworkManager-dispatcher.service

特殊ユニットではなく、通常のユニットです。
これもNetworkManager関連のユニットで、dispatcherはネットワークイベントが発生した場合に、スクリプトを実行するもののようです。
詳細は省略します。

参考URL等

時刻ズレを安全に復旧する(Linux,Chrony)

概要

「時刻同期できておらず、気付いたら時刻がズレていた!」という場合、復旧方法を間違えると大きなトラブルにつながりかねません。
本記事は、時刻ズレを安全に復旧する方法をまとめたものです。主に、RHEL7、CentOS7以降でOS標準のChronyを使用した環境を対象としていますが、基本的な考え方はどのシステムでも共通です。
Chrony全般の説明はこちらの記事にまとめてあります。
なお、あくまで本記事は参考情報です。実際の復旧作業に際しては二次トラブルが生じないよう十分な検討と準備が必要です。

  • 時刻ズレによるトラブル発生リスクを考慮する。
  • 時刻ズレの復旧計画を適切に検討する。

まずは参考手順

稼働させたまま時刻をゆっくり修正(slew)

本記事は、状況整理や復旧計画を立てる流れについて説明しますが、ひとまず参考になりそうな「サーバや業務サービスを稼働させたまま時刻をゆっくり修正(slew)する」手順を記載します。
※この手順が適切かどうかは状況によりますので、詳細は記事の続きをご確認ください。

時刻をゆっくり修正(slew)する場合、以下のようにchrony.confのmakestep 1.0 3行をコメントアウトしてから、Chronyサービスを再起動します。
仮定として、正常に時刻同期できるようにするために、間違っていた参照先NTPサーバの設定の修正(およびその反映のためにChronyサービスの再起動)が必要といったケースを想定しています。

# vi /etc/chrony.conf

#makestep 1.0 3 ←コメントアウト
※また、必要に応じserver行の参照先NTPサーバの指定等、適切な設定修正も行う

# systemctl restart chronyd
(参考)# date; systemctl restart chronyd; date のようにサービス再起動前後にdateを実行しておくと記録を取りやすいです。

Chrony(chronyd) のデフォルト設定では、Chronyのサービス起動時にNTPサーバと大幅に時刻がズレていた場合、一気に時刻修正(stepモード)が行われます。上記の手順は、そのstepモードによる時刻修正を無効化してからChronyサービスを再起動するものです。

Chronyサービスの再起動後、正常に時刻同期できるようになったとして、以下のように通常のslewモードによりゆっくり時刻同期されることを監視します。Chronyはデフォルトで1秒の時刻ズレを最速12秒間で修正します(maxslewrate)。1分間の時刻ズレを修正するのにかかる時間が最速で720秒(12分)です。

$ chronyc sourcesにて、行頭が ^* になっている行が表示され、NTPサーバと時刻同期できていることを確認します。

(★マークは説明用の目印です)
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
========================================================
^*★ ntp-server1.domain.com          1   3   111    22  -1000us[ -100ms] +/-   10ms
^?  ntp-server2.domain.com          1   3   111    22  -1000us[ -100ms] +/-   10ms
※値はダミーです

また、$ chronyc trackingを間隔を置きながら何度か実行し、System time行のX.XXXX second slow(もしくはfast)…の数値が徐々に小さくなり、時刻修正が進んでいることを確認します。
$ chronyc tracking

(★マークは説明用の目印です)
Reference ID    : AB00123C (domain.com)
…
System time     :  0.000000555 seconds slow of NTP time ★
…
※値はダミーです。

各設定やコマンドの詳細は、こちらの記事にまとめてあります。

業務サービスを稼働させたまま上記の手順を進める場合は、業務サービスの方に影響が無いかも随時確認することをお勧めします。

時刻修正が完了した後は、コメントアウトしたmakestep 1.0 3行のコメントを解除し、再度Chronyを再起動しておきます。コメントアウトしたままが良ければそのままで良いです。

基本

ここからは、時刻ズレが発生した際の状況整理や復旧計画について説明します。

時刻ズレによるトラブル発生リスク

時刻を正確に扱うシステムでは、少しの時刻ズレが深刻なデータ不整合やサービス停止を引き起こす場合があります。データベースシステム、認証系システム(SSO全般、Kerberos、TOTP)等です。
時刻ズレを発見した場合には、速やかに復旧計画を立てましょう。

時刻ズレを発見したときにすべきこと

以下のようなポイントを整理する必要性があります。

  • 時刻ズレにより、既にトラブルが発生していないか
  • 時刻ズレが生じているサーバを全て洗い出したか
  • 時刻ズレの状況は、サーバ側の「時刻が遅れている」か「時刻が進んでいる」か
  • 時刻ズレが生じた原因が明確か

サーバ側の「時刻が遅れている」よりも「時刻が進んでいる」方が、仮に一気に時刻修正してしまった場合には時刻が戻る(逆進する)ので危険なケースが多いです(これは一概には言えませんが)。
また「時刻ズレの原因」も正確に把握しておくべきです。NTP設定自体が漏れていた、設定していたがNTPサーバと正常に通信できなくなっていた、等。何をどう直せば時刻同期できるようになるのかを明確にすることが重要です。

復旧計画の立案

以下のようなポイントを整理する必要性があります。

  1. 基本的な復旧手順の確立
  2. 制約事項の整理
  3. 復旧計画の確定

順に説明します。

1. 基本的な復旧手順の確立

まず「時刻ズレの原因」に応じ、基本的な復旧手順を確立します。NTP設定やネットワーク設定の見直しなどです。サーバの再起動やNTPサービス(Chrony)の再起動が必要か、等を正確に整理しておきます。
手順確立のため使用できるテスト機があれば、先に試しておきましょう。

2. 制約事項の整理

焦って復旧方法を間違えると、さらに大きなトラブルに発展する可能性もあります。適切に復旧方法を決めるため、例えば以下の優先度順で状況を整理します。

  1. 時刻修正のため、対象のサーバやサービス(業務アプリ等)を停止可能か
    停止可能な場合は、まずサーバやサービスを停止してから安全に復旧作業を開始する計画を立てます。これにより、データやサービスが時刻修正による影響を受けないことを担保できます。
    停止不可の場合は、次の項目を確認します。

  2. 対象のサーバやサービス(業務アプリ等)は、稼働したまま時刻を一気に修正(step)しても問題が無いか
    問題が無い場合(時刻を正確に扱わないシステムの場合)は、サーバやサービスを稼働させたまま一気に時刻修正する計画を立てます。
    時刻修正が逆進かどうかもここで考慮します。サーバ側の「時刻が遅れている」場合は、一気に時刻修正するとサーバ上の時刻が急に進みます。逆に「時刻が進んでいる」場合は、一気に時刻修正するとサーバ上の時刻が急に戻ります。使用している業務アプリ等で不都合が無いかを慎重に判断します。
    問題がある場合は、次の項目を確認します。

  3. 対象のサーバやサービス(業務アプリ等)は、稼働したまま時刻をゆっくり修正(slew)すれば問題ないか
    問題が無い場合は、サーバやサービスを稼働させたままゆっくり時刻修正(slew)する計画を立てます。
    時刻修正の「ゆっくり」の程度はここで考慮します。Chronyの場合、chrony.confのmakestep行をコメントアウトすることで、次回のChronyサービス起動時のstepモードでの時刻修正を回避でき、その後slewモードで時刻が修正されます。slewモードの時刻修正の速度(maxslewrate)のデフォルト値は83333.333 ppmで、これは「1秒の時刻ズレを12秒間で修正」するものです。さらにゆっくり修正したい場合はmaxslewrateを小さくします。詳細はこちらの記事にまとめてあります。
    なお、ゆっくり時刻修正することですら問題がある場合は、そもそも現実的に復旧計画を立てられる状況にないので、再度サーバやサービスの停止可否から調整し直しましょう。

3. 復旧計画の確定

上記で整理した、復旧手順や、サーバ/サービスの停止可否、一気に時刻修正(step) or ゆっくり時刻修正(slew)を考慮して復旧計画を確定します。

一気に時刻修正(step)しても良ければ、正常に時刻同期ができるよう対処すれば良いだけです。

ゆっくり時刻修正(slew)する場合には、本記事の冒頭に記載した手順が参考になります。

なお、復旧すべき対象サーバが複数ある場合には、相互に連携する機能が無いかといった点を考慮し、同時に対処する等を検討しておきます。

ESXiサーバのLAG設定

概要

VMware vSphere環境において、ESXiサーバの性能向上のためLAGを使用することがあります。リンクアグリゲーション、IEEE802.3ad(IEEE802.1AX-2008)のことです。呼び方は、ポートチャネルや、CiscoではEtherChannel、HPEではトランク等…。
本記事は、ESXiサーバにおけるLAG設定の概要をまとめたものです。 主な対象はESXi 6系、7系です。

  • ESXiサーバのLAG設定の概要を把握する。
  • 設定のポイントや、接続先の物理スイッチと一致させる設定箇所を把握する。

基本

ESXiサーバで利用可能なLAG構成

使用する仮想スイッチの種類により、サポートされるLAG構成が異なります。

仮想スイッチ種別 サポートされるLAG構成
標準仮想スイッチ(vSS) static LAG(静的)のみ
分散仮想スイッチ(vDS) static LAG(静的)、およびLACP(動的)

vDSは、vSphere Enterprise Plus相当で利用可能です。vSphere Standardでは利用できません。
当然ですが、ESXiサーバの接続先となる物理スイッチでも使用するLAG構成をサポートしている必要性があります。

ESXiサーバにおけるLAGの用途や基本構成

LAGを構成することで、より大きなネットワーク帯域の確保や、ネットワーク障害時にも運用継続するためのNIC冗長性の確保ができます。
例えば、以下のトラフィック用にLAGを適用する等が考えられます。

LAG構成では、必要に応じて以下の構成も検討します。

  • 10Gbps NIC
  • ジャンボフレーム
  • ESXiサーバ側でLAGを構成する物理ポートは、複数のネットワークカードから構成(1つのネットワークカード障害時の運用継続)
  • 物理スイッチ側でLAGを構成する物理ポートは、複数の筐体から構成(1つの筐体の障害時の運用継続)
    ※スタック構成やマルチシャーシLAG(MLAG)等

static LAGの設定

標準仮想スイッチもしくは分散仮想スイッチにて対象NICチーミングを構成し、物理スイッチのstatic LAGを設定したポートと接続します。

static LAGの場合、仮想スイッチ側の設定におけるポイントは以下です。

  • 仮想スイッチのロードバランシングモードは「IPハッシュに基づいたルート」
  • ネットワーク障害検出ポリシーは「リンクステータスのみ」
  • すべてのNICを「アクティブ」

以下、参考になるVMwareのdocsです。

LACPの設定

分散仮想スイッチにて対象NICチーミング(LAGという設定項目)を構成し、物理スイッチのLACPを設定したポートと接続します。
LACPの場合、仮想スイッチ側の設定におけるポイントは以下です。

以下、参考になるVMwareのdocsです。

詳細

注意点

LAGとiSCSIマルチパスの併用は未サポート

ESXiにてLAGを構成するNICを、iSCSIマルチパスに使用することはVMware社にてサポートされていません(iSCSIマルチパス:複数のvmnicをそれぞれiSCSI用にポートバインドさせるソフトウェアベースの冗長パス構成)。
異なるレイヤの冗長化機能を同時に使用することになるためと思われます。
分かりやすい説明が見当たりませんでしたが、VMware社のKBに、「iSCSI ソフトウェアのマルチパスには使用しないでください」といった記載があります。

LAGの動作確認

LAGを構成したポートが意図通りに動作しているか動作確認の観点についてです。
うまく通信ができない場合や、あるいはうまく通信できているように見えても実は設定が間違っている場合があるかもしれません。例えば、設定が間違っている場合、パケットロスが発生して通信が不安定になる等、分かりづらい現象が発生する可能性もあります。
以下のような動作確認の観点が挙げられます。

  • ESXiサーバ側(あるいは物理スイッチ側)の対象NICを一部切断し冗長性の確認
  • 物理スイッチ側のログやステータス確認コマンドにて、LAGのネゴシエーションが意図通りに成功していることの確認(特にLACP使用時)
  • テスト用にトラフィックを発生させ、遅延やロスが無いことの確認(アプリケーションの通信や、pingなど)

ESXiサーバのジャンボフレーム疎通確認(vmkping)

概要

VMware vSphere環境において、ESXiサーバの性能向上のためジャンボフレームを使用することがあります。NFSiSCSIを用いたストレージ通信や、VMotionの通信などです。
本記事は、ESXiサーバにおけるジャンボフレームの疎通確認方法をまとめたものです。 主な対象はESXi 6系、7系です。MTUの説明などは主にIPv4環境について記載しています(IPv6でなく)。

  • ESXiサーバが任意の通信相手とジャンボフレーム疎通できているか確認する。
  • ジャンボフレーム疎通できない場合に、切り分けする。

基本

ESXiサーバからのpingによる疎通確認(vmkping)

ESXiサーバにsshログイン後、CLIにて以下のコマンドを実行します。
# vmkping -I (送信元vmkernel) -d -s (送信サイズ) (送信先IPアドレス)

オプション 説明
-I (vmk名) 送信元vmkernelポート指定
-d DF bit(Don’t Fragmentフラグ)指定
-s (サイズ) 送信サイズ指定(単位:バイト)
ICMPヘッダを含まないICMPデータ部のサイズ
デフォルトは56バイト

疎通確認したい経路や送信先に対して適切にping送信できるようオプション指定します。
-Iオプションでは、ping送信元のインタフェースを指定します。vmkernelの名前(vmk0等)を指定可能です。ESXiサーバは複数のvmkernelで構成することが多いので、明示的に指定した方が分かりやすいです。
-dオプションは、ジャンボフレームの疎通確認時には必須のオプションです。このオプションの指定が漏れた場合、経路上でフラグメント(分割)が可能なDF bitオフのpingデータを送信することになるため、本当はMTU 1500の経路なのにping疎通が成功してしまうといった動作が生じ得ます。
-sオプションは、送信するpingデータの大きさを指定します。このオプションで指定したバイト数+28バイトが経路のMTU範囲内であれば、ping疎通が成功します。具体的には以下の通りです。

  • MTU 9000の経路における疎通確認時
    • -s 8972 を指定 (+28すると9000):ping成功する
    • -s 8973 を指定 (+28すると9001):ping失敗する
  • MTU 1500の経路における疎通確認時
    • -s 1472 を指定 (+28すると1500):ping成功する
    • -s 1473 を指定 (+28すると1501):ping失敗する

この+28の意味については、後述します。

VMware社のKBに詳細な説明があります。

また、ESXiサーバ上でvmkping --helpを実行することでvmkpingコマンドのヘルプを参照できます。

vmkpingが失敗する場合の切り分け

ジャンボフレームを指定したvmkpingが失敗する場合、以下のようにオプションを変更しながらvmkpingを再実行することにより、経路上のどの箇所でジャンボフレームの疎通ができなくなっているかを切り分けます。

  • -sで指定する値を小さくしていき、どの値までなら疎通可能かを確認する。
  • 送信先IPアドレスが別ネットワークである場合、まず同一ネットワーク内のIPアドレスでジャンボフレーム疎通なものがあればそれを送信先IPアドレスとして指定する。
  • 可能であれば、vmkpingを実行したホストとは別のホスト(ストレージ等)から同様にジャンボフレームの疎通確認を行う。

基本的には、送信元と送信先の間の経路にあるすべての機器や仮想スイッチが意図したサイズのジャンボフレームを許可するよう設定できている必要性があります。

詳細

vmkpingの-sオプションの値とMTUサイズの違い

vmkpingの-s オプションで指定する値は、「ICMPヘッダを含まないICMPデータ部のサイズ」です。
以下の説明にあるように28バイトを加えることで、IPレイヤまでのデータのサイズになります。

  • ICMPデータ部のサイズ(-sオプションで指定)
  • ICMPヘッダのサイズ(8バイト)
  • IPv4ヘッダのサイズ(20バイト)

上記の合計サイズが経路のMTU範囲内であれば疎通可となります。

ちなみ、上記の合計サイズに対してさらに、

も加えると、それがイーサネットフレームのサイズです。
(さらに余談ですがフレッツ網などPPPoEの場合は別ですがESXi環境とはほぼ関係無いので省略します)

SPSSライセンスサーバのログ確認、最大同時使用数の確認

概要

IBM SPSS Statisticsをそれなりの規模で運用する際、ライセンスサーバを用意してコンカレント・ライセンス(同時使用ユーザ数)で管理することが多いです。
SPSSは高価なソフトウェアなので、購入/更新するライセンス数を最低限に抑えられるとコスト削減になります。そのためには、今までのSPSS利用実績から最大同時使用数(=最大ライセンス消費数)を確認できるとライセンス数見直しの参考になります。
本記事は、SPSSライセンスサーバのログ確認方法をまとめたものです。

  • SPSSライセンスサーバのログを確認する。
  • ライセンス管理上の注意点を把握する。

基本

ライセンスサーバのログファイルのパス

ライセンスサーバの実行ファイル(lserv)の起動オプションとして、-lオプションの後に指定されたパスにログファイルが記録されます。
詳細は、ライセンスサーバのマニュアルか、IBM社のサポートページに、ログ出力方法の説明があります。

ライセンスサーバのログフォーマット

IBM社のサポートページ(How do I analyze a License Manager usage log file?)に、ログフォーマットの説明があります。

おおまかには、ログの中でFCodeごとのTimeInUseの最大値を確認すれば、そのログ期間中の製品/機能ごとの最大同時使用数(=最大ライセンス消費数)を確認できます。

以下は、このIBM社の説明に沿ってライセンスサーバのログを実際に確認し補足事項を加えたログフォーマット説明です。No.は左からスペース区切りで数えたものです。

No. 項目名 説明
1~3 (不明) IBM社のサポートページに説明はないが、1~3フィールド目には詳細不明なログが記録されている
4 DoW 曜日(day of week:)
5 Month
6 Date
7 Year
8 FCode 製品コード/機能コード(詳細は後述)
9 ProdVer その製品/機能のバージョン
例:v280はそのFCodeに対応する製品/機能のバージョン28を表す
10 TranType ライセンス処理の種類
数値の表す意味はおそらく以下
0: issued(例:SPSSクライアント起動によるライセンス払い出し時)
2: returned(例:SPSSクライアント終了によるライセンス返却時)
(他にdenied,checkout,checkinがあるらしい)
11 LicInUse その時点でのライセンス使用数
※ライセンス処理後の使用数が記録されるので、その行がライセンス払い出しのログであれば、その払い出し後の使用数
※FCodeとProdVerの組合せごとに集計されるため、同じ製品/機能の複数バージョンを同時に使用した場合、バージョンごとに集計される
12 TimeInUse そのライセンスが使用されていた時間(秒)
ライセンス返却時に記録されると思われる
13 UserName クライアントを起動したユーザ名
Windows上でSPSSクライアントを起動した場合は、そのWindowsにログオンしていたユーザ名
14 HostName クライアントを起動したユーザ名
Windows上でSPSSクライアントを起動した場合は、そのWindowsのコンピュータ名
15 LMVer ライセンスサーバのバージョン
以降 (不明) この後にもフィールドはあるが詳細不明
ライセンス返却時には「sc_RetToken」という文字列が記録されると思われる

ライセンスサーバのログの例

以下、ログの例です。

X X XXXXXXXX Thu May 05 12:55:55 2022  XXXXXXXX 1200 v280 0 10 0 user01 pc01 9.X.X.XXXX …
X X XXXXXXXX Thu May 05 13:05:55 2022  XXXXXXXX 1200 v280 2 9 600 user01 pc01 9.X.X.XXXX X sc_RetToken …

上記のログでは、2022年5月5日12:55:55にSPSS Statistics Base(SPSS本体のこと、FCodeは1200)のバージョン28のライセンスを1つ払い出し、その10分後にライセンスが返却されています。ライセンス使用数(LicInUse)は払い出し後に10になり、返却後には9に戻りました。使用したユーザはuser01で、pc01というコンピュータを使用していました。

ライセンスサーバのログ確認時の注意点

前述の通り、ライセンス使用数(LicInUse)は、FCodeとProdVerの組合せごとに集計されるため、同じ製品/機能の複数バージョンを同時に使用した場合、バージョンごとに集計されます。つまり、同じ製品/機能の複数バージョンを同時使用している場合には、そのFCodeの各バージョンの同時使用数の合計値が本来のライセンス使用数になります。この合計のライセンス使用数が、実際のライセンス購入数を超えてはいけません。

また、これは推測ですが、ライセンス購入/発行の仕方により、一部の製品/機能の使用に関するログが記録されない場合があるかもしれません。詳細はlsmonコマンドの箇所に記載してあります。正確な情報が必要な場合、IBMのサポートに問い合わせた方が良さそうです。

詳細

その他のライセンス情報の確認ツール

lmshowlicコマンド

SPSS本体(Base)とそのオプションのライセンスを全て表示します。
ただし、なぜかAmos分のライセンスについては表示されないかもしれません。

lsmonコマンド

SPSS本体(Base)とその一部オプションのライセンスを表示します。
Amos分のライセンスも表示されるようです。

ただし、SPSS本体と同数購入したオプション、あるいは同時に発行したライセンスが表示されないかもしれません。(先に説明したログファイルについても、このlsmonと同様に記録されていない製品/機能があるかもしれません)
例えば、SPSS本体(Base)を起動後、Advanced Statisticsを利用したのに、Base分の利用状況しかログファイルやlsmonに記録/表示されない場合、Advanced Statistics分のライセンスがBase分のライセンスと一体になっており、個別に記録/表示されない仕様ではないかと思われます(これは推測です)。

SPSSクライアント上で利用可能な製品を確認(show lic.)

SPSSクライアント上で、利用可能な製品/機能のライセンス情報を確認することもできます。
IBM社のサポートページに説明があります。

1. Statistics を起動します。
2. メニューより [ファイル]→[新規作成]→[シンタックス] を選択し、シンタックスエディタを起動します。
3. 以下のコマンドを入力します。 *コマンドの一番最後にピリオド . を入力してください。  
show lic.
4. メニューより [実行]→[すべて] を選択します。
5. Statistics の出力ビューアに認証されて、利用可能なオプション(Component: コンポーネント)、有効期限、バージョンが表示されます。
SPSSクライアント上で利用可能な製品を確認(インストール時)

SPSSクライアントのインストール時、ライセンスサーバを指定したときにも、インストーラ内の画面で、利用可能な製品/機能のライセンス情報を確認することもできます。

FCodeの説明
FCode 製品名、機能名
1200 Statistics Base
1201 Statistics Tables (Original)
1202 Statistics Regression
1203 Statistics Advanced Statistics
1204 Statistics Trends Original
1205 Statistics Exact Tests
1206 Statistics Categories
1207 Statistics Missing Values
1208 Statistics Conjoint
1210 Statistics Custom Tables
1211 Statistics Complex Samples
1212 Statistics Decision Trees
1213 Statistics Data Preparation
1214 Statistics Programmability
1215 Statistics Advanced Visualization
1216 Statistics Forecasting
1217 Statistics Data Adapter
1218 Statistics Neural Networks
1219 Statistics Direct Marketing
1220 Statistics Bootstrapping
1221 Statistics Developer
1320 Visualization Designer
6000 Text Analytics for Surveys 4.0.1
8000 Text Analysis for Surveys 3.0.0
8300 Text Analytics for Surveys 4.0.0
8400 Modeler
9005 Amos (Base)
9503 SamplePower
9800 AnswerTree