時刻ズレを直す - hwclock
Windows のスリープや休止から復帰した後に、WSL2 内の時計が数秒〜数分遅れる現象。TLS 証明書検証や JWT の有効期限判定が失敗する原因になる。
概念図
構文
bash
sudo hwclock -s
timedatectl status実例
現在時刻と時差を確認
bash
dateハードウェアクロック(Windows 側)から即時同期
bash
sudo hwclock -ssystemd-timesyncd の同期状態を確認
bash
timedatectl status概要
WSL2 のカーネルは起動時に Windows のハードウェアクロックを読み取って自身の時計を合わせます。
しかし Windows がスリープや休止、あるいは電源プランによる低電力状態に入ると、VM 内のクロックはティックが止まる一方、実世界の時間は進みます。
復帰時に VM が再開しても、内部時刻は「止まっていた時間分」遅れたまま戻ることがあります。
数秒のズレでも、TLS 証明書の有効期間境界、JWT / OIDC トークンの exp / nbf 検証、Kerberos の 5 分窓、ログの時系列整合などに影響します。
再現性の悪い「たまに HTTPS が通らない」「ログインだけ失敗する」などの挙動の裏にこの問題が潜んでいることがあります。
典型的な用途
- ノート PC を閉じて移動し、カフェで開いたら
git pushが TLS エラーで失敗するケース - AWS / GCP / Azure の API 認証が「時計がずれています」と拒否される(AWS の 15 分、GCP の 10 分等のスキュー)
- OIDC 認証で
nbf/expが成立せずログインループする - Docker コンテナ内の時計もホスト WSL2 に追従するため、同じ問題を受ける
- 分散システムのローカル開発で、ノード間のイベント順序が乱れる
コマンド例
# ズレを確認
date
# Fri Apr 18 10:32:11 UTC 2026
# Windows 側のハードウェアクロックから即時同期(systemd 不要)
sudo hwclock -s
# systemd が有効なら NTP 同期
timedatectl status
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd
# 手動 NTP
sudo apt install -y ntpdate
sudo ntpdate pool.ntp.org
# 軽めの回避策: スリープ明けにホストクロックから引き直す
# /etc/wsl.conf(WSL 起動時に実行されるコマンドを登録)
[boot]
command="hwclock -s"
ベストプラクティス
- systemd を有効化(
wsl.confの[boot] systemd=true)し、systemd-timesyncdかchronyで継続同期させる - 1 発補正で十分な環境では
/etc/wsl.confの[boot] command="hwclock -s"を入れておく - スリープ復帰後に挙動がおかしいと感じたら、まず
dateで時刻を確認する癖をつける - CI 実機環境との差が問題になる場合は Docker コンテナ側にも
tzdataと NTP クライアントを導入し、独立に同期させる - Kubernetes ローカルクラスタ(kind, k3d)を使う場合、ノード Pod の時刻も同じホストから引くため、ホストの時刻同期を最優先にする
注意点
- WSL2 のカーネルは比較的新しい版でスリープ復帰時のクロック補正を改善している。まず
wsl --updateで最新に保つ ntpdateは後方互換ツールで UDP 123 がブロックされた環境では失敗する。chronyに切り替える- Windows 側のタイムゾーンと WSL2 側のタイムゾーンがズレていると、
dateの表示だけ違って見えて「直したつもりが直っていない」状態になる - Docker Desktop を介した場合、
docker-desktopディストリ側の時計もズレる。必要なら同様に同期設定する - Hyper-V の時刻同期統合(Time Synchronization Integration Services)は WSL2 ではユーザーが直接制御しにくい
関連トピック
WSL2- Windows Subsystem for Linux の第 2 世代。Hyper-V 技術を基盤にした軽量 VM 上で本物の Linux カーネルを動かす方式で、WSL1 のエミュレーションとは根本的に別物。Docker Desktop の標準バックエンドでもある。 Docker Desktop- Docker Desktop for Windows は WSL2 をバックエンドとしてコンテナを動かす構成。`docker-desktop` 専用ディストリに dockerd を常駐させ、ユーザーのディストリからは統合機能で透過的に使える。 systemd- かつて WSL2 は独自 init を使っており systemd が動かなかったが、2022 年以降の WSL でネイティブサポートされた。`/etc/wsl.conf` に `systemd=true` を書き、`wsl --shutdown` で再起動するだけで有効になる。 