Docker for Macでの高いCPU使用率の診断


20

MacOSでDockerの原因を診断するには、具体的にcom.docker.hyperkitはCPUを100%使用しますか?

DockerのCPU使用率

Docker統計

Docker統計は、実行中のすべてのコンテナのCPU、メモリ、ネットIO、ブロックIOが低いことを示しています。

ドッカー統計出力

iosnoop

iosnoopはcom.docker.hyperkit、ファイルに対して毎秒約50回、合計500KB /秒の書き込みを実行することを示していますDocker.qcow2。よるとDocker.qcow2は何ですか?Docker.qcow2すべてのドッカーコンテナの永続ストレージだスパースファイルです。

私の場合、ファイルはそれほどスパースではありません。物理サイズは論理サイズと一致します。

docker.qcowの実際のサイズ

dtrace(dtruss)

dtruss sudo dtruss -p $DOCKER_PIDは多数のpsynch_cvsignaland psynch_cvwait呼び出しを示します。

psynch_cvsignal(0x7F9946002408, 0x4EA701004EA70200, 0x4EA70100)          = 257 0
psynch_mutexdrop(0x7F9946002318, 0x5554700, 0x5554700)           = 0 0
psynch_mutexwait(0x7F9946002318, 0x5554702, 0x5554600)           = 89474819 0
psynch_cvsignal(0x10BF7B470, 0x4C8095004C809600, 0x4C809300)             = 257 0
psynch_cvwait(0x10BF7B470, 0x4C8095014C809600, 0x4C809300)               = 0 0
psynch_cvwait(0x10BF7B470, 0x4C8096014C809700, 0x4C809600)               = -1 Err#316
psynch_cvsignal(0x7F9946002408, 0x4EA702004EA70300, 0x4EA70200)          = 257 0
psynch_cvwait(0x7F9946002408, 0x4EA702014EA70300, 0x4EA70200)            = 0 0
psynch_cvsignal(0x10BF7B470, 0x4C8097004C809800, 0x4C809600)             = 257 0
psynch_cvwait(0x10BF7B470, 0x4C8097014C809800, 0x4C809600)               = 0 0
psynch_cvwait(0x10BF7B470, 0x4C8098014C809900, 0x4C809800)               = -1 Err#316

更新:topDockerホスト上

https://stackoverflow.com/a/58293240/30900から:

docker run -it --rm --pid host busybox top

Docker組み込みホストのCPU使用率は約3%です。MacBookのCPU使用率は100%以下でした。つまり、Docker組み込みホストがCPU使用率の急上昇を引き起こしていません。

ドッカーホストトップ

更新:最も一般的なスタックトレースのdtraceスクリプトの実行

以下の回答のdtraceスクリプトからのスタックトレース:https : //stackoverflow.com/a/58293035/30900

これらのカーネルスタックトレースは無害に見えます。

              AppleIntelLpssGspi`AppleIntelLpssGspi::regRead(unsigned int)+0x1f
              AppleIntelLpssGspi`AppleIntelLpssGspi::transferMmioDuplexMulti(void*, void*, unsigned long long, unsigned int)+0x91
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::transferDataMmioDuplexMulti(void*, void*, unsigned int, unsigned int)+0xb2
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::_transferDataSubr(AppleInfoLpssSpiControllerTransferDataRequest*)+0x5bc
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::_transferData(AppleInfoLpssSpiControllerTransferDataRequest*)+0x24f
              kernel`IOCommandGate::runAction(int (*)(OSObject*, void*, void*, void*, void*), void*, void*, void*, void*)+0x138
              AppleIntelLpssSpiController`AppleIntelLpssSpiDevice::transferData(IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, unsigned int, AppleIntelSPICompletion*)+0x151
              AppleHSSPISupport`AppleHSSPIController::transferData(IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, unsigned int, AppleIntelSPICompletion*)+0xcc
              AppleHSSPISupport`AppleHSSPIController::doSPITransfer(bool, AppleHSSPITransferRetryReason*)+0x97
              AppleHSSPISupport`AppleHSSPIController::InterruptOccurred(IOInterruptEventSource*, int)+0xf8
              kernel`IOInterruptEventSource::checkForWork()+0x13c
              kernel`IOWorkLoop::runEventSources()+0x1e2
              kernel`IOWorkLoop::threadMain()+0x2c
              kernel`call_continuation+0x2e
               53

              kernel`waitq_wakeup64_thread+0xa7
              pthread`__psynch_cvsignal+0x495
              pthread`_psynch_cvsignal+0x28
              kernel`psynch_cvsignal+0x38
              kernel`unix_syscall64+0x27d
              kernel`hndl_unix_scall64+0x16
               60

              kernel`hndl_mdep_scall64+0x4
              113

              kernel`ml_set_interrupts_enabled+0x19
              524

              kernel`ml_set_interrupts_enabled+0x19
              kernel`hndl_mdep_scall64+0x10
             5890

              kernel`machine_idle+0x2f8
              kernel`call_continuation+0x2e
            43395

ユーザー空間で最も一般的なスタックトレースが17秒以上続くことは、明らかにcom.docker.hyperkitに関係しています。com.docker.hyperkit1秒あたり平均80スレッドになるスレッドを作成した17秒の1365スタックトレースがあります。

              com.docker.hyperkit`0x000000010cbd20db+0x19f9
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               19

              Hypervisor`hv_vmx_vcpu_read_vmcs+0x1
              com.docker.hyperkit`0x000000010cbd4c4f+0x2a
              com.docker.hyperkit`0x000000010cbd20db+0x174a
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               22

              Hypervisor`hv_vmx_vcpu_read_vmcs
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               34

              com.docker.hyperkit`0x000000010cbd878d+0x36
              com.docker.hyperkit`0x000000010cbd20db+0x42f
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               47

              Hypervisor`hv_vcpu_run+0xd
              com.docker.hyperkit`0x000000010cbd20db+0x6b6
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
              135

関連する問題

Github- docker / for-mac:com.docker.hyperkit 100%cpu使用率が再び戻ってきました#3499 。コメントの1つは、https://www.docker.com/blog/user-guided-caching-in-docker-for-mac/で説明されているボリュームキャッシングの追加を提案しています。私はこれを試してみて、CPU使用量を約10%削減しました。


画像を作成していますか?また、多くのブロックIOを実行するコンテナーにも焦点を当てます。Kubernetesを有効にしているかどうかも重要です。
BMitch

1
クラスターを構築して数分間実行した後、すべてのメトリックを収集しました。Kubernetesが無効になっています。ただし、どのマシンも多くのブロックIOを実行しません。コンテナは何もしていません。CPU使用率はおおよそコンテナーの数に相関しているようです。
Joe

マシンにはいくつのコア/ CPUがありますか?
-BMitch

また、コンテナーではなく、エンジンとデスクトップクライアント全体の再起動を試みましたか?
BMitch

私は4コアの2018 MBP 2.8 GHz Core i7を実行しています。DockerエンジンのCPUコアの数を微調整してみました。1、3、4、6コアを試してみました。dockerに制限すると、CPU使用率が100%から60%に減少しました。
Joe

回答:


5

私は同じ問題を抱えています。すべてのボリュームを削除した後、CPU使用率が通常に戻りました。

docker system prune --volumes

名前付きボリュームも手動で削除しました。

docker volume rm NameOfVolumeHere

Mac用のDockerでボリュームを使用できないという全体的な問題は解決しません。現在、使用しているボリュームの量に注意し、使用していないときはDockerデスクトップを閉じています。


3

私の疑いは、この問題はIO関連であるということです。MacOSボリュームでは、これにはosxfsが含まれ、実行できるパフォーマンスチューニングがいくつかあります。主に、受け入れられる整合性チェックの数が少ない場合は、delegatedパフォーマンスを向上させるためにボリュームモードをに設定できます。詳細については、https://docs.docker.com/docker-for-mac/osxfs-caching/のドキュメントをご覧ください。ただし、画像に多数の小さなファイルが含まれている場合は、特に多くの画像レイヤーもある場合、パフォーマンスが低下します。

次のコマンドを試して、Dockerが使用する組み込みVM内のプロセスの問題をデバッグすることもできます。

docker run -it --rm --pid host busybox top

(終了するには、を使用<ctrl>-c


IOかどうかを追跡するには、次の方法も試すことができます。

$ docker run -it --rm --pid host alpine /bin/sh
$ apk add sysstat
$ pidstat -d 5 12

これは、VM pid名前空間で実行されている高山コンテナ内で実行され、そのプロセスがコンテナ内にあるかどうかに関係なく、任意のプロセスから発生するIOを示します。統計は1分間5秒ごと(12回)であり、プロセスごとの平均テーブルを提供します。その後<ctrl>-d、高山コンテナを破壊することができます。


コメントと編集から、これらの統計はチェックアウトされるかもしれません。4コアのMBPには8つのスレッドがあるため、MacOSが他のUnixベースのシステムと同じことを報告している場合、完全なCPU使用率は800%になります。VM内には、過去1分間の平均(5と15の平均からは下がっています)の上部のコマンドに表示されている100%を超える負荷があります。システムとユーザーのパーセンテージを追加する必要があるため、瞬間的な使用率は3%ではなく、上から12%を超えています。また、pidstatに表示されるIO番号は、qcow2イメージに書き込まれたものとほぼ一致します。


Dockerエンジン自体がスラッシングしている場合(たとえば、コンテナーの再起動、または多数のヘルスチェックの実行)、次の出力を監視してデバッグできます。

docker events

すべてのボリュームマウントをに変更しましdelegatedたが、パフォーマンスは向上しませんでした。top組み込みVMでコマンドを実行しましたが、CPU使用率は約3%で止まっていました。
Joe

pidstatIOの問題をより適切に追跡するために更新されました。
-BMitch

pidstatすべてのPIDの読み取りが0 kB /秒であることを示します。書き込みの場合:logwrite平均でinfluxd8.5kB / s を書き込み、平均で0.61kB / s を書き込みます。プロセスの残りの部分は0である
ジョー

1

これは、カーネルが時間を費やしている場所を見つけるために使用する小さなdTraceスクリプトです(Solarisからのものであり、Solaris 10の初期にさかのぼります)。

#!/usr/sbin/dtrace -s

profile:::profile-1001hz
/arg0/
{
    @[ stack() ] = count();
}

カーネルスタックトレースをサンプリングし、@hot集計で検出された各トレースをカウントします。

ルートとして実行します。

... # ./kernelhotspots.d > /tmp/kernel_hot_spots.txt

CPUの問題が発生している間は、ある程度の時間実行してから、実行しCTRL-Cてスクリプトを中断します。遭遇したすべてのカーネルスタックトレースを出力します。最も一般的なものは最後です。デフォルトからより多くの(またはより少ない)スタックフレームが必要な場合

    @[ stack( 15 ) ] = count();

これにより、15コールの深さのスタックフレームが表示されます。

最後のいくつかのスタックトレースは、カーネルがほとんどの時間を費やしている場所です。これは有益な場合とそうでない場合があります。

このスクリプトは、ユーザー空間のスタックトレースに対しても同じことを行います。

#!/usr/sbin/dtrace -s

profile:::profile-1001hz
/arg1/
{
    @[ ustack() ] = count();
}

同様に実行します。

... # ./userspacehotspots.d > /tmp/userspace_hot_spots.txt

ustack() 少し遅い-実際の関数名を出力するには、dTraceが適切なプロセスのアドレス空間からそれらを取得するために、さらに多くの作業を行う必要があります。

システム整合性保護を無効にすると、スタックトレースを改善できる場合があります。

詳細については、DTraceアクションの基本を参照してください。


おかげで、スクリプトの結果で質問を更新しました。ユーザー空間のスタックトレースは、com.docker.hyperkitが多くのスレッドを作成することを示しています。
Joe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.