VSCode on WSLでdevcontainerの初期セットアップがHTTPプロキシ環境下だとめんどい

要約

多分なんか設定を見落としてるか手順を間違えてるか何かな気はするが…

でもなんで治ったかわかってない

ただ、よくわからないのは、なぜかリダイレクトした先で失敗する。

やっていることは以下だ。.devcontainer/devcontainer.jsonを作るまでに以下の通信をしているっぽい。(>Dev Container: log とかすれば確認できる)

  1. ghcr.ioからトークンを得る
  2. トークンを使いghcr.ioからマニフェストファイル一式(blob.tar)を取得する → pkg-containers.githubusercontent.comへリダイレクト
  3. pkg-containers.githubusercontent.comから取得する → タイムアウトError getting blob: Error: connect ETIMEDOUT 2606:50c0:8001::154:443

このIPv6がなんなのかすぐにわからなかったが、pkg-containers.githubusercontent.comを名前解決すると複数あるやつの1つということがわかった。

単純に環境変数HTTPS_PROXY設定の問題なのであれば、(1)か(2)の時点で失敗するはず…なんだけど、ここはなぜか、なぜか、通過した。

悩みながらログを見ていて思ったのが、このdevcontainers拡張機能自体はWSLではなくホスト機の方で動いているので、もしかしてホスト機のProxyの環境変数が必要なのでは?と思い、ホスト機からcmdで以下のようにして起動しなおす。(環境変数を設定して起動するだけ)

set HTTPS_PROXY=https://id:pass@proxy.example.local:8080
code

これだけでうまくいった。なので解決して「よかったですね」で終わるのだけど。

解せない

解せないのはそこまで到達できているのはなんなんだ、ということ。

プロキシを通らないとインターネットに出れない環境なので、その前のghcr.ioの通信はどうやって解決しているのか。そもそも(1)のトークンの時点でキャッシュできない内容なのでインターネットに出るのは間違いないし、(3)のURLを得るには(2)の通信が必要で、どうやって通信したのか?

スタックトレースを頼りに軽く処理を見た感じ、該当のコードはここっぽい。リダイレクトの実装はfollow-redirectsパッケージを使っていそう。Proxy対応にはproxy-agentを使っている模様。(なおNodeJS自体にはHTTPS_PROXY環境変数を解釈する機能はない!)うーん、でもそれなら動くんじゃないんか…

ということでよくわからず。

悩んだが気になったのはghcr.ioの時はIPv4で、pkg-containers.githubusercontent.comのときはIPv6で通信しようとしているので、これがリダイレクト周りで何か変な動きになるのだろうか。いやでもそれならHTTPS_PROXYの指定が無かった時にも動かないはずじゃろうて・・・リダイレクト時のプロキシの通信がおかしいのか?わけわからん。難しい。

WD製のHDDに搭載されているらしいIntelliParkについて調べた

調べた

WD製のHDDにはIntelliParkというエコ機能があるらしい。調べてみたが、公式の文書はもはやないようなのと、サポートで検索してみてもなぜかBAD Gatewayとなって検索できなかったり、謎の機能。でも実装はされているらしい。

ググると、磁気ヘッドを退避(アンロード)させて待機状態にすることで省電力になるというものらしい。この省電力の状態を Idle 3 と呼んでいるらしい。製品によるかもしれないがデフォルトでは8秒でこの状態に移行するらしい。

しかしアンロードの操作回数は寿命の1つの目安でもあるため「それを無駄に行うとはけしからん!無効化したりしなかったりしろ!」と言われる機能らしい。

無効化するには?

非公式だけど、最近はhdparmで設定できるらしい。オプションが面白すぎる

https://wiki.archlinux.org/title/hdparm#Power_management_for_Western_Digital_Green_drives

もちろん無効化ではなくIdle 3に移行するまでの猶予時間を指定することもできる。Arch Linux Wikiでは30秒当たりが良いのではとのこと。使われ方にもよると思うけど。

試した。デバイス/dev/sdbは適宜置き換える。多分他のデバイスにやると危険かもしれない。

# バージョン
hdparm -V
# => hdparm v9.54

# 設定値確認(-Jオプションのみで引数を与えない)
sudo hdparm -J /dev/sdb

# => /dev/sdb:
# =>  wdidle3      = 8.0 secs

# 設定しようとしてみる(オプションがないので失敗)
sudo hdparm -J 0 /dev/sdb

# => /dev/sdb:
# => Use of -J is EXTREMELY DANGEROUS.
# => This implementation is not as thorough as the official WDIDLE3.EXE. Use at your own risk!
# => Please also supply the --please-destroy-my-drive flag if you really want this.

# 無効化の設定 (-Jオプションの引数として0を与える)
sudo hdparm -J 0 --please-destroy-my-drive /dev/sdb

# => /dev/sdb:
# =>  setting wdidle3 to disabled
# =>  wdidle3      = disabled

# 30秒の設定
sudo hdparm -J 30 --please-destroy-my-drive /dev/sdb

# => /dev/sdb:
# =>  setting wdidle3 to 30 secs (or 12.9 secs for older drives)
# =>  wdidle3      = 30 secs (or 12.9 secs for older drives)

感想

ロード/アンロードで寿命に影響するのか?

個人的には「別にヘッドはランダムアクセスしたらもっと激しく動き続けるんだから電源オン/オフで変わるもんなの?」という思いがある。

今WD60EZAXを使っているが、その製品仕様は以下のように公開されている(URLは変わるかも)

https://documents.westerndigital.com/content/dam/doc-library/en_us/assets/public/western-digital/product/internal-drives/wd-blue-hdd/product-brief-western-digital-wd-blue-pc-hdd.pdf

で、そこに「Load/unload cycles (Controlled unload at ambient condition.)」で300,000回とある。これが十分な回数かどうかはわからないが、よく1分毎にログを取るということはサーバ用途ではやりますから、ちょっと強引ですが60秒ごとにアクセスするとしてみる。すると8秒で待機状態になるなら60秒に1回ロードが起きる。これを基準にすると208日で到達してしまう。そう考えるとこの30万回というのはちょっと少なすぎるという印象。とはいえ、そもそもサーバ用途に使うことは想定されてなくて保証も2年だから多分想定が違いそう。1日8時間使い倒すスタイルならロード回数が1/3以下になるので保証期間内ギリギリという感じになりそう。

とはいえ長く使いたい。そういったときにIntelliparkをオフにするもしくは長めに設定する価値があるのかという話。

ただ個人的には、ずっとWDのHDDをつかってNASを組んでおり、特にハードな使い方をしているわけではないとはいえ、7年でようやく1台故障したという経験がある。

そして今の4TB x 4のNASはそこからしばらく動いているので、うーんといった印象。省電力機能が逆に機能しているともいえそうだけど。

とりあえず現状はこんな感じ。正直、LVMの関係でめんどくさいことになってる。

# mdadmのRAID1とHDDデバイスのマッピング確認
$ cat /proc/mdstat
Personalities : [raid1]
md126 : active raid1 sdd[3] sde[2]
      3907017560 blocks super 1.2 [2/2] [UU]
      [===========>.........]  check = 55.7% (2176986368/3907017560) finish=197.6min speed=145879K/sec

md127 : active raid1 sdc[2] sdb[3]
      3907017560 blocks super 1.2 [2/2] [UU]
      [===========>.........]  check = 55.4% (2167825664/3907017560) finish=201.0min speed=144183K/sec

unused devices: <none>
# PVとLVのマッピング確認
$ sudo lvs -o+seg_pe_ranges
  LV            VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert PE Ranges
  nas          vg1       -wi-ao----  <5.64t                                                     /dev/md126:524288-953860
  nas          vg1       -wi-ao----  <5.64t                                                     /dev/md126:393216-487930
  nas          vg1       -wi-ao----  <5.64t                                                     /dev/md127:0-953860
  iscsi vg1       -wi-ao----  <1.64t                                                     /dev/md126:0-393215
  iscsi vg1       -wi-ao----  <1.64t                                                     /dev/md126:487931-524287

# こんな感じにマッピングされている

# |iscsi|nas|iscsi | nas          |
# | md126          | md127        | 
# | sdd / sde      | sdb / sdc    | # <= ここはRAID1なので1台分

# なんでこんなヘンテコな割り当てにしたんだろう…
# 一応用途としては、iscsiはあまり使われていなくて、nasをよく使っている。  /dev/md127である sdb/sdcはよく使われているということ

# sdb(/dev/md127のほう)
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   200   200   051    Pre-fail  Always       -       0
  3 Spin_Up_Time            0x0027   170   169   021    Pre-fail  Always       -       6475
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       30
  5 Reallocated_Sector_Ct   0x0033   200   200   140    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   100   253   000    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   043   043   000    Old_age   Always       -       42174
 10 Spin_Retry_Count        0x0032   100   253   000    Old_age   Always       -       0
 11 Calibration_Retry_Count 0x0032   100   253   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       30
192 Power-Off_Retract_Count 0x0032   200   200   000    Old_age   Always       -       15
193 Load_Cycle_Count        0x0032   191   191   000    Old_age   Always       -       29487
194 Temperature_Celsius     0x0022   103   099   000    Old_age   Always       -       47
196 Reallocated_Event_Count 0x0032   200   200   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   200   200   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   200   200   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x0008   200   200   000    Old_age   Offline      -       0

# sdd(/dev/md126のほう)
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   200   200   051    Pre-fail  Always       -       0
  3 Spin_Up_Time            0x0027   165   164   021    Pre-fail  Always       -       6725
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       30
  5 Reallocated_Sector_Ct   0x0033   200   200   140    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x002e   100   253   000    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   043   043   000    Old_age   Always       -       42165
 10 Spin_Retry_Count        0x0032   100   253   000    Old_age   Always       -       0
 11 Calibration_Retry_Count 0x0032   100   253   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       30
192 Power-Off_Retract_Count 0x0032   200   200   000    Old_age   Always       -       15
193 Load_Cycle_Count        0x0032   001   001   000    Old_age   Always       -       1204985
194 Temperature_Celsius     0x0022   102   099   000    Old_age   Always       -       48
196 Reallocated_Event_Count 0x0032   200   200   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   200   200   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   200   200   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x0008   200   200   000    Old_age   Offline      -       0

Load_Cycle_Count はsddのほうが狂ったように増えている…ISCSIで繋げている弊害だろうか…

まぁでもこれだけやっても動いているんだし…気にせんでもよいのでは感がある。 (壊れていてただたまたまアクセスが発生していないから問題になってないという可能性もありそうだが。ただその場合はRAIDの同期で悲鳴が上がるはずだしなぁ。)

とはいえ、無効にしてみたさはあるので、次のNASには設定をしてみたいと思う。

(実はまだNASの移行が終わってない。作って満足しちゃって空き容量もまだあるから移行するきっかけがなくてめんどくさくなっちゃって…)

今どきのHDDの内周と外周をfioで計測してみる

結構前に試してtwitterに流していたネタを賑やかしにこっちにも投稿する。

HDDの内周と外周で速度が変わるというものがある。円盤なので同じ回転数なら外側のほうがスピードが出るし、同じ1回転なら外側のほうが面積が大きくなるので読み書き性能が良くなるというもの。実際に試したことがなかったのと、最近はどうなんだろうと思っていたところ、fioのoffsetでそれっぽいことができそうなので試した。

自作したNASにあるHDDでシーケンシャルな読み取りを試したところ、外周:202MiB/s、内周:92.6MiB/sだった。思っていたより差が出た。HDDの型番はWD60EZAX。

fioを入れればすぐに試せるコマンド例と計測時のログを貼っておく。

ディスクの内周と外周を測ってみる.sh · GitHub

なお、fio上は内周と外周の概念はなく、offsetの違いをみて判断している。今回であればOffset=0のほうがスループットが出ていたのでこちらを外周としている。(目視で見たわけではないのでもしかしたら内周の結果かもしれないが、offsetで違いが出ているという事実は変わらないので、まぁいいのではないでしょうか。)

また、上記のスクリプトファイルシステムではなくデバイスに対して読み書きをするので、素直に書き込み処理を実行するとファイルシステムメタデータを平気でぶち壊します。注意しましょう(1敗)