<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
  <channel rdf:about="https://www.fraction.jp/log/">
    <title>煩悩分画</title>
    <link>https://www.fraction.jp/log/</link>
    <description>世の中に寝るより楽はなかりけり&lt;br /&gt;浮世の馬鹿は起きて働く</description>
    
    <dc:creator>O. Yuanying</dc:creator>
	<dc:date>2025-05-29T09:06:24+00:00</dc:date>
	<admin:generatorAgent rdf:resource="https://github.com/yuanyig/komo"/>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2025/05/29/evo-x2-gfx1151" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2025/01/14/ubuntu-on-raspberry-pi5" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2023/07/22/utsunomiya-aizu-echigo" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2023/05/02/jetson-pytorch" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2023/04/29/jetson-k8s" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2023/04/27/jetson-orin-nano" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2023/03/23/new-pc" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2022/10/27/mt-otsuka" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2022/10/13/choshi-cape" />
        <rdf:li rdf:resource="https://www.fraction.jp/log/archives/2022/09/29/kubevirt-noip-after-restart" />
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="https://www.fraction.jp/log/archives/2025/05/29/evo-x2-gfx1151">
    <title>Ryzen AI MAX+395（on Ubuntu）で PyTorch をビルド</title>
    <link>https://www.fraction.jp/log/archives/2025/05/29/evo-x2-gfx1151</link>
    <description>GMKtec の EVO-X2 を買った。Windows はここ最近使ったことなかったので、速攻で Ubuntu をインストールしたのだが、結構茨の道だった。そもそも手順が悪いのか、ROCmがまだ Ryzen AI Max+ 395 (gfx1151) に対応してないからなのか、pytorch が動かない。すなわち芋蔓式に、Stable Diffusionも動かなければFramepackも動かないし、llama.cpp も Vulkan で動かさざるを得ない。ということで Ryzen AI Max...</description>
    <content:encoded><![CDATA[
        <p>GMKtec の EVO-X2 を買った。</p>

<p class='image'>
<img  src='/log/archives/2025/05/29/IMG_0960.jpg'
      width='800'
      height='600'
      alt='GMKtec Evo-X2'  />
</p>


<p>Windows はここ最近使ったことなかったので、速攻で Ubuntu をインストールしたのだが、結構茨の道だった。そもそも手順が悪いのか、ROCmがまだ Ryzen AI Max+ 395 (gfx1151) に対応してないからなのか、pytorch が動かない。</p>

<p>すなわち芋蔓式に、Stable Diffusionも動かなければFramepackも動かないし、llama.cpp も Vulkan で動かさざるを得ない。</p>

<p>ということで Ryzen AI Max+ 395 で動く pytorch は自分でビルドすれば手に入るということを知ったので自分でビルドした。</p>

<p>ちなみに、単にコンテナで動かしたいだけなら以下のコンテナイメージをベースにすれば良さそう。</p>

<ul>
<li><a href="https://github.com/ROCm/TheRock/pkgs/container/therock_pytorch_dev_ubuntu_24_04_gfx1151">therock_pytorch_dev_ubuntu_24_04_gfx1151</a></li>
</ul>


<p>こんな感じで動作確認できる。</p>

<pre><code class="bash">$ sudo docker run -it --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
--device=/dev/kfd --device=/dev/dri --group-add video \
--ipc=host ghcr.io/rocm/therock_pytorch_dev_ubuntu_24_04_gfx1151:nightly \
python -c "import torch; a=torch.randn(3).to('cuda'); print(a)"
tensor([0.0159, 0.7455, 1.3787], device='cuda:0')
</code></pre>

<p>ビルドするなら、現時点で自分が試したのは以下の二つ。</p>

<ol>
<li><a href="https://github.com/ROCm/TheRock"><code>ROCm/TheRock</code></a></li>
<li><a href="https://github.com/scottt/rocm-TheRock"><code>scottt/rocm-TheRock</code></a></li>
</ol>


<h2>環境</h2>

<pre><code class="Dockerfile">FROM ubuntu:24.04
</code></pre>

<p>自分はメインの作業をコンテナ上でやっているので上記となる。ちなみにホストのOSも Ubuntu 24.04である。</p>

<h2><code>ROCm/TheRock</code></h2>

<p>実際のところ、<code>ghcr.io/rocm/therock_pytorch_dev_ubuntu_24_04_gfx1151:nightly</code> に gfx1151 用の pytorch がインストールされているので再ビルドすることもなくそれを持ってこれればいいのだけど、インストール済みの python パッケージを再パッケージ化する方法がわからなかったので、ビルドした。</p>

<p>方法は docker がインストールされていれば単純で、READMEに書いてある通りに、</p>

<pre><code class="bash"># Install Ubuntu dependencies
sudo apt install gfortran git git-lfs ninja-build cmake g++ pkg-config xxd patchelf automake python3-venv python3-dev libegl1-mesa-dev

# Clone the repository
git clone https://github.com/ROCm/TheRock.git
cd TheRock

# Init python virtual environment and install python dependencies
python -m venv .venv &amp;&amp; source .venv/bin/activate
pip install -r requirements.txt

# Download submodules and apply patches
python ./build_tools/fetch_sources.py
</code></pre>

<p>そして、おもむろに <code>docker build</code></p>

<pre><code class="bash">sudo docker build --build-arg AMDGPU_TARGETS=gfx1151 \
     --file dockerfiles/pytorch-dev/pytorch_dev_ubuntu_24.04.Dockerfile \
     --target pytorch_build --tag ghcr.io/rocm/therock_pytorch_dev_ubuntu_24_04_gfx1151:pytorch_build \
     .
</code></pre>

<p>PyTorch のコンテナイメージをビルドする <code>Dockerfile</code> が <code>dockerfiles/pytorch-dev/pytorch_dev_ubuntu_24.04.Dockerfile</code> にあるのだけど、ビルドが終了するとせっかく生成した <code>torch-*.whl</code> が削除されてしまうので、途中の <code>pytorch_build</code> をターゲットにしてビルドする。</p>

<p>出来上がった <code>ghcr.io/rocm/therock_pytorch_dev_ubuntu_24_04_gfx1151:pytorch_build</code> には</p>

<ul>
<li><code>/opt/rocm</code>: gfx1151 用の ROCm</li>
<li><code>/therock/pytorch/dist</code>: pytorch の wheel が含まれたディレクトリ</li>
<li><code>/therock/pytorch_vision/dist</code>: pytorch_vision の wheel が含まれたディレクトリ</li>
<li><code>/thero-k/pytorch_audio/dist</code>: pytorch_audio の wheel が含まれたディレクトリ</li>
</ul>


<p>があるので、よしなにコピーしてきて使う。(<code>docker run</code> した後に <code>docker cp</code> して持ってくるなど。)</p>

<p>ちなみに、性能はそれほど良くない。</p>

<h2><code>scottt/rocm-TheRock</code></h2>

<p>実際、上記を試してて、Stable Diffusionが遅いなーと思っていたところ、TheRock をメンテしてるっぽい scottt さん<code>scottt/rocm-TheRock</code> を知った。</p>

<ul>
<li><a href="https://github.com/ROCm/TheRock/discussions/244">gfx1151: I have pytorch, pytorch-vision, and hipBLASLt working well enough to run GPT2</a></li>
</ul>


<p>gfx1151 で GPT2 を十分に動かすことができる <code>pytorch</code>, <code>pytorch-vision</code>, <code>hipBLASLt</code> を持ってるらしい。マジか。</p>

<p>コメントにはご丁寧にもビルド方法が書いてある。</p>

<pre><code class="bash">git clone git@github.com:scottt/rocm-TheRock.git
cd rocm-TheRock
git switch gfx1151
podman build -t rocm-dev-f41 -f ./dockerfiles/pytorch-dev/rocm_fedora.Dockerfile .
podman build -t pytorch-dev-f41 -f dockerfiles/pytorch-dev/pytorch_dev_fedora.Dockerfile .
podman build -t pytorch-vision-dev-f41 -f dockerfiles/pytorch-dev/pytorch_vision_dev_fedora.Dockerfile .
</code></pre>

<p>最終的にできた <code>pytorch-vision-dev-f41</code> に、<code>hipBLASLt</code> が有効化された <code>ROCm</code> と <code>torch</code>, <code>torch_vision</code> が含まれているのだが、出来上がったパッケージが python3.13 用だったりビルドがうまく走らなかったりしたのでちょっと修正した。</p>

<pre><code class="diff">diff --git a/dockerfiles/pytorch-dev/pytorch_dev_fedora.Dockerfile b/dockerfiles/pytorch-dev/pytorch_dev_fedora.Dockerfile
index 462af8c..24f3705 100644
--- a/dockerfiles/pytorch-dev/pytorch_dev_fedora.Dockerfile
+++ b/dockerfiles/pytorch-dev/pytorch_dev_fedora.Dockerfile
@@ -15,6 +15,10 @@ RUN --mount=type=cache,id=pytorch-f${FEDORA_VER},target=/therock \
                --no-patch \
                --no-hipify

+RUN --mount=type=cache,id=f${FEDORA_VER},target=/var/cache/dnf  \
+       dnf5 install -y python3.12 python3.12-devel &amp;&amp; \
+    alternatives --install /usr/bin/python python /usr/bin/python3.12 2
+
 # pytorch-prep
 # for `git am`
 RUN git config --global user.email "you@example.com" &amp;&amp; \
@@ -31,7 +35,8 @@ RUN --mount=type=cache,id=pytorch-f${FEDORA_VER},target=/therock \
 # pytorch-build
 RUN --mount=type=cache,id=pytorch-f${FEDORA_VER},target=/therock \
        cd /therock/pytorch &amp;&amp; \
-       uv pip install --system -r requirements.txt
+       uv pip install --system -r requirements.txt &amp;&amp; \
+       uv pip install --system cmake==3.25.2

 ENV CMAKE_PREFIX_PATH=/opt/rocm
 ENV USE_KINETO=OFF
@@ -50,8 +55,12 @@ RUN --mount=type=cache,id=pytorch-f${FEDORA_VER},target=/therock \
 # Development image
 FROM rocm-dev-f${FEDORA_VER} AS pytorch-dev-f${FEDORA_VER}
 COPY --from=build /opt/torch-*.whl /opt
-RUN uv pip install --system /opt/*.whl
+RUN \
+    dnf5 install -y python3.12 python3.12-devel &amp;&amp; \
+    alternatives --install /usr/bin/python python /usr/bin/python3.12 2 &amp;&amp; \
+    python -m ensurepip
+RUN python -m pip install /opt/*.whl

 # the setuptools from rocm-dev-f${FEDORA_VER} could be too new
 # and cause C++ extensions of pytorch, like pytorch-vision to fail to build
-RUN uv pip install --system 'setuptools&gt;=62.3.0,&lt;75.9'
+RUN python -m pip install 'setuptools&gt;=62.3.0,&lt;75.9'
</code></pre>

<p>できたがったコンテナイメージから、<code>/opt/rocm</code> と <code>/opt/*.whl</code> をコピーして利用する。</p>

<p>ちなみに <code>docker build</code> で動かなかったので <code>podman</code> を Ubuntu にインストールする必要があったりする。</p>

<h2>終わりに</h2>

<p><code>scottt/rocm-TheRock</code> でビルドしたパッケージはそのままだと Ubuntu で動かないので <code>LD_LIBRARY_PATH</code> に <code>/opt/rocm/lib/llvm/lib</code> を加える必要があったり、その他必要パッケージがあったりするのでよしなにインストールしてください。</p>

    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2025-05-29T17:12:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2025/01/14/ubuntu-on-raspberry-pi5">
    <title>Ubuntu で Raspberry Pi 5 の NVMe ブート</title>
    <link>https://www.fraction.jp/log/archives/2025/01/14/ubuntu-on-raspberry-pi5</link>
    <description>TL;DRMon 23 Sep 13:02:56 UTC 2024 のファームウェアだとデフォルトで NVMe に対応してるので何もせず NVMe に好きな OS を書き込めば勝手に起動する。Ubuntu Server 24.04.01 だと ssh がデフォルトでパスワードログインがオフになっているため、ヘッドレスでインストールしたかったら user-data を変更する必要がある。承前Raspberry Pi 5 を衝動買いしてしまった。自宅で飼ってる Kubernetes クラスターのコント...</description>
    <content:encoded><![CDATA[
        <h2>TL;DR</h2>

<ul>
<li><code>Mon 23 Sep 13:02:56 UTC 2024</code> のファームウェアだとデフォルトで NVMe に対応してるので何もせず NVMe に好きな OS を書き込めば勝手に起動する。</li>
<li><a href="https://ubuntu.com/download/raspberry-pi">Ubuntu Server 24.04.01</a> だと ssh がデフォルトでパスワードログインがオフになっているため、ヘッドレスでインストールしたかったら <code>user-data</code> を変更する必要がある。</li>
</ul>


<h2>承前</h2>

<p>Raspberry Pi 5 を衝動買いしてしまった。自宅で飼ってる Kubernetes クラスターのコントロールプレーンノードに Raspberry Pi 4 を使ってるのだけれども、<code>etcdHighCommitDurations</code> のアラートがよく出るようになってしまったのでノードをアップグレードしたかったのもある。</p>

<p>ということで、何はともあれ Raspberry Pi 5 に Ubuntu サーバーのインストールだ。</p>

<p class='image'>
<img  src='/log/archives/2025/01/14/IMG_0473.jpg'
      width='800'
      height='600'
      alt=''  />
</p>


<p>今回は PoE + NVMe を追加する HAT を買ったので、だいぶコンパクトになった。(2.5inch SSDはデカかった。)</p>

<h2>ラズパイの状況確認</h2>

<p>まずは SD カードにラズパイOSをインストールして NVMe に SSD を繋げた状態で状況を確認してみる。</p>

<p><code>lsblk</code> を実行してみたところ、最初から NVMe の SSD が見えてる。</p>

<pre><code class="bash">yuanying@raspberrypi:~$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mmcblk0     179:0    0  57.6G  0 disk
├─mmcblk0p1 179:1    0   512M  0 part /boot/firmware
└─mmcblk0p2 179:2    0  57.1G  0 part /
nvme0n1     259:0    0 119.2G  0 disk
</code></pre>

<p>ファームウェアを確認してみたところ、どうやら最新っぽい。多分、つい最近公式で <a href="https://www.raspberrypi.com/news/raspberry-pi-ssds-and-ssd-kits/">Raspberry Pi SSDs and SSD Kits</a> が売り出されたのでそのタイミングで有効化されたのでは無いだろうか。</p>

<pre><code class="bash">yuanying@raspberrypi:~$ sudo rpi-eeprom-update
BOOTLOADER: up to date
   CURRENT: Mon 23 Sep 13:02:56 UTC 2024 (1727096576)
    LATEST: Mon 23 Sep 13:02:56 UTC 2024 (1727096576)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader-2712/default)
            Use raspi-config to change the release.
</code></pre>

<p>ということで、eeprom も特に編集を行わず、Ubuntu を NVMe にインストールすることにする。</p>

<h2>Ubuntu のインストール</h2>

<h3>Ubuntu のダウンロード</h3>

<p>まずは、UbuntuのOSイメージをダウンロードしてくる。現時点で LTS の最新をダウンロード。</p>

<pre><code class="bash">curl -LO https://cdimage.ubuntu.com/releases/24.04.1/release/ubuntu-24.04.1-preinstalled-server-arm64+raspi.img.xz
</code></pre>

<h3>ダウンロードしたイメージをカスタマイズ</h3>

<p>ラズパイにはキーボードやディスプレイを繋げずSSHからヘッドレスでインストールを完結したかったので、OSイメージをカスタマイズする。
ダウンロードしてきたOSイメージの最初のパーティションに <code>user-data</code> があるので、それを変更してやれば良い。</p>

<p>ので、まずはイメージを解凍。</p>

<pre><code class="bash">xzcat &lt; ubuntu-24.04.1-preinstalled-server-arm64+raspi.img.xz \
      &gt; ubuntu-24.04.1-preinstalled-server-arm64+raspi.img
</code></pre>

<p><code>raspi.img</code> の一つ目のパーティションをマウントする。手順は以下。</p>

<ol>
<li><code>raspi.img</code> を loopback device として認識させる。</li>
</ol>


<pre><code class="bash">yuanying@raspberrypi:~ $ sudo losetup -f --show ubuntu-24.04.1-preinstalled-server-arm64+raspi.img
/dev/loop0
</code></pre>

<ol>
<li>パーティションを認識させる。</li>
</ol>


<pre><code class="bash">yuanying@raspberrypi:~ $ sudo partprobe /dev/loop0

yuanying@raspberrypi:~ $ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0         7:0    0   3.4G  0 loop
|-loop0p1   259:3    0   512M  0 part
`-loop0p2   259:4    0   2.9G  0 part
mmcblk0     179:0    0  57.6G  0 disk
|-mmcblk0p1 179:1    0   512M  0 part /boot/firmware
`-mmcblk0p2 179:2    0  57.1G  0 part /
nvme0n1     259:0    0 119.2G  0 disk
</code></pre>

<ol>
<li><code>loop0p1</code> をマウントする。</li>
</ol>


<pre><code class="bash">yuanying@raspberrypi:~ $ sudo mount -t vfat /dev/loop0p1 /mnt
</code></pre>

<ol>
<li><code>/mnt/usr-data</code> を編集する。</li>
</ol>


<pre><code class="bash">yuanying@raspberrypi:~ $ sudo vi /mnt/user-data
</code></pre>

<p>自分は以下のエントリを追加した。</p>

<pre><code class="yaml">users:
- name: yuanying
  primary_group: staff
  groups: users, adm
  sudo: ["ALL=(ALL) NOPASSWD:ALL"]
  shell: /bin/bash
  ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvZ4sFxzmLCYdEm...
</code></pre>

<ol>
<li>後処理</li>
</ol>


<pre><code class="bash">sudo umount /mnt
sudo losetup -D
</code></pre>

<p>アンマウントしてloopback deviceの関連付けを削除したら終了。</p>

<h3>カスタマイズしたイメージをインストール</h3>

<p>あとは NVMe に Ubuntu を書き込んで終了。</p>

<pre><code class="bash">sudo dd if=ubuntu-24.04.1-preinstalled-server-arm64+raspi.img of=/dev/nvme0n1 bs=4M status=progress
</code></pre>

<p>SDカードを外して再起動したところ、無事起動した。</p>

    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2025-01-14T18:30:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2023/07/22/utsunomiya-aizu-echigo">
    <title>会津西街道</title>
    <link>https://www.fraction.jp/log/archives/2023/07/22/utsunomiya-aizu-echigo</link>
    <description>子供達が夏休みとなり、うまい具合にその3人を祖父祖母に一週間ほど押し付けることができたので久しぶりに泊まりがけで自転車旅行とあいなった。いつもならば日帰りなので、300kmほどを1日で駆け抜けるところを余裕を持って二日に分けることができるのでとても気楽である。予定としては、0日目: 新幹線で宇都宮1日目: 宇都宮から日光に入り、会津西街道で会津若松まで2日目: 会津若松から適当にどこかの新幹線の駅まで二日目は三つほどプランを考えており、どれを選ぶかは1日目終了時点のやる気次第ということにした。0日...</description>
    <content:encoded><![CDATA[
        <p>子供達が夏休みとなり、うまい具合にその3人を祖父祖母に一週間ほど押し付けることができたので久しぶりに泊まりがけで自転車旅行とあいなった。</p>

<p>いつもならば日帰りなので、300kmほどを1日で駆け抜けるところを余裕を持って二日に分けることができるのでとても気楽である。</p>

<p>予定としては、</p>

<ul>
<li>0日目: 新幹線で宇都宮</li>
<li>1日目: 宇都宮から日光に入り、会津西街道で会津若松まで</li>
<li>2日目: 会津若松から適当にどこかの新幹線の駅まで</li>
</ul>


<p>二日目は三つほどプランを考えており、どれを選ぶかは1日目終了時点のやる気次第ということにした。</p>

<h2>0日目 宇都宮</h2>

<p class='image'>
<img  src='/log/archives/2023/07/22/IMG_1270.jpeg'
      width='800'
      height='600'
      alt=''  />
</p>


    ]]></content:encoded>
    <dc:subject>自転車</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2023-07-22T07:24:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2023/05/02/jetson-pytorch">
    <title>Jetson Orin Nano に PyTorchとtorchvisionをインストール</title>
    <link>https://www.fraction.jp/log/archives/2023/05/02/jetson-pytorch</link>
    <description>JetPack 5.10 がインストールされたJetson上のコンテナにPyTorchとtorchvisionをインストールしたい。そのままインストールができなかったため以下を参考にする。Machine Learning Containers for Jetson and JetPackPyTorch のインストールこれはドキュメントを参考に。Installing PyTorch for Jetson Platform$ export TORCH_INSTALL=https://developer...</description>
    <content:encoded><![CDATA[
        <p>JetPack 5.10 がインストールされたJetson上のコンテナにPyTorchとtorchvisionをインストールしたい。そのままインストールができなかったため以下を参考にする。</p>

<ul>
<li><a href="https://github.com/dusty-nv/jetson-containers/blob/master/Dockerfile.pytorch">Machine Learning Containers for Jetson and JetPack</a></li>
</ul>


<h2>PyTorch のインストール</h2>

<p>これはドキュメントを参考に。</p>

<ul>
<li><a href="https://docs.nvidia.com/deeplearning/frameworks/install-pytorch-jetson-platform/index.html">Installing PyTorch for Jetson Platform</a></li>
</ul>


<pre><code>$ export TORCH_INSTALL=https://developer.download.nvidia.cn/compute/redist/jp/v51/pytorch/torch-2.0.0a0+8aa34602.nv23.03-cp38-cp38-linux_aarch64.whl
$ python3 -m pip install --no-cache $TORCH_INSTALL
</code></pre>

<h2>torchvisionのインストール</h2>

<p><code>
</code></p>

    ]]></content:encoded>
    <dc:subject>Program/Python</dc:subject>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2023-05-02T19:01:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2023/04/29/jetson-k8s">
    <title>Jetson Orin Nano を Kubernetes のノードにした</title>
    <link>https://www.fraction.jp/log/archives/2023/04/29/jetson-k8s</link>
    <description>前回の続き。containerd の設定CRI のデフォルトランタイムを以下を参考に nvidia に変更。NVIDIA Cloud Native Stack - v8.1 Install Guide for Jetson AGX Xavier or Jetson Xavier NX DevKit or Jetson Orin$ sudo mkdir -p /etc/containerd$ sudo curl -o /etc/containerd/config.toml https://raw.g...</description>
    <content:encoded><![CDATA[
        <p><a href="/log/archives/2023/04/27/jetson-orin-nano">前回</a>の続き。</p>

<h2>containerd の設定</h2>

<p>CRI のデフォルトランタイムを以下を参考に <code>nvidia</code> に変更。</p>

<ul>
<li><a href="https://github.com/NVIDIA/cloud-native-stack/blob/master/install-guides/Jetson_Xavier_v9.0.md#Installing-Containerd">NVIDIA Cloud Native Stack - v8.1 Install Guide for Jetson AGX Xavier or Jetson Xavier NX DevKit or Jetson Orin</a></li>
</ul>


<pre><code>$ sudo mkdir -p /etc/containerd
$ sudo curl -o /etc/containerd/config.toml https://raw.githubusercontent.com/NVIDIA/cloud-native-stack/master/playbooks/config.toml
$ sudo systemctl restart containerd
</code></pre>

<h2>Kernel のリビルド</h2>

<p>下記の記事によると、前世代のJetson NanoをKubernetesのノードにするためにはカーネルのリビルドが必要になるらしい。（どうでもいいけどKubernetesに関連する記事を検索すると高確率で同僚の記事がヒットするのが面白い。）</p>

<ul>
<li><a href="https://zenn.dev/nkte8/articles/2021-12-06-r01">Jetson nanoをk8sクラスタ参加させた(kubeadm)</a></li>
<li><a href="https://qiita.com/ysakashita/items/566e082a5d060eef5046">NVIDIA Jetson Nano in Kubernetesの検証</a></li>
</ul>


<p>Jetson Orin Nano 上で確認したところ、最低限の設定はされていそう。</p>

<pre><code>$ zcat /proc/config.gz | grep CONFIG_IP_NF_TARGET_REDIRECT
CONFIG_IP_NF_TARGET_REDIRECT=m

$ zcat /proc/config.gz | grep CONFIG_CGROUP_HUGETLB
CONFIG_CGROUP_HUGETLB=y
</code></pre>

<p>どちらにしろ、CSIでISCSIを有効化するためには以下を設定しないといけないのでどちらにしろカーネルビルドをやってみることにする。</p>

<ul>
<li><a href="https://forums.developer.nvidia.com/t/jetson-nano-and-iscsi-module-support/199993/3">Jetson nano and iscsi module support</a></li>
</ul>


<pre><code>$ zcat /proc/config.gz | grep ISCSI
# CONFIG_ISCSI_IBFT is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_ISCSI_TCP is not set
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_SCSI_QLA_ISCSI is not set
</code></pre>

<h3>コンパイル準備</h3>

<p>とりあえず公式ドキュメントでカーネルコンパイルの方法を確認。</p>

<ul>
<li><a href="https://docs.nvidia.com/jetson/archives/r35.3.1/DeveloperGuide/text/SD/Kernel/KernelCustomization.html">Manually Downloading and Expanding Kernel Sources</a></li>
</ul>


<p>以下からカーネルのソースを入手。</p>

<ul>
<li><a href="https://developer.nvidia.com/embedded/jetson-linux-r3531">Jetson Linux 35.3.1</a></li>
</ul>


<pre><code>$ curl -LO https://developer.nvidia.com/downloads/embedded/l4t/r35_release_v3.1/sources/public_sources.tbz2
$ tar -xjf public_sources.tbz2
</code></pre>

<p>カーネルのソースコードを解凍。</p>

<pre><code>$ cd Linux_for_Tegra/source/public
$ tar -xjf kernel_src.tbz2
$ cd kernel/kernel-5.10/
</code></pre>

<p>現状の <code>.config</code> を入手して <code>make nconfig</code> で設定。</p>

<p>Jetson で iSCSI デバイスを使うための設定は以下の情報を参考にした。</p>

<ul>
<li><a href="https://www.netapp.com/media/21140-tr-4875-design.pdf">Configuring NVIDIA Jetson Nano with NetApp E-Series Storage Systems</a></li>
</ul>


<pre><code>$ zcat /proc/config.gz &gt; .config.org
$ cp .config.org .config
$ make nconfig
</code></pre>

<p>こんな感じ。</p>

<pre><code class="diff">$ diff -u .config.org .config
--- .config.org 2023-04-29 13:15:52.741355433 +0900
+++ .config     2023-04-29 15:33:25.786778247 +0900
@@ -2,10 +2,10 @@
 # Automatically generated file; DO NOT EDIT.
 # Linux/arm64 5.10.104 Kernel Configuration
 #
-CONFIG_CC_VERSION_TEXT="aarch64-buildroot-linux-gnu-gcc.br_real (Buildroot 2020.08) 9.3.0"
+CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
 CONFIG_CC_IS_GCC=y
-CONFIG_GCC_VERSION=90300
-CONFIG_LD_VERSION=233010000
+CONFIG_GCC_VERSION=90400
+CONFIG_LD_VERSION=234000000
 CONFIG_CLANG_VERSION=0
 CONFIG_LLD_VERSION=0
 CONFIG_CC_CAN_LINK=y
@@ -445,6 +445,7 @@
 CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y
 CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y
 CONFIG_AS_HAS_PAC=y
+CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y
 # end of ARMv8.3 architectural features

 #
@@ -807,10 +808,6 @@
 # end of GCOV-based kernel profiling

 CONFIG_HAVE_GCC_PLUGINS=y
-CONFIG_GCC_PLUGINS=y
-# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
-# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set
-# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set
 # end of General architecture-dependent options

 CONFIG_RT_MUTEXES=y
@@ -1134,6 +1131,7 @@
 #
 CONFIG_NETFILTER_XT_MARK=m
 CONFIG_NETFILTER_XT_CONNMARK=m
+# CONFIG_NETFILTER_XT_SET is not set

 #
 # Xtables targets
@@ -1216,7 +1214,24 @@
 CONFIG_NETFILTER_XT_MATCH_U32=m
 # end of Core Netfilter Configuration

-# CONFIG_IP_SET is not set
+CONFIG_IP_SET=m
+CONFIG_IP_SET_MAX=256
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPMARK=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_IPMAC=m
+CONFIG_IP_SET_HASH_MAC=m
+CONFIG_IP_SET_HASH_NETPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETNET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_IP_VS=m
 # CONFIG_IP_VS_IPV6 is not set
 # CONFIG_IP_VS_DEBUG is not set
@@ -1439,6 +1454,7 @@
 # CONFIG_NET_EMATCH_META is not set
 # CONFIG_NET_EMATCH_TEXT is not set
 # CONFIG_NET_EMATCH_CANID is not set
+# CONFIG_NET_EMATCH_IPSET is not set
 # CONFIG_NET_EMATCH_IPT is not set
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=m
@@ -2166,15 +2182,18 @@
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
 # CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_LOGGING=y
 # CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_SCAN_ASYNC=y

 #
 # SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_SCSI_SAS_LIBSAS=m
 CONFIG_SCSI_SAS_ATA=y
@@ -2183,12 +2202,12 @@
 # end of SCSI Transports

 CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_SCSI_CXGB3_ISCSI is not set
-# CONFIG_SCSI_CXGB4_ISCSI is not set
-# CONFIG_SCSI_BNX2_ISCSI is not set
-# CONFIG_BE2ISCSI is not set
+CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_CXGB4_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -2243,6 +2262,8 @@
 # CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_VIRTIO is not set
 # CONFIG_SCSI_DH is not set
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_ALUA=y
 # end of SCSI device support

 CONFIG_HAVE_PATA_PLATFORM=y
@@ -2350,22 +2371,38 @@
 CONFIG_BLK_DEV_DM_BUILTIN=y
 CONFIG_BLK_DEV_DM=y
 # CONFIG_DM_DEBUG is not set
+CONFIG_DM_DEBUG=y
+CONFIG_DM_BIO_PRISON=y
+CONFIG_DM_PERSISTENT_DATA=y
 CONFIG_DM_BUFIO=y
 # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set
 # CONFIG_DM_UNSTRIPED is not set
 CONFIG_DM_CRYPT=y
 # CONFIG_DM_SNAPSHOT is not set
+CONFIG_DM_SNAPSHOT=y
 # CONFIG_DM_THIN_PROVISIONING is not set
+CONFIG_DM_THIN_PROVISIONING=y
 # CONFIG_DM_CACHE is not set
+CONFIG_DM_CACHE=y
+CONFIG_DM_CACHE_SMQ=y
 # CONFIG_DM_WRITECACHE is not set
 # CONFIG_DM_EBS is not set
 # CONFIG_DM_ERA is not set
+CONFIG_DM_ERA=y
 # CONFIG_DM_CLONE is not set
 # CONFIG_DM_MIRROR is not set
+CONFIG_DM_MIRROR=y
+CONFIG_DM_LOG_USERSPACE=y
 # CONFIG_DM_RAID is not set
+CONFIG_DM_RAID=y
 # CONFIG_DM_ZERO is not set
+CONFIG_DM_ZERO=y
 # CONFIG_DM_MULTIPATH is not set
+CONFIG_DM_MULTIPATH=y
+CONFIG_DM_MULTIPATH_QL=y
+CONFIG_DM_MULTIPATH_ST=y
 # CONFIG_DM_DELAY is not set
+CONFIG_DM_DELAY=y
 # CONFIG_DM_DUST is not set
 # CONFIG_DM_INIT is not set
 CONFIG_DM_UEVENT=y
@@ -2374,7 +2411,10 @@
 CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
 # CONFIG_DM_VERITY_FEC is not set
 # CONFIG_DM_SWITCH is not set
+CONFIG_DM_SWITCH=y
 # CONFIG_DM_LOG_WRITES is not set
+CONFIG_DM_LOG_WRITES=y
+CONFIG_DM_ZONED=y
 # CONFIG_DM_INTEGRITY is not set
 # CONFIG_TARGET_CORE is not set
 # CONFIG_FUSION is not set
@@ -2508,6 +2548,7 @@
 CONFIG_CHELSIO_T3=m
 CONFIG_CHELSIO_T4=m
 CONFIG_CHELSIO_T4VF=m
+CONFIG_CHELSIO_LIB=m
 CONFIG_CHELSIO_INLINE_CRYPTO=y
 CONFIG_NET_VENDOR_CISCO=y
 CONFIG_ENIC=m
@@ -7586,7 +7627,6 @@
 CONFIG_TEGRA_HV_PM_CTL=y
 CONFIG_TEGRA_HV_MANAGER=y
 CONFIG_TEGRA_VIRTUALIZATION=y
-CONFIG_TEGRA_NVLINK=y
 # end of Device Drivers

 #
@@ -7925,10 +7965,6 @@
 # Memory initialization
 #
 CONFIG_INIT_STACK_NONE=y
-# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
-# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
-# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set
-# CONFIG_GCC_PLUGIN_STACKLEAK is not set
 # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
 # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
 # end of Memory initialization
</code></pre>

<h3>コンパイル</h3>

<p>準備ができたのでコンパイル。数時間かかるそうなので放置。</p>

<pre><code>$ make prepare
$ make modules_prepare
$ make -j5 Image
$ make -j5 modules
</code></pre>

<h3>カーネルのインストール</h3>

<p>インストールして再起動。</p>

<pre><code>$ sudo cp /boot/Image /boot/Image.org
$ sudo cp arch/arm64/boot/Image /boot/Image
$ sudo make modules_install
$ sudo reboot
</code></pre>

<p>カーネルがついさっきビルドしたものに変わっていることを確認。</p>

<pre><code>$ uname -a
Linux uribo 5.10.104 #2 SMP PREEMPT Sat Apr 29 14:42:12 JST 2023 aarch64 aarch64 aarch64 GNU/Linux
</code></pre>

<h2>Kubernetes へ Join</h2>

<p>自分は <code>kubeadm</code> を使ってないので適時 kubelet をインストールし systemd などの設定を手作業でやったが、普通は <code>kubeadm join</code> で大丈夫と思われる。</p>

<pre><code>✦ ➜ k get node uribo -o wide
NAME    STATUS   ROLES    AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
uribo   Ready    &lt;none&gt;   63s   v1.24.6   192.168.1.152   &lt;none&gt;        Ubuntu 20.04.5 LTS   5.10.104         containerd://1.6.12
</code></pre>

<p>無事、Kubernetesにノードとして追加された。</p>

<p>ちなみに、メモリも少ないので kubelet の設定で Swap を有効化しておいた。</p>

<pre><code class="yaml">apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
...
(snip)
...
failSwapOn: false
featureGates:
  NodeSwap: true
</code></pre>

<h3>nvidia device plugin のインストール</h3>

<p>下記の記事に従って、device plugin をインストールする。</p>

<ul>
<li><a href="https://medium.com/techbeatly/running-kubernetes-on-gpu-nodes-9ddd97dc4793">Running Kubernetes on GPU Nodes</a></li>
</ul>


<p>containerdはすでに設定しており、<code>nvidia-container-toolkit</code> もインストール済みのため、<code>/etc/docker/daemon.json</code> を少し編集して、</p>

<pre><code class="json">{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}
</code></pre>

<p>マニフェストをapplyするのみ。</p>

<pre><code>$ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
</code></pre>

<h3>動作確認</h3>

<p>devicequery を実行。</p>

<pre><code>✦ ➜ cat &lt;&lt;EOF | k apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: devicequery
spec:
  restartPolicy: Never
  containers:
  - name: nvidia
    image: xift/jetson_devicequery:r32.5.0
    command: [ "./deviceQuery" ]
    resources:
      limits:
        nvidia.com/gpu: 1
  nodeSelector:
    kubernetes.io/hostname: "uribo"
  tolerations:
  - effect: NoSchedule
    key: nvidia.com/gpu
    operator: Exists
EOF
✦ ➜ k get pod devicequery
NAME          READY   STATUS      RESTARTS   AGE
devicequery   0/1     Completed   0          11s

✦ ➜ k logs devicequery
./deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "Orin"
  CUDA Driver Version / Runtime Version          11.4 / 10.2
  CUDA Capability Major/Minor version number:    8.7
  Total amount of global memory:                 6480 MBytes (6794899456 bytes)
MapSMtoCores for SM 8.7 is undefined.  Default to use 64 Cores/SM
MapSMtoCores for SM 8.7 is undefined.  Default to use 64 Cores/SM
  ( 8) Multiprocessors, ( 64) CUDA Cores/MP:     512 CUDA Cores
  GPU Max Clock rate:                            624 MHz (0.62 GHz)
  Memory Clock rate:                             624 Mhz
  Memory Bus Width:                              64-bit
  L2 Cache Size:                                 2097152 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
  Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  1536
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and kernel execution:          Yes with 2 copy engine(s)
  Run time limit on kernels:                     No
  Integrated GPU sharing Host Memory:            Yes
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Disabled
  Device supports Unified Addressing (UVA):      Yes
  Device supports Compute Preemption:            Yes
  Supports Cooperative Kernel Launch:            Yes
  Supports MultiDevice Co-op Kernel Launch:      Yes
  Device PCI Domain ID / Bus ID / location ID:   0 / 0 / 0
  Compute Mode:
     &lt; Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) &gt;

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 11.4, CUDA Runtime Version = 10.2, NumDevs = 1
Result = PASS
</code></pre>

<p>どうやら動いてるらしいが、色々クセがあってなんか使いづらい。。</p>

<h3>ホストの CUDA 関連ライブラリがPodにインストールされていない</h3>

<p>nvidia-container-runtimeは <code>/etc/nvidia-container-runtime/host-files-for-container.d/</code> にある csv を参照して、ホストのライブラリその他をコンテナにマウントしてくれるらしい。</p>

<ul>
<li><a href="https://github.com/dusty-nv/jetson-containers/issues/194">OSError: libcurand.so.10: cannot open shared object file: No such file or directory</a></li>
</ul>


<p>しかし、JetPack 5.1からはなぜか <code>l4t.csv</code> のみが存在し、今まであったはずの <code>cuda.csv</code> や <code>cudnn.csv</code> が見当たらない。</p>

<pre><code>$ ls -la /etc/nvidia-container-runtime/host-files-for-container.d/
total 24
drwxr-xr-x 2 root root  4096 Mar 20 12:01 .
drwxr-xr-x 3 root root  4096 Apr 29 18:15 ..
-rw-r--r-- 1 root root 16370 Mar 20 00:14 l4t.csv
</code></pre>

<p>下記のフォーラムを見ると、コンテナ内に自分でインストールする必要があるらしい。</p>

<ul>
<li><a href="https://forums.developer.nvidia.com/t/missing-cuda-csv-cudnn-csv-tensorrt-csv-in-etc-nvidia-container-runtime-host-files-for-container-d/240831/8">Missing cuda.csv, cudnn.csv, tensorrt.csv in /etc/nvidia-container-runtime/host-files-for-container.d/</a></li>
</ul>


<p>ただ、コンテナごとにインストールするのが面倒だったので、結局 <code>hostPath</code> でマウントすることにした。</p>

<pre><code class="yaml">      volumes:
      - name: cuda
        hostPath:
          path: /usr/local/cuda-11.4
      - name: cudnn
        hostPath:
          path: /usr/lib/aarch64-linux-gnu/libcudnn.so.8
</code></pre>

<h3>コンテナのユーザがrootじゃないとGPUを利用できない</h3>

<p>コンテナ内でPyTorchをインストールして一般ユーザでGPUが利用できるかチェックしたところ、以下のエラー。</p>

<pre><code>➜ python3 -c "import torch; print(torch.cuda.is_available())"
NvRmMemInitNvmap failed with Permission denied
549: Memory Manager Not supported


****NvRmMemInit failed**** error type: 196626


*** NvRmMemInit failed NvRmMemConstructor
/home/yuanying/src/github.com/yuanying/uribo/.venv/lib/python3.8/site-packages/torch/cuda/__init__.py:107: UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount(). Did you run some cuda functions before calling NumCudaDevices() that might have already set an error? Error 801: operation not supported (Triggered internally at /opt/pytorch/pytorch/c10/cuda/CUDAFunctions.cpp:109.)
  return torch._C._cuda_getDeviceCount() &gt; 0
False
</code></pre>

<p><code>Permission denied</code> とは何のPermissionかわからなかったが、<code>/dev/nvhost*</code> を確認したところ、一般ユーザがGPUを使うためには<code>video</code> グループに属していないといけないようだった。</p>

<p>ということで、<code>Dockerfile</code> で作成した一般ユーザを <code>video</code> グループに追加したらうまく動くようになった。</p>

<pre><code>RUN useradd -G video -g 50 -m -s /bin/bash  -u 501 "$USER"
</code></pre>

<p>ただ、gpu-operatorで作成した環境だと、<code>/dev/nvhost*</code> は誰でも読み書きできるようになっていたため、色々謎がある。</p>

    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2023-04-29T11:25:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2023/04/27/jetson-orin-nano">
    <title>Jetson Orin Nano のセットアップ</title>
    <link>https://www.fraction.jp/log/archives/2023/04/27/jetson-orin-nano</link>
    <description>Jetson Orin Nano を買ったのでセットアップしました。インストールしたのは JetPack v5.1.1。まあ、普通にSDカードからOSを起動してもいいのですが、せっかくNVMeがついてるので、NVMe接続のSSDにOSをインストールすることにしました。また、後々K8sのノードとして利用する予定なので不要なGUI周りのパッケージをアンインストールしました。NVMeからのOS起動普通にSDカードにOSをインストールして起動したのちに、ターミナルからJetPackをダウンロードして NV...</description>
    <content:encoded><![CDATA[
        <p>Jetson Orin Nano を買ったのでセットアップしました。</p>

<p class='image'>
<img  src='/log/archives/2023/04/27/IMG_0860.jpg'
      width='720'
      height='540'
      alt=''  />
</p>


<p>インストールしたのは JetPack v5.1.1。</p>

<p>まあ、普通にSDカードからOSを起動してもいいのですが、せっかくNVMeがついてるので、NVMe接続のSSDにOSをインストールすることにしました。また、後々K8sのノードとして利用する予定なので不要なGUI周りのパッケージをアンインストールしました。</p>

<h2>NVMeからのOS起動</h2>

<p>普通にSDカードにOSをインストールして起動したのちに、ターミナルからJetPackをダウンロードして NVMe のSSDに書き込みます。</p>

<pre><code>$ curl -LO https://developer.nvidia.com/downloads/embedded/l4t/r35_release_v3.1/sd_card_b49/jp511-orin-nano-sd-card-image.zip

$ /usr/bin/unzip -p jp511-orin-nano-sd-card-image.zip | sudo /bin/dd of=/dev/nvme0n1 bs=1M status=progress
[sudo] password for yuanying:
22029074432 bytes (22 GB, 21 GiB) copied, 291 s, 75.7 MB/s
0+337904 records in
0+337904 records out
22144876544 bytes (22 GB, 21 GiB) copied, 293.348 s, 75.5 MB/s
</code></pre>

<p>そのままNVMeに書き込んだOSイメージから起動できれば良いのだが、イメージ中の<code>/boot/extlinux/extlinux.conf</code> を書き換えないと起動しないとのことなので書き換える。</p>

<p>NVMeのSSDをマウントしたのちに、</p>

<pre><code>$ sudo mount /dev/nvme0n1p1 /mnt
</code></pre>

<p><code>/mnt/boot/extlinux/extlinux.conf</code> を以下のように書き換える。(<code>/dev/mmcblk1p1</code> でSDカードが指定してあったところを <code>/dev/nvme0n1p1</code> に変更。)</p>

<pre><code class="diff">--- extlinux.conf.backup        2023-04-27 17:45:49.921921693 +0900
+++ extlinux.conf       2023-04-27 17:46:20.238288895 +0900
@@ -8,7 +8,7 @@
       LINUX /boot/Image
       FDT /boot/dtb/kernel_tegra234-p3767-0003-p3768-0000-a0.dtb
       INITRD /boot/initrd
-      APPEND ${cbootargs} root=/dev/mmcblk1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0
+      APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0

 # When testing a custom kernel, it is recommended that you create a backup of
 # the original kernel and add a new entry to this file so that the device can
</code></pre>

<p>アンマウントしたのちに再起動。</p>

<pre><code>$ sudo umount /mnt
$ sudo reboot
</code></pre>

<h2>GUI のパッケージ削除</h2>

<p>Jetson をディスプレイに繋いで利用するつもりはなかったので、GUIその他を諸々削除します。</p>

<p>まずは、とりあえず以下の記事を参考に <code>multi-user.target</code> をデフォルトに変更。</p>

<ul>
<li><a href="https://www.youtalk.jp/2023/03/28/jetson-orin-nano.html">NVIDIA Jetson Orin Nano開発者キットのセットアップ</a></li>
</ul>


<pre><code>$ sudo systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
</code></pre>

<p>SSHでログインしたところ、まだGNOME関連のプロセスが起動していたので、それらも以下の記事を参考に削除。</p>

<ul>
<li><a href="https://nvidia-ai-iot.github.io/jetson-min-disk/step1.html">Guide to Minimizing Jetson Disk Usage</a></li>
</ul>


<p>上記の記事中の <code>nvubuntu-focal-packages_only-in-desktop</code> はリンクが切れていたので、github にあった多分同じものと思われるリストを利用。</p>

<pre><code>$ sudo apt-get update
$ suro apt-get -y install curl
$ curl -LO https://raw.githubusercontent.com/NVIDIA-AI-IOT/jetson-min-disk/main/assets/nvubuntu-focal-packages_only-in-desktop.txt
$ sudo apt-get purge $(cat nvubuntu-focal-packages_only-in-desktop.txt)
$ sudo apt-get install -y netwprk-kanager netplan.io
$ cat &lt;&lt;EOF | sudo tee /etc/netplan/00-init.yaml
network:
  renderer: NetworkManager
  ethernets:
    eno1:
      dhcp4: true
  version: 2
EOF
$ sudo netplan apply
</code></pre>

<p>削除後に、<code>network-manager</code> を再度インストールしないとネットワークに繋がらなくなって酷い目にあうらしいので注意。自分は<code>netplan</code>で設定した。</p>

<h2>感想</h2>

<p>VanillaなUbuntu Serverをインストールしたいんだけど、なぜかうまくいかない。</p>

    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2023-04-27T17:48:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2023/03/23/new-pc">
    <title>自宅のKubernetesにGPUノードを追加した</title>
    <link>https://www.fraction.jp/log/archives/2023/03/23/new-pc</link>
    <description>ChatGPT周りが面白かったので、LLM関連を学習したくなり、久しぶりにPCを自作した。最近はNUCやらDeskMiniなどのベアボーン、ラズパイばかり触っていたので自作PC周りはなかなかの浦島太郎状態。ブログのエントリをあさってみると2007年のPC環境で自作PCをデスクトップに使ってるのを発見できた。グラボはATIしか買った記憶はなかったのだが、GeForce 7900 GS とか使ってる。。謎だ。HW自作PCは久しぶりということもあって全く状況が掴めなかったのもあり、一瞬、どこかのPCショ...</description>
    <content:encoded><![CDATA[
        <p>ChatGPT周りが面白かったので、LLM関連を学習したくなり、久しぶりにPCを自作した。
最近はNUCやらDeskMiniなどのベアボーン、ラズパイばかり触っていたので自作PC周りはなかなかの浦島太郎状態。</p>

<p>ブログのエントリをあさってみると<a href="/log/archives/2007/08/1208">2007年のPC環境</a>で自作PCをデスクトップに使ってるのを発見できた。グラボはATIしか買った記憶はなかったのだが、GeForce 7900 GS とか使ってる。。謎だ。</p>

<h2>HW</h2>

<p>自作PCは久しぶりということもあって全く状況が掴めなかったのもあり、一瞬、どこかのPCショップのBTOでも買うかと日和った考えが頭によぎったが、最近、自転車の組み立てで自分で組むのは面倒、という理由でショップに任せたところとても不快なめにあったので、自分でできることは自分でしようという気分になりパーツを買い集めた。</p>

<p class='image'>
<img  src='/log/archives/2023/03/23/IMG_0654.jpg'
      width='800'
      height='600'
      alt=''  />
</p>


<ul>
<li>CPU: Intel  Core i5 13400 BOX

<ul>
<li>32,640円</li>
</ul>
</li>
<li>MB: ASUS  TUF GAMING B760M-PLUS D4 (B760 1700 MicroATX)

<ul>
<li>26,446円</li>
</ul>
</li>
<li>Memory: Crucial CT32G4DFD832A DDR4-3200 32GB x2

<ul>
<li>21,300円 x 2</li>
</ul>
</li>
<li>SSD: Crucial  P5 Plus CT1000P5PSSD8JP (M.2 2280 1TB)

<ul>
<li>12,660円</li>
</ul>
</li>
<li>GPU: NVRTXA4000 [NVIDIA RTX A4000 16GB GDDR6]

<ul>
<li>135,800 円</li>
</ul>
</li>
</ul>


<p>電源とケースは使い回し。自作PCは久しぶりなはずだが、電源とケースが余っているのが謎だ。</p>

<h2>SW</h2>

<h3>OSインストール</h3>

<ul>
<li>OS: Ubuntu 22.04.03</li>
<li>Container Runtime: containerd</li>
<li>Kubernetes: v1.24.6</li>
</ul>


<p>OS は Ubuntu 22.04 を選んだが、そのままインストールすると途中で処理が止まりインストールできず。少し焦った。
最新のカーネルのバックポートを利用してインストールする必要があったようだ。 メモ: <code>Boot and Install with the HWE kernel</code> 。</p>

<p>OSをインストールしたらそのまま containerd/kubelet をインストールしてクラスタにジョイン。</p>

<h3>GPU のドライバのインストール</h3>

<p>Kubernetesクラスタの一員になったのでドライバのインストールも GPU Operator に任せる。</p>

<ul>
<li><a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/getting-started.html#common-deployment-scenarios">NVIDIA GPU OPERATOR: Getting Started</a></li>
</ul>


<p>ノードの名前は <code>poissonnerie</code>。ドライバやFeature DiscoveryはGPUノードにだけいればいいので、いい感じにラベルとtaintをつける。</p>

<pre><code>k label node poissonnerie unstable.cloud/nvidia-gpu=yes
k taint node poissonnerie nvidia.com/gpu=:NoSchedule
</code></pre>

<p>インストールはhelmから直接せずに一旦templateでファイルに落としてからkustomizeをかける。</p>

<pre><code>helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

# renovate: datasource=helm depName=gpu-operator-chart packageName=gpu-operator registryUrl=https://helm.ngc.nvidia.com/nvidia
CHART_VER=22.9.2
CHART=nvidia/gpu-operator
VALUES=src/values.yaml
MANIFEST=src.yaml
NAMESPACE=gpu-operator
NAME=gpu-operator

helm template --include-crds --version v${CHART_VER} --values ${VALUES} --namespace ${NAMESPACE} ${NAME} ${CHART} &gt; ${MANIFEST}
</code></pre>

<p>kustomizeからいきなりhelmを使えるのだが、一旦helmの出力するマニフェストを確認したいので毎回templateで出力してる。</p>

<pre><code>resources:
- src.yaml
patchesStrategicMerge:
- |-
  apiVersion: apps/v1
  kind: DaemonSet
  metadata:
    name:  gpu-operator-node-feature-discovery-worker
  spec:
    template:
      spec:
        nodeSelector:
          unstable.cloud/nvidia-gpu: "yes"
</code></pre>

<p>こんな感じでyamlを作った後に、<code>kubectl apply -k .</code> でインストール。</p>

<pre><code>✦ ➜ k get pod
NAME                                                          READY   STATUS      RESTARTS      AGE
gpu-feature-discovery-q57nz                                   1/1     Running     0             10m
gpu-operator-5df795584-2mknv                                  1/1     Running     2 (40m ago)   46m
gpu-operator-node-feature-discovery-master-84c7c7c6cf-h7lpf   1/1     Running     0             46m
gpu-operator-node-feature-discovery-worker-tdhs2              1/1     Running     0             11m
nvidia-container-toolkit-daemonset-j6xbw                      1/1     Running     0             10m
nvidia-cuda-validator-j9qwp                                   0/1     Completed   0             8m2s
nvidia-dcgm-exporter-sbw6w                                    1/1     Running     0             10m
nvidia-device-plugin-daemonset-ddjj9                          1/1     Running     0             10m
nvidia-device-plugin-validator-2p4hf                          0/1     Completed   0             6m20s
nvidia-driver-daemonset-klfrn                                 1/1     Running     0             10m
nvidia-operator-validator-f8jr5                               1/1     Running     0             10m
</code></pre>

<p>いい感じにCPUノードだけで動いてる。</p>

<pre><code>✦ ➜ k get node poissonnerie -o json | jq '.status.allocatable'
{
  "cpu": "16",
  "ephemeral-storage": "884016022498",
  "hugepages-1Gi": "0",
  "hugepages-2Mi": "0",
  "memory": "65483284Ki",
  "nvidia.com/gpu": "1",
  "pods": "110"
}
</code></pre>

<p><code>"nvidia.com/gpu": "1"</code> がついた。</p>

<pre><code>yuanying@poissonnerie:~$ sudo cat /etc/containerd/config.toml| grep nvidia
      default_runtime_name = "nvidia"
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]
            BinaryName = "/usr/local/nvidia/toolkit/nvidia-container-runtime"
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia-experimental]
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia-experimental.options]
            BinaryName = "/usr/local/nvidia/toolkit/nvidia-container-runtime-experimental"
</code></pre>

<p>GPU Operator は <code>/etc/containerd/config.toml</code> もいじってくるらしい。変に自分で編集しないように気をつけたい。</p>

<pre><code>cat &lt;&lt;EOF | k apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: cuda-vectoradd
spec:
  restartPolicy: OnFailure
  containers:
  - name: cuda-vectoradd
    image: "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04"
    resources:
      limits:
        nvidia.com/gpu: 1
  tolerations:
  - effect: NoSchedule
    key: nvidia.com/gpu
    operator: Exists
EOF
</code></pre>

<p>Getting Started 通りにサンプルアプリケーションをインストール。</p>

<pre><code>✦ ➜ k get pod
NAME             READY   STATUS      RESTARTS   AGE
cuda-vectoradd   0/1     Completed   0          9s

✦ ➜ k logs cuda-vectoradd
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done
</code></pre>

<p>ちゃんと動いた。</p>

<h3>Wake on LAN の有効化</h3>

<p>GPUは電気を食うので使わないときはシャットダウンしておきたい。ということで同時に Wake on LAN も以下を参考に有効化した。</p>

<ul>
<li><a href="https://chatnoirlibre.com/ubuntu-22-04-wake-on-lan/">Ubuntu 22.04　Wake on LanでリモートのUbuntuデスクトップパソコンを起動する</a></li>
<li><a href="https://kapibara-sos.net/archives/949">LinuxでWake on LAN設定</a></li>
<li><a href="https://www.asus.com/jp/support/FAQ/1045950/">[マザーボード] BIOSでWOL (Wake On Lan) 機能を設定する方法</a></li>
</ul>


<h2>その他</h2>

<p>Kubernetes上で Stable Diffusion も動いた。</p>

<p class='image'>
<img  src='/log/archives/2023/03/23/Screenshot-sd.png'
      width='1000'
      height='743'
      alt=''  />
</p>


<p>満足したので機械学習の学習をする。</p>

    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2023-03-23T15:32:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2022/10/27/mt-otsuka">
    <title>大塚山ハイキング</title>
    <link>https://www.fraction.jp/log/archives/2022/10/27/mt-otsuka</link>
    <description>自転車で大塚山にハイキングに行ってきました。OIKAZE RNCとりあえず気になっていた場所をいくつか回ろうと、いつもより少なめの距離でルートを設定。一つ目の目標地は Instagram で最近房総半島サイクリング関係をフォローしてるとよく見かけるようになった OIKAZE RNC。古民家を改装した、、、というか改装中のカフェで、うぐいす通りからちょっと脇道に逸れた場所にあり、特に目立つ看板などが置いてあるわけでもない、フツーの民家なので知らないと誰も辿りづけないんじゃないかという感じ。中も、ちょ...</description>
    <content:encoded><![CDATA[
        <p>自転車で大塚山にハイキングに行ってきました。</p>

<h2>OIKAZE RNC</h2>

<p>とりあえず気になっていた場所をいくつか回ろうと、いつもより少なめの距離でルートを設定。</p>

<p>一つ目の目標地は Instagram で最近房総半島サイクリング関係をフォローしてるとよく見かけるようになった <a href="https://lit.link/en/Oikazernc">OIKAZE RNC</a>。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2984.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>古民家を改装した、、、というか改装中のカフェで、うぐいす通りからちょっと脇道に逸れた場所にあり、
特に目立つ看板などが置いてあるわけでもない、フツーの民家なので知らないと誰も辿りづけないんじゃないかという感じ。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2989.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>中も、ちょうど訪ねた時には「これから冬になり、寒くなるので天井を塞いでた」らしく、めっちゃ改装作業中。</p>

<p>と言っても、出てきたアンコサンドイッチは美味しかったし、コーヒーも美味しかったです。
うぐいす通りは房総の奥に行く際の通り道なのでこれから通うかもしれない。</p>

<h2>月崎トンネル</h2>

<p>二つ目の目標は「月崎トンネル」。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2992.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>ここはトンネルの途中が崩落して天井が抜けているのが特徴の、結構有名な隧道なのだが、Strava でルートを引くと、折り返しできない林道になっており、
わざわざ行って帰ってくるのはなんとなく嫌だなーと思っていた場所。</p>

<p>実際は行ってみると奥に未舗装路が繋がっており、ちょっと頑張って走れば林道万田野線に繋がってそうな感じを受けたが、
残念ながらヌタヌタのぐっちゃぐちゃな路面状況で 28c のロードバイクで走る気になれなかったため引き返す。</p>

<p>微妙にグラベルバイクが欲しくなる。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2993.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>それとは別に、ハイキングコースもあったが、今日の予定は大塚山であるのでこちらも残念ながら未踏。</p>

<p>まあ、300mそこらだったらロードバイクを置いて行って帰ってきてもよかったかもしれない。</p>

<h2>隧道やダムたち</h2>

<p>そして最後の目標地が大塚山なのだが、そのまま直接行くと大して距離が稼げないので、無駄に養老渓谷の奥まで足を伸ばし折り返す。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2994.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>適当に林道に入ると出会う隧道たち。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2997.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>コンクリートで舗装されているとちょっと残念。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_2998.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>電灯が付いていないのがまた趣深い。</p>

<p>慣れてない頃はフロントライトをつけないでそのまま突っ込んでいたが、意外に何にも見えずに危険ということがわかったので、最近は事前にちゃんと点灯して突っ込む。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_3003.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>そして平沢ダム。</p>

<p>出来立てなのか知らないが、湖の底から枯れた木がいくつも立っている。</p>

<p>趣深い。</p>

<h2>大塚山</h2>

<p>そして最後の目標地である、大塚山。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_3004.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>本当は全部ロードバイクに乗って頂上まで行くつもりだったのだが、、</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_3005.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>思ったよりグラベルが。。石の存在感が大きい。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_3007.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>ここでもまた、グラベルバイクが欲しくなる。。。。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_3011.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>途中の階段などもバイクを背負って登ったが、最後の急登のみは諦めてバイクを置いて登山。</p>

<p>頂上にあった神社にお賽銭投げて任務完了。</p>

<p class='image'>
<img  src='/log/archives/2022/10/27/IMG_0357.jpeg'
      width='500' 
      height='500' 
      alt=''  />
</p>


<p>いつもより短い130kmのツーリング。途中でハイキングしたりお茶したりしてたのでグロスアベレージは当然のように20km/hを切っていた。</p>

<p>たまにはこんなのんびりした自転車もイイネ。</p>

    ]]></content:encoded>
    <dc:subject>自転車</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2022-10-27T09:13:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2022/10/13/choshi-cape">
    <title>銚子岬</title>
    <link>https://www.fraction.jp/log/archives/2022/10/13/choshi-cape</link>
    <description>房総半島をちょくちょくロードバイクで走るようになったのだが、千葉県というと有名どころである銚子岬は犬吠埼にはまだ行ったことがなかった。何度か行こうかと思ったことがあるのだが、どうしても利根川サイクリングロードの景色の変わらない道を延々と走る気になれず先延ばしにしてるうちに結局行かずじまい。そんな重い腰をようやく上げて、銚子岬に行くことにしたのはなんでだったか。。。この、「海から74.5km」という道標を撮った場所と変わらぬ景色が延々と74.5km続く。。特になんのイベントも発生せず、銚子岬に着く。...</description>
    <content:encoded><![CDATA[
        <p>房総半島をちょくちょくロードバイクで走るようになったのだが、千葉県というと有名どころである銚子岬は犬吠埼にはまだ行ったことがなかった。
何度か行こうかと思ったことがあるのだが、どうしても利根川サイクリングロードの景色の変わらない道を延々と走る気になれず先延ばしにしてるうちに結局行かずじまい。</p>

<p>そんな重い腰をようやく上げて、銚子岬に行くことにしたのはなんでだったか。。。</p>

<p class='image'>
<img  src='/log/archives/2022/10/13/IMG_0319.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>この、「海から74.5km」という道標を撮った場所と変わらぬ景色が延々と74.5km続く。。</p>

<p class='image'>
<img  src='/log/archives/2022/10/13/IMG_0323.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>特になんのイベントも発生せず、銚子岬に着く。くそつまらん。。</p>

<p class='image'>
<img  src='/log/archives/2022/10/13/IMG_0325.jpeg'
      width='720' 
      height='540' 
      alt=''  />
</p>


<p>その後も、いつ走っても全然楽しく感じない九十九里海岸を南に走り、ゴールとした東金街道沿いいにある「みきの湯」に到着。
なんだろうね、、毎回北総地域は走っていて面白いと感じることが少ない。</p>

<p>とりあえず利根川サイクリングロードはもう二度と走りたくない。</p>

    ]]></content:encoded>
    <dc:subject>自転車</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2022-10-13T09:20:00+09:00</dc:date>
  </item>
  <item rdf:about="https://www.fraction.jp/log/archives/2022/09/29/kubevirt-noip-after-restart">
    <title>kubevirtのVMをリスタートしたらIPアドレスが消えた</title>
    <link>https://www.fraction.jp/log/archives/2022/09/29/kubevirt-noip-after-restart</link>
    <description>症状UbuntuのVMをkubectl virt restart した後に ssh しようとしたところ、No route to host となって繋がらなくなった。$ k virt restart node-01VM node-01 was scheduled to restart$ ssh ubuntu@node-01.staging.vms.svc.fraction.clusterssh: connect to host node-01.staging.vms.svc.fraction.clu...</description>
    <content:encoded><![CDATA[
        <h2>症状</h2>

<p>UbuntuのVMを<code>kubectl virt restart</code> した後に ssh しようとしたところ、<code>No route to host</code> となって繋がらなくなった。</p>

<pre><code>$ k virt restart node-01
VM node-01 was scheduled to restart

$ ssh ubuntu@node-01.staging.vms.svc.fraction.cluster
ssh: connect to host node-01.staging.vms.svc.fraction.cluster port 22: No route to host
</code></pre>

<h3>再起動後の Mac Address が変わっていた</h3>

<p><code>kubectl virt console</code> で調べてみたところ、Mac Addressが再起動後に変わっていた。</p>

<pre><code class="diff">➜ diff -u before.txt after.txt
--- before.txt  2022-09-29 00:12:28.024068282 +0000
+++ after.txt   2022-09-29 00:13:00.940507202 +0000
@@ -5,9 +5,5 @@
        valid_lft forever preferred_lft forever
     inet6 ::1/128 scope host
        valid_lft forever preferred_lft forever
-2: enp1s0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000
-    link/ether b2:81:6c:00:81:56 brd ff:ff:ff:ff:ff:ff
-    inet 10.244.8.23/24 metric 100 brd 10.244.8.255 scope global dynamic enp1s0
-       valid_lft 86313396sec preferred_lft 86313396sec
-    inet6 fe80::b081:6cff:fe00:8156/64 scope link
-       valid_lft forever preferred_lft forever
+2: enp1s0: &lt;BROADCAST,MULTICAST&gt; mtu 1500 qdisc noop state DOWN group default qlen 1000
+    link/ether 62:1c:50:f6:fe:e3 brd ff:ff:ff:ff:ff:ff
</code></pre>

<p>netplan の設定ファイルを見るに、初回起動時の Mac Address を指定してネットワークの設定を行なっていた。</p>

<pre><code class="yaml">ubuntu@node-01:~$ cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp1s0:
            dhcp4: true
            match:
                macaddress: f2:a5:6b:0c:3b:9f
            set-name: enp1s0
    version: 2
</code></pre>

<h2>解決方法</h2>

<p><code>networkData</code> を指定して、システムデフォルトの設定を上書きする。</p>

<pre><code class="yaml">      - cloudInitNoCloud:
          networkData: |
            version: 2
            ethernets:
              enp1s0:
                dhcp4: true
          userData: |-
            #cloud-config
            password: password
        name: cloudinitdisk
</code></pre>

<p>以上。</p>

<ul>
<li>https://github.com/kubevirt/kubevirt/issues/1646</li>
</ul>


    ]]></content:encoded>
    <dc:subject>Linux</dc:subject>
    <dc:subject>Program/技術</dc:subject>
    <dc:creator>O. Yuanying</dc:creator>
    <dc:date>2022-09-29T09:04:00+09:00</dc:date>
  </item>
</rdf:RDF>
