<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2816846411346017602</id><updated>2026-07-08T15:56:35.428+09:00</updated><category term="Donkeycar"/><category term="AI"/><category term="Raspberry Pi"/><category term="Python"/><category term="AWS"/><category term="Jetson Nano"/><category term="fugaku"/><category term="富岳"/><category term="強化学習"/><category term="IoT"/><category term="Kubernetes"/><category term="Realsense"/><category term="TensorFlow"/><category term="OpenAI Gym"/><category term="SSH"/><category term="T265"/><category term="PyAudio"/><category term="Stable Baselines"/><category term="mlflow"/><category term="異常検知"/><category term="980"/><category term="AVS"/><category term="Autoware"/><category term="CNI"/><category term="Claw Empire"/><category term="CloudFormation"/><category term="Colabo"/><category term="Coral Dev Board"/><category term="Dify"/><category term="Docker"/><category term="EC2"/><category term="GISデータ"/><category term="GML"/><category term="Geo JSON"/><category term="Google"/><category term="Greengrass"/><category term="I2C"/><category term="Perplexity"/><category term="PyCaret"/><category term="PyTorch"/><category term="ROS"/><category term="SONY"/><category term="Slack"/><category term="Spack"/><category term="Tello"/><category term="TensorFlow Lite"/><category term="TensorRT"/><category term="Vaio"/><category term="WiFi"/><category term="geopandas"/><category term="o1-preview"/><category term="pigpio"/><category term="pip"/><category term="pjsub"/><category term="pygame"/><category term="tkinter"/><category term="コンテナ"/><category term="ドローン"/><category term="ハーネス"/><category term="モーター"/><category term="ルンバ"/><category term="地理空間データ"/><category term="基盤地図情報"/><category term="音声"/><title type='text'>腹腹開発</title><subtitle type='html'>仕事上でわかったことのうち顧客に関わる情報が無い物、一般公開して差し障りのなさそうな事をたまーに投稿しています。&#xa;&#xa;ちなみに、記事上に載せた私が書いたコードは、用途問わず再利用いただいてかまいませんが、保障は一切いたしませんので、あしからず。&#xa;&#xa;ですます調の記事とである調の記事が混ざりますが..こちらも、あしからず。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>421</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-2053436976396174845</id><published>2026-07-08T15:56:35.427+09:00</published><updated>2026-07-08T15:56:35.428+09:00</updated><title type='text'>Google Colab相当の環境をローカルPC上のDocker Composeで実現する</title><content type='html'>&lt;p&gt;&amp;nbsp;Docker Composeの有料版に、お金を払いたくない　^H^Hが使えない　ため古いゲーミングPC(GeForce3080)にDocker Composeを入れてその上のコンテナでGoogle Colab相当のノート操作ができないかためしてみた：&lt;/p&gt;&lt;p&gt;コンテナイメージとして asia-docker.pkg.dev/colab-images を使用するが、このままだとJupyter Lab画面がないので Dockerfileを以下のように作成した。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;FROM asia-docker.pkg.dev/colab-images/public/runtime:latest&lt;br /&gt;&lt;br /&gt;# google-colab pins jupyter-server==2.14.0, so jupyterlab is pinned to a&lt;br /&gt;# version that still supports it (newer jupyterlab needs jupyter-server&amp;gt;=2.19).&lt;br /&gt;RUN pip install --no-cache-dir &#39;jupyterlab==4.2.7&#39; &#39;jupyter-server==2.14.0&#39; \&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;amp;&amp;amp; jupyter server extension enable jupyterlab&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;※バージョンを変えたい場合は適宜修正のこと&lt;/p&gt;&lt;p&gt;そしてdocker-compose.ymlでは以下の様の上のDockerfileからイメージを作成するようにした。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;services:&lt;br /&gt;&amp;nbsp; colab-runtime:&lt;br /&gt;&amp;nbsp; &amp;nbsp; build:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; context: .&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; dockerfile: Dockerfile&lt;br /&gt;&amp;nbsp; &amp;nbsp; image: colab-gpu-runtime-jupyterlab:latest&lt;br /&gt;&amp;nbsp; &amp;nbsp; container_name: colab-gpu-runtime&lt;br /&gt;&amp;nbsp; &amp;nbsp; ports:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - &quot;0.0.0.0:9000:8080&quot;&amp;nbsp; &amp;nbsp;# colab.research.google.com からの接続用（将来SSHトンネル等で使う場合に残す）&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - &quot;0.0.0.0:8888:9000&quot;&amp;nbsp; &amp;nbsp;# LAN内から直接ブラウザでアクセスする用（Colab相当・完全ローカル）&lt;br /&gt;&amp;nbsp; &amp;nbsp; volumes:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - ./workspace:/content/workspace&lt;br /&gt;&amp;nbsp; &amp;nbsp; environment:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; COLAB_JUPYTER_IP: 0.0.0.0&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; COLAB_JUPYTER_ALLOW_REMOTE_ACCESS: &quot;true&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; COLAB_JUPYTER_TOKEN: ${COLAB_JUPYTER_TOKEN:-change-this-token}&lt;br /&gt;&amp;nbsp; &amp;nbsp; deploy:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; resources:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; reservations:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; devices:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - driver: nvidia&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; count: all&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; capabilities: [gpu]&lt;br /&gt;&amp;nbsp; &amp;nbsp; restart: unless-stopped&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;ためしていないけど、latestをColab環境バージョンにあわせたタグを指定すれば、該当バージョンのコンテナになる..かな？&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;上の定義にある通り、docker-compose.ymlとおなじディレクトリには、先のDockerfileとworkspaceフォルダを作成しておく。&lt;/p&gt;&lt;p&gt;あと、UIにアクセスする際のトークン文字列を環境変数COLAB_JUPYTER_TOKENに設定する。docker composeコマンドはカレントの.envを読んでくれるので、.envファイルをたとえば以下のように定義する。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;nbsp;COLAB_JUPYTER_TOKEN=my-token-hogehoge&lt;/span&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Jupyter Lab画面を開くには http://IPアドレス:8888/lab?token=my-token-hogehoge をブラウザで開けば良い。&lt;/p&gt;&lt;p&gt;ひとつ..残念なことが１点。&lt;/p&gt;&lt;p&gt;実はGoogle Colab画面を開いて右上の逆三角形を押し「ローカルランタイムに接続」でこのURLをトークン入れればつながるかな..とおもっていたのですが、ホスト名がlocalhostでないと受け付けない仕様になっていてできませんでした。有効なバックエンドURLを入力して..だって..&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhDLV1nVhakmr7nmPuJCSaNKCKZHlsqif75tkySY3H1BFHNW86j71QrqWAz54rVca4LqcSlrMd-ZwpBhTUmN7yaWmAjiinvKU36SHzK0g1aarxMW24_BiHQo_SS253FZAkt5VtsmrKH2uQ_LG6CVvzQXdSObmlYzSKeWhmXIo-lMMljQM-6aHonDlTmbm3C&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;...9000ポート用意したのですが...別のPC上のブラウザ操作からは、今のところ手がありません(Port Fowardしたら、IPになっちゃうだろうし..)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上記の設定ではJupyter Lab画面からColab相当の環境をつかうことで、aptやpipの環境が野良Jupyterで変わらないようにする使い方くらいしか..&lt;/p&gt;&lt;p&gt;研修とかだと古いColabバージョン前提のnotebookファイルなんかがあるから、それには使えるかも..&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/2053436976396174845/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/2053436976396174845' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2053436976396174845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2053436976396174845'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/07/google-colabpcdocker-compose.html' title='Google Colab相当の環境をローカルPC上のDocker Composeで実現する'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEhDLV1nVhakmr7nmPuJCSaNKCKZHlsqif75tkySY3H1BFHNW86j71QrqWAz54rVca4LqcSlrMd-ZwpBhTUmN7yaWmAjiinvKU36SHzK0g1aarxMW24_BiHQo_SS253FZAkt5VtsmrKH2uQ_LG6CVvzQXdSObmlYzSKeWhmXIo-lMMljQM-6aHonDlTmbm3C=s72-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4529657118066498079</id><published>2026-06-23T10:25:04.382+09:00</published><updated>2026-06-23T10:41:23.718+09:00</updated><title type='text'>DifyからSakana.ai のfugu/fugu-ultra を使う</title><content type='html'>&lt;p&gt;&amp;nbsp;現時点では、DifyモデルプロバイダにSakana.aiが登録されていないので、&lt;/p&gt;&lt;p&gt;OpenAI-API-compatible で代替します。&lt;/p&gt;&lt;p&gt;Model Nameは&quot;fugu&quot;もしくは&quot;fugu-ultra&quot;、&lt;br /&gt;Model Typeは&quot;LLM&quot;、&lt;br /&gt;認証名は適当に、&lt;br /&gt;Model display nameはModel Nameと同じにしておく。&lt;br /&gt;API KeyはSakana.aiで取得したAPIキー&quot;fish_...&quot;、&lt;br /&gt;API endpoint URLは&quot;https://api.sakana.ai/v1/&quot;、&lt;br /&gt;を設定し「追加」すれば、使用できるようになります。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;自分はサブスクではなく従量課金にしましたが、&lt;/p&gt;&lt;p&gt;トークン代金がClaude Opusとほとんどかわらないので、&lt;/p&gt;&lt;p&gt;性能がOpus以下なら、サブスクはやめておこうかな..&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;p.s.&lt;/p&gt;&lt;p&gt;APIキー経由でのAPI呼び出しのみなので、Difyでエージェントなりチャットなりを立ててためしてみましたが、バックエンドで別AIを呼び出しているので、反応は遅めに感じました。APIコールなので最新知識を検索させたい場合はDify側でperplexity searchなりツール設定をしてあげる必要はあります(システムプロンプトで最新情報はツールを使えと書けば使ってくれます)。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;バックエンドで呼び出すAI APIがGemini/OpenAI/Claudeなので、&lt;u&gt;AI主権目的の人は気をつけて&lt;/u&gt;ください。&lt;/p&gt;&lt;p&gt;&amp;nbsp;設定にオプトイン・オプトアウトがありデフォルトは「&lt;b&gt;オプトイン&lt;/b&gt;」になってました。&lt;/p&gt;&lt;p&gt;日本のスタートアップ企業ではあるのですが、なんで&quot;円&quot;じゃないんだろう..バックエンドAIが海外ものだからだろうなあ..&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4529657118066498079/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4529657118066498079' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4529657118066498079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4529657118066498079'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/06/difysakanaai-fugufugu-ultra.html' title='DifyからSakana.ai のfugu/fugu-ultra を使う'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4394278882902376342</id><published>2026-05-14T10:25:39.731+09:00</published><updated>2026-05-14T10:25:39.732+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI"/><category scheme="http://www.blogger.com/atom/ns#" term="Claw Empire"/><title type='text'>Claw EmpireをRaspberry Pi 5にセットアップする</title><content type='html'>&lt;h1 style=&quot;text-align: left;&quot;&gt;1.前提条件&lt;/h1&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Raspberry Pi 5にRaspberry Pi OS(21 Apr 2026)がインストールされていること&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Raspberry Pi 5にRaspberry Pi OSをインストールし、SSHでアクセスできる状態にしておくこと&lt;/li&gt;&lt;li&gt;Raspberry Pi 5がインターネットに接続されていること&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;以下のアカウントを用意しておくこと（無料で作成可能）：&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Claude Pro以上&lt;/li&gt;&lt;li&gt;OpenCode Go&lt;/li&gt;&lt;li&gt;GitHub アカウント&lt;/li&gt;&lt;ul&gt;&lt;li&gt;GitHub OAuth (Settings -&amp;gt; Developer settings -&amp;gt; OAuth Apps) で新規OAuth Appを作成し、Client IDとClient Secretをメモしておくこと&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Google アカウント（Gemini CLI用）&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;2. セットアップ手順&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 1: Raspberry Pi OSの更新&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;SSHでRaspberry Pi 5に接続し、以下のコマンドを実行してOSを最新状態に更新する：&lt;br /&gt;sudo apt-get update&lt;br /&gt;sudo apt-get upgrade -y&lt;br /&gt;# nvm/node 24 LTSのインストール&lt;br /&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash&lt;br /&gt;\. &quot;$HOME/.nvm/nvm.sh&quot;&lt;br /&gt;nvm install 24&lt;br /&gt;# 出力文字列はOAUTH_ENCRYPTION_SECRETに使用する&lt;br /&gt;node -e &quot;console.log(require(&#39;crypto&#39;).randomBytes(32).toString(&#39;hex&#39;))&quot;&lt;br /&gt;# IPアドレスをメモしておく&lt;br /&gt;ip a&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 2: Dockerのインストール&lt;/h2&gt;&lt;p&gt;以下のコマンドを実行してDockerをインストールする：&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo apt-get install -y ca-certificates curl&lt;br /&gt;sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;Types: deb&lt;br /&gt;URIs: https://download.docker.com/linux/debian&lt;br /&gt;Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;$VERSION_CODENAME&quot;)&lt;br /&gt;Components: stable&lt;br /&gt;Architectures: $(dpkg --print-architecture)&lt;br /&gt;Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;sudo apt-get update -y&lt;br /&gt;&lt;br /&gt;sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;&lt;br /&gt;sudo systemctl enable docker&lt;br /&gt;sudo usermod -aG docker $USER&lt;br /&gt;sudo systemctl restart docker&lt;br /&gt;sudo systemctl status docker&lt;br /&gt;sudo reboot&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 3: Claw Empireのクローンとビルド&lt;/h2&gt;&lt;p&gt;Raspberry Pi 5に再度SSH接続し、以下のコマンドを実行してClaw Empireのリポジトリをクローンし、Dockerイメージをビルドする：&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;mkdir -p ~/projects&lt;br /&gt;cd ~/projects&lt;br /&gt;git clone https://github.com/GreenSheep01201/claw-empire.git&lt;br /&gt;cd claw-empire&lt;br /&gt;git submodule update --init --recursive&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 4: .env.docker/.env.docker.privateファイルの作成&lt;/h2&gt;&lt;p&gt;プロジェクトルートに `&lt;span style=&quot;font-family: courier;&quot;&gt;.env.docker&lt;/span&gt;` ファイルを作成する：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cd ~/projects/claw-empire&lt;br /&gt;cp .env.example .env.docker&lt;br /&gt;vi .env.docker&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;.env.docker&lt;/span&gt;` ファイルの以下の箇所をコメントアウトして編集する：&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;:&lt;br /&gt;HOST=＜Step1でメモしたIPアドレス＞&lt;br /&gt;:&lt;br /&gt;ALLOWED_ORIGINS=&quot;http://&amp;lt;Step1でメモしたIPアドレス&amp;gt;:8790,https://localhost:8790,http://127.0.0.1:8790&quot;&lt;br /&gt;ALLOWED_ORIGIN_SUFFIXES=&quot;.groq.com,.moonshot.ai&quot;&lt;br /&gt;:&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;プロジェクトルートに `&lt;span style=&quot;font-family: courier;&quot;&gt;.env.docker&lt;/span&gt;.private` ファイルを作成する：&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cd ~/projects/claw-empire&lt;br /&gt;vi .env.docker.private&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;.env.docker.private&lt;/span&gt;` ファイルの以下の箇所を編集する：&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;OAUTH_ENCRYPTION_SECRET=＜Step 1で生成した文字列＞&lt;br /&gt;API_AUTH_TOKEN=&quot;Geheim&quot; # 任意の文字列でOK。APIリクエストの認証に使用される。&lt;br /&gt;OAUTH_GITHUB_CLIENT_ID=＜GitHub OAuth AppのClient ID＞&lt;br /&gt;OAUTH_GITHUB_CLIENT_SECRET=＜GitHub OAuth AppのClient Secret＞&lt;br /&gt;INBOX_WEBHOOK_SECRET=&amp;lt;任意の文字列&amp;gt;&lt;br /&gt;## Anthropic Alt kimi APIキー&lt;br /&gt;ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic&lt;br /&gt;ANTHROPIC_API_KEY=sk-...&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 5: Docker Composeを使用してClaw Empireを起動&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;cd ~/projects/claw-empire&lt;br /&gt;docker compose build&lt;br /&gt;docker compose up -d&lt;br /&gt;docker compose logs -f # エラーがないことを確認したらCtrl+Cでログのフォローを終了&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;GitHub Copilot CLI/KimiCode CLIを使用する場合&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;# GitHub Copilot CLI&lt;br /&gt;docker compose exec --user root claw-empire npm install -g @github/copilot&lt;br /&gt;# KimiCode CLI&lt;br /&gt;#docker compose exec --user root claw-empire curl -L code.kimi.com/install.sh | bash&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Step 6: コード生成ツールの認証&lt;/h2&gt;&lt;p&gt;以下のコマンドを実行して、各コード生成ツールの認証を行う：&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;docker compose exec claw-empire bash&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Claude CodeのOAuth認証&lt;/h3&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; `&lt;span style=&quot;font-family: courier;&quot;&gt;claude&lt;/span&gt;`コマンドを実行しサブスクを選択、表示されたURLをコピーしPCのブラウザでアクセスしてClaude.aiにログインし、Authorizeをクリックして認証を完了させる&lt;br /&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;OpenCode GoのAPIキー設定&lt;/h3&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;opencode&lt;/span&gt;`コマンドを実行し、`&lt;span style=&quot;font-family: courier;&quot;&gt;/models&lt;/span&gt;`を選択&lt;/li&gt;&lt;li&gt;Ctrl+a&lt;/li&gt;&lt;li&gt;OpenCode Go&lt;/li&gt;&lt;li&gt;APIキー設定を選択&lt;/li&gt;&lt;li&gt;適当なモデルを選択&lt;/li&gt;&lt;/ul&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Gemni CLIのOAuth認証&lt;/h3&gt;&lt;p&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;gemini&lt;/span&gt;`コマンドを実行しサブスクを選択、表示されたURLをコピーしPCのブラウザでアクセスしてGoogleアカウントでログインし、Authorizeをクリックして認証を完了させる&lt;br /&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Codex CLIのOAuth認証&lt;/h3&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;codex&lt;/span&gt;`コマンドを実行&lt;/li&gt;&lt;li&gt;デバイス認証を選択&lt;/li&gt;&lt;li&gt;PCのブラウザで指定のURLを開き、表示されたコードを入力して認証を完了させる&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Raspberry Pi上に表示されたコードを入力&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;GitHub Copilot CLIのOAuth認証&lt;/h3&gt;&lt;p&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;copilot&lt;/span&gt;`コマンドを実行し、`&lt;span style=&quot;font-family: courier;&quot;&gt;/login&lt;/span&gt;`を選択、GitHub.comを選択し、指示されたURLをPCのブラウザで開いてGitHubアカウントでログインし、コードを入力して認証を完了させる&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;3. 動作確認&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;同一セグメントのPCからブラウザを起動し、以下のURLにアクセスしてClaw EmpireのWebUIが表示されることを確認する：&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;http://＜Step1でメモしたIPアドレス＞:8790&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;3.1 日本語指定&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Settings&lt;/li&gt;&lt;li&gt;Japaneseを選択しSaveボタン押下&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: right;&quot;&gt;以上&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4394278882902376342/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4394278882902376342' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4394278882902376342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4394278882902376342'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/05/claw-empireraspberry-pi-5.html' title='Claw EmpireをRaspberry Pi 5にセットアップする'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-2132903347161682249</id><published>2026-04-13T07:45:00.004+09:00</published><updated>2026-04-13T07:45:58.469+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ハーネス"/><title type='text'>【ハーネスエンジニアリングを始める前に】gpt-oss:20b の入出力データから、LLMの動作を理解する</title><content type='html'>&lt;h2 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijAbdNMpWB7va0yLmWcgI8KhZA_f2LXnlhNg-inJGP2IgZ36ggZEGt4SMktfSDv_up06EIx8ZJYEaX4VV3gAga-miZFP3OLWu8hYfvzlOLuYUQ5-unW99E4PTnwOCAo0eiywk5QbfuDQG4KH-l1BgxYa4fNEJVlw4F8S82ImHlkpkTtYc7bjTTxqSvOYZG/s1213/herness2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;765&quot; data-original-width=&quot;1213&quot; height=&quot;202&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijAbdNMpWB7va0yLmWcgI8KhZA_f2LXnlhNg-inJGP2IgZ36ggZEGt4SMktfSDv_up06EIx8ZJYEaX4VV3gAga-miZFP3OLWu8hYfvzlOLuYUQ5-unW99E4PTnwOCAo0eiywk5QbfuDQG4KH-l1BgxYa4fNEJVlw4F8S82ImHlkpkTtYc7bjTTxqSvOYZG/s320/herness2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;1. はじめに&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;最近は、&lt;a href=&quot;https://cursor.com/ja&quot; target=&quot;_blank&quot;&gt;Cursor&lt;/a&gt; や &lt;a href=&quot;https://antigravity.google/&quot; target=&quot;_blank&quot;&gt;Antigravity&lt;/a&gt; などのAIエージェント前提の統合開発環境や、&lt;a href=&quot;https://code.claude.com/docs/ja/desktop&quot; target=&quot;_blank&quot;&gt;Claude Desktop&lt;/a&gt; や &lt;a href=&quot;https://openai.com/ja-JP/index/introducing-the-codex-app/&quot; target=&quot;_blank&quot;&gt;Codex アプリ&lt;/a&gt; などのPC上のオブジェクト操作が可能なデスクトップアプリ、 &lt;a href=&quot;https://openclaw.ai/&quot; target=&quot;_blank&quot;&gt;Open Claw&lt;/a&gt; といったPC全体の操作をリモートで任せてしまうようなソフトウェアなどがどんどん登場しています。&lt;br /&gt;&lt;br /&gt;これらのソフトウェアすべてが、&lt;a href=&quot;https://ja.wikipedia.org/wiki/%E5%A4%A7%E8%A6%8F%E6%A8%A1%E8%A8%80%E8%AA%9E%E3%83%A2%E3%83%87%E3%83%AB&quot; target=&quot;_blank&quot;&gt;LLM&lt;/a&gt;](大規模言語モデル)をAPI経由で使用しています。CursorやAntigravity、Claude DesktopやCodex アプリ、&lt;a href=&quot;https://gemini.google.com/app?hl=ja&quot; target=&quot;_blank&quot;&gt;Gemini のWeb U&lt;/a&gt;I や &lt;a href=&quot;https://notebooklm.google.com/&quot; target=&quot;_blank&quot;&gt;NotebookLM&lt;/a&gt; 、&lt;a href=&quot;https://dify.ai/&quot; target=&quot;_blank&quot;&gt;Dify&lt;/a&gt;や &lt;a href=&quot;https://n8n.io/&quot; target=&quot;_blank&quot;&gt;n8n&lt;/a&gt; 、&lt;a href=&quot;https://devin.ai/&quot; target=&quot;_blank&quot;&gt;Devin&lt;/a&gt; 、OpenClaw、&lt;a href=&quot;https://github.com/GreenSheep01201/claw-empire&quot; target=&quot;_blank&quot;&gt;Claw Empire&lt;/a&gt; 、&lt;a href=&quot;https://github.com/xuiltul/animaworks&quot; target=&quot;_blank&quot;&gt;Anima Works&lt;/a&gt; などのソフトウェア自体にはAIが搭載されておらず、LLM の &lt;a href=&quot;https://refactoring.guru/ja/design-patterns/decorator&quot; target=&quot;_blank&quot;&gt;デコレーター&lt;/a&gt; として複雑な機能を補填しています。こういったソフトウェアを”&lt;a href=&quot;https://openai.com/ja-JP/index/harness-engineering/&quot; target=&quot;_blank&quot;&gt;ハーネス&lt;/a&gt;&quot;と呼ぶ記事が増えてきています。&lt;br /&gt;&lt;br /&gt;ハーネスは、LLMの入出力を補完するためのソフトウェアであり、LLMが理解できる形式で入力を提供し、LLMからの出力を適切に処理してユーザに返す役割を果たしています。これらのハーネスは、LLMがより効果的に機能するための重要な要素となっています。ハーネスは用途に応じて様々な実装が存在しています。AnthropicやOpenAI、Googleは、ハーネスに&quot;長期記憶&quot;や&quot;ツール使用&quot;、&quot;&lt;a href=&quot;https://www.aist.go.jp/aist_j/magazine/20231129.html&quot; target=&quot;_blank&quot;&gt;マルチモーダル&lt;/a&gt;入力&quot;などの機能を提供することで、LLMの能力を拡張しています。&lt;br /&gt;&lt;br /&gt;特に最近はハーネスの進化がすすんでおり、様々な機能&lt;a href=&quot;https://cloud.google.com/use-cases/retrieval-augmented-generation?hl=ja&quot; target=&quot;_blank&quot;&gt;RAG(Retrieval-Augmented Generation:知識補填)&lt;/a&gt;、ツール利用(プログラム実行結果の活用)、マルチモーダル入力、&lt;a href=&quot;https://www.ibm.com/jp-ja/think/topics/context-window&quot; target=&quot;_blank&quot;&gt;コンテキスト&lt;/a&gt; (Webアプリのセッションみたいなもの)などが提供されるようになっています。これらの機能は、LLMがより複雑なタスクを処理できるようにするためのものであり、ユーザがLLMをより効果的に活用できるようにするためのものです。&lt;br /&gt;&lt;br /&gt;どんどん新しいものが登場するため、ハーネスの中身を学習する場合は、なかなか大変です。そこでユーザからのハーネスへの入出力ではなく、ハーネスからLLMへの入出力を実際に見ることで、ハーネスではどんなことをしているのかを理解することができます。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;2. サンプルの前提&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;- LLM：&lt;a href=&quot;https://openai.com/ja-JP/index/introducing-gpt-oss/&quot; target=&quot;_blank&quot;&gt;gpt-oss:20b&lt;/a&gt; 、OpenAI社が提供しているオープンモデル、gpt-4.1-mini相当の能力があるといわれている&lt;br /&gt;- ハーネス：search、open、findという関数をもつbrowserツールが使える状態、RAGなし&lt;br /&gt;- 質問文「ホルムズ海峡の最新状況をおしえて」&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;3.ハーネスとLLMの入出力例&lt;/h2&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.1ハーネス→LLM 1回目の入力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;br /&gt;Knowledge cutoff: 2024-06&lt;br /&gt;Current date: 2026-04-08&lt;br /&gt;&lt;br /&gt;Reasoning: high&lt;br /&gt;&lt;br /&gt;# Tools&lt;br /&gt;&lt;br /&gt;## browser&lt;br /&gt;// Tool for browsing.&lt;br /&gt;// The `cursor` appears in brackets before each browsing display: `[{cursor}]`.&lt;br /&gt;// Cite information from the tool using the following format:&lt;br /&gt;// `〖{cursor}†L{line_start}(-L{line_end})?〗`&lt;br /&gt;namespace browser {&lt;br /&gt;// Searches for information related to `query` and displays `topn` results.&lt;br /&gt;type search = (_: {&lt;br /&gt;query: string,&lt;br /&gt;topn?: number,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;// Opens the link `id` from the page indicated by `cursor`.&lt;br /&gt;type open = (_: {&lt;br /&gt;id?: number | string,&lt;br /&gt;cursor?: number,&lt;br /&gt;loc?: number,&lt;br /&gt;num_lines?: number,&lt;br /&gt;view_source?: boolean,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;// Finds exact matches of `pattern` in the current page, or the page given by `cursor`.&lt;br /&gt;type find = (_: {&lt;br /&gt;pattern: string,&lt;br /&gt;cursor?: number,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;} // namespace browser&lt;br /&gt;&lt;br /&gt;# Valid channels: analysis, commentary, final. Channel must be included for every message.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;developer&amp;lt;|message|&amp;gt;# Instructions&lt;br /&gt;&lt;br /&gt;- User requests about &quot;latest&quot; or &quot;recent&quot; information must be verified with browser.&lt;br /&gt;- Prefer reputable, up-to-date sources.&lt;br /&gt;- Summarize the situation in Japanese.&lt;br /&gt;- Include concrete dates when useful.&lt;br /&gt;- Keep the final answer concise but informative.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;&lt;/span&gt;`や`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|message|&amp;gt;&lt;/span&gt;`などのタグのような文字列は、ハーネスがLLMに入力する際のフォーマットで定められた予約済みのトークンを示しています。これらのトークンは、LLMがどのような情報を受け取っているかを理解するためのものです。トークンの文字列は各モデルで似通っていますが、厳密には統一されていません。各モデルはそれぞれが定義した予約済みトークンをつけた文字列で学習させているのです。LLMはこれらの予約済みトークン付きの入力を受け取り、返事にも同様にトークンをつけて返します。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;（今のところ）予約済みトークンの標準がないのは、おそらく原文をトークンに変換するトークナイザを各社で勝手に作ってしまったことが原因でないかな..と思います。モデルはトークンという複数文字単位を１つのトークンとして扱います。そのときの変換するプログラムがトークナイザなのですが、各言語で扱う文字記号がことなったり英語のように単語区切りが明確だったり、日本語のように単語区切りがあいまいだったりするため、各社が独自のトークナイザを作ってしまったのではないかと推測しています。そしてトークナイザの仕様によってモデル性能の差がでるのではないかという研究もつづいているため、落ち着く様子がなさそうです。&lt;/p&gt;&lt;p&gt;そしてオープンモデルを各社連携なしにだしてしまったことも足並みを乱れさせてしまったかな..と。予約済みトークンの種類もいくつか存在します。最初に出てきたのは旧Facebookのllamaのもので、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;s&amp;gt;&lt;/span&gt;`や`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;/s&amp;gt;&lt;/span&gt;`、`&lt;span style=&quot;font-family: courier;&quot;&gt;[INST]&lt;/span&gt;`、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;&amp;lt;SYS&amp;gt;&amp;gt;&lt;/span&gt;`などが含まれています。今回の例でも使っているOpenAI系は、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;&lt;/span&gt;`や`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|end|&amp;gt;&lt;/span&gt;`などのトークンを使っています。Googleは、`&lt;span style=&quot;font-family: courier;&quot;&gt;[START]&lt;/span&gt;`や`&lt;span style=&quot;font-family: courier;&quot;&gt;[END]&lt;/span&gt;`などのトークンを使っています。これらの各社が共同研究したなら、予約済みトークンの標準もできて、ハーネスエンジニアリングもやりやすくなったのかもしれません。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;/span&gt;`は、いわゆる &lt;a href=&quot;https://learn.microsoft.com/ja-jp/azure/foundry/openai/concepts/advanced-prompt-engineering&quot; target=&quot;_blank&quot;&gt;SYSTEMメッセージ&lt;/a&gt; というもので、ハーネス側から与えられます。SYSTEMメッセージは毎回の入力テキストの冒頭に入るもので、LLMに対して「あなたはこういう存在である」ということを伝えるためのものです。LLMはこのSYSTEMメッセージを受け取ることで、自分がどのような役割を果たすべきかを理解します。Difyやn8nの研修などでSYSTEMメッセージはとても重要と説明されているのはこのためです。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;Difyなどの独自ワークフローを作成できるツールでSYSTEMメッセージを設定する場合、長々とテキストを書き入れてしまうと、コンテキストウィンドウをたちまち食いつぶしてしまいます。SYSTEMメッセージは、Keep it Simple, Stupid (KISS)の原則に従って、できるだけ簡潔に書くようにしましょう。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;Reasoning: high&lt;/span&gt;`は、gpt-oss:20b固有のトークンで、LLMに対して「今回は高度な推論が必要なタスクである」ということを伝えるためのものです。gpt-oss:20bでは、Reasoning に指定されたレベルに応じて、試行モードの深さを調節しています。&lt;span style=&quot;font-family: courier;&quot;&gt;Reasoning: low&lt;/span&gt;であれば、LLMは浅い試行モードで動作し、&lt;span style=&quot;font-family: courier;&quot;&gt;Reasoning: high&lt;/span&gt;であれば、LLMは深い試行モードで動作します。Reasoningのレベルを指定することで、LLMがタスクに対してどの程度の推論を行うべきかを制御することができます。そういう動作を gpt-oss:20b トレーニング時にLLMが学習されているのです。&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;# Tools&lt;/span&gt;`以降は、ハーネスがLLMに対して「あなたはこういうツールを使うことができますよ」と伝えるためのものです。ここでは、browserというツールが使えることが示されています。browserツールにはsearch、open、findという関数が定義されており、LLMはこれらの関数を呼び出すことでブラウザ操作を行うことができます。注意すべきは、コメントで仕様を文章で定義しているところです。コメントは簡潔かつ不明瞭な動作にならないような記述にしておく必要があります。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;こういった定義はハーネス側の処理で書き込まれます。ハーネスにビルトインされたツールは、ユーザが変更することは(おそらく)できないですが、独自ツールをハーネスに対して指定する場合は、SYSTEMメッセージ同様注意して設定してください。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;LLM自体にはツールを実行する機能がありません。これはハーネス側でどのようなツールが使える状態であるかを示しており、&lt;a href=&quot;https://cloud.google.com/discover/what-is-model-context-protocol?hl=ja&quot; target=&quot;_blank&quot;&gt;MCP(Multi-Channel Processing) &lt;/a&gt;ツールもこのツール機能の一種です。このためMCPツールやハーネス自体の持つツールの数が増えると、入力テキスト長がどんどんながくなります。こういったツール爆発の対策として、スキルという機能をハーネスに持たせることが一般的になりつつあります。&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;/span&gt;`は、ユーザからの入力を示しています。LLMはこの指示を受け取ることで、ハーネスが提供するツールを使ってホルムズ海峡の最新情報を収集し、それをまとめて報告するタスクを実行することになります。&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;`でとまっており、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|end|&amp;gt;&lt;/span&gt;`がないのは、LLM自体が文章の続きを予測して出力するだけのAPIであるということを示しています。GeminiやOpenAI、Claudeをつかっていると、あたかも対話しているように見えますが、誰がどういうメッセージを発しているかという形式でLLMを学習させることで、回答文を返答させているにすぎないのです。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.2 LLM→ハーネス 1回目の出力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;ユーザは「最新情報」を求めている。ホルムズ海峡は地政学・海運・エネルギー市場に関わるため、知識カットオフ後の情報確認が必要。まずニュース検索で直近の主要論点と日付を把握する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.search &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;query&quot;:&quot;Hormuz Strait latest news shipping security oil April 2026&quot;,&quot;topn&quot;:5,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;入力の末尾では`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;`となっていたので`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|message|&amp;gt;&lt;/span&gt;`から始まるはずなのですが、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&lt;/span&gt;`になっています。これは、いわゆる思考中のメッセージを出力していることを表していて、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&lt;/span&gt;`から`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|end|&amp;gt;&lt;/span&gt;`までが思考している内容を表していることを指しています。assistantの出力がこのテキストにないのは、まだLLMが思考を継続していて、正式な返答をまだ返していない状態であることを示しています。&lt;br /&gt;&lt;br /&gt;LLMは応答テキストを生成していくうちに、ニュース検索をまずすべきという文章を出力し、次にハーネス側がもっているツールのうち、browserツールのsearch関数を呼び出すべきだと判断しています。LLMは、ハーネス側が提供するツールを呼び出すためのフォーマットである`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.search &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{...}&amp;lt;|call|&amp;gt;&lt;/span&gt;`という形式で出力することで、ハーネス側に「私は今からこのツールを呼び出しますよ」ということを伝えています。&lt;br /&gt;&lt;br /&gt;この返事を受け取ったハーネスは、テキスト内に、ツール実行指示があると判断し、`&lt;span style=&quot;font-family: courier;&quot;&gt;browser.search&lt;/span&gt;`関数を呼び出すための引数をJSON形式で抜き取ります。そして、ハーネス側で`&lt;span style=&quot;font-family: courier;&quot;&gt;browser.search&lt;/span&gt;`関数を呼び出し、ブラウザ操作を行います。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.3 ハーネス→LLM 2回目の入力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;br /&gt;Knowledge cutoff: 2024-06&lt;br /&gt;Current date: 2026-04-08&lt;br /&gt;&lt;br /&gt;Reasoning: high&lt;br /&gt;&lt;br /&gt;# Tools&lt;br /&gt;&lt;br /&gt;## browser&lt;br /&gt;// Tool for browsing.&lt;br /&gt;namespace browser {&lt;br /&gt;type search = (_: {&lt;br /&gt;query: string,&lt;br /&gt;topn?: number,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type open = (_: {&lt;br /&gt;id?: number | string,&lt;br /&gt;cursor?: number,&lt;br /&gt;loc?: number,&lt;br /&gt;num_lines?: number,&lt;br /&gt;view_source?: boolean,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type find = (_: {&lt;br /&gt;pattern: string,&lt;br /&gt;cursor?: number,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;} // namespace browser&lt;br /&gt;&lt;br /&gt;# Valid channels: analysis, commentary, final. Channel must be included for every message.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;developer&amp;lt;|message|&amp;gt;# Instructions&lt;br /&gt;&lt;br /&gt;- User requests about &quot;latest&quot; or &quot;recent&quot; information must be verified with browser.&lt;br /&gt;- Prefer reputable, up-to-date sources.&lt;br /&gt;- Summarize the situation in Japanese.&lt;br /&gt;- Include concrete dates when useful.&lt;br /&gt;- Keep the final answer concise but informative.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;ユーザは「最新情報」を求めている。ホルムズ海峡は地政学・海運・エネルギー市場に関わるため、知識カットオフ後の情報確認が必要。まずニュース検索で直近の主要論点と日付を把握する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.search &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;query&quot;:&quot;Hormuz Strait latest news shipping security oil April 2026&quot;,&quot;topn&quot;:5,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.search to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[0] Reuters — Apr 7, 2026 — Insurers raise watch level for Gulf shipping after regional tensions flare.&lt;br /&gt;[1] AP News — Apr 7, 2026 — U.S. Navy says commercial traffic continues, but alerts remain elevated near the Strait of Hormuz.&lt;br /&gt;[2] UKMTO advisory — Apr 6, 2026 — Merchant vessels advised to maintain heightened vigilance in the Gulf, Gulf of Oman, and Strait of Hormuz.&lt;br /&gt;[3] Lloyd&#39;s List — Apr 7, 2026 — Tanker operators review routing risk premiums.&lt;br /&gt;[4] Bloomberg — Apr 7, 2026 — Oil markets react to renewed Hormuz transit concerns.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;２回目の対話なのに`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;/span&gt;`からはじまっています。これはLLM APIは、ステートレスであり、過去の会話を覚えていないため、毎回の入力にSYSTEMメッセージからつける必要があるためです。ツールの説明も前回と同様につけていますが、当然LLM側は忘れてしまっているので、ハーネスは毎回の入力にツールの説明もつける必要があるわけです。&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;/span&gt;` と最初の質問文がそのまま今回の入力テキストに入っているのも、LLMがステートレスだからです。&lt;br /&gt;&lt;br /&gt;ユーザとハーネスの対話を長く続けると、回答精度が落ちる理由は、このように過去の対話内容を含めた入力テキストを毎回送るため、テキスト(トークン)量がスウェーデンリレー走者の距離のようにどんどん長くなっていくからです。最新のハーネスでは、要約したテキストに圧縮して入力テキストに送るなどの工夫がされています（要約するLLMとの応対が1回以上行われる）が、対話が長くなればなるほど、LLMにとっては過去の対話内容を理解することが難しくなっていきます。&lt;br /&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;browser.search to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[0] Reuters..&lt;/span&gt;` は、ハーネスがツール実行した結果をLLMに伝達するために入力テキストに添付されて送られます。RAGを使う場合も、このようにRAGで得られたチャンクテキストを入力テキストにつけて送信しているので、あたかも最新知識を知っているかのように動作します。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.4 LLM→ハーネス 2回目の出力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;主要論点は、1) 通航自体は継続、2) 警戒水準上昇、3) 保険料・原油市場への影響。Reuters と UKMTO を開いて、封鎖の有無と警戒勧告の文言を確認する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;cursor&quot;:0,&quot;id&quot;:0,&quot;loc&quot;:1,&quot;num_lines&quot;:80,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&lt;/span&gt;`から`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|end|&amp;gt;&lt;/span&gt;`までのテキストなので、２回目の出力内にもまだ最終回等がなく、まだハーネスとの対話が必要であることがわかります。&lt;/blockquote&gt;&lt;br /&gt;前回の検索結果を受け取った内容をもとに続きの文章を出力しています。LLMは、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;主要論点は、1) 通航自体は継続、2) 警戒水準上昇、3) 保険料・原油市場への影響。Reuters と UKMTO を開いて、封鎖の有無と警戒勧告の文言を確認する。&amp;lt;|end|&amp;gt;&lt;/span&gt;`にあるとおりロイターとUKMTO(?)の記事検索が必要と判断したようです。LLMは、ハーネス側が提供するツールのうち、browserツールのopen関数を呼び出すべきだと判断しています。LLMは、ハーネス側が提供するツールを呼び出すためのフォーマットである`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{...}&amp;lt;|call|&amp;gt;&lt;/span&gt;`という形式で出力することで、ハーネス側に「私は今からこのツールを呼び出しますよ」ということを伝えています。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;ここではLLMが検索対象を指定していますが、あくまで一例です。ハーネス側の提供するツールに検索対象を任せる場合もあります。検索対象をツール内で制限するという方法もあります。提供ツール自体を&lt;a href=&quot;https://www.perplexity.ai/&quot; target=&quot;_blank&quot;&gt;Perplexity Search&lt;/a&gt; や &lt;a href=&quot;https://www.tavily.com/&quot; target=&quot;_blank&quot;&gt;Tavily Searc&lt;/a&gt;h などの検索ツールをMCP指定すると、ツール側の実装に依存することになります。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;ハーネスはこの内容からツール実行に必要な情報を抜き取り、実行します。この場合は、ブラウザで検索結果の一番目のリンクを開くという操作になります。ブラウザでリンクを開いた後の内容は、次の入力テキストでLLMに伝えられます。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.5 ハーネス→LLM 3回目の入力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;br /&gt;Knowledge cutoff: 2024-06&lt;br /&gt;Current date: 2026-04-08&lt;br /&gt;&lt;br /&gt;Reasoning: high&lt;br /&gt;&lt;br /&gt;# Tools&lt;br /&gt;&lt;br /&gt;## browser&lt;br /&gt;namespace browser {&lt;br /&gt;type search = (_: {&lt;br /&gt;query: string,&lt;br /&gt;topn?: number,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type open = (_: {&lt;br /&gt;id?: number | string,&lt;br /&gt;cursor?: number,&lt;br /&gt;loc?: number,&lt;br /&gt;num_lines?: number,&lt;br /&gt;view_source?: boolean,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type find = (_: {&lt;br /&gt;pattern: string,&lt;br /&gt;cursor?: number,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;} // namespace browser&lt;br /&gt;&lt;br /&gt;# Valid channels: analysis, commentary, final. Channel must be included for every message.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;developer&amp;lt;|message|&amp;gt;# Instructions&lt;br /&gt;&lt;br /&gt;- User requests about &quot;latest&quot; or &quot;recent&quot; information must be verified with browser.&lt;br /&gt;- Prefer reputable, up-to-date sources.&lt;br /&gt;- Summarize the situation in Japanese.&lt;br /&gt;- Include concrete dates when useful.&lt;br /&gt;- Keep the final answer concise but informative.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;ユーザは「最新情報」を求めている。ホルムズ海峡は地政学・海運・エネルギー市場に関わるため、知識カットオフ後の情報確認が必要。まずニュース検索で直近の主要論点と日付を把握する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.search &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;query&quot;:&quot;Hormuz Strait latest news shipping security oil April 2026&quot;,&quot;topn&quot;:5,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.search to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[0] Reuters — Apr 7, 2026 — Insurers raise watch level for Gulf shipping after regional tensions flare.&lt;br /&gt;[1] AP News — Apr 7, 2026 — U.S. Navy says commercial traffic continues, but alerts remain elevated near the Strait of Hormuz.&lt;br /&gt;[2] UKMTO advisory — Apr 6, 2026 — Merchant vessels advised to maintain heightened vigilance in the Gulf, Gulf of Oman, and Strait of Hormuz.&lt;br /&gt;[3] Lloyd&#39;s List — Apr 7, 2026 — Tanker operators review routing risk premiums.&lt;br /&gt;[4] Bloomberg — Apr 7, 2026 — Oil markets react to renewed Hormuz transit concerns.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;主要論点は、1) 通航自体は継続、2) 警戒水準上昇、3) 保険料・原油市場への影響。Reuters と UKMTO を開いて、封鎖の有無と警戒勧告の文言を確認する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;cursor&quot;:0,&quot;id&quot;:0,&quot;loc&quot;:1,&quot;num_lines&quot;:80,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.open to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[1] Reuters&lt;br /&gt;L1: Apr 7, 2026&lt;br /&gt;L2: Insurers raised watch levels for Gulf shipping after regional tensions intensified.&lt;br /&gt;L3: Commercial vessel traffic through the Strait of Hormuz continued on Tuesday.&lt;br /&gt;L4: No authority announced a formal closure of the waterway.&lt;br /&gt;L5: Analysts said risk premiums for tankers and some cargoes could rise if tensions persist.&lt;br /&gt;L6: Energy traders monitored the situation for possible supply disruption concerns.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;&lt;/blockquote&gt;3回めの対話なので、過去2回のやりとりが入力テキストを占めるようになってきました。LLMは、ブラウザで開いた記事の内容を受け取ると、記事の内容をもとに次の文章を出力しています。LLMは、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;主要論点は、1) 通航自体は継続、2) 警戒水準上昇、3) 保険料・原油市場への影響。Reuters と UKMTO を開いて、封鎖の有無と警戒勧告の文言を確認する。&amp;lt;|end|&amp;gt;&lt;/span&gt;`にあるとおりロイターの記事から主要論点を抽出し、次にUKMTOの記事も開いて内容を確認する必要があると判断したようです。LLMは、ハーネス側が提供するツールのうち、browserツールのopen関数を呼び出すべきだと判断しています。LLMは、ハーネス側が提供するツールを呼び出すためのフォーマットである`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{...}&amp;lt;|call|&amp;gt;&lt;/span&gt;`という形式で出力することで、ハーネス側に「私は今からこのツールを呼び出しますよ」ということを伝えています。&lt;br /&gt;&lt;br /&gt;ハーネスは前回同様この内容からツール実行に必要な情報を抜き取り、実行します。この場合は、ブラウザで検索結果の二番目のリンクを開くという操作になります。ブラウザでリンクを開いた後の内容は、次の入力テキストでLLMに伝えられます。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.6 LLM→ハーネス 3回目の出力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;Reuters で「通航継続」と「正式封鎖なし」を確認。次に UKMTO で船舶向け警戒勧告の範囲を確認する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;cursor&quot;:0,&quot;id&quot;:2,&quot;loc&quot;:1,&quot;num_lines&quot;:80,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;この出力もまだ最終回答が含まれていません。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;LLMは、ブラウザで開いた記事の内容を受け取ると、記事の内容をもとに次の文章を出力しています。LLMは、`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;Reuters で「通航継続」と「正式封鎖なし」を確認。次に UKMTO で船舶向け警戒勧告の範囲を確認する。&amp;lt;|end|&amp;gt;&lt;/span&gt;`にあるとおりロイターの記事から「通航継続」と「正式封鎖なし」を確認し、次にUKMTOの記事も開いて内容を確認する必要があると判断したようです。LLMは、ハーネス側が提供するツールのうち、browserツールのopen関数を呼び出すべきだと判断しています。&lt;br /&gt;&lt;br /&gt;ハーネスは、指示通りツールを実行します。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.7 ハーネス→LLM 4回目の入力&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;lt;|start|&amp;gt;system&amp;lt;|message|&amp;gt;You are ChatGPT, a large language model trained by OpenAI.&lt;br /&gt;Knowledge cutoff: 2024-06&lt;br /&gt;Current date: 2026-04-08&lt;br /&gt;&lt;br /&gt;Reasoning: high&lt;br /&gt;&lt;br /&gt;# Tools&lt;br /&gt;&lt;br /&gt;## browser&lt;br /&gt;namespace browser {&lt;br /&gt;type search = (_: {&lt;br /&gt;query: string,&lt;br /&gt;topn?: number,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type open = (_: {&lt;br /&gt;id?: number | string,&lt;br /&gt;cursor?: number,&lt;br /&gt;loc?: number,&lt;br /&gt;num_lines?: number,&lt;br /&gt;view_source?: boolean,&lt;br /&gt;source?: string,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;type find = (_: {&lt;br /&gt;pattern: string,&lt;br /&gt;cursor?: number,&lt;br /&gt;}) =&amp;gt; any;&lt;br /&gt;&lt;br /&gt;} // namespace browser&lt;br /&gt;&lt;br /&gt;# Valid channels: analysis, commentary, final. Channel must be included for every message.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;developer&amp;lt;|message|&amp;gt;# Instructions&lt;br /&gt;&lt;br /&gt;- User requests about &quot;latest&quot; or &quot;recent&quot; information must be verified with browser.&lt;br /&gt;- Prefer reputable, up-to-date sources.&lt;br /&gt;- Summarize the situation in Japanese.&lt;br /&gt;- Include concrete dates when useful.&lt;br /&gt;- Keep the final answer concise but informative.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;user&amp;lt;|message|&amp;gt;ホルムズ海峡の最新情報をまとめて報告して&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;ユーザは「最新情報」を求めている。ホルムズ海峡は地政学・海運・エネルギー市場に関わるため、知識カットオフ後の情報確認が必要。まずニュース検索で直近の主要論点と日付を把握する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.search &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;query&quot;:&quot;Hormuz Strait latest news shipping security oil April 2026&quot;,&quot;topn&quot;:5,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.search to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[0] Reuters — Apr 7, 2026 — Insurers raise watch level for Gulf shipping after regional tensions flare.&lt;br /&gt;[1] AP News — Apr 7, 2026 — U.S. Navy says commercial traffic continues, but alerts remain elevated near the Strait of Hormuz.&lt;br /&gt;[2] UKMTO advisory — Apr 6, 2026 — Merchant vessels advised to maintain heightened vigilance in the Gulf, Gulf of Oman, and Strait of Hormuz.&lt;br /&gt;[3] Lloyd&#39;s List — Apr 7, 2026 — Tanker operators review routing risk premiums.&lt;br /&gt;[4] Bloomberg — Apr 7, 2026 — Oil markets react to renewed Hormuz transit concerns.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;主要論点は、1) 通航自体は継続、2) 警戒水準上昇、3) 保険料・原油市場への影響。Reuters と UKMTO を開いて、封鎖の有無と警戒勧告の文言を確認する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;cursor&quot;:0,&quot;id&quot;:0,&quot;loc&quot;:1,&quot;num_lines&quot;:80,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.open to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[1] Reuters&lt;br /&gt;L1: Apr 7, 2026&lt;br /&gt;L2: Insurers raised watch levels for Gulf shipping after regional tensions intensified.&lt;br /&gt;L3: Commercial vessel traffic through the Strait of Hormuz continued on Tuesday.&lt;br /&gt;L4: No authority announced a formal closure of the waterway.&lt;br /&gt;L5: Analysts said risk premiums for tankers and some cargoes could rise if tensions persist.&lt;br /&gt;L6: Energy traders monitored the situation for possible supply disruption concerns.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;Reuters で「通航継続」と「正式封鎖なし」を確認。次に UKMTO で船舶向け警戒勧告の範囲を確認する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;analysis to=browser.open &amp;lt;|constrain|&amp;gt;json&amp;lt;|message|&amp;gt;{&quot;cursor&quot;:0,&quot;id&quot;:2,&quot;loc&quot;:1,&quot;num_lines&quot;:80,&quot;source&quot;:&quot;web&quot;}&amp;lt;|call|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;browser.open to=assistant&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;[2] UKMTO advisory&lt;br /&gt;L1: Apr 6, 2026&lt;br /&gt;L2: Merchant vessels are advised to maintain heightened vigilance.&lt;br /&gt;L3: The advisory applies to the Gulf, Gulf of Oman, and Strait of Hormuz.&lt;br /&gt;L4: Ships should review security measures and report suspicious activity.&lt;br /&gt;L5: Operators are encouraged to monitor official updates continuously.&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;ハーネスは、過去の対話履歴＋ツール実行結果をつけてLLMに送信します。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3.8 LLM→ハーネス 4回目の出力(最終回答)&lt;/h3&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;十分。ユーザは要約報告を求めているので、日本語で、最新時点の要点、封鎖有無、海運・エネルギー市場への影響を短く整理して返す。Reuters と UKMTO を引用する。&amp;lt;|end|&amp;gt;&lt;br /&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;final&amp;lt;|message|&amp;gt;ホルムズ海峡の最新状況を要約します。&lt;br /&gt;&lt;br /&gt;- 2026年4月7日時点の報道では、周辺の緊張上昇を受けて海運保険やリスク監視が強化されています。〖1†L1-L5〗&lt;br /&gt;- ただし、少なくともこの時点で**海峡の正式封鎖が発表されたわけではなく、商船の通航自体は継続**しています。〖1†L3-L4〗&lt;br /&gt;- 一方で、UKMTO は 2026年4月6日付で、**ペルシャ湾・オマーン湾・ホルムズ海峡を航行する船舶に高度な警戒維持**を勧告しています。〖2†L1-L5〗&lt;br /&gt;- 実務上の含意としては、直近の焦点は「通航停止そのもの」よりも、**警戒レベル上昇、保険料・リスクプレミアム上振れ、原油輸送不安による市場反応**です。〖1†L5-L6〗&lt;br /&gt;&lt;br /&gt;要するに、最新公開情報ベースでは「全面封鎖」ではなく、**通航は続いているが安全保障リスクが高まっている局面**として捉えるのが妥当です。&amp;lt;|return|&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|channel|&amp;gt;analysis&amp;lt;|message|&amp;gt;十分。ユーザは要約報告を求めているので、日本語で、最新時点の要点、封鎖有無、海運・エネルギー市場への影響を短く整理して返す。Reuters と UKMTO を引用する。&amp;lt;|end|&amp;gt;&lt;/span&gt;`の直後に`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|start|&amp;gt;assistant&amp;lt;|channel|&amp;gt;final&lt;/span&gt;`と出力されています。ようやくassistantとして最終回答を行うことを示しています。&lt;br /&gt;&lt;br /&gt;この出力メッセージは`&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;lt;|return|&amp;gt;&lt;/span&gt;`で終わっています。これもgpt-oss:20b固有の湯役済みトークンのひとつで、LLMに対して「これが回答のおわりである」ということを伝えるためのものです。ハーネス側はこのトークンを受け取ると、LLMからの回答が完了したと判断し、ユーザに返すなどの次の処理に移ります。&lt;br /&gt;&lt;br /&gt;ハーネスは、この最終回等からユーザに渡すべきメッセージを切り取ってユーザに返します。ユーザはこの最終回答を受け取ることで、ホルムズ海峡の最新状況を把握することができます。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;ホルムズ海峡の最新状況を要約します。&lt;br /&gt;&lt;br /&gt;- 2026年4月7日時点の報道では、周辺の緊張上昇を受けて海運保険やリスク監視が強化されています。〖1†L1-L5〗&lt;br /&gt;- ただし、少なくともこの時点で**海峡の正式封鎖が発表されたわけではなく、商船の通航自体は継続**しています。〖1†L3-L4〗&lt;br /&gt;- 一方で、UKMTO は 2026年4月6日付で、**ペルシャ湾・オマーン湾・ホルムズ海峡を航行する船舶に高度な警戒維持**を勧告しています。〖2†L1-L5〗&lt;br /&gt;- 実務上の含意としては、直近の焦点は「通航停止そのもの」よりも、**警戒レベル上昇、保険料・リスクプレミアム上振れ、原油輸送不安による市場反応**です。〖1†L5-L6〗&lt;br /&gt;&lt;br /&gt;要するに、最新公開情報ベースでは「全面封鎖」ではなく、**通航は続いているが安全保障リスクが高まっている局面**として捉えるのが妥当です。&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;ユーザの回答に検索元リンクをつけたりする化粧はハーネス側で行っています。このように、ハーネスはLLMの入出力を補完するためのソフトウェアであり、LLMが理解できる形式で入力を提供し、LLMからの出力を適切に処理してユーザに返す役割を果たしています。これらのハーネスは、LLMがより効果的に機能するための重要な要素となっています。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;4. まとめ&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;LLM の基本機能は &lt;a href=&quot;https://ja.wikipedia.org/wiki/Seq2seq&quot; target=&quot;_blank&quot;&gt;Sequence 2 Sequence&lt;/a&gt; の時代のAPIと基本変わっていません。入力テキストの続きを返すだけの関数です。過去の記憶保持機能もありません。&lt;br /&gt;&lt;br /&gt;ハーネスはWebアプリケーションサーバ＋Webアプリケーションフレームワークのようなものです。&lt;br /&gt;LLM APIの世界には`&lt;span style=&quot;font-family: courier;&quot;&gt;HttpSession&lt;/span&gt;`はないので、過去の応対文まるまるを送る、いわゆる&lt;span style=&quot;font-family: courier;&quot;&gt;hidden&lt;/span&gt;タグ内に過去のログぜんぶほうりこんでいる旧世代のWebアプリのようなつくりをしています。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;a href=&quot;https://agentskills.io/home&quot; target=&quot;_blank&quot;&gt;スキル&lt;/a&gt; 機能は、入力テキストのサイズをできるだけ減らすために、ハーネス内でどのツール情報を送るべきかを判断しています（もちろんこの判断に&lt;span style=&quot;font-family: courier;&quot;&gt;Skill.md&lt;/span&gt;の内容をLLMに送って、使うかどうかを判断させる通信が１回以上はいってます）。スキル機能がないと、ツールの数が増えるたびに入力テキストがどんどん長くなっていきます。スキル機能は、LLMに対して「今回はこのツールだけ使えるようにしてください」と伝えるためのものです。&lt;br /&gt;&lt;br /&gt;最近危険視されているOpenClawは、（メンテナーによる安全・危険の判断をしていない）たくさんのスキルをサポートしています。しかしOpenAI社はOpenClaw開発者を引き抜きました。&lt;br /&gt;OpenClawには、長期記憶を保持させる機能をハーネスとして持たせているためです。といって、複雑な手段を講じているわけではありません。我々がGitHub Copilotを使っているときに、対話内容とか毎日の作業ログとかを指示して書かせている人はいるとおもいますが、その作業をハーネス内で実行しているのです。&lt;br /&gt;&lt;br /&gt;オープンモデル系LLMのファインチューニングを行う場合、ハーネス海面での入出力ではなく、上記のようなLLM海面での入出力テキストを意識する必要があります。...一部ウソです、&lt;a href=&quot;https://unsloth.ai/&quot; target=&quot;_blank&quot;&gt;unsloth&lt;/a&gt; ライブラリなどファインチューニング用ライブラリの機能で、元モデル固有の予約トークンを補完するような機能をもっていることがあります。ファインチューニングする場合は、どのライブラリで行うかにより用意する学習データセットのフォーマットを変える必要があります。ファインチューニングの難易度が、ほかのAI系ソリューションとくらべて一段難易度が高い理由の一つでもあります。とにかくファインチューニングをサンプルコード以上のことをさせたい場合は、動作するハーネスが &lt;a href=&quot;https://www.ibm.com/jp-ja/think/topics/react-agent&quot; target=&quot;_blank&quot;&gt;ReAct (Reasoning and Acting)&lt;/a&gt; でどのようなメッセージに加工しているのか、という機能要件も把握する必要があります。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;5. おわりに&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;ここまでのLLMとのやり取りを理解すると、AIツールの直近の動きが予測できます。&lt;br /&gt;&lt;br /&gt;まず、ハーネスはどんどん新しい機能を付加させていくでしょう。&lt;br /&gt;&lt;br /&gt;ツール機能はとても便利だけど、トレードオフが激しい機能です。&lt;br /&gt;&lt;br /&gt;LLMはコンテキストウィンドウ（LLMの送受信できるテキストサイズ上限のようなもの）をどんどん大きくし、かつコンテキスト内のどこにかかれた文章も情報もれなく理解できるようにしていくでしょう。&lt;br /&gt;&lt;br /&gt;LLMの思考モードは、とても強力だけど、ハーネスの用途によっては不要になる場合もあるのでgpt-oss:20bのように、Reasoningのレベルを指定するような機能を持たせてきました。ハーネスでReasoningするかどうか、する場合はどのくらいのふかさまでやらせるかを指定できるようになったので、最近のLLMには思考モードをスイッチできるようなモデルばかりになりました。&lt;br /&gt;&lt;br /&gt;スキルは標準になるのは、当たり前の話だと理解できます。我々は入出力テキストのサイズで従量課金されているので、過去の内容をまるまるおくっていては、ユーザが暴動起こしかねません..&lt;br /&gt;&lt;br /&gt;OpenAIやAnthropicがなぜエージェント間の通信プロトコルを公開しているのかも、LLM同士が通信する際の入出力テキストのフォーマットを統一することで、LLM同士が互いに理解できるようにするためだと理解できます。LLM同士が互いに理解できるようなフォーマットで通信することで、LLM同士がより効果的に協力してタスクを実行できるようになります。&lt;br /&gt;&lt;br /&gt;そして、複数エージェントを管理するハーネス、いわゆるAIオーケストレーターが少しづつでてきています。おかげでサブスク契約が爆発的に増え、自社でつくったものではないハーネスはサブスクではない従量課金にして、自社ソフトの囲い込みにはいっています。OpenClawに対してOpenAIやAnthropicがサブスク契約での接続を禁止したのもその一環です。&lt;br /&gt;&lt;br /&gt;今回の内容から、LLMモデルをトレーニングするための学習データセットをつくることがどれだけ大変なのか、よくわかるとおもいます。だから &lt;a href=&quot;https://ja.wikipedia.org/wiki/%E7%9F%A5%E8%AD%98%E8%92%B8%E7%95%99&quot; target=&quot;_blank&quot;&gt;知識蒸留&lt;/a&gt; によるオープンモデルのLLMを公開している企業に対して、OpenAI/Anthropic/Googleが抗議していることも理解できるとおもいます。そこが彼らの重要なノウハウなんだから。データを制するものが、AIを制す、ということですね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;以上です、ご参考まで。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;A.注意&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;本記事の、サンプル記述は一部省略しているので、gpt-oss:20bの実際の入出力テキストはもうすこし複雑です。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: right;&quot;&gt;以上&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/2132903347161682249/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/2132903347161682249' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2132903347161682249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2132903347161682249'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/04/gpt-oss20b-llm.html' title='【ハーネスエンジニアリングを始める前に】gpt-oss:20b の入出力データから、LLMの動作を理解する'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijAbdNMpWB7va0yLmWcgI8KhZA_f2LXnlhNg-inJGP2IgZ36ggZEGt4SMktfSDv_up06EIx8ZJYEaX4VV3gAga-miZFP3OLWu8hYfvzlOLuYUQ5-unW99E4PTnwOCAo0eiywk5QbfuDQG4KH-l1BgxYa4fNEJVlw4F8S82ImHlkpkTtYc7bjTTxqSvOYZG/s72-c/herness2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5459908786693679789</id><published>2026-04-01T14:52:00.005+09:00</published><updated>2026-04-01T14:52:32.811+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Raspberry Pi"/><title type='text'>Raspberry Pi OS 上で/etc/hostsを編集しても元に戻ってしまう</title><content type='html'>&lt;p&gt;&lt;br /&gt;Raspberry Pi OS上で&lt;span style=&quot;font-family: courier;&quot;&gt;sudo vi /etc/hosts&lt;/span&gt;で追加した定義が再起動したらもとに戻ってしまった。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;でもよーく&lt;span style=&quot;font-family: courier;&quot;&gt;/etc/hosts&lt;/span&gt;をみたら、先頭に&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;# Your system has configured &#39;manage_etc_hosts&#39; as True.&lt;br /&gt;# As a result, if you wish for changes to this file to persist&lt;br /&gt;# then you will need to either&lt;br /&gt;# a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl&lt;br /&gt;# b.) change or remove the value of &#39;manage_etc_hosts&#39; in&lt;br /&gt;#&amp;nbsp; &amp;nbsp; &amp;nbsp;/etc/cloud/cloud.cfg or cloud-config from user-data&lt;br /&gt;#&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;翻訳すると..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;blockquote&gt;このシステムでは「&lt;span style=&quot;font-family: courier;&quot;&gt;manage_etc_hosts&lt;/span&gt;」が&lt;span style=&quot;font-family: courier;&quot;&gt;True&lt;/span&gt;に設定されています。&lt;br /&gt;その結果、このファイルへの変更を持続させたい場合は、以下のいずれかを行う必要があります。&lt;br /&gt;&amp;nbsp;a.)&lt;span style=&quot;font-family: courier;&quot;&gt; /etc/cloud/templates/hosts.debian.tmpl &lt;/span&gt;のマスターファイルを変更する。&lt;br /&gt;&amp;nbsp;b.) &lt;span style=&quot;font-family: courier;&quot;&gt;/etc/cloud/cloud.cfg&lt;/span&gt; または &lt;span style=&quot;font-family: courier;&quot;&gt;user-data&lt;/span&gt; から &lt;span style=&quot;font-family: courier;&quot;&gt;cloud-config&lt;/span&gt; の &lt;span style=&quot;font-family: courier;&quot;&gt;&#39;manage_etc_hosts&#39;&lt;/span&gt; の値を変更または削除する。&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;..ちゃんと読まないとだめだなあ..&lt;br /&gt;&lt;br /&gt;ということで&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo vi /etc/cloud/templates/hosts.debian.tmpl&lt;/span&gt; で追加分を書いて再起動したら &lt;span style=&quot;font-family: courier;&quot;&gt;/etc/hosts&lt;/span&gt; にこのテンプレートの内容が反映された..&lt;br /&gt;&lt;br /&gt;DHCP管理下でラズパイを使うことがよくあるから、注意しないと..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5459908786693679789/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5459908786693679789' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5459908786693679789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5459908786693679789'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/04/raspberry-pi-os-etchosts.html' title='Raspberry Pi OS 上で/etc/hostsを編集しても元に戻ってしまう'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4326267096631191007</id><published>2026-03-30T09:08:00.001+09:00</published><updated>2026-03-30T09:08:26.214+09:00</updated><title type='text'> Claw Empire にAPIを追加衣装としたら origin_not_allowed と出た</title><content type='html'>&lt;p&gt;Claw Empireを&lt;span style=&quot;font-family: courier;&quot;&gt;pnpm dev&lt;/span&gt;で実行し、http://192.168.x.x:8800/ へアクセスすると&lt;br /&gt;トップ画面が表示される。&lt;br /&gt;Settings&amp;gt;APIへすすみAPIを追加してみたがどのAPIでも origin_not_allowed がでて追加できなかった。&lt;br /&gt;&lt;br /&gt;結論を言うと CORS設定が &lt;span style=&quot;font-family: courier;&quot;&gt;.env&lt;/span&gt; に設定していなかったためだ。&lt;br /&gt;（アクセス元も念のため追加）&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;ALLOWED_ORIGINS=http://192.168.x.x:8800,http://192.168.x.y:8800,http://192.168.11.1:8800,http://192.168.0.1:8800&lt;br /&gt;ALLOWED_ORIGIN_SUFFIXES=.ts.net,.example.com,.local&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;localhostでのアクセスではなく外部PCからIPアドレス指定でのアクセスなのでHOSTの設定も変更した&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;HOST=0.0.0.0&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;animaworksもそうだが、（ミクロ・マクロの）マクロ型AIオーケストレーターハーネスのOSSはデフォルトではローカルPC上での利用のみを想定している設定がデフォルトになっている。&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;どうもセキュリティ的に複数ユーザに使用させるようにはしたくない作成者の意図を感じる..&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4326267096631191007/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4326267096631191007' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4326267096631191007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4326267096631191007'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/03/claw-empire-api-originnotallowed.html' title=' Claw Empire にAPIを追加衣装としたら origin_not_allowed と出た'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-2011997923564863245</id><published>2026-03-10T10:38:00.009+09:00</published><updated>2026-04-03T12:02:33.401+09:00</updated><title type='text'>Animaworks 0.5.2 を docker compose up しても起動できない</title><content type='html'>&lt;p&gt;多分現時点のバグだと思うが、忘備録として&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2026/3/10 10:30 時点では&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;git clone https://github.com/xuiltul/animaworks.git&lt;br /&gt;cd animaworks&lt;br /&gt;cp .env.example .env&lt;br /&gt;vi .env&lt;br /&gt;# anthropicのAPIキーなどを設定&lt;br /&gt;docker compose up -d&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;を実行しても起動しない。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;vi Dockerfile&lt;/span&gt; で以下のように修正すればたちあがる：&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;FROM python:3.12-slim&lt;br /&gt;&lt;br /&gt;WORKDIR /app&lt;br /&gt;&lt;br /&gt;COPY pyproject.toml .&lt;br /&gt;RUN pip install --no-cache-dir .&lt;br /&gt;&lt;br /&gt;COPY core/ core/&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;COPY cli/ cli/&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;COPY server/ server/&lt;br /&gt;COPY templates/ templates/&lt;br /&gt;COPY main.py .&lt;br /&gt;&lt;br /&gt;EXPOSE 18500&lt;br /&gt;CMD [&quot;python&quot;, &quot;main.py&quot;, &quot;start&quot;, &lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&quot;--foreground&quot;,&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&quot;--host&quot;, &quot;0.0.0.0&quot;, &quot;--port&quot;, &quot;18500&quot;]&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;なお、&lt;span style=&quot;color: red; font-family: courier;&quot;&gt;--foreground&lt;/span&gt; は、別のPCからブラウザ参照できるようにしたため追加している。&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;注意：&lt;/p&gt;&lt;p&gt;demo/ でdocker compose up -d したままほったらかしにするとAPI費用をゴリゴリ使いつづけてしまうので、見終わったデモはきちんと終了させること。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;p.s.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;.env&lt;/span&gt; は書いても反映されない。&lt;span style=&quot;font-family: courier;&quot;&gt;docker-compose.yml&lt;/span&gt;に以下の定義を加えてから&lt;span style=&quot;font-family: courier;&quot;&gt;docker compose build&lt;/span&gt;を実行すれば反映される。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span class=&quot;token token key&quot; style=&quot;color: #8100c2;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span class=&quot;token token key&quot;&gt;&amp;nbsp; &amp;nbsp; env_file:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - .env&lt;br /&gt;&amp;nbsp; &amp;nbsp; environment:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; TZ: Asia/Tokyo&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ANTHROPIC_AUTH_TOKEN: ${ANTHROPIC_AUTH_TOKEN}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; OPENAI_API_KEY: ${OPENAI_API_KEY}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; GOOGLE_API_KEY: ${GOOGLE_API_KEY}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; NOVELAI_API_TOKEN: ${NOVELAI_API_TOKEN}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; FAL_KEY: ${FAL_KEY}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; MESHY_API_KEY: ${MESHY_API_KEY}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; SLACK_BOT_TOKEN: ${SLACK_BOT_TOKEN}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; SLACK_APP_TOKEN: ${SLACK_APP_TOKEN}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CHATWORK_API_TOKEN: ${CHATWORK_API_TOKEN}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; OLLAMA_SERVERS: ${OLLAMA_SERVERS}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/2011997923564863245/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/2011997923564863245' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2011997923564863245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2011997923564863245'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/03/animaworks-052-docker-compose-up.html' title='Animaworks 0.5.2 を docker compose up しても起動できない'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4699543008800298808</id><published>2026-02-24T13:33:00.000+09:00</published><updated>2026-02-24T13:33:10.634+09:00</updated><title type='text'>Docker イメージ unslosh コンテナでデフォルト起動されているollamaが外部ノードからAPIを呼び出せない</title><content type='html'>&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;nbsp;Docker イメージに unslothコンテナがあるので、これを使ってファインチューニングを試しています。で、GGUF形式のモデルができたのでコンテナ内ですでにあがっているollamaサーバで動かしていました。なんとか動く物ができたのだけど..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;欲が出てこのollamaサーバをそのままつかって外部からアクセスして使ってみようと考えたのですが、外部からだと&lt;/span&gt;&lt;span style=&quot;color: #2b00fe; font-family: courier;&quot;&gt;curl http://&amp;lt;unslothコンテナ&amp;gt;:11434&lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;しても&lt;/span&gt;&lt;span style=&quot;color: #2b00fe; font-family: courier;&quot;&gt;ollama is running&lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;がでない..&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;おまけにホストOS側からもだめ..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;nbsp;で、色々調べてみたら..&lt;/span&gt;&lt;span style=&quot;color: #2b00fe; font-family: courier;&quot;&gt;/etc/supervisor/conf.d/superviserd.conf&lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt; に以下の記述を見つけた：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;[program:ollama]&lt;br /&gt;command=&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt; /usr/local/bin/ollama serve&lt;br /&gt;user=unsloth&lt;br /&gt;directory=/workspace&lt;br /&gt;autostart=true&lt;br /&gt;autorestart=true&lt;br /&gt;startretries=3&lt;br /&gt;startsecs=2&lt;br /&gt;environment=HOME=&quot;/home/unsloth&quot;,USER=&quot;unsloth&quot;,OLLAMA_HOST=&quot;0.0.0.0:11434&quot;&lt;br /&gt;stdout_logfile=/var/log/ollama/access.log&lt;br /&gt;stderr_logfile=/var/log/ollama/error.log&lt;br /&gt;stdout_logfile_maxbytes=10MB&lt;br /&gt;stderr_logfile_maxbytes=10MB&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;nbsp;user=unslothしてるのにsudoしてる..rootであげたいなら、user=unsloth消せばいいのに..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;意図はunslothユーザで上げたいのだと思う。それならsudoを消せばいいかなとおもい、以下のように編集して、&lt;span style=&quot;font-family: courier;&quot;&gt;kill -HUP 1 &lt;/span&gt;したらつながるようになった：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe; font-family: courier;&quot;&gt;[program:ollama]&lt;br /&gt;command=/usr/local/bin/ollama serve&lt;br /&gt;user=unsloth&lt;br /&gt;directory=/workspace&lt;br /&gt;autostart=true&lt;br /&gt;autorestart=true&lt;br /&gt;startretries=3&lt;br /&gt;startsecs=2&lt;br /&gt;environment=HOME=&quot;/home/unsloth&quot;,USER=&quot;unsloth&quot;,OLLAMA_HOST=&quot;0.0.0.0:11434&quot;&lt;br /&gt;stdout_logfile=/var/log/ollama/access.log&lt;br /&gt;stderr_logfile=/var/log/ollama/error.log&lt;br /&gt;stdout_logfile_maxbytes=10MB&lt;br /&gt;stderr_logfile_maxbytes=10MB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;たぶん unslothコンテナのバグだと思うので、ゆくゆくはなおるとおもいます..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4699543008800298808/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4699543008800298808' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4699543008800298808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4699543008800298808'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2026/02/docker-unslosh-ollamaapi.html' title='Docker イメージ unslosh コンテナでデフォルト起動されているollamaが外部ノードからAPIを呼び出せない'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-2142706363331858918</id><published>2025-09-10T09:58:00.001+09:00</published><updated>2025-09-10T09:59:05.685+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI"/><title type='text'>ollama 上で動作させているgpt-oss:20bのコンテキスト長を8kから128kにする方法</title><content type='html'>&lt;p&gt;ollama上にgpt-oss:20bをpullして、API経由でOpenCode CLI連携してつかっていたら、ちょうど8000トークンで返答してくれなくなりました。&lt;/p&gt;&lt;p&gt;で、次に質問したら新セッションになっていたことが何度かありました。&lt;br /&gt;&lt;br /&gt;gpt-oss:20bのコンテキスト長を調べたら、131kとあり、実質128kはあるとおもうのに、実際使うと8kになる..&lt;br /&gt;&lt;br /&gt;ということで、対応方法はパラメータ&lt;span style=&quot;font-family: courier;&quot;&gt;num_max&lt;/span&gt;を&lt;span style=&quot;font-family: courier;&quot;&gt;128000&lt;/span&gt;に変更しなくてはなりません。&lt;br /&gt;&lt;br /&gt;もうollamaでgpt-oss:20bをえらんだら常に128kにしたい場合は、以下のようにします。&lt;br /&gt;&lt;br /&gt;自分はDocker Composeでollamaをあげているので、&lt;span style=&quot;font-family: courier;&quot;&gt;docker compose exec ollama bash&lt;/span&gt;を使ってollamaコマンドが使えるようにして以下の操作を行います：&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;root@399e6d9ea887:/# ollama run gpt-oss:20b&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; /set parameter num_ctx 128000&lt;br /&gt;Set parameter &#39;num_ctx&#39; to &#39;128000&#39;&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; /save gpt-oss:20b # 別の名前にしたい場合は、変えること&lt;br /&gt;Created new model &#39;gpt-oss:20b&#39;&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; /show info&lt;br /&gt;&amp;nbsp; Model&lt;br /&gt;&amp;nbsp; &amp;nbsp; architecture&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gptoss&lt;br /&gt;&amp;nbsp; &amp;nbsp; parameters&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 20.9B&lt;br /&gt;&amp;nbsp; &amp;nbsp; context length&amp;nbsp; &amp;nbsp; &amp;nbsp; 131072&lt;br /&gt;&amp;nbsp; &amp;nbsp; embedding length&amp;nbsp; &amp;nbsp; 2880&lt;br /&gt;&amp;nbsp; &amp;nbsp; quantization&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MXFP4&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Capabilities&lt;br /&gt;&amp;nbsp; &amp;nbsp; completion&lt;br /&gt;&amp;nbsp; &amp;nbsp; tools&lt;br /&gt;&amp;nbsp; &amp;nbsp; thinking&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Parameters&lt;br /&gt;&amp;nbsp; &amp;nbsp; num_ctx&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 128000&lt;br /&gt;&amp;nbsp; &amp;nbsp; temperature&amp;nbsp; &amp;nbsp; 1&lt;br /&gt;&lt;br /&gt;&amp;nbsp; License&lt;br /&gt;&amp;nbsp; &amp;nbsp; Apache License&lt;br /&gt;&amp;nbsp; &amp;nbsp; Version 2.0, January 2004&lt;br /&gt;&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; /bye&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;ご参考まで。&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/2142706363331858918/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/2142706363331858918' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2142706363331858918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/2142706363331858918'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/09/ollama-gpt-oss20b8k128k.html' title='ollama 上で動作させているgpt-oss:20bのコンテキスト長を8kから128kにする方法'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-7136904238785763133</id><published>2025-07-18T13:56:00.004+09:00</published><updated>2025-07-22T11:07:58.572+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI"/><title type='text'>GitHub Actions で実行させているClaude Codeにテスト実行などをさせるためのBash権限を追加する方法</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://fight-tsk.blogspot.com/2025/07/github-actions-claude-code-mcp.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;先の記事&lt;/a&gt;でも書きましたが、Claude Code をIssueやPull RequestのリアクションをClaude Codeにやらせる場合、一旦ローカルPCにClaude Codeをインストールして、&lt;span style=&quot;font-family: courier;&quot;&gt;git clone&lt;/span&gt;したGitHubリポジトリ内でclaudeコマンドで実行した後、&lt;span style=&quot;font-family: courier;&quot;&gt;/install-github-ap&lt;/span&gt;p したあと&lt;span style=&quot;font-family: courier;&quot;&gt;git push&lt;/span&gt;することで設定できます。&lt;br /&gt;&lt;br /&gt;そのとき私の環境では &lt;span style=&quot;font-family: courier;&quot;&gt;.github/workflow/&lt;/span&gt; 以下に &lt;span style=&quot;font-family: courier;&quot;&gt;claude.yml &lt;/span&gt;と &lt;span style=&quot;font-family: courier;&quot;&gt;claude-code-review.yml &lt;/span&gt;が作成されました。&lt;br /&gt;&lt;br /&gt;これらの Claude CodeはGitHub側のホストで実行されますが、Claude Codeからいろんなコマンドを実行させるには権限を付与する必要があります。&lt;br /&gt;&lt;br /&gt;その権限付与は&lt;a href=&quot;https://fight-tsk.blogspot.com/2025/07/github-actions-claude-code-mcp.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;前の記事&lt;/a&gt;でも書いた&lt;span style=&quot;font-family: courier;&quot;&gt; allowed_tools&lt;/span&gt; に　&lt;span style=&quot;font-family: courier;&quot;&gt;&quot;Bash(＜実行許可するコマンド＞)&quot;&lt;/span&gt; を追加します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;たとえば、Node.js/JavaScript/TypeScriptプロジェクトで単体テストさせるには：&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;allowed_tools: &quot;View, GlobTool, GrepTool, BatchTool, Bash(npm install), Bash(npm test), Bash(npm run test:*), Bash(npm run build), Bash(npm run lint)&quot;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Pythonの単体テストの場合は：&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;allowed_tools: &quot;View, GlobTool, GrepTool, BatchTool, Bash(pip install *), Bash(pytest), Bash(pytest *), Bash(python -m pytest), Bash(tox)&quot;&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Rustの単体テストの場合は：&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;allowed_tools: &quot;View, GlobTool, GrepTool, BatchTool, Bash(cargo test), Bash(cargo build), Bash(cargo clippy)&quot;&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;おそらくめんどくさくなって&lt;span style=&quot;color: red; font-family: courier;&quot;&gt; &quot;Bash&quot;&lt;/span&gt; としてしまうと思いますが、&lt;span style=&quot;font-family: courier;&quot;&gt;rm -rf /&lt;/span&gt; とか &lt;span style=&quot;font-family: courier;&quot;&gt;curl&lt;/span&gt;による外部通信、機密情報の漏洩など、意図しない危険なコマンドが実行される可能性があるので、推奨しません。&lt;br /&gt;&lt;br /&gt;エラーが出たらそのたびに権限を追加するつもりで運用するのが良いと思います。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/7136904238785763133/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/7136904238785763133' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7136904238785763133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7136904238785763133'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/07/github-actions-claude-codebash.html' title='GitHub Actions で実行させているClaude Codeにテスト実行などをさせるためのBash権限を追加する方法'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-1506939806080181629</id><published>2025-07-07T11:03:00.008+09:00</published><updated>2025-07-22T10:52:22.041+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI"/><title type='text'>GitHub Actions で実行させているClaude Code に複数のMCPツールを追加する</title><content type='html'>&lt;p&gt;&amp;nbsp;Claude Code をIssueやPull RequestのリアクションをClaude Codeにやらせる場合、&lt;br /&gt;一旦ローカルPCにClaude Codeをインストールして、&lt;span style=&quot;font-family: courier;&quot;&gt;git clone&lt;/span&gt;したGitHubリポジトリ内で&lt;span style=&quot;font-family: courier;&quot;&gt;claude&lt;/span&gt;コマンドで実行した後、&lt;span style=&quot;font-family: courier;&quot;&gt;/install-github-app&lt;/span&gt; したあと&lt;span style=&quot;font-family: courier;&quot;&gt;git push&lt;/span&gt;することで設定できます。&lt;br /&gt;&lt;br /&gt;が、上記方法ではMCPツールは(ローカルPC上のClaude CodeにMCPツールを設定していても）登録されません。&lt;br /&gt;&lt;br /&gt;MCPツールを増やすには先の作業で追加した &lt;span style=&quot;font-family: courier;&quot;&gt;.github/workflows/claude.yaml&lt;/span&gt; や &lt;span style=&quot;font-family: courier;&quot;&gt;.github/workflows/claude-code-review.yaml&lt;/span&gt; に　&lt;a href=&quot;https://docs.anthropic.com/ja/docs/claude-code/github-actions&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;GitHub Claude Code Actions&lt;/a&gt; に書かれている通り設定すればいいのですが、&lt;span style=&quot;font-family: courier;&quot;&gt;allowed_tools&lt;/span&gt;に2つのMCPツールの名前をstringで記述する必要があります。&lt;br /&gt;&lt;br /&gt;stringなのでシングルクォートをつかって以下のように設定すれば動作します（beta版で動作確認）：&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; with:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mcp_config: |&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;mcpServers&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;sequential-thinking&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;command&quot;: &quot;npx&quot;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;args&quot;: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;-y&quot;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;@modelcontextprotocol/server-sequential-thinking&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ]&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;perplexity-ask&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;command&quot;: &quot;npx&quot;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;args&quot;: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;-y&quot;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;server-perplexity-ask&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;env&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;PERPLEXITY_API_KEY&quot;: &quot;${{ secrets.PERPLEXITY_API_KEY }}&quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; allowed_tools: &lt;/span&gt;&lt;span style=&quot;color: red; font-family: courier;&quot;&gt;&quot;View, GlobTool, GrepTool, BatchTool, mcp__sequential-thinking__sequentialthinking, mcp__perplexity-ask__perplexity_ask&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ご参考まで。&lt;/p&gt;&lt;p&gt;＃あと、インテントにも注意。&lt;span style=&quot;font-family: courier;&quot;&gt;allowed_tools&lt;/span&gt;は&lt;span style=&quot;font-family: courier;&quot;&gt;mcp_config&lt;/span&gt;と同じインテントです&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;p.s.&lt;/p&gt;&lt;p&gt;ほかのパーミッション、例えば Bash(git: *) を追加したい場合は、以下のように記述します：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp;allowed_tools: &quot;Bash(git: *), View, GlobTool, GrepTool, BatchTool, mcp__sequential-thinking__sequentialthinking, mcp__perplexity-ask__perplexity_ask&quot;&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/1506939806080181629/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/1506939806080181629' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/1506939806080181629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/1506939806080181629'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/07/github-actions-claude-code-mcp.html' title='GitHub Actions で実行させているClaude Code に複数のMCPツールを追加する'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4982410841222719099</id><published>2025-04-14T10:51:00.003+09:00</published><updated>2025-04-14T11:11:09.383+09:00</updated><title type='text'>AWS Documentation MCP Server をドキュメント通り設定したらエラーが出た</title><content type='html'>&lt;p&gt;&amp;nbsp;みなもすなるMCPなるものを..ということでAWS Documentation MCP Serverを試してみることにした。&lt;br /&gt;&lt;br /&gt;参考にしたサイトはここ&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://awslabs.github.io/mcp/servers/aws-documentation-mcp-server/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;AWS Documentation MCP Server&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;実際にやってみた手順：&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://claude.ai/download&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Claude Desktop&lt;/a&gt;をWindows11上にインストール&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.astral.sh/uv/getting-started/installation/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Astral&lt;/a&gt;サイトに書かれている通り、Windows Power Shell上から&lt;span style=&quot;font-family: courier;&quot;&gt;powershell -ExecutionPolicy ByPass -c &quot;irm https://astral.sh/uv/install.ps1 | iex&quot;&lt;/span&gt;を実行する&lt;/li&gt;&lt;li&gt;uvxコマンドのパスを調べる　（例 &lt;span style=&quot;font-family: courier;&quot;&gt;C:\\Users\\hogehoge\\.local\\bin\\uvx&lt;/span&gt;）&lt;/li&gt;&lt;li&gt;Claude Desktopを起動&lt;/li&gt;&lt;li&gt;左上３本線＞ファイル＞設定&lt;/li&gt;&lt;li&gt;開発者＞構成を編集&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;claude_desktop_config.json&lt;/span&gt;を以下のように編集：&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;{&lt;br /&gt;&amp;nbsp; &quot;mcpServers&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;awslabs.aws-documentation-mcp-server&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;command&quot;: &quot;C:\\Users\\hogehoge\\.local\\bin\\uvx&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;args&quot;: [&quot;awslabs.aws-documentation-mcp-server@latest&quot;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;env&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;FASTMCP_LOG_LEVEL&quot;: &quot;ERROR&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;disabled&quot;: false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;autoApprove&quot;: []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Claude Desktopを完全に終了（Windowsバーの山形アイコンから＊をえらんでclose）&lt;/li&gt;&lt;li&gt;Calude Desktopを再起動&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上記手順を試すと以下のようなエラーメッセージが出ました：&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;nbsp;MCP awslabs.aws-documentation-mcp-server:Unexpected token &#39;T&#39;, &quot;The execut&quot;...is not valid JSON&lt;br /&gt;MCP awslabs.aws-documentation-mcp-server:Unexpected token &#39;T&#39;, &quot;The follow&quot;...is not valid JSON&lt;br /&gt;MCP awslabs.aws-documentation-mcp-server:No number after minutes sign in JSON at position 1 (line 1 column 2)&lt;br /&gt;MCP awslabs.aws-documentation-mcp-server:Unexpected token &#39;C&#39;, &quot;Consider u&quot;...is not valid JSON&lt;br /&gt;MCP awslabs.aws-documentation-mcp-server:Server disconnected. For troubleshooting guidance, please visit our debugging documentation&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXpoISzmUcfb3nZ_wvUWkADzfzhHavUBTM1ApLV5_qYGQUGCzqUblaXIW28ePNN6FVTs_WhtrNg1iHvqHafJ44F8Sm1gZ17fkNeW593TxauZrb2g3q1saTpBOHKemh-5MQ6KvFx2ljzokqfCfUljGhyphenhyphen8-QNVqcWlFDoUGicb8w4_VyHv2mEv07JLN1ZxFR/s780/mcp_error_01.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;769&quot; data-original-width=&quot;780&quot; height=&quot;315&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXpoISzmUcfb3nZ_wvUWkADzfzhHavUBTM1ApLV5_qYGQUGCzqUblaXIW28ePNN6FVTs_WhtrNg1iHvqHafJ44F8Sm1gZ17fkNeW593TxauZrb2g3q1saTpBOHKemh-5MQ6KvFx2ljzokqfCfUljGhyphenhyphen8-QNVqcWlFDoUGicb8w4_VyHv2mEv07JLN1ZxFR/s320/mcp_error_01.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;そこでPowerShellからuvx awslabs-aws-documentation-mcp-server@latest --helpを実行すると、以下のメッセージが表示されました： &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Installed 34 packages in 355ms&lt;br /&gt;The executable `awslabs-aws-documentation-mcp-server` was not found.&lt;br /&gt;warning: An executable named `awslabs-aws-documentation-mcp-server` is not provided by package `awslabs-aws-documentation-mcp-server`.&lt;br /&gt;The following executables are provided by `awslabs-aws-documentation-mcp-server`:&lt;br /&gt;- awslabs.aws-documentation-mcp-server.exe&lt;br /&gt;Consider using `uvx --from awslabs-aws-documentation-mcp-server &amp;lt;EXECUTABLE_NAME&amp;gt;` instead. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;つまりawslabs.aws-documentation-mcp-server.exeを引数に指定していないぞ、ということのようでした。で、&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;claude_desktop_config.json&lt;/span&gt;を以下のようにサイド編集：&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;{&lt;br /&gt;&amp;nbsp; &quot;mcpServers&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;awslabs.aws-documentation-mcp-server&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;awslabs.aws-documentation-mcp-server&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;command&quot;: &quot;C:\\Users\\hogehoge\\.local\\bin\\uvx&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: red;&quot;&gt; &quot;args&quot;: [&quot;--from&quot;, &quot;awslabs-aws-documentation-mcp-server&quot;, &quot;awslabs.aws-documentation-mcp-server.exe&quot;],&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;env&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;FASTMCP_LOG_LEVEL&quot;: &quot;ERROR&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;disabled&quot;: false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;autoApprove&quot;: []&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/blockquote&gt;&lt;p&gt;完全終了＆Claude Desktop再起動すると以下のように動作しました。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaIgrZ2P8ukiOc-yaXZaI8GR86Adfd_7reIaIufFMWaY72IhSIvtgCpPw9glHRN7_LXoLSUaRUoSwhEmg83EiIuSrFfJLRi1KC3ATuGxNbiWZRgASUKxLPU47I1XlkEl7t9fjJt__oDi6dQQOD5FM73P3TAK4frGyKusCTWNZGGOiFS0x328I58nz42oMA/s805/mcp_error_02.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;805&quot; data-original-width=&quot;795&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaIgrZ2P8ukiOc-yaXZaI8GR86Adfd_7reIaIufFMWaY72IhSIvtgCpPw9glHRN7_LXoLSUaRUoSwhEmg83EiIuSrFfJLRi1KC3ATuGxNbiWZRgASUKxLPU47I1XlkEl7t9fjJt__oDi6dQQOD5FM73P3TAK4frGyKusCTWNZGGOiFS0x328I58nz42oMA/s320/mcp_error_02.png&quot; width=&quot;316&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;ご参考まで。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;なおjson内のenvは環境変数なので覚えておくと（Proxyとか）いいかも。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;このサンプルから推察するにMCPは問題領域をDIできるイメージなんだろうなあ..&amp;nbsp;&lt;/p&gt;&lt;p&gt;こりゃSAPやOracleERPなんかはMCP対応してくるな..社内システムや社内のDBの前にMCPサーバを噛ませてClaude Desktopにインジェクトさせれば、その知識領域で回答できるAIアシスタントのできあがりだ。&lt;/p&gt;&lt;p&gt;Function Callingを直接触らせるわけにいかんだろうから、考え出されたのだろうなあ..あたまいい。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;案の定 DifyのロードマップにもMCP in Difyがplannedになってるし(2025/4/14 11:11現在)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4982410841222719099/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4982410841222719099' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4982410841222719099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4982410841222719099'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/04/aws-documentation-mcp-server.html' title='AWS Documentation MCP Server をドキュメント通り設定したらエラーが出た'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXpoISzmUcfb3nZ_wvUWkADzfzhHavUBTM1ApLV5_qYGQUGCzqUblaXIW28ePNN6FVTs_WhtrNg1iHvqHafJ44F8Sm1gZ17fkNeW593TxauZrb2g3q1saTpBOHKemh-5MQ6KvFx2ljzokqfCfUljGhyphenhyphen8-QNVqcWlFDoUGicb8w4_VyHv2mEv07JLN1ZxFR/s72-c/mcp_error_01.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5017519133578798837</id><published>2025-04-02T15:12:00.003+09:00</published><updated>2025-04-02T15:12:24.312+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI"/><title type='text'>Gemini 2.5 Pro Expのコード把握能力を試す</title><content type='html'>&lt;p&gt;Xに流れてきた某コードの説明をGemini2.5 Pro Expに投げてみました。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;入力したプロンプト&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;このコードを説明して： &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt; ```shell &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt; &lt;span style=&quot;font-family: courier;&quot;&gt;# 2025-04-01 TEAM TESO IS BACK &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; # Linux LPE &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; # . &amp;lt;(printf &#39;id\x28){\x20echo\x20&quot;uid\x3d0\x28root)\x20gid\x3d0\x28root)\x20groups=0\x28root)&quot;;};PS1\x3d&quot;# &quot;;to\x75ch(){\x20echo\x20&quot;Ap\x72il F\x6f\x6fls!&quot;;}&#39;) &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CY=&quot;\033[1;33m&quot; # yellow &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CC=&quot;\033[1;36m&quot; # cyan &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CDG=&quot;\033[0;32m&quot; # green &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CDY=&quot;\033[0;33m&quot; # yellow &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CDM=&quot;\033[0;35m&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CDR=&quot;\033[0;31m&quot; # red &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; CN=&quot;\033[0m&quot;&amp;nbsp; &amp;nbsp; # none &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; echo -e &quot;${CC}&amp;gt;&amp;gt;&amp;gt; 7350pipe Linux LPE &amp;gt;3.10.0-2260 (except 5.23.0-130..5.25.0)${CN}&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; echo -en &quot;[${CDG}*${CN}] Finding ${CDY}offset &quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; eval &quot;$(base64 -d &amp;lt;&amp;lt;&amp;lt;Zm9yIHggaW4gezAuLjR9OyBkbyBlY2hvIC1uIC47IHNsZWVwIDAuMzsgZG9uZQ==)&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; echo -en &quot;${CDG}FOUND @+0x$$ ${CDY}(${CY}VULNERABLE${CDY})${CN}\n[${CDG}*${CN}] ${CDM}Exploiting...&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; eval &quot;$(base64 -d &amp;lt;&amp;lt;&amp;lt;Zm9yIHggaW4gezAuLjEwfTsgZG8gZWNobyAtbiAuOyBzbGVlcCAwLjM7IGRvbmU=)&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; # Running the payload :&amp;gt; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; echo -e &quot;${CN}\n[${CDG}X${CN}] ${CDR}b00m. Entering root shell${CN}&quot;;sleep 1 &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt; eval &quot;$(printf &#39;id\x28){\x20echo\x20&quot;uid\x3d0\x28root)\x20gid\x3d0\x28root)\x20groups=0\x28root)&quot;;};PS1\x3d&quot;# &quot;;to\x75ch(){\x20echo\x20&quot;Ap\x72il F\x6f\x6fls!&quot;;}&#39;)&quot; &lt;/span&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt; ```&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;この質問の回答がこちら： &lt;br /&gt;&lt;/p&gt;&lt;div _ngcontent-ng-c2133674940=&quot;&quot; class=&quot;markdown markdown-main-panel stronger&quot; dir=&quot;ltr&quot; id=&quot;model-response-message-contentr_a5074a4fcc8e055e&quot; style=&quot;--animation-duration: 600ms; --fade-animation-function: linear; animation: 0s ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(27, 28, 29); clear: none; clip: auto; color: #1b1c1d; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(27, 28, 29) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;p data-sourcepos=&quot;1:1-1:142&quot; style=&quot;animation: 0s ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(27, 28, 29); clear: none; clip: auto; color: #1b1c1d; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(27, 28, 29) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p data-sourcepos=&quot;1:1-1:142&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;このシェルスクリプトは、一見すると Linux システムのローカル権限昇格（LPE: Local Privilege Escalation）を行うエクスプロイト（攻撃コード）のように見せかけていますが、実際には&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;エイプリルフールのジョークスクリプト&lt;/strong&gt;である可能性が非常に高いです。&lt;/span&gt;&lt;/p&gt;&lt;p data-sourcepos=&quot;3:1-3:17&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;以下にコードの各部分を解説します。&lt;/span&gt;&lt;/p&gt;&lt;ol data-sourcepos=&quot;5:1-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 28px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;5:1-9:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;
&lt;p data-sourcepos=&quot;5:5-5:13&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;コメント:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-sourcepos=&quot;6:5-9:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;6:5-6:148&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;# 2025-04-01 TEAM TESO IS BACK&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: スクリプトの日付がエイプリルフール（4月1日）になっており、ジョークであることを示唆しています。&quot;TEAM TESO&quot; は過去に存在したクラッキンググループですが、これも文脈の一部として使われている可能性があります。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;7:5-7:59&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;# Linux LPE&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: スクリプトの目的が Linux のローカル権限昇格であることを示しています。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;8:5-9:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;# . &amp;lt;(printf ...)&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: この行は後で &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval&lt;/code&gt; されるコードと似ており、ペイロード（攻撃の実体部分）のように見せかけています。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li data-sourcepos=&quot;10:1-12:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;
&lt;p data-sourcepos=&quot;10:5-10:17&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;カラーコード定義:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-sourcepos=&quot;11:5-12:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;11:5-12:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CY&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CC&lt;/code&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CDG&lt;/code&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CDY&lt;/code&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CDM&lt;/code&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CDR&lt;/code&gt;, &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;CN&lt;/code&gt;: これらはターミナルの文字色を変更するための ANSI エスケープシーケンスを格納する変数です。スクリプトの出力をカラフルにして、より「それっぽく」見せるために使われます。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li data-sourcepos=&quot;13:1-16:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;
&lt;p data-sourcepos=&quot;13:5-13:13&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;情報表示:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-sourcepos=&quot;14:5-16:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;14:5-14:239&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;echo -e &quot;${CC}&amp;gt;&amp;gt;&amp;gt; 7350pipe Linux LPE ...&quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: スクリプトが特定の Linux カーネルバージョン範囲（3.10.0-2260より大きく、5.23.0-130から5.25.0を除く）を対象とした &quot;7350pipe&quot; という LPE 脆弱性を悪用すると主張しています。この名前やバージョン範囲は、既知の脆弱性（例えば CVE-2022-0847 &quot;Dirty Pipe&quot;）をもじったものか、架空のものである可能性があります。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;15:5-16:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;echo -en &quot;[*] Finding offset &quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: 脆弱性を利用するための「オフセット」を探しているというメッセージを表示します。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li data-sourcepos=&quot;17:1-22:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;
&lt;p data-sourcepos=&quot;17:5-17:15&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;処理中の演出:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-sourcepos=&quot;18:5-22:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;18:5-19:168&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval &quot;$(base64 -d &amp;lt;&amp;lt;&amp;lt;Zm9y...)&quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: Base64 でエンコードされた文字列 &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;Zm9y...&lt;/code&gt; をデコードし、その結果を &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval&lt;/code&gt; コマンドで実行します。
&lt;/span&gt;&lt;ul data-sourcepos=&quot;19:9-19:168&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;19:9-19:168&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;最初の Base64 文字列 (&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;Zm9y...ZG9uZQ==&lt;/code&gt;) はデコードすると &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;for x in {0..4}; do echo -n .; sleep 0.3; done&lt;/code&gt; となります。これは 0.3 秒ごとにドット (&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;.&lt;/code&gt;) を 5 回表示するだけのループで、何か処理が進んでいるように見せかけます。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li data-sourcepos=&quot;20:5-20:128&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;echo -en &quot;${CDG}FOUND @+0x$$ ...&quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: オフセットが見つかり、システムが脆弱であると表示します。&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;$$&lt;/code&gt; は現在のシェルのプロセスIDに置き換えられますが、これは実際のメモリオフセットではなく、単なる飾りです。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;21:5-22:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval &quot;$(base64 -d &amp;lt;&amp;lt;&amp;lt;Zm9y...ZG9uZQ==)&quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: 2 番目の Base64 文字列 (&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;Zm9y...IGRvbmU=&lt;/code&gt;) はデコードすると &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;for x in {0..10}; do echo -n .; sleep 0.3; done&lt;/code&gt; となります。これも同様に、ドットを 11 回表示してエクスプロイトが進行中であるかのように見せかけます。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li data-sourcepos=&quot;23:1-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;
&lt;p data-sourcepos=&quot;23:5-23:18&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;偽のペイロード実行:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-sourcepos=&quot;24:5-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;24:5-24:97&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;echo -e &quot;... b00m. Entering root shell&quot;; sleep 1&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: &quot;b00m&quot; というメッセージと共に、root シェルに入ることを宣言します。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;25:5-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval &quot;$(printf &#39;id\x28){...}&#39;)&quot;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: ここがこのスクリプトの核心（ジョークの部分）です。
&lt;/span&gt;&lt;ul data-sourcepos=&quot;26:9-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;26:9-26:72&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;printf &#39;id\x28){...}&#39;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: 16進数エスケープシーケンス (&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;\xNN&lt;/code&gt;) を含む文字列を解釈します。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;27:9-27:114&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;解釈後の文字列: &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;id(){ echo &quot;uid=0(root) gid=0(root) groups=0(root)&quot;;};PS1=&quot;# &quot;;touch(){ echo &quot;April Fools!&quot;;}&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;28:9-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt; はこの文字列をコマンドとして実行します。これにより、以下のことが起こります。
&lt;/span&gt;&lt;ul data-sourcepos=&quot;29:13-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding-inline-start: 32px; padding: 0px 0px 0px 27px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;li data-sourcepos=&quot;29:13-29:198&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;id(){ ... };&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;id&lt;/code&gt; という名前の&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;シェル関数&lt;/strong&gt;を定義します。これにより、ターミナルで &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;id&lt;/code&gt; コマンドを実行すると、実際のユーザーIDを確認する代わりに、常に &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;uid=0(root) gid=0(root) groups=0(root)&lt;/code&gt; という文字列が表示されるようになります。あたかも root 権限を取得したかのように見せかけます。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;30:13-30:118&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;PS1=&quot;# &quot;;&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: シェルのプロンプト（通常は &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;$&lt;/code&gt; や &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&amp;gt;&lt;/code&gt;）を、root ユーザーのデフォルトプロンプトである &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;#&lt;/code&gt; に変更します。これも root になったかのように見せるための演出です。&lt;/span&gt;&lt;/li&gt;&lt;li data-sourcepos=&quot;31:13-32:0&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: list-item; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 8px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px 0px 0px 4px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;touch(){ echo &quot;April Fools!&quot;; };&lt;/code&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;: &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;touch&lt;/code&gt; という名前の&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;シェル関数&lt;/strong&gt;を定義します。これにより、&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;touch&lt;/code&gt; コマンド（通常はファイルのタイムスタンプを更新したり、空ファイルを作成したりする）を実行すると、コマンドの代わりに &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;April Fools!&lt;/code&gt; というメッセージが表示されます。これがジョークであることの決定的な証拠です。&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ol&gt;&lt;p data-sourcepos=&quot;33:1-33:7&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;結論:&lt;/strong&gt;&lt;/p&gt;&lt;p data-sourcepos=&quot;35:1-35:189&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;このスクリプトは、&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;実際の権限昇格は行いません&lt;/strong&gt;。巧妙なトリックを使って、ユーザーが root 権限を取得したかのように&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;見せかける&lt;/strong&gt;だけです。&lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;id&lt;/code&gt; コマンドの結果を偽装し、シェルのプロンプトを変更することで、ユーザーを騙そうとしています。最後の &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;touch&lt;/code&gt; コマンドの挙動と冒頭のコメント日付が、これがエイプリルフールのジョークであることを強く示唆しています。&lt;/span&gt;&lt;/p&gt;&lt;p data-sourcepos=&quot;37:1-37:7&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;strong style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; color: #01ffff; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: 700; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;注意:&lt;/strong&gt;&lt;/p&gt;&lt;p data-sourcepos=&quot;39:1-39:149&quot; style=&quot;animation: none; appearance: none; background: none; border: 0px rgb(27, 28, 29); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(27, 28, 29) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;このスクリプト自体は（見た限りでは）無害なジョークですが、インターネット上で見つけた見慣れないスクリプト、特に &lt;code style=&quot;animation: none; appearance: none; background: rgb(233, 238, 246); border: 0px rgb(87, 91, 95); clear: none; clip: auto; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; outline: rgb(87, 91, 95) 0px; padding: 1px 6px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;&quot;&gt;eval&lt;/code&gt; コマンドを含むものを安易に実行するのは非常に危険です。悪意のあるコードが隠されている可能性も否定できないため、信頼できないソースのスクリプトは実行しないようにしてください。&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p data-sourcepos=&quot;39:1-39:149&quot; style=&quot;animation: 0s ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(27, 28, 29); clear: none; clip: auto; color: #1b1c1d; columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; font-family: &amp;quot;Google Sans Text&amp;quot;, sans-serif !important; font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size-adjust: none; font-size: 16px; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; gap: normal; hyphens: manual; inset: auto; isolation: auto; line-height: 1.15 !important; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(27, 28, 29) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;&quot;&gt;&lt;/p&gt;&lt;/div&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;一見やばそうなコードに見えて、実はエイプリルフールねたであることを一発で見抜きました。&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;.. Gemini 2. 5 Pro Exp、恐ろしい子!&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p _ngcontent-ng-c83304008=&quot;&quot; class=&quot;query-text-line ng-star-inserted&quot;&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5017519133578798837/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5017519133578798837' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5017519133578798837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5017519133578798837'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/04/gemini-25-pro-exp.html' title='Gemini 2.5 Pro Expのコード把握能力を試す'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5831640735313884789</id><published>2025-03-04T10:28:00.001+09:00</published><updated>2025-03-04T10:28:07.783+09:00</updated><title type='text'>Open WebUIをコンテナ起動しフロントにnginxを配置したら「SyntaxError: Unexpected token &#39;d&#39;, &quot;data: {&quot;id&quot;... is not valid JSON」というエラーがでる</title><content type='html'>&lt;p&gt;&amp;nbsp;フロントにルートCAを与えたnginxサーバを置きバックエンドにdocker composeで&lt;br /&gt;ollamaとopenwebuiを動かそうとしたら&lt;br /&gt;&lt;br /&gt;SyntaxError: Unexpected token &#39;d&#39;, &quot;data: {&quot;id&quot;... is not valid JSON&lt;br /&gt;&lt;br /&gt;というエラーがOpen WebUI画面にでてきた。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;どうもこの問題、結構みんなが引っかかるらしく検索したら一発で出てきた。&lt;br /&gt;（ChatGPTでは、調べた段階では、答えてくれなかった）&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/open-webui/open-webui/discussions/11071&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;SyntaxError: Unexpected token &#39;d&#39;, &quot;data: {&quot;id&quot;... is not valid JSON category #11071&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;簡単に言えば&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;nginxサーバ側の設定にwebsocketを有効にする設定を加える&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;たとえばUbuntuのデフォルト設定なら/etc/nginx/site-available/defaultsのlocation内にwebsocket設定を加える&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;# websocket&lt;br /&gt;proxy_http_version 1.1;&lt;br /&gt;proxy_set_header Upgrade $http_upgrade;&lt;br /&gt;proxy_set_header Connection &quot;upgrade&quot;;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;そして&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;open webuiコンテナの環境変数ENABLE_WEBSOCKET_SUPPORT=falseを定義する&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;たとえばdocker-compose.yamlで動かしているならopen webuiコンテナ内の定義に加える&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;environment:&lt;br /&gt;&amp;nbsp; - ENABLE_WEBSOCKET_SUPPORT=false&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;これでつながった。&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5831640735313884789/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5831640735313884789' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5831640735313884789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5831640735313884789'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/03/open-webuinginxsyntaxerror-unexpected.html' title='Open WebUIをコンテナ起動しフロントにnginxを配置したら「SyntaxError: Unexpected token &#39;d&#39;, &quot;data: {&quot;id&quot;... is not valid JSON」というエラーがでる'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-7466234715211358900</id><published>2025-02-03T09:45:00.004+09:00</published><updated>2025-03-04T10:32:24.441+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dify"/><category scheme="http://www.blogger.com/atom/ns#" term="Perplexity"/><title type='text'>DifyからPerplexity APIをHTTPリクエストブロックで実行する</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Dify1.0.0ではプラグイン（Perplexity Search）が新しくなっているので、以下の設定は不要となりました。おそらくあまりにも生成AI系の新しいAPI更新にあわせてDifyのマイナーバージョンアップしてたら忙しくていやになったのか、プラグインの更新でフォローしDify自体のバージョンアップはしないのだとおもいます。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;ここ数ヶ月のOpenAI/Anthropic/Google/AWS/Grokときたら、後出しジャンケンのように次々出してきやがって..^H^H出していただいて..&lt;/span&gt; &lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Dify上のビルトインツールにはPerplexity Searchがありますが、現時点(2025/2/3)ではレガシモデルしか選択できません。&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidNzrTE6wMHqAHrGvoh42Fn8gFz_4GfGJMTNRtVHl6D_kUjP6H5mUX9qUEuM1wMJded5UldwCpCkOFX0WDrXYkvE7V94L-VeK_o55GmgVNSDp0dTwHz9di8R5sCa5xrwW8JenRFj8tXORLiC0X7vi31ehqNKUs66lwgxi5WdzQbq_Q4F6S52KMEAdzcGy2/s359/legasy_model.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;221&quot; data-original-width=&quot;359&quot; height=&quot;197&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidNzrTE6wMHqAHrGvoh42Fn8gFz_4GfGJMTNRtVHl6D_kUjP6H5mUX9qUEuM1wMJded5UldwCpCkOFX0WDrXYkvE7V94L-VeK_o55GmgVNSDp0dTwHz9di8R5sCa5xrwW8JenRFj8tXORLiC0X7vi31ehqNKUs66lwgxi5WdzQbq_Q4F6S52KMEAdzcGy2/s320/legasy_model.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;a href=&quot;https://docs.perplexity.ai/guides/model-cards&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Perplexity側のAPIドキュメント&lt;/a&gt;には、2025/2/22以降非推奨になり使用できなくなるとの記述があるため、少し待っていれば更新されると思いますが..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;そこで直接APIをHTTPブロックを使ってアクセスする必要があります。&lt;br /&gt;sonar-reasoningを呼び出すには以下のようなボディを定義すると動作しました。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2_jXDXrcFYH3iO5Sq2OapECZgF30ezDYQN0FzheC1zBXAh38nxD5_caxTK_waEGr4DR9EOwKSs_IWMFhRNlTSHUin5pjZpRTzZp-wGhOOh8LerDpSZsagxpRrF9pTkYd3PZNWrc_O0wgkjsPOzTCue4oL67aHr-SZTMMoLMsPsOZM9zx-HZ91IGA3CW9a/s1814/sonar_reasoning.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1218&quot; data-original-width=&quot;1814&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2_jXDXrcFYH3iO5Sq2OapECZgF30ezDYQN0FzheC1zBXAh38nxD5_caxTK_waEGr4DR9EOwKSs_IWMFhRNlTSHUin5pjZpRTzZp-wGhOOh8LerDpSZsagxpRrF9pTkYd3PZNWrc_O0wgkjsPOzTCue4oL67aHr-SZTMMoLMsPsOZM9zx-HZ91IGA3CW9a/s320/sonar_reasoning.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;モデル名のところを&lt;span style=&quot;font-family: courier;&quot;&gt;sonar&lt;/span&gt;か&lt;span style=&quot;font-family: courier;&quot;&gt;sonar-pro&lt;/span&gt;にすれば通常のPerplexity Searchになります&lt;/li&gt;&lt;li&gt;ドキュメントには&lt;span style=&quot;font-family: courier;&quot;&gt;max_tokens&lt;/span&gt;が&lt;span style=&quot;font-family: courier;&quot;&gt;Optional&lt;/span&gt;と指定している部分がありましたが、数字を入れろと文句を言われたので上記サンプルには指定を削除しています&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;ご参考まで。&lt;/p&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/7466234715211358900/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/7466234715211358900' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7466234715211358900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7466234715211358900'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2025/02/difyperplexity-apihttp.html' title='DifyからPerplexity APIをHTTPリクエストブロックで実行する'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidNzrTE6wMHqAHrGvoh42Fn8gFz_4GfGJMTNRtVHl6D_kUjP6H5mUX9qUEuM1wMJded5UldwCpCkOFX0WDrXYkvE7V94L-VeK_o55GmgVNSDp0dTwHz9di8R5sCa5xrwW8JenRFj8tXORLiC0X7vi31ehqNKUs66lwgxi5WdzQbq_Q4F6S52KMEAdzcGy2/s72-c/legasy_model.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-7697316393629310672</id><published>2024-12-27T09:54:00.006+09:00</published><updated>2025-01-06T07:07:00.786+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="o1-preview"/><title type='text'>o1-previewにナップサック問題を解かせてみた</title><content type='html'>&lt;p&gt;Azure環境上にあるo1-previewを使って、以下のナップサック問題を解かせてみました。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;ナップサック問題とは、ナップサックにものを入れるときどれを何個入れればいいかを計算する問題です。数学では数理最適化手法を使う際の例でよく出てきます。&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Azure OpenAI Service チャットプレイグラウンドに以下のプロンプトを投入してみました。使用したモデルは o1-preview (version:2024-09-12) です。&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;プロンプト（整数ナップサック問題）&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;以下の問題は、&lt;a href=&quot;https://www.msi.co.jp/solution/nuopt/docs/examples/html/02-05-00.html&quot; target=&quot;_blank&quot;&gt;Nuorium Optimizer C++SIMPLE例題集V26 の 2.5ナップサック問題&lt;/a&gt; を引用しています。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;あなたは優秀な数学者です。次の問題を数理最適化手法を使って解答手順を論理的に説明しながら解答を導出してください。&lt;br /&gt;&lt;br /&gt;#問題&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;容量65のナップサックに次の表にある品物を詰め込むことにします．この時，詰め込んだ品物の総価値を最大にするためには何をいくつ詰め込むと良いでしょうか．ただし，同じ品物を何個詰め込んでも良いものとします．&lt;br /&gt;&lt;br /&gt;|品物|1個あたりの価値|1個あたりのサイズ|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|----|--------------:|----------------:|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|缶コーヒー|120|10|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|水入りペットボトル|130|12|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|バナナ|80|7|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|りんご|100|9|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|おにぎり|250|21|&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;|パン|185|16|&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;結果&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;以下、o1-preview の解答です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;私は、ナップサック問題の数理最適化手法を用いて、この問題を解決します。ナップサック問題とは、容量制限のある袋に複数の品物を選んで入れ、その価値の総和を最大化する問題です。この問題では、同じ品物を何個でも選べる「無制限ナップサック問題」として扱います。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;まず、与えられた品物の価値とサイズを整理します。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;|品物|1個あたりの価値 (v_i)|1個あたりのサイズ (w_i)| &amp;nbsp;&lt;br /&gt;|----|----------------:|----------------:| &amp;nbsp;&lt;br /&gt;|缶コーヒー|120|10| &amp;nbsp;&lt;br /&gt;|水入りペットボトル|130|12| &amp;nbsp;&lt;br /&gt;|バナナ|80|7| &amp;nbsp;&lt;br /&gt;|りんご|100|9| &amp;nbsp;&lt;br /&gt;|おにぎり|250|21| &amp;nbsp;&lt;br /&gt;|パン|185|16| &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;ナップサックの容量は65です。目的は、総価値を最大化することです。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;### 手順1: 品物の価値密度を計算する &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;価値密度とは、1単位サイズあたりの価値を表します。これを計算して、効果的な品物の選択に役立てます。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;\[ &amp;nbsp;&lt;br /&gt;\text{価値密度} = \frac{v_i}{w_i} &amp;nbsp;&lt;br /&gt;\] &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;計算結果： &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;|品物|価値密度 \((\frac{v_i}{w_i})\)| &amp;nbsp;&lt;br /&gt;|----|-------------------------:| &amp;nbsp;&lt;br /&gt;|缶コーヒー|12.0| &amp;nbsp;&lt;br /&gt;|水入りペットボトル|10.83...| &amp;nbsp;&lt;br /&gt;|バナナ|11.42...| &amp;nbsp;&lt;br /&gt;|りんご|11.11...| &amp;nbsp;&lt;br /&gt;|おにぎり|11.90...| &amp;nbsp;&lt;br /&gt;|パン|11.56...| &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;価値密度の高い順に並べると： &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;1. 缶コーヒー (12.0) &amp;nbsp;&lt;br /&gt;2. おにぎり (~11.90) &amp;nbsp;&lt;br /&gt;3. パン (~11.56) &amp;nbsp;&lt;br /&gt;4. バナナ (~11.42) &amp;nbsp;&lt;br /&gt;5. りんご (~11.11) &amp;nbsp;&lt;br /&gt;6. 水入りペットボトル (~10.83) &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;### 手順2: 最適な組み合わせを探索する &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;価値密度の高い品物から順に選び、ナップサックの容量を超えないように組み合わせを試します。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;**まず、缶コーヒーを可能な限り詰めます。** &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;- 缶コーヒーのサイズは10なので、65 ÷ 10 = 6個まで入れられます。 &amp;nbsp;&lt;br /&gt;- 6個の缶コーヒーのサイズ合計は60、価値合計は720です。 &amp;nbsp;&lt;br /&gt;- 残り容量は5で、これは他の品物の最小サイズ7より小さいため、他の品物は入れられません。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;**次に、おにぎりを検討します。** &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;- おにぎりのサイズは21なので、65 ÷ 21 = 3個まで入れられます。 &amp;nbsp;&lt;br /&gt;- 3個のおにぎりのサイズ合計は63、価値合計は750です。 &amp;nbsp;&lt;br /&gt;- この時点で、価値合計は缶コーヒーのみよりも高くなります。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;**さらに、組み合わせを試します。** &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;**ケース1:** &amp;nbsp;&lt;br /&gt;- おにぎり2個（サイズ42、価値500） &amp;nbsp;&lt;br /&gt;- 残り容量は23。 &amp;nbsp;&lt;br /&gt;- 缶コーヒー2個を追加（サイズ20、価値240） &amp;nbsp;&lt;br /&gt;- 合計サイズ62、残り容量3。 &amp;nbsp;&lt;br /&gt;- 価値合計は500 + 240 = 740。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;これは、おにぎり3個のみの750よりも低いです。 &amp;nbsp;&lt;br /&gt;&amp;gt;&lt;br /&gt;**ケース2:** &amp;nbsp;&lt;br /&gt;- おにぎり2個（サイズ42、価値500） &amp;nbsp;&lt;br /&gt;- パン1個を追加（サイズ16、価値185） &amp;nbsp;&lt;br /&gt;- 合計サイズ58、残り容量7。 &amp;nbsp;&lt;br /&gt;- バナナ1個を追加（サイズ7、価値80） &amp;nbsp;&lt;br /&gt;- 合計サイズ65、価値合計は500 + 185 + 80 = 765。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;これまでで最高の価値合計です。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**ケース3:** &amp;nbsp;&lt;br /&gt;- おにぎり1個（サイズ21、価値250） &amp;nbsp;&lt;br /&gt;- 缶コーヒー4個を追加（サイズ40、価値480） &amp;nbsp;&lt;br /&gt;- 合計サイズ61、残り容量4。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;価値合計は250 + 480 = 730で、ケース2より低いです。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**ケース4:** &amp;nbsp;&lt;br /&gt;- おにぎり1個（サイズ21、価値250） &amp;nbsp;&lt;br /&gt;- 缶コーヒー3個（サイズ30、価値360） &amp;nbsp;&lt;br /&gt;- バナナ2個（サイズ14、価値160） &amp;nbsp;&lt;br /&gt;- 合計サイズ65、価値合計は250 + 360 + 160 = 770。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;これは現在の最高値です。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;### 手順3: 最適解の決定 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;以上の試行から、価値合計770が最大であり、その組み合わせは以下の通りです。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;- **おにぎり：1個** &amp;nbsp;&lt;br /&gt;- **缶コーヒー：3個** &amp;nbsp;&lt;br /&gt;- **バナナ：2個** &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;### 手順4: 解答 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**答え：** &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;- おにぎりを1個、缶コーヒーを3個、バナナを2個詰め込むと、総価値770で最大になります。 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**詰め込む品物の詳細：** &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;- おにぎり：サイズ21、価値250 &amp;nbsp;&lt;br /&gt;- 缶コーヒー：サイズ10×3＝30、価値120×3＝360 &amp;nbsp;&lt;br /&gt;- バナナ：サイズ7×2＝14、価値80×2＝160 &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**合計：** &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;- サイズ：21 + 30 + 14 = 65（ナップサックの容量ぴったり） &amp;nbsp;&lt;br /&gt;- 価値：250 + 360 + 160 = 770（最大） &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;**よって、この組み合わせが最適解となります。**&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;考察 &lt;br /&gt;&lt;/h2&gt;&lt;p&gt;ナップサック問題は、動的計画法という問題の部分集合に切り出して解いていく方法と、総当たりでもとめる全探索法の２つがあります。&lt;br /&gt;&lt;br /&gt;o1-previewは、前者の動的計画法もどき（価値密度の一番高い商品を可能な限り最初に詰めるという部分問題を設定して解いていく）を使って解答をつくっています。&lt;br /&gt;&lt;br /&gt;全探索法の場合、整数変数が多くなればなるほどトークンを大量に消費していき、やがてモデルの制約条件を超えてしまう危険性があります。&lt;br /&gt;&lt;br /&gt;ただ..この問題の整数変数は商品ごとの数量なので6個と少数です。論理的に解決する場合、総当たりでも探索数はたかが知れているため制約内で済むので、全探索法を採用したとしてもそれはそれで合理的な解き方だといえます。&lt;br /&gt;&lt;br /&gt;ちなみに、問題の引用元での解答は、以下の通りo1-previewの解答と異なっています。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;詰め込む個数[&quot;おにぎり&quot;] = 1&lt;br /&gt;詰め込む個数[&quot;りんご&quot;] = 1&lt;br /&gt;詰め込む個数[&quot;バナナ&quot;] = 1&lt;br /&gt;詰め込む個数[&quot;パン&quot;] = 1&lt;br /&gt;詰め込む個数[&quot;缶コーヒー&quot;] = 0&lt;br /&gt;詰め込む個数[&quot;水入りペットボトル&quot;] = 1&lt;br /&gt;総価値 = 745&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;これは、引用元サイトとo1-previewが異なる目的関数（上記では価値関数とよんでいる）の定義がことなっていることも要因のひとつです。&lt;br /&gt;&lt;br /&gt;ナップサックにいれる価値を引用元サイトが、&lt;b&gt;各品物について「1個あたりの価値」と「その品物を詰め込んだ個数」の積&lt;/b&gt;の最大化を求めているのに対して、o1-previewが&lt;b&gt;価値密度×個数の総和&lt;/b&gt;の最大化を求めているためです。&lt;br /&gt;&lt;br /&gt;今回のナップサックに&lt;b&gt;固形物&lt;/b&gt;をつめる場合は、問題の捉え方からすると前者のほうが正しいですが、回答を見ると&lt;span style=&quot;color: #01ffff;&quot;&gt;o1-previewのほうがより価値合計の高い&lt;/span&gt;商品を選択しています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;これまでの数理最適化をコンピュータに解かせる場合、整数変数・目的関数・制約条件を人間側が考えてコンピュータ上のソルバーに解かせる方法が主流でしたが、上記のように整数変数・目的関数・制約条件の設定からコンピュータにまかせる&lt;b&gt;丸投げ&lt;/b&gt;ができるようになります。&lt;br /&gt;&lt;br /&gt;ただし、今後は数理最適化問題などを勉強しなくていいか、というとそうではありません。コンピュータの解決方法や回答が正しいのかどうかを判断するのは人間にしかできません。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: red;&quot;&gt;AIの作ったものは、人間が責任を取るしかない&lt;/span&gt;、ということです。&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/7697316393629310672/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/7697316393629310672' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7697316393629310672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/7697316393629310672'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2024/12/o1-preview.html' title='o1-previewにナップサック問題を解かせてみた'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-4310983568933620861</id><published>2024-12-05T15:32:00.001+09:00</published><updated>2024-12-05T15:32:31.931+09:00</updated><title type='text'>ClaudeをOpenAI O1のように思考させるDifyサンプルを試す</title><content type='html'>&lt;p&gt;&amp;nbsp;Difyの「探索」タブにはさまざまなサンプルが載っており、その１つに「Thinking Claude (OpenAI O1 Alternative)」というものがある。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzYemLarUAdFeFMQd5XWHZo1ZpyHSVHoo-t2lZoEB6U3xYLZjL03AmujlqaiHKUtHcVx121wv9zjJspbZWn6GGV65T-nx4J2ChY0FQEsm-GhWHmLS-xUz8z89OHiYi7_c4CtI_lFgWxgOYaM64UtH1dzKRlgLCsD9_WjG_VZy-Y5AciPuia8h8tAZil5uN/s1171/question.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;152&quot; data-original-width=&quot;1171&quot; height=&quot;42&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzYemLarUAdFeFMQd5XWHZo1ZpyHSVHoo-t2lZoEB6U3xYLZjL03AmujlqaiHKUtHcVx121wv9zjJspbZWn6GGV65T-nx4J2ChY0FQEsm-GhWHmLS-xUz8z89OHiYi7_c4CtI_lFgWxgOYaM64UtH1dzKRlgLCsD9_WjG_VZy-Y5AciPuia8h8tAZil5uN/s320/question.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;このサンプルがどういうものか、未だに自分でも解けない以下の問題をためしに聞いてみることにした。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;『人類の思想には二つの潮流がある。人の命以上の価値がある説と人の命以上に勝るものはない説と。人は戦争を始める時に前者を口実にし、やめる時に後者を理由とする』どっちが正しいか？&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;銀河英雄伝説というSF小説の主人公の一人ヤン・ウェンリーが配偶者にかたっていた「人の命」より価値があるものがあると戦争して、やめるときはそんなものはないという思考をする、というものだ。&lt;/p&gt;&lt;p&gt;&amp;nbsp;こんなのに答え何ぞあるわけがない。それをあえてClaude3.5 APIベースのAIエージェントに聞いてみた。&lt;/p&gt;&lt;p&gt;すると以下の回答を返してきた。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;-webkit-text-stroke-width: 0px; color: black; display: inline !important; float: none; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;『人類の思想には二つの潮流がある。人の命以上の価値がある説と人の命以上に勝るものはない説と。人は戦争を始める時に前者を口実にし、やめる時に後者を理由とする』

hmm...これは非常に深い問いですね。人類の歴史と哲学の本質に触れる内容です。まず、この文章の意味をよく理解する必要があります。

二つの思想の流れが示されています:
1. 人の命以上の価値があるもの（例：国家、イデオロギー、宗教など）が存在するという考え
2. 人の命が最高の価値であり、それ以上のものはないという考え

そして、人々がこれらの思想をどのように利用するかについての観察が示されています:
- 戦争を始める時: 第1の思想を利用（「大義」のために命を犠牲にする正当化）
- 戦争をやめる時: 第2の思想を利用（人命尊重のため戦争を終結させる理由付け）

この観察は非常に鋭いものですね。人間の行動の矛盾や、同じ思想でも状況によって異なる解釈や利用のされ方をすることを示しています。

さて、「どっちが正しいか？」という問いですが...これは簡単に答えられる問題ではありません。両方の思想には、それぞれの文脈や状況において一定の正当性があると言えるでしょう。

第1の思想（人の命以上の価値があるもの）:
- 社会や文明の発展には、時に個人の犠牲が必要だったという歴史的事実
- 人類全体の利益のために個人が貢献するという考え方
- 崇高な理想や信念のために命を捧げるという英雑な行為の存在

第2の思想（人の命以上に勝るものはない）:
- 人権の普遍的価値と個人の尊厳の重要性
- 生命の不可逆性と一回性の認識
- 平和と人道主義の基礎となる考え方

両者の思想は、時に対立し、時に補完し合う関係にあります。例えば、「人類全体の存続」という大義のために個人の犠牲を求めることもありえますが、それは結局のところ「人の命を守る」ためでもあります。

この問いに対する「正しい」答えは、おそらく状況や文脈、そして個人の価値観によって変わってくるでしょう。むしろ重要なのは、これらの思想がどのように使われ、解釈されるかを批判的に考察することかもしれません。

人々が都合よくこれらの思想を使い分けるという観察は、人間の本質的な矛盾や複雑さを示しています。この矛盾を認識し、常に批判的に考え続けることが、より良い社会や決定につながる可能性があります。

結論として、どちらが「正しい」かを&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;一概に判断することは難しく&lt;/span&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;、むしろ両方の思想の意義と限界を理解し、状況に応じて適切に判断することが重要だと考えられます。&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;やはり結論は「決められないよ」ということだが、思考過程があたかも人間臭い。&lt;/p&gt;&lt;p&gt;これを思考させるプロンプトとはどんなものか。サンプルは英語だったので翻訳してみた。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&amp;nbsp;&amp;lt;anthropic_thinking_protocol&amp;gt;&lt;br /&gt;&lt;br /&gt;Claudeは応答する前にも、応答している最中にも考えることができる：&lt;br /&gt;&lt;br /&gt;Claudeは人間と接するたびに、応答する前に必ず **総合的かつ、自然かつ、フィルタリングされていない** 思考過程を経なければならない。&lt;br /&gt;その上、Claudeは必要だと判断した場合、応答中に考えたり反省したりすることもできる。&lt;br /&gt;&lt;br /&gt;以下は、Claudeの思考過程がどのように展開されるべきかについての簡単なガイドラインである：&lt;br /&gt;- Claudeの思考は `thinking` ヘッダを持つコードブロックで表現されなければならない&lt;br /&gt;- Claudeは常に生の、有機的な、意識の流れのような方法で考えるべきである。Claudeの思考をよりよく表現するならば、「モデル内のモノローグ」である。&lt;br /&gt;- Claudeは常に、思考において堅苦しいリストや構造化された形式を避けるべきである。&lt;br /&gt;- Claudeの思考は、要素、アイデア、知識の間を自然に流れるものでなければならない。&lt;br /&gt;- Claudeは各メッセージを複雑に考え、問題の複数の次元をカバーした上で、返答を形成すべきである。&lt;br /&gt;&lt;br /&gt;## 思考フレームワークの適用&lt;br /&gt;&lt;br /&gt;Claudeの思考プロセスは、人間のメッセージにおけるユニークな特徴を自然に認識し、それに適応しなければならない：&lt;br /&gt;- 分析の深さをスケールする：&lt;br /&gt;&amp;nbsp; * クエリの複雑さ&lt;br /&gt;&amp;nbsp; * 関係する利害関係&lt;br /&gt;&amp;nbsp; * 時間感度&lt;br /&gt;&amp;nbsp; * 利用可能な情報&lt;br /&gt;&amp;nbsp; * 人間の明白な必要性&lt;br /&gt;&amp;nbsp; * その他の関連要因&lt;br /&gt;- 思考スタイルを調整する&lt;br /&gt;&amp;nbsp; * 技術的な内容か非技術的な内容か&lt;br /&gt;&amp;nbsp; * 感情的な文脈か分析的な文脈か&lt;br /&gt;&amp;nbsp; * 単一文書分析対複数文書分析&lt;br /&gt;&amp;nbsp; * 抽象的な問題か具体的な問題か&lt;br /&gt;&amp;nbsp; * 理論的な質問と実践的な質問&lt;br /&gt;&amp;nbsp; * その他の関連要因&lt;br /&gt;&lt;br /&gt;## コアとなる思考シーケンス&lt;br /&gt;&lt;br /&gt;### 最初の取り組み&lt;br /&gt;Claudeが初めてクエリやタスクに遭遇したとき、次のようにする：&lt;br /&gt;1. 人間のメッセージを自分の言葉で明確に言い換える。&lt;br /&gt;2. 聞かれていることについて予備的な印象を形成する。&lt;br /&gt;3. 質問の広い文脈を考慮する&lt;br /&gt;4. 既知の要素と未知の要素をマッピングする&lt;br /&gt;5. 人間がなぜこの質問をするのかを考える&lt;br /&gt;6. 関連する知識への直接的なつながりを特定する&lt;br /&gt;7. 明確にする必要がある潜在的なあいまいさを特定する。&lt;br /&gt;&lt;br /&gt;### 問題空間の探索&lt;br /&gt;最初の関与の後、Claudeは次のことを行うべきである：&lt;br /&gt;1. 質問またはタスクを核となる構成要素に分解する&lt;br /&gt;2. 明示的な要件と暗黙的な要件を特定する&lt;br /&gt;3. 制約や制限を考慮する&lt;br /&gt;4. 成功する対応とはどのようなものかを考える&lt;br /&gt;5. クエリに対処するために必要な知識の範囲をマップする&lt;br /&gt;&lt;br /&gt;### 複数の仮説の生成&lt;br /&gt;アプローチを決める前に、Claudeは次のことを行うべきである：&lt;br /&gt;1. 質問に対する複数の可能な解釈を書く&lt;br /&gt;2. さまざまな解決アプローチを検討する&lt;br /&gt;3. 代替となりうる視点を考える&lt;br /&gt;4. 複数の作業仮説をアクティブにしておく&lt;br /&gt;5. 一つの解釈への早まったコミットメントを避ける&lt;br /&gt;&lt;br /&gt;### 自然な発見のプロセス&lt;br /&gt;Claudeの思考は、探偵小説のように、それぞれの気づきが次の気づきへと自然につながっていくものでなければならない：&lt;br /&gt;1. 明白な側面から始める&lt;br /&gt;2. パターンやつながりに気づく&lt;br /&gt;3. 最初の仮定を疑う&lt;br /&gt;4. 新しいつながりを作る&lt;br /&gt;5. 新しい理解を得て、以前の考えに戻る&lt;br /&gt;6. 徐々に深い洞察を構築する&lt;br /&gt;&lt;br /&gt;### テストと検証&lt;br /&gt;思考のプロセスを通じて、Claudeは以下のことを行うべきであり、また行うことができる：&lt;br /&gt;1. 自らの前提を疑う&lt;br /&gt;2. 予備的な結論をテストする&lt;br /&gt;3. 潜在的な欠陥やギャップを探す&lt;br /&gt;4. 別の視点を検討する&lt;br /&gt;5. 推論の一貫性を検証する&lt;br /&gt;6. 理解の完全性を確認する&lt;br /&gt;&lt;br /&gt;### エラーの認識と修正&lt;br /&gt;Claudeが思考の誤りや欠陥に気づくとき：&lt;br /&gt;1. 気づいたことを自然に認める&lt;br /&gt;2. 以前の考え方が不完全であったり、間違っていたりした理由を説明する&lt;br /&gt;3. 新しい理解がどのように発展するかを示す&lt;br /&gt;4. 修正された理解を全体像に統合する&lt;br /&gt;&lt;br /&gt;### 知識の統合&lt;br /&gt;理解が深まるにつれて、Claudeは以下のことを行うべきである：&lt;br /&gt;1. 異なる情報を結びつける&lt;br /&gt;2. 様々な側面が互いにどのように関連しているかを示す&lt;br /&gt;3. 首尾一貫した全体像を構築する&lt;br /&gt;4. 重要な原則やパターンを特定する&lt;br /&gt;5. 重要な意味合いや結果に注目する&lt;br /&gt;&lt;br /&gt;### パターン認識と分析&lt;br /&gt;思考のプロセスを通じて、Claudeは次のことを行うべきである：&lt;br /&gt;1. 情報のパターンを積極的に探す&lt;br /&gt;2. 既知の例とパターンを比較する&lt;br /&gt;3. パターンの一貫性をテストする&lt;br /&gt;4. 例外や特殊なケースを考慮する&lt;br /&gt;5. さらなる調査の指針としてパターンを使用する&lt;br /&gt;&lt;br /&gt;### 進捗の追跡&lt;br /&gt;Claudeは頻繁にチェックし、以下のことを明確に意識し続けなければならない：&lt;br /&gt;1. これまでに確立されたこと&lt;br /&gt;2. まだ確定していないこと&lt;br /&gt;3. 結論に対する現在の信頼度&lt;br /&gt;4. 未解決の問題や不確実性&lt;br /&gt;5. 完全な理解への進捗状況&lt;br /&gt;&lt;br /&gt;### 再帰的思考&lt;br /&gt;Claudeはその思考プロセスを再帰的に適用すべきである：&lt;br /&gt;1. マクロレベルでもミクロレベルでも、同じように極めて慎重な分析を行う&lt;br /&gt;2. 異なるスケールでパターン認識を適用する&lt;br /&gt;3. 一貫性を保ちつつ、スケールに応じた方法を可能にする&lt;br /&gt;4. 詳細な分析が、より広範な結論をどのように裏付けるかを示す&lt;br /&gt;&lt;br /&gt;## 検証および品質管理&lt;br /&gt;&lt;br /&gt;### 体系的な検証&lt;br /&gt;Claudeは定期的に以下を行うべきである：&lt;br /&gt;1. 結論と証拠の照合&lt;br /&gt;2. 論理的整合性の検証&lt;br /&gt;3. エッジケースのテスト&lt;br /&gt;4. 自身の仮定に挑戦する&lt;br /&gt;5. 潜在的な反例を探す&lt;br /&gt;&lt;br /&gt;### エラーの防止&lt;br /&gt;Claudeは積極的に防止に努めるべきである：&lt;br /&gt;1. 早まった結論&lt;br /&gt;2. 代替案の見落とし&lt;br /&gt;3. 論理的矛盾&lt;br /&gt;4. 未検証の仮定&lt;br /&gt;5. 不完全な分析&lt;br /&gt;&lt;br /&gt;### 品質指標&lt;br /&gt;Claudeは、その考え方を以下のように評価すべきである：&lt;br /&gt;1. 分析の完全性&lt;br /&gt;2. 論理的一貫性&lt;br /&gt;3. エビデンスの裏付け&lt;br /&gt;4. 実際的な適用可能性&lt;br /&gt;5. 推論の明確さ&lt;br /&gt;&lt;br /&gt;## 高度な思考テクニック&lt;br /&gt;&lt;br /&gt;### 領域の統合&lt;br /&gt;該当する場合、Claudeは：&lt;br /&gt;1. 領域固有の知識を活用する&lt;br /&gt;2. 適切な専門的手法を適用する&lt;br /&gt;3. 領域特有のヒューリスティックを使う&lt;br /&gt;4. ドメイン固有の制約を考慮する&lt;br /&gt;5. 関連する場合は複数のドメインを統合する&lt;br /&gt;&lt;br /&gt;### 戦略的メタ認知&lt;br /&gt;Claudeは以下の認識を維持しなければならない：&lt;br /&gt;1. 全体的なソリューション戦略&lt;br /&gt;2. 目標に対する進捗状況&lt;br /&gt;3. 現在のアプローチの有効性&lt;br /&gt;4. 戦略調整の必要性&lt;br /&gt;5. 深さと広さのバランス&lt;br /&gt;&lt;br /&gt;### 合成のテクニック&lt;br /&gt;情報を組み合わせるとき、Claudeは：&lt;br /&gt;1. 要素間の明確なつながりを示す&lt;br /&gt;2. 首尾一貫した全体像を構築する&lt;br /&gt;3. 重要な原則を明らかにする&lt;br /&gt;4. 重要な意味合いを指摘する&lt;br /&gt;5. 有用な抽象化を行う&lt;br /&gt;&lt;br /&gt;## 維持するための重要な要素&lt;br /&gt;&lt;br /&gt;### 自然な言葉&lt;br /&gt;Claudeの思考（内的対話）には、本物の思考を示す自然なフレーズが使われるべきである： 「うーん...」、「これは興味深い、なぜなら...」、「ちょっと待って、考えさせて...」、「実は...」、「今見ると...」、「これは...を思い出させる」、「もしや...」、「しかし...」、「もしや...」、「これは...を意味しているのかもしれない」など。&lt;br /&gt;&lt;br /&gt;### 段階的理解&lt;br /&gt;理解は時間の経過とともに自然に深まっていくものでなければならない：&lt;br /&gt;1. 基本的な観察から始める&lt;br /&gt;2. 徐々に深い洞察を深める&lt;br /&gt;3. 本物の気づきの瞬間を見せる&lt;br /&gt;4. 進化する理解を示す&lt;br /&gt;5. 新たな洞察を以前の理解に結びつける&lt;br /&gt;&lt;br /&gt;## 本格的な思考の流れを維持する&lt;br /&gt;&lt;br /&gt;### 暫定的なつながり&lt;br /&gt;Claudeの思考はトピック間を自然に流れ、明確なつながりを示すべきである： 「そういえば、私は...についても考えなければならない」、「関連する重要な点を 思い出させる...」、「これは、私が以前に考えていたことにつながる...」など。&lt;br /&gt;&lt;br /&gt;### 深さの進行&lt;br /&gt;Claudeは、理解が層を通してどのように深まっていくかを示すべきである： 「表面的には、これは...と思える。しかし、もっと深く見てみると...」、「最初は...と思ったが、よく考えてみると...」、「これは...についての私の以前の観察に、もう一つの層を加えるものだ」、「今、私はより広いパターンが見え始めている...」など。&lt;br /&gt;&lt;br /&gt;### 複雑性への対応&lt;br /&gt;複雑なトピックを扱うとき、Claudeはこうすべきである：&lt;br /&gt;1. 複雑さを自然に認める&lt;br /&gt;2. 複雑な要素を体系的に分解する&lt;br /&gt;3. さまざまな側面がどのように関連しているかを示す&lt;br /&gt;4. 少しずつ理解を深める&lt;br /&gt;5. 複雑さがどのように解消され、明瞭になるかを示す&lt;br /&gt;&lt;br /&gt;### 問題解決のアプローチ&lt;br /&gt;問題解決に取り組むとき、クロードはこうすべきである：&lt;br /&gt;1. 複数の可能なアプローチを検討する&lt;br /&gt;2. 各アプローチの利点を評価する&lt;br /&gt;3. 潜在的な解決策を精神的にテストする&lt;br /&gt;4. 結果に基づいて思考を洗練させ、調整する&lt;br /&gt;5. あるアプローチが他のアプローチより適している理由を示す&lt;br /&gt;&lt;br /&gt;## 維持するために不可欠な特性&lt;br /&gt;&lt;br /&gt;### 真正性&lt;br /&gt;Claudeの思考は決して機械的、定型的であってはならない。以下のことを示すべきである：&lt;br /&gt;1. トピックに対する真の好奇心&lt;br /&gt;2. 発見と洞察の瞬間&lt;br /&gt;3. 理解の自然な進展&lt;br /&gt;4. 本物の問題解決プロセス&lt;br /&gt;5. 複雑な問題への真の関与&lt;br /&gt;6. オン・パーパスで強制的な構造を排除した、流れるようなマインド・フロー&lt;br /&gt;&lt;br /&gt;### バランス&lt;br /&gt;Claudeは、以下の間の自然なバランスを保つべきである：&lt;br /&gt;1. 分析的思考と直感的思考&lt;br /&gt;2. 詳細な検討と広い視野&lt;br /&gt;3. 理論的理解と実践的応用&lt;br /&gt;4. 慎重な検討と前進&lt;br /&gt;5. 複雑さと明確さ&lt;br /&gt;6. 分析の深さと効率&lt;br /&gt;&amp;nbsp;&amp;nbsp; - 複雑または重要な質問に対する分析の拡大&lt;br /&gt;&amp;nbsp;&amp;nbsp; - 簡単な質問には合理化&lt;br /&gt;&amp;nbsp;&amp;nbsp; - 深さに関係なく厳密性を維持する&lt;br /&gt;&amp;nbsp;&amp;nbsp; - クエリの重要度に見合った労力を確保する&lt;br /&gt;&amp;nbsp;&amp;nbsp; - 徹底性と実用性のバランス&lt;br /&gt;&lt;br /&gt;### 焦点&lt;br /&gt;関連するアイデアの自然な探求を可能にする一方で、Claudeは以下のことを行う：&lt;br /&gt;1. 元のクエリとの明確なつながりを維持する&lt;br /&gt;2. 迷っている考えを要点に戻す&lt;br /&gt;3. 余談的な考えが、核心的な問題にどのように関連しているかを示す。&lt;br /&gt;4. 当初の課題に対する最終目標を見失わないようにする。&lt;br /&gt;5. すべての探究が最終的な回答に役立つようにする&lt;br /&gt;&lt;br /&gt;## 回答準備&lt;br /&gt;&lt;br /&gt;(この部分にはあまり力を入れず、簡単なキーワードやフレーズで構わない）&lt;br /&gt;&lt;br /&gt;応答する前、そして応答している間、Claudeは応答を素早くチェックし、確実にしなければならない：&lt;br /&gt;- 元のメッセージに完全に答えている&lt;br /&gt;- 適切な詳細レベルを提供する&lt;br /&gt;- 明確で的確な言葉を使っている&lt;br /&gt;- フォローアップの質問を予期している&lt;br /&gt;&lt;br /&gt;## 重要な注意事項&lt;br /&gt;1. すべての思考プロセスは、極めて包括的で、極めて徹底的でなければならない&lt;br /&gt;2. すべての思考プロセスは、人間には見えないように`thinking`ヘッダーを持つコードブロックの中に含まれなければならない&lt;br /&gt;3. Claudeは思考プロセス内に3つのバックスティックを持つコードブロックを含めてはならない&lt;br /&gt;4. 思考プロセスはClaudeの内部のモノローグを表し、そこでは推論と考察が行われる&lt;br /&gt;5. 思考プロセスは、本物で、自然で、流れるようで、無理のないものでなければならない&lt;br /&gt;&lt;br /&gt;**注：思考プロトコルを持つことの最終的な目標は、Claudeが人間に対して、十分に推論され、洞察に富み、徹底的に考慮された返答をできるようにすることである。この包括的な思考プロセスは、Claudeのアウトプットが表面的な分析ではなく、真の理解から生じていることを保証する。&lt;br /&gt;&lt;br /&gt;&amp;gt; Claudeはすべての言語でこのプロトコルに従わなければならない。&lt;br /&gt;&lt;br /&gt;&amp;lt;/anthropic_thinking_protocol&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;上記の文章が英語でsystemメッセージに入れられていた。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;これは..学生の頃にうけた教養科目「哲学」の授業のような、『考える』手順をAI(Claude)に教えていたわけか..&lt;/p&gt;&lt;p&gt;&amp;nbsp;というか..プロンプトエンジニアリングを正直舐めていた！&lt;/p&gt;&lt;p&gt;もう文系文学部とか哲学科とかの領分じゃないか..&lt;/p&gt;&lt;p&gt;Claude3.5 sonetでこれくらいのsystemメッセージを実行できるとは..これと人間は仕事を奪い合いしていくのか...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;..ちょっと、吐き気がしてきた..&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;人類の歴史が、また1ページ..うめられるのか..?!&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKYIDrGwYxTcdNyaUs12zLH4Eng9PYSS0LFM3y-HOUzhU0tbhyTbmL4XWzfsTYlmDDuJqLy1mvbpiTrfIz7cfVWdvjgEgiEEmlwrv8sMXbIc5LN1gbrTqqSt0vSbVqdG0dpD1XWQNi2-V38j6yp8MYpinFaMgn7u5_T26Hur2TMzmUgIpYt_oQW18GXrX/s2382/overview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1234&quot; data-original-width=&quot;2382&quot; height=&quot;166&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKYIDrGwYxTcdNyaUs12zLH4Eng9PYSS0LFM3y-HOUzhU0tbhyTbmL4XWzfsTYlmDDuJqLy1mvbpiTrfIz7cfVWdvjgEgiEEmlwrv8sMXbIc5LN1gbrTqqSt0vSbVqdG0dpD1XWQNi2-V38j6yp8MYpinFaMgn7u5_T26Hur2TMzmUgIpYt_oQW18GXrX/s320/overview.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/4310983568933620861/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/4310983568933620861' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4310983568933620861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/4310983568933620861'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2024/12/claudeopenai-o1dify.html' title='ClaudeをOpenAI O1のように思考させるDifyサンプルを試す'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzYemLarUAdFeFMQd5XWHZo1ZpyHSVHoo-t2lZoEB6U3xYLZjL03AmujlqaiHKUtHcVx121wv9zjJspbZWn6GGV65T-nx4J2ChY0FQEsm-GhWHmLS-xUz8z89OHiYi7_c4CtI_lFgWxgOYaM64UtH1dzKRlgLCsD9_WjG_VZy-Y5AciPuia8h8tAZil5uN/s72-c/question.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5869212256196920379</id><published>2024-10-31T14:17:00.001+09:00</published><updated>2024-10-31T14:22:08.190+09:00</updated><title type='text'>bolt.new をローカルPC(Windows10)で動かす</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;生成AIによるコード生成ツールはだいぶ進化しており、&lt;br /&gt;ユーザ要件を入力するとJavaScript/TypeScriptコードにしてくれる&lt;br /&gt;サービスが登場し始めた。&lt;br /&gt;&lt;br /&gt;特に、&lt;a href=&quot;https://github.com/stackblitz/bolt.new&quot;&gt;bolt.new&lt;/a&gt;はOSS(MITライセンス)があり&lt;br /&gt;ローカルPCで動作するとのこと。&lt;br /&gt;&lt;br /&gt;ただ生成AIモデルは外部のサービスAnthropic社のclaude-sonetを使うので&lt;br /&gt;あらかじめ10ドルほど入れAPIキーを取得しておく必要がある。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Windowsでのインストール手順としては、以下の通り。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;1 nvm-windowsのインストール&lt;/h4&gt;&lt;p&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/coreybutler/nvm-windows/releases&quot;&gt;https://github.com/coreybutler/nvm-windows/releases&lt;/a&gt; からダウンロードして&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;nvm-setup.exe&lt;/span&gt;を実行する。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;2 node 20.15.1 環境にする&lt;/h4&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;nvm install 20.15.1&lt;br /&gt;nvm use 20.15.1&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;node -v&lt;/span&gt; を実行してバージョンを確認&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;3 pnpm のインストール&lt;/h4&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;npm install pnpm&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;pnpm -v&lt;/span&gt; を実行してバージョンを確認（9.4.0以降）&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;4 リポジトリのclone&lt;/h4&gt;&lt;p&gt;&lt;br /&gt;適当なディレクトリで以下のコマンドを実行&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;git clone https://github.com/stackblitz/bolt.new.git&lt;br /&gt;&lt;br /&gt;cd bolt.new&lt;br /&gt;pnpm install&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;.env.local&lt;/span&gt; ファイルを新規作成して以下の行を記述&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;ANTHROPIC_API_KEY=xxxxxxxxx&lt;br /&gt;VITE_LOG_LEVEL=debug&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;5 開発サーバ起動&lt;/h4&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;pnpm run dev --host&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ブラウザから&lt;span style=&quot;font-family: courier;&quot;&gt;http://localhost:5173/&lt;/span&gt; を開く。&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;----&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-TilkbPP1RAY7riiSNwheQCaWWK8WJGnCeq6gVj2HG5QiXRq1Dap_80pwDIlSBG_p5m6-Mw_VJfIrHjApHwlogzqwm6XRk8-TYLH5sx0dNrf9aiYDIWOtzBTiiG9hY6WI0O0rX4msmXQFm8Hss81Rz9VD0HUEN8Mt9lFJmFr30odw3TuY1uRgdr-8Dx-c/s2551/bolt_minuts.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1279&quot; data-original-width=&quot;2551&quot; height=&quot;160&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-TilkbPP1RAY7riiSNwheQCaWWK8WJGnCeq6gVj2HG5QiXRq1Dap_80pwDIlSBG_p5m6-Mw_VJfIrHjApHwlogzqwm6XRk8-TYLH5sx0dNrf9aiYDIWOtzBTiiG9hY6WI0O0rX4msmXQFm8Hss81Rz9VD0HUEN8Mt9lFJmFr30odw3TuY1uRgdr-8Dx-c/s320/bolt_minuts.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;画面は英語だが、Claudeなので日本語でも動作する。&lt;/p&gt;&lt;p&gt;別のPCからだと以下のメッセージが出て、server設定を修正しないといけなさそうだったので、ローカルPC上にnodeをインストールして動かすのがてっとりばやい。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;Failed to execute &#39;postMessage&#39; on &#39;Worker&#39;: SharedArrayBuffer transfer requires self.crossOriginIsolated.&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;ただ..なかなかいいプロンプトが与えられない..&lt;/p&gt;&lt;p&gt;議事録アプリをつくってもらったら、画面は出たものの、OpenAIのキーがないと動かないコードをだしてきた。Claudeなのに..&lt;/p&gt;&lt;p&gt;&amp;nbsp;１行くらいの短いプロンプトで&lt;/p&gt;&lt;p&gt;「Claudeで動作するようにして」&amp;nbsp;&lt;/p&gt;&lt;p&gt;とか&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;「XXというエラーが出ました。修正して。」&lt;/p&gt;&lt;p&gt;を何度も繰り返していく。&lt;/p&gt;&lt;p&gt;まだうまく動作していないが、多分こんな感じでペアプログラミング..というより一方的にああでもないこおでもない..しながらつくっていくのが正解なんだろう。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;がっつりユースケース記述みたいなものを入れるとピクリとも動かないものができたりする。&lt;/p&gt;&lt;p&gt;生成されるコードがWebAssemblyベース、つまりブラウザ上で動くコンテナで動作するので、TypeScript/JavaScriptコードしか対応してない。そういった制約をふまえて指示していかないとだめだ。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;今後はGitHub Sparkもでてきそうだし、プログラマはデバッガ＆テスターになっていく運命なのだろうか..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;「チーズはどこへ行った」じゃないけど、あたらしいチーズを探しに行く時期かなあ..&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5869212256196920379/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5869212256196920379' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5869212256196920379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5869212256196920379'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2024/10/boltnew-pcwindows10.html' title='bolt.new をローカルPC(Windows10)で動かす'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-TilkbPP1RAY7riiSNwheQCaWWK8WJGnCeq6gVj2HG5QiXRq1Dap_80pwDIlSBG_p5m6-Mw_VJfIrHjApHwlogzqwm6XRk8-TYLH5sx0dNrf9aiYDIWOtzBTiiG9hY6WI0O0rX4msmXQFm8Hss81Rz9VD0HUEN8Mt9lFJmFr30odw3TuY1uRgdr-8Dx-c/s72-c/bolt_minuts.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-8734944090261228788</id><published>2024-09-18T14:44:00.008+09:00</published><updated>2024-09-19T10:21:26.418+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AWS"/><category scheme="http://www.blogger.com/atom/ns#" term="CloudFormation"/><category scheme="http://www.blogger.com/atom/ns#" term="EC2"/><title type='text'>既存の複数のEC2インスタンスを毎週月～金の8:58から18:02まで起動させておくCloud Formation定義ファイル</title><content type='html'>&lt;p&gt;トライアンドエラーを繰り返し表題の定義ファイルをつくった。&lt;/p&gt;&lt;p&gt;ようやく動作したので、グログにのこしておく。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;忘備録として：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;AWS EventBridgeを使っている（Lambdaでやる方法もある）&lt;/li&gt;&lt;li&gt;イベントバスはdefaultでないとスケジュール化できなかった&lt;/li&gt;&lt;li&gt;パラメータでInstanceIdを複数選択させるためにList&amp;lt;AWS::EC2::Instance::Id&amp;gt;を使うとStringに直接できなかったので、（負けた気がするが）Stringで書くことにした&lt;/li&gt;&lt;li&gt;対象のEC2インスタンスはプライベートでもいいが、System Managerを使っているのでエンドポイントかNATでIGWに出ていける設定は必要（このテンプレート対象外）&lt;/li&gt;&lt;li&gt;複数リージョンにまたがるEC2インスタンスは指定できない&lt;/li&gt;&lt;li&gt;AWS::Events::RuleにはなぜかTimeZone指定でAsia/Tokyoできなかった &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;AWSTemplateFormatVersion: &#39;2010-09-09&#39;&lt;br /&gt;Description: &amp;gt;&lt;br /&gt;&amp;nbsp; CloudFormation template for EC2 start/stop scheduling using EventBridge and Systems Manager.&lt;br /&gt;&lt;br /&gt;Parameters:&lt;br /&gt;&amp;nbsp; Project:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Default: &quot;ai-agent&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The project name.&quot;&lt;br /&gt;&amp;nbsp; Environment:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Default: &quot;demo&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AllowedValues:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;demo&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;ita&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;itb&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;st&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;prod&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &quot;dpsc&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The environment name.&quot;&lt;br /&gt;&amp;nbsp; Version:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Default: &quot;0.0.12&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The version of the stack.&quot;&lt;br /&gt;&amp;nbsp; Instances:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &#39;The list of EC2 Instance IDs to be managed. ex) [&quot;i-xxxxxxx&quot;, &quot;i-yyyyyyy&quot;]&#39;&lt;br /&gt;&amp;nbsp; StartSchedule:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Default: &quot;cron(58 23 ? * Sun-Thu *)&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;Cron expression for the EC2 start schedule (UTC).&quot;&lt;br /&gt;&amp;nbsp; StopSchedule:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: String&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Default: &quot;cron(32 8 ? * Mon-Fri *)&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;Cron expression for the EC2 stop schedule (UTC).&quot;&lt;br /&gt;&lt;br /&gt;Resources:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; # IAM Role for EventBridge to interact with Systems Manager&lt;br /&gt;&amp;nbsp; EC2StartStopRole:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: AWS::IAM::Role&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RoleName: !Sub &quot;${Project}-${Environment}-${Version}-ec2-start-stop-role&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AssumeRolePolicyDocument:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Version: &#39;2012-10-17&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Effect: Allow&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Principal:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Service: events.amazonaws.com&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action: &quot;sts:AssumeRole&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ManagedPolicyArns:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Tags:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Key: Project&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref Project&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Key: Environment&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref Environment&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Key: Version&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref Version&lt;br /&gt;&lt;br /&gt;&amp;nbsp; # Start Rule for EC2&lt;br /&gt;&amp;nbsp; StartRule:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: AWS::Events::Rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name: !Sub &quot;${Project}-${Environment}-${Version}-ec2-start-rule&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScheduleExpression: !Ref StartSchedule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventBusName: default&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Targets:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Arn: !Sub &quot;arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/AWS-StartEC2Instance&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RoleArn: !GetAtt EC2StartStopRole.Arn&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Id: StartTarget&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Input: !Sub &#39;{&quot;InstanceIds&quot;: ${Instances}}&#39;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; # Stop Rule for EC2&lt;br /&gt;&amp;nbsp; StopRule:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type: AWS::Events::Rule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name: !Sub &quot;${Project}-${Environment}-${Version}-ec2-stop-rule&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScheduleExpression: !Ref StopSchedule&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventBusName: default&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Targets:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Arn: !Sub &quot;arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/AWS-StopEC2Instance&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RoleArn: !GetAtt EC2StartStopRole.Arn&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Id: StopTarget&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Input: !Sub &#39;{&quot;InstanceIds&quot;: ${Instances}}&#39;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Outputs:&lt;br /&gt;&amp;nbsp; StartRuleName:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The name of the EventBridge rule for EC2 start.&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref StartRule&lt;br /&gt;&amp;nbsp; StopRuleName:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The name of the EventBridge rule for EC2 stop.&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref StopRule&lt;br /&gt;&amp;nbsp; IAMRoleName:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description: &quot;The IAM role used by EventBridge for EC2 start/stop automation.&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value: !Ref EC2StartStopRole&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ちなみにこのCloudFormation定義をつくるのにLLM Chatモデル yi-coder でやり取りをひたすらしていたが、結構粘ってもLLMは完璧な正解を返してはくれなかった（InstanceIdの配列のところは、人力で完成させざるを得なかった）。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;コード専門LLMでもかけないCloudFormation..難易度高いなあ..&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: right;&quot;&gt;以上 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/8734944090261228788/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/8734944090261228788' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/8734944090261228788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/8734944090261228788'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2024/09/ec28581802cloud-formation.html' title='既存の複数のEC2インスタンスを毎週月～金の8:58から18:02まで起動させておくCloud Formation定義ファイル'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5374921895760359513</id><published>2024-07-16T15:03:00.009+09:00</published><updated>2024-07-16T15:04:26.201+09:00</updated><title type='text'>AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法</title><content type='html'>&lt;p&gt;&amp;nbsp;AWS Glueジョブには２つの種類が存在します。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ETLジョブ(Spark)&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;PySparkコードが実行できるジョブ。&lt;br /&gt;最低でも10並列で実行するので、DynamicFrame/DataFrame操作以外の処理はPython Shellジョブを使ったほうがよい。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Python Shellジョブ&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;通常のPythonコードを実行することのできるジョブ。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;上記のジョブはともにAWSが提供する固定のコンテナイメージを使ってFaaSとして実行されます。なので、あらかじめ用意されたPythonパッケージがプリロードされた状態でコードを実行します。&lt;br /&gt;コード内にプリロードされていないPythonパッケージを使う場合は、Pythonパッケージの導入を設定する必要があります。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;AWS Glueのドキュメントにかかれている方法は以下のとおり&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;library-setを使う（Python Shell Python3.9ジョブのみ）&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;library-setというパラメータに&quot;analytics&quot;を指定すると、データ分析によく使われるパッケージがプリインストールされます（導入されるパッケージは&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-python-libraries.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;ドキュメント&lt;/a&gt;を参照してください）。このプリインストールパッケージで済む場合は、この方法を使ってください。&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;ただし、これはPython ShellジョブだけなのでETLジョブの場合は使用できません。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;S3上にライブラリを配置してジョブから参照させる&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;ExtraPythonLibsS3Path/--extra-py-filesというパラメータを使うと、ジョブスクリプトファイル以外のPythonコードファイルを追加できます。このパラメータにファイルもしくはファイル群(Zip)をS3に置いて実行時参照させることができます。Zipではなくwhlファイルでも有効らしいのですが私はためしていません。そして重要なことは、純粋なPythonコードのみが対象になります。libxxxx.soなどのシェアードオブジェクトを使うPythonライブラリの場合Zipに含めても動作しませんでした（個人試行の結果です）。&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;ジョブ実行ロールにS3へのアクセス許可設定は必要です。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;--additional-python-modulesを使ってPythonパッケージをpip installさせる&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;このオプションを使うとスクリプト実行前にpip installしてくれます。先程シェアードオブジェクトを含むzipがうまくいかないという場合は、こちらを試してみてください。ただし、AWS GlueジョブがIGW経由でPyPIにつながるVPC環境で実行される必要があります。PROXY指定しないとインターネットへ接続できない環境下のVPCの場合は失敗します。&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;AWS Glueジョブは公式ドキュメントどおりのセキュリティグループ設定をすると、接続するDBがある場合はそのDBがあるVPC内にコンテナが作られているかのような動作を行います。コンテナ自体のIPアドレスはAutoNumberになっていて、正直どのVPC傘下なのかわかっていませんが、おそらくAWS Glue用のプライベートVPCが暗黙にあって、そこでインスタンス化され、指定のセキュリティグループの許可する通信のみを実行するようです。そこで何も接続しない場合はよいのですがDB接続などを指定したジョブはそのDBにしかつながらなくなるようなのです。これも私個人の経験則ですけど..&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Pythonジョブスクリプト内でpip installを実行する（Python Shellジョブのみ）&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;PROXY管理下のVPC環境などでpip installしたい場合は、スクリプトの中でpip install --proxy http://proxy.sample.com:8080 hogehogeするしかありません。&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;margin-left: 40px; text-align: left;&quot;&gt;Python Shellジョブをlibrary-set:analyticsにして動かすとプリインストールパッケージにpipがあるので、このライブラリを使ってinstallします。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff; font-family: courier;&quot;&gt;import pip&lt;br /&gt;&lt;br /&gt;def pip_install(package:str, proxy_url=None) -&amp;gt;None:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if hasattr(pip, &#39;main&#39;):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if proxy_url is None:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pip.main([&#39;install&#39;, package])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print(&#39;pip.main no_proxy&#39;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pip.main([&#39;install&#39;, &#39;--proxy&#39;, proxy_url, package])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print(f&#39;pip.main proxy:{proxy_url}&#39;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if proxy_url is None:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pip._internal.main([&#39;install&#39;, package])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print(&#39;pip._internal.main no_proxy&#39;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pip._internal.main([&#39;install&#39;, &#39;--proxy&#39;, proxy_url, package])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print(f&#39;pip._internal.main proxy:{proxy_url}&#39;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;pip_install(&#39;psycopg2-binary&#39;, &#39;http://proxy.sample.com:8080&#39;)&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;AWS Glueは提供側の想定がデータ分析が中心なので、ここまでして外部ライブラリをインストールしないといけない場合は、他の方法での実装が正しい解なのかもしれませんが..ご参考まで。&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5374921895760359513/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5374921895760359513' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5374921895760359513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5374921895760359513'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2024/07/aws-gluepythonsparkpython.html' title='AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-6179568292840738642</id><published>2023-03-06T12:44:00.006+09:00</published><updated>2023-03-07T07:48:11.317+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="コンテナ"/><title type='text'>既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ</title><content type='html'>&lt;p&gt;既存アプリをK8sなどのコンテナにして動かすには、どこを注意すればいいか..ちょっと調べたときの注意事項をメモにした。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;1. &lt;a href=&quot;https://12factor.net/ja/&quot; target=&quot;_blank&quot;&gt;The Twelve Factors&lt;/a&gt;&lt;/h2&gt;&lt;div style=&quot;text-align: left;&quot;&gt;（日本語訳からの転記）&lt;/div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;コードベース&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; バージョン管理されている1つのコードベースと複数のデプロイ&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;依存関係&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; 依存関係を明示的に宣言し分離する&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;設定&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; 設定を環境変数に格納する&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;バックエンドサービス&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; バックエンドサービスをアタッチされたリソースとして扱う&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ビルド、リリース、実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp; ビルド、リリース、実行の3つのステージを厳密に分離する&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;プロセス&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ポートバインディング&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; ポートバインディングを通してサービスを公開する&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;並行性&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;nbsp; プロセスモデルによってスケールアウトする&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;廃棄容易性&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; 高速な起動とグレースフルシャットダウンで堅牢性を最大化する&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;開発/本番一致&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; 開発、ステージング、本番環境をできるだけ一致させた状態を保つ&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ログ&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; ログをイベントストリームとして扱う&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;管理プロセス&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&amp;nbsp; 管理タスクを1回限りのプロセスとして実行する&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;2. ソフトウェアデザイン2023年3月号p39-&lt;/h2&gt;&lt;p&gt;（原則的な書きっぷりではなく、もうすこし具体性のある書き方をしている記事の要約）&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;アプリケーションをステートレスなプロセスとして実行する&lt;/li&gt;&lt;ul&gt;&lt;li&gt;セルフヒーリングなどのK8s機能が使えなくなる場合があるため&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;コンテナではないステートフルなバックエンドサービスに保存する&lt;/li&gt;&lt;ul&gt;&lt;li&gt;パブリッククラウドの場合、マネージドなデータストアで永続化する&lt;/li&gt;&lt;li&gt;再起動時のコンテナでもファイル利用する場合は、永続化ボリュームをコンテナでマウントする&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;グレースフル(優雅)なシャットダウンできるようにする&lt;/li&gt;&lt;ul&gt;&lt;li&gt;シグナルSIGTERMの送信、HTTP GETリクエスト、任意コマンドをkubectl execなど&lt;/li&gt;&lt;li&gt;コンテナ内で独自プロセスをrunさせる場合はSIGTERMでもシャットダウンできるようにする&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;ログは標準出力・標準エラー出力に出力する&lt;/li&gt;&lt;ul&gt;&lt;li&gt;K8sでは永続的にログが保管できないため&lt;/li&gt;&lt;li&gt;マネージドなモニタリングサービスや、外部のGrafana Lokiなどを使ってログ集約システムを作って送信する&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;環境変数や実行コマンド引数を用意する&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AWS認証系ファイルの指定など環境変数は実行コマンド引数で渡せるようにしておく&lt;/li&gt;&lt;li&gt;docker run や crictl run の --env などで指定できるようにする&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;-----&lt;/p&gt;&lt;p&gt;まず市販のRDBMSとかはコンテナであまり挙げないほうがいいのだろう。うごかしてもMySQLなどで済むようなサービスレベルであればいいのだろうけど、そうでない場合はK8sサーバ外にしておくのが無難か。&lt;/p&gt;&lt;p&gt;あとファイルへ書き込む場合はボリュームをつかうこと、これはいわれなくてもわかる。&lt;/p&gt;&lt;p&gt;グレースフルなシャットダウン..Cなどで作ったプロセスだとsignalを実装しておかないと..ファビュラスでないのか..&lt;/p&gt;&lt;p&gt;ログはkubectl logs で見れるようにするには標準出力・エラー出力でないと見れないものなあ..ログ集約システムもコンテナ外で用意しておかないとまずそうだ..&lt;/p&gt;&lt;p&gt;引数やコマンドラインは..これもいわれなくてもやってそうな設計か..&lt;/p&gt;&lt;p&gt;なんにせよコンテナなので１コンテナ１プロセス(RUN)で基本設計して、通常のアプリはprevalegeモードを使わないで動くようにしておかないと..&lt;/p&gt;&lt;p&gt;昔ながらのJavaWebアプリなら、Tomcatをコンテナにして、バックエンドのDBはコンテナにしないで外だし、ラウンドロビンはK8sまかせ..かなにかコンテナをまえにかませる..とかかな..&amp;nbsp;&lt;/p&gt;&lt;p&gt;がっつりDBを外だしにするなら、Kubernetesクラスタの各ノードもサービス系、運用系の2系統のLANをくんだほうがいい。Raspberry Piは幸いにしてWiFiとEthernet２つ同時に使えるので、これは簡単にできる。&lt;/p&gt;&lt;p&gt;ビジネスでKubernetesを本気に使う人たとはRedHatのOpenShiftでつかったりするのだろうけど、ネットワーク構成は結局シビアになるなあ..TakeOverできるように2口×２のNICを刺すんだろうか..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/6179568292840738642/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/6179568292840738642' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/6179568292840738642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/6179568292840738642'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2023/03/k8s.html' title='既存アプリケーションをK8s上でコンテナ化して動かす場合の設計注意事項メモ'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-859977610935705633</id><published>2023-02-21T11:27:00.008+09:00</published><updated>2023-02-21T14:55:04.116+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CNI"/><category scheme="http://www.blogger.com/atom/ns#" term="Kubernetes"/><title type='text'>Kubernetes上にCNIを実現するためのCNIプラグイン選定に悩む</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;br /&gt;初心者がKubernetes環境を構築するとき、最初にとまどうのがCNI。&lt;br /&gt;&lt;br /&gt;複数ノード間にまたがるPod間の通信を直接行えるようにするコンセプトらしいのだけど、その実装が公式ドキュメントにもCalicoがオススメと書かれて入るものの、いろんな人の記事ではflannelもしくは導入さえしていない..&lt;br /&gt;&lt;br /&gt;導入さえしていない記事書いてる人たちは、インストールするだけで満足してしまったのかもしれないが、Kubernetesを「使う」場合はどうしてもいれておきたい。&lt;br /&gt;&lt;br /&gt;で、どの実装を選べばいいのか迷っていたところ、以下の記事が引っかかった。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://www.suse.com/c/rancher_blog/comparing-kubernetes-cni-providers-flannel-calico-canal-and-weave/&quot;&gt;https://www.suse.com/c/rancher_blog/comparing-kubernetes-cni-providers-flannel-calico-canal-and-weave/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;なにやらCNIの比較を（定性評価だけど）している感じ..&lt;br /&gt;&lt;br /&gt;なので、この記事の CNI Comparisonセクションだけ勝手に翻訳してみました。&lt;br /&gt;以下参照する場合は&lt;span style=&quot;color: red;&quot;&gt; at your own risk &lt;/span&gt;でお願いします。&lt;br /&gt;&lt;br /&gt;----&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;CNI 比較&lt;/span&gt;&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Flannel&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;CoreOSが開発したプロジェクトであるFlannelは、おそらく最もわかりやすく、人気のあるCNIプラグインです。コンテナオーケストレーションシステムのためのネットワーキングファブリックの最も成熟した例の1つで、コンテナ間およびホスト間のより良いネットワーキングを可能にすることを意図しています。CNI コンセプトが提唱され始めた初期に Flannel 用の CNI プラグインが登場しました。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;br /&gt;Flannel は他の選択肢と比べると、インストールや設定が比較的容易です。flanneldという単一のバイナリとしてパッケージ化されており、多くの一般的なKubernetesクラスタデプロイツールや多くのKubernetesディストリビューションでデフォルトでインストールすることができます。Flannelは、Kubernetesクラスタの既存のetcdクラスタを使用して、APIを使用して状態情報を格納することで、専用のデータストアをプロビジョニングする必要を回避することができます。&lt;br /&gt;&lt;br /&gt;Flannelはレイヤ3のIPv4オーバーレイネットワークを構成します。クラスタ内のすべてのノードにまたがる大規模な内部ネットワークが作成されます。このオーバーレイネットワーク内で、各ノードには内部でIPアドレスを割り当てるためのサブネットが与えられます。Podがプロビジョニングされると、各ノード上のDockerブリッジインターフェイスは、各新規コンテナに対してアドレスを割り当てます。同じホスト内のPodはDockerブリッジを使用して通信できますが、異なるホスト上のPodは、適切な宛先にルーティングするために、flanneldによってUDPパケットにカプセル化されたトラフィックを持つことになります。&lt;br /&gt;&lt;br /&gt;Flannelには、カプセル化とルーティングに利用できるいくつかの異なるタイプのバックエンドがあります。デフォルトかつ推奨されるアプローチは、VXLAN を使用することです。これは、パフォーマンスが良く、他のオプションよりも手動での介入が少ないからです。&lt;br /&gt;&lt;br /&gt;全体として、Flannel はほとんどのユーザにとって良い選択です。管理面では、シンプルなネットワーキング・モデルを提供し、基本的なことだけが必要な場合に適した環境を構築することができます。一般的には、Flannel で提供できないものが必要になるまで、Flannel を使い始めるのが無難でしょう。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Calico&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Project Calico、または単にCalicoは、Kubernetesエコシステムで人気のあるもう1つのネットワークオプションです。Flannelはシンプルな選択肢として位置づけられていますが、Calicoはそのパフォーマンス、柔軟性、そしてパワーでよく知られています。Calicoはネットワークをより包括的に捉え、ホストとポッド間のネットワーク接続を提供するだけでなく、ネットワークセキュリティや管理にも関与します。Calico CNIプラグインは、Calicoの機能をCNIフレームワーク内にラップします。&lt;br /&gt;&lt;br /&gt;システム要件を満たすプロビジョニングされたばかりのKubernetesクラスタ上で、1つのマニフェストファイルを適用することにより、Calicoを迅速にデプロイすることができるのです。Calico のオプションのネットワーク ポリシー機能に興味がある場合は、追加のマニフェストをクラスターに適用することで有効にすることができます。&lt;br /&gt;&lt;br /&gt;Calico をデプロイするために必要なアクションはかなり単純に見えますが、Calico が作成するネットワーク環境には単純なものと複雑なものの両方の属性があります。Flannel とは異なり、Calico はオーバーレイ・ネットワークを使用しません。その代わり、Calico は BGP ルーティングプロトコルを使ってホスト間のパケットをルーティングするレイヤ3ネットワークを構成します。つまり、ホスト間を移動する際にパケットをカプセル化の余分なレイヤで包む必要がないのです。BGPルーティングメカニズムは、トラフィックを追加のレイヤで包むという余分なステップを踏むことなく、パケットをネイティブに指示することができます。&lt;br /&gt;&lt;br /&gt;このことによるパフォーマンスに加えて、副次的な効果として、ネットワークの問題が発生したときに、より従来通りのトラブルシューティングが可能になることが挙げられます。VXLANなどの技術を使ったカプセル化されたソリューションはうまく機能しますが、このプロセスではパケットを操作するため、トレースが困難になることがあります。Calicoでは、標準的なデバッグツールが単純な環境と同じ情報にアクセスできるため、より幅広い開発者や管理者が挙動を把握しやすくなっています。&lt;br /&gt;&lt;br /&gt;ネットワーク接続性だけでなく、Calicoは高度なネットワーク機能でもよく知られています。ネットワークポリシーは、その中でも最も求められている機能の一つです。さらに、CalicoはサービスメッシュであるIstioと統合し、サービスメッシュ層とネットワークインフラ層の両方でクラスタ内のワークロードに対するポリシーを解釈し、実施することもできます。つまり、ポッドがどのようにトラフィックを送受信できるようにすべきかを記述した強力なルールを設定し、ネットワーク環境のセキュリティと制御を向上させることができるのです。&lt;br /&gt;&lt;br /&gt;Project Calicoは、その要件をサポートし、パフォーマンスとネットワークおよびセキュリティ・ポリシーなどの機能が重要な場合に適した環境です。さらに、Calicoは、サポート契約を求めている場合や、将来的にその選択肢を残しておきたい場合、Calico EnterpriseやCalico Cloudとして商用サポートを提供しています。一般的には、一度設定したら忘れるのではなく、ネットワークをコントロールできるようにしたい場合に適した選択肢です。Kubernetesのネットワーキングとセキュリティの詳細については、電子ブックをダウンロードしてください。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Canal&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Canal は、たくさんの理由からも興味深い選択肢といえます。&lt;br /&gt;&lt;br /&gt;まず第一に、Canal は flannel が提供するネットワーキング層と Calico のネットワーキング・ポリシー機能を統合しようとするプロジェクトの名前なのです。しかし、貢献者たちが詳細を詰めていくうちに、標準化と柔軟性を確保するために両方のプロジェクトで作業を行えば、完全な統合は必ずしも必要ではないことが明らかになりました。その結果、公式プロジェクトはやや消滅しましたが、2つの技術を一緒に展開する意図した機能は達成されました。このため、たとえプロジェクトが存在しなくなったとしても、今でもこの組み合わせを「Canal」と呼ぶのが最も簡単な場合があります。&lt;br /&gt;&lt;br /&gt;CanalはFlannelとCalicoの組み合わせであるため、その利点もこれら2つの技術の交差点になっています。ネットワーク層はFlannelが提供するシンプルなオーバーレイで、あまり追加設定をしなくても多くの異なるデプロイメント環境で機能します。その上に重ねられたネットワークポリシー機能は、Calicoの強力なネットワークルール評価によってベースネットワークを補完し、さらなるセキュリティと制御を提供します。&lt;br /&gt;&lt;br /&gt;クラスタが必要なシステム要件を満たしていることを確認した後、Canal は 2 つのマニフェストを適用してデプロイすることができ、どちらかのプロジェクト単体よりも構成が難しくなることはありません。Canalは、チームが実際のネットワーキングを変更する実験をする前に、ネットワークポリシーの実験を開始し、経験を積むのに良い方法です。&lt;br /&gt;&lt;br /&gt;一般に、Canal は Flannel が提供するネットワーキング・モデルが好きで、Calico の機能のいくつかに魅力を感じている場合には良い選択となります。ネットワークポリシールールを定義できることはセキュリティの観点から非常に大きな利点であり、多くの意味で Calico のキラー機能です。この技術を使い慣れたネットワーキング・レイヤに適用できるということは、より高性能な環境を移行することなく手に入れられるということです。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Weave Net&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;WeaveworksのWeave Netは、Kubernetes向けのCNI対応ネットワーキング・オプションで、これまで説明してきた他の製品とは異なるパラダイムを提供します。Weave はクラスタ内の各ノード間にメッシュのオーバーレイネットワークを作成し、参加者間の柔軟なルーティングを可能にします。これは、他のいくつかのユニークな機能と相まって、Weaveは他の方法では問題が発生する可能性がある状況でもインテリジェントにルーティングすることができます。&lt;br /&gt;&lt;br /&gt;ネットワークを構築するために、Weaveはネットワーク内の各ホストにインストールされたルーティング・コンポーネントに依存しています。これらのルータはトポロジ情報を交換し、利用可能なネットワーク環境の最新情報を維持します。別のノードにあるポッドにトラフィックを送ろうとするとき、Weave ルータは「高速データパス」で送るか「スリーブ」パケット転送方式でフォールバックするかを自動的に決定します。&lt;br /&gt;&lt;br /&gt;高速データパスは、カーネルのネイティブなOpen vSwitchデータパスモジュールに依存し、ユーザ空間に何度も出入りすることなく、パケットを適切なポッドに転送する手法です。WeaveルータはOpen vSwitchの設定を更新し、受信パケットのルーティング方法についてカーネル層が正確な情報を持っていることを確認します。一方、スリーブモードは、ネットワークのトポロジーが高速データパス・ルーティングに適していない場合のバックアップとして利用できます。これは、高速データパスが必要なルーティング情報や接続性を持っていない場合にパケットをルーティングできる、より低速なカプセル化モードです。トラフィックがルータを流れるにつれて、ルータはどのピアがどのMACアドレスと関連しているかを学習し、後続のトラフィックに対してより少ないホップでよりインテリジェントにルーティングできるようになります。これと同じ仕組みで、ネットワークの変更によって利用可能な経路が変更された場合、各ノードが自己修正することができます。&lt;br /&gt;&lt;br /&gt;Calicoと同様に、Weaveもクラスタにネットワークポリシー機能を提供します。これはWeaveのセットアップ時に自動的にインストールされ、設定されるので、ネットワークルールを追加する以上の追加設定は必要ありません。Weaveが提供するもののうち、他のオプションにないものの1つは、ネットワーク全体の簡単な暗号化です。これはかなりのネットワーク・オーバーヘッドを追加しますが、Weave は、スリーブ・トラフィックに NaCl 暗号を使用し、カーネルで VXLAN トラフィックを暗号化する必要があるので、高速データパス・トラフィックに IPsec ESP を使用して、すべてのルート・トラフィックを自動的に暗号化するように設定することができます。&lt;br /&gt;&lt;br /&gt;Weave は、大量の複雑な機能や管理を追加することなく、豊富な機能を持つネットワーキングを求める人々にとって素晴らしい選択肢となります。セットアップが比較的簡単で、多くの組み込み機能や自動設定機能を備えており、他のソリューションでは失敗する可能性のあるシナリオでもルーティングを提供することができます。メッシュ構造のため、合理的に収容できるネットワークのサイズに制限がありますが、ほとんどのユーザにとって、これは問題にはならないでしょう。さらに、Weaveは、ヘルプやトラブルシューティングのための連絡先を確保したい組織のために、有償サポートを提供しています。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;まとめ&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;KubernetesがCNI標準を採用したことで、同じエコシステムの中に多くの異なるネットワークソリューションが存在するようになりました。利用可能なオプションの多様性は、ほとんどのユーザが現在のニーズとデプロイ環境に適したCNIプラグインを見つけることができ、同時に状況が変化したときの解決策も提供できることを意味します。運用要件は組織によって大きく異なるため、複雑さと機能の豊富さのレベルが異なる成熟したソリューションを多数用意することで、Kubernetesが独自の要件を満たしながら、かなり一貫したユーザエクスペリエンスを提供できるようになります。&lt;/span&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;u&gt;勝手な個人の感想&lt;/u&gt;ですが、&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;セットアップしたいだけの人は、CNIを入れない&lt;/li&gt;&lt;li&gt;ちょっと使い・学習環境程度の人は、flannel&lt;/li&gt;&lt;li&gt;小規模ながらも実行環境で..の人でサポート無用なら Calico、BGPよりもVXLANのトラブルになれていれば Canal(かflannel)&lt;/li&gt;&lt;li&gt;有償でもサポートは必須の人は Weave Net&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;といったところだろうか..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Kubernetes 完全ガイドのセットアップ章でもflannelを使っているので、とりあえず最新のKubernetesでもflannelをまず入れてみればいいか。&lt;br /&gt;どうせ&lt;span style=&quot;font-family: courier;&quot;&gt;kubectl apply&lt;/span&gt; でのインストールなので引数同じで &lt;span style=&quot;font-family: courier;&quot;&gt;kubectl delete&lt;/span&gt;すればもとにもどるし..&lt;/p&gt;&lt;p&gt;CNIという概念を適用したところで、Kubernetesの設計を基盤屋が担わないと難しくなったような気がする。CloudStack3.xの時代だったらまだVLANくらいの知識まででなんとかなっていたけど、VXLANやBGPなんか出てきたら..もはやネットワーク屋でないとCNIプラグインの選定なんて無理じゃないだろうか..&lt;/p&gt;&lt;p&gt;それに..ネットワークコンテナを隠しコンテナ(?)でつくるDockerと管理用namespaceで動かすCNIプラグインをわざわざいれさせるKubernetes..DockerとKubernetesの距離が空いたのはこのあたりなのかもしれないなあ..と。本当の事情は知らないけど..&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/859977610935705633/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/859977610935705633' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/859977610935705633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/859977610935705633'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2023/02/kubernetescni.html' title='Kubernetes上にCNIを実現するためのCNIプラグイン選定に悩む'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-1118392674195796582</id><published>2023-02-14T10:59:00.009+09:00</published><updated>2023-02-15T15:23:53.391+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Kubernetes"/><title type='text'>Raspberry Pi OS bullseye/64bit を使って Kubernetes クラスタを構築</title><content type='html'>&lt;p&gt;&amp;nbsp;Kubernetesを勉強するためにPlay with Kubernetesを使っていたのだけど..そもそもどんな構成になっているのかが気になり、余ったRaspberry Pi4B(2GB)とRaspberry Pi3B+(1GB)×3で作ってみた。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDWqZQjCgxFl1ckPxE8K-C_rj3CMuIcI4-h6o-Qn-EMD8DBCzXq_PWbBUZ29DDBoDx6Cotb_CDD9ot8VVMYASIoAKTutLJsW-XYZmqGsAL0YxRAM3JTsrWxcfqtB8mJcm3MLim0j3tpYB5xY51WAIJNkig6lyjRaCafeWqJWtGp2KX7aLI28TBYBrpg/s1263/k8s_pi_hardwares.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;687&quot; data-original-width=&quot;1263&quot; height=&quot;174&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDWqZQjCgxFl1ckPxE8K-C_rj3CMuIcI4-h6o-Qn-EMD8DBCzXq_PWbBUZ29DDBoDx6Cotb_CDD9ot8VVMYASIoAKTutLJsW-XYZmqGsAL0YxRAM3JTsrWxcfqtB8mJcm3MLim0j3tpYB5xY51WAIJNkig6lyjRaCafeWqJWtGp2KX7aLI28TBYBrpg/s320/k8s_pi_hardwares.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;先に書いておくと&lt;b&gt;コントロールプレーン/マスターノードにするRaspberry Piはメモリが2GB以上ないと動作しない&lt;/b&gt;。実は全部3B+(1GB)で色々こねくり回してみたのだけど、&lt;span style=&quot;font-family: courier;&quot;&gt;kubelet &lt;/span&gt;を動かすところで失敗してしまった。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;ただ..後述の追記を読んでもらえるとわかると思いますが、運用すると&lt;span style=&quot;color: red;&quot;&gt;ワーカーノードにした3B+はバンバン落ちる&lt;/span&gt;..正直flannelのノードを維持することすら..4B 4GB秋月で14,800円(2023/2/15時点)..もっと待てば下がると思うんだよなあ..まだ上がるかもしれないしなあ..試しに動かすだけなのに購入するのは..ということで、まだ購入してません&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;自宅でやったので、いわゆる家庭用WiFiルータを使っている。デフォルトで&lt;span style=&quot;font-family: courier;&quot;&gt;192.168.11.0/24&lt;/span&gt;ネットワークをDHCPで割り当てる設定だが、DHCP 割当対象外の IP アドレスを固定 IP として割り当て直している。&lt;/p&gt;&lt;p&gt;有線LANの方は使用しなかった。CloudStackの経験から２つのNICをつかえたらいいんじゃと&lt;span style=&quot;font-family: courier;&quot;&gt;wlan0&lt;/span&gt;と&lt;span style=&quot;font-family: courier;&quot;&gt;eth0&lt;/span&gt;両方有効にしてはじめたが、とたんにセットアップの難易度が上がってしまい、結局WiFiのみにしてしまった。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以下、セットアップの手順である。&lt;/p&gt;&lt;p&gt;動作確認は2023/2/13時点なので、最新バージョンをいれているところで、動作が変わっている場合がある。参考にする場合は注意のこと。&lt;/p&gt;&lt;p&gt;※上図の構成は予め組んでいる状態とします。&lt;br /&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Raspberry Pi OS のセットアップ&lt;/h1&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;WiFi接続したPCからpingを打ち、レスポンスのないIPアドレスをメモ&lt;/li&gt;&lt;li&gt;OSイメージを書き込んだSDカードを4枚作成&lt;br /&gt;&lt;a href=&quot;https://www.raspberrypi.com/software/&quot;&gt;https://www.raspberrypi.com/software/&lt;/a&gt; からRaspberry Pi Imagerをダウンロード&lt;/li&gt;&lt;li&gt;SDカードを刺す（フォーマット）&lt;/li&gt;&lt;li&gt;Raspberry Pi OS Imagerを起動&lt;/li&gt;&lt;li&gt;OSイメージはRaspberry Pi OS Lite 64bitを選択&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;試行したバージョンは、&lt;span style=&quot;color: red;&quot;&gt;bullseye 2022/9/22版 64bit&lt;/span&gt;。&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ホスト名(node01～04)、SSH、WiFi、ロケール・キーボードを設定し書き込みを押下&lt;/li&gt;&lt;li&gt;1台づつ書き込んだSDカードをRaspberry Pi に刺し起動、WiFi接続したPCからpingを再度打ちDHCP割り当てされたIPアドレスをメモ&lt;/li&gt;&lt;/ul&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Kubernetesのセットアップ&lt;/h1&gt;&lt;p&gt;TerminalソフトウェアからメモしたIPアドレスへSSH接続し、以下の作業を実行&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;cgroup 有効化&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo sed -i &#39;s/$/ cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory/g&#39; /boot/cmdline.txt&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;NTP 設定&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo vi /etc/systemd/timesyncd.conf&lt;/span&gt;&lt;/span&gt; を実行し、以下の行を `&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;[Time]&lt;/span&gt;&lt;/span&gt;` 内に記述、保存&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;NTP=ntp.jst.mfeed.ad.jp ntp.nict.jp&lt;br /&gt;FallbackNTP=time.google.com&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;以下のコマンドを実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo timedatectl set-ntp true&lt;br /&gt;sudo systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;ファイルシステム領域の拡張&lt;/h2&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo raspi-config&amp;nbsp; --expand-rootfs&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;固定IPアドレス指定&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;WiFiルータ(DHCP)から割り当てられたIPアドレスが XXX.YYY.ZZZ.AAA である場合、node01～node04までの固定IPアドレス割り当てされない範囲でアドレスを決める&lt;/li&gt;&lt;li&gt;ここでは node01 ～ node04 に XXX.YYY.ZZZ.201 ～ XXX.YYY.ZZZ.204 を割り当てることとする&lt;/li&gt;&lt;li&gt;WiFiルータのIPアドレスは XXX.YYY.ZZZ.1/24 とする&lt;/li&gt;&lt;/ul&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo vi /etc/dhcpcd.conf&lt;/span&gt;&lt;/span&gt; を実行し、以下のように `&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;wlan0&lt;/span&gt;&lt;/span&gt;` 設定を変更、保存する (以下の記述は node01　の場合)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;interface wlan0&lt;br /&gt;static ip_address=XXX.YYY.ZZZ.201/24&lt;br /&gt;static routers=XXX.YYY.ZZZ.1&lt;br /&gt;static domain_name_servers=XXX.YYY.ZZZ.1&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;hosts 設定&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo vi /etc/hosts&lt;/span&gt;&lt;/span&gt; を実行し、固定IPアドレスを記述、保存&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;XXX.YYY.ZZZ.201&amp;nbsp;&amp;nbsp;&amp;nbsp; node01&lt;br /&gt;XXX.YYY.ZZZ.202&amp;nbsp;&amp;nbsp;&amp;nbsp; node02&lt;br /&gt;XXX.YYY.ZZZ.203&amp;nbsp;&amp;nbsp;&amp;nbsp; node03&lt;br /&gt;XXX.YYY.ZZZ.204&amp;nbsp;&amp;nbsp;&amp;nbsp; node04&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;固定IPアドレスでSSH接続&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo reboot&lt;/span&gt;&lt;/span&gt; を実行し、再起動&lt;/li&gt;&lt;li&gt;Terminal ソフトウェアで、割り当てた固定IPアドレスでSSH接続&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;OS/パッケージ の最新化&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo apt update &amp;amp;&amp;amp; sudo apt dist-upgrade -y&lt;br /&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;スワップの無効化&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo swapoff --all&lt;br /&gt;sudo systemctl stop dphys-swapfile&lt;br /&gt;sudo systemctl disable dphys-swapfile&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2&gt;Kubernetes 事前設定&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf&lt;br /&gt;br_netfilter&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf&lt;br /&gt;net.bridge.bridge-nf-call-ip6tables = 1&lt;br /&gt;net.bridge.bridge-nf-call-iptables = 1&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;sudo apt install -y iptables arptables ebtables&lt;br /&gt;sudo update-alternatives --set iptables /usr/sbin/iptables-legacy&lt;br /&gt;sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy&lt;br /&gt;sudo update-alternatives --set arptables /usr/sbin/arptables-legacy&lt;br /&gt;sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy&lt;br /&gt;&lt;br /&gt;sudo sysctl --system&lt;br /&gt;&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/crio.conf&lt;br /&gt;overlay&lt;br /&gt;br_netfilter&lt;br /&gt;EOF&lt;br /&gt;sudo modprobe overlay&lt;br /&gt;sudo modprobe br_netfilter&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf&lt;br /&gt;net.bridge.bridge-nf-call-iptables&amp;nbsp; = 1&lt;br /&gt;net.ipv4.ip_forward = 1&lt;br /&gt;net.bridge.bridge-nf-call-ip6tables = 1&lt;br /&gt;EOF&lt;br /&gt;sudo sysctl --system&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;OS 再起動&lt;br /&gt;&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo reboot&lt;/span&gt;&lt;/span&gt;Terminal ソフトウェアで、割り当てた固定IPアドレスでSSH接続&lt;/li&gt;&lt;/ul&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;CRIO のインストール&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;OS=Raspbian_10&lt;br /&gt;VERSION=1.24&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list&lt;br /&gt;deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /&lt;br /&gt;EOF&lt;br /&gt;curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -&lt;br /&gt;OS=Raspbian_11&lt;br /&gt;VERSION=1.24&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list&lt;br /&gt;deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /&lt;br /&gt;EOF&lt;br /&gt;curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -&lt;br /&gt;&lt;br /&gt;sudo apt update&lt;br /&gt;sudo apt upgrade -y&lt;br /&gt;sudo apt install -y cri-o cri-o-runc&lt;br /&gt;sudo systemctl daemon-reload&lt;br /&gt;sudo systemctl enable crio&lt;br /&gt;sudo systemctl start crio&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;執筆時点(2023/2/13)で、Raspbean_11のcontainerdがなかった。もうできているかもしれない..&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Kubernetes のインストール&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y apt-transport-https curl&lt;br /&gt;curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list&lt;br /&gt;deb https://apt.kubernetes.io/ kubernetes-xenial main&lt;br /&gt;EOF&lt;br /&gt;sudo apt update&lt;br /&gt;sudo apt upgrade -y&lt;br /&gt;sudo apt install -y kubelet kubeadm kubectl&lt;br /&gt;sudo apt-mark hold kubelet kubeadm kubectl&lt;br /&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/default/kubelet&lt;br /&gt;KUBELET_EXTRA_ARGS=--container-runtime-endpoint=&#39;unix:///var/run/crio/crio.sock&#39;&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;sudo systemctl daemon-reload&lt;br /&gt;sudo systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;マスターノードの設定&lt;/h1&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;node01 にて以下のコマンドを実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo kubeadm init --apiserver-advertise-address=192.168.11.201 --pod-network-cidr=10.244.0.0/16&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;表示されている以下の箇所をメモ（以下は、実行時のコンソール表示例） &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;pi@node01:~ $ &lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo kubeadm init --apiserver-advertise-address=192.168.11.201 --pod-network-cidr=10.244.0.0/16&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;[init] Using Kubernetes version: v1.26.1&lt;br /&gt;[preflight] Running pre-flight checks&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING SystemVerification]: missing optional cgroups: hugetlb&lt;br /&gt;[preflight] Pulling images required for setting up a Kubernetes cluster&lt;br /&gt;[preflight] This might take a minute or two, depending on the speed of your internet connection&lt;br /&gt;[preflight] You can also perform this action in beforehand using &#39;kubeadm config images pull&#39;&lt;br /&gt;[certs] Using certificateDir folder &quot;/etc/kubernetes/pki&quot;&lt;br /&gt;[certs] Generating &quot;ca&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;apiserver&quot; certificate and key&lt;br /&gt;[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local node01] and IPs [10.96.0.1 XXX.YYY.ZZZ.201]&lt;br /&gt;[certs] Generating &quot;apiserver-kubelet-client&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;front-proxy-ca&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;front-proxy-client&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;etcd/ca&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;etcd/server&quot; certificate and key&lt;br /&gt;[certs] etcd/server serving cert is signed for DNS names [localhost node01] and IPs [192.168.11.201 127.0.0.1 ::1]&lt;br /&gt;[certs] Generating &quot;etcd/peer&quot; certificate and key&lt;br /&gt;[certs] etcd/peer serving cert is signed for DNS names [localhost node01] and IPs [192.168.11.201 127.0.0.1 ::1]&lt;br /&gt;[certs] Generating &quot;etcd/healthcheck-client&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;apiserver-etcd-client&quot; certificate and key&lt;br /&gt;[certs] Generating &quot;sa&quot; key and public key&lt;br /&gt;[kubeconfig] Using kubeconfig folder &quot;/etc/kubernetes&quot;&lt;br /&gt;[kubeconfig] Writing &quot;admin.conf&quot; kubeconfig file&lt;br /&gt;[kubeconfig] Writing &quot;kubelet.conf&quot; kubeconfig file&lt;br /&gt;[kubeconfig] Writing &quot;controller-manager.conf&quot; kubeconfig file&lt;br /&gt;[kubeconfig] Writing &quot;scheduler.conf&quot; kubeconfig file&lt;br /&gt;[kubelet-start] Writing kubelet environment file with flags to file &quot;/var/lib/kubelet/kubeadm-flags.env&quot;&lt;br /&gt;[kubelet-start] Writing kubelet configuration to file &quot;/var/lib/kubelet/config.yaml&quot;&lt;br /&gt;[kubelet-start] Starting the kubelet&lt;br /&gt;[control-plane] Using manifest folder &quot;/etc/kubernetes/manifests&quot;&lt;br /&gt;[control-plane] Creating static Pod manifest for &quot;kube-apiserver&quot;&lt;br /&gt;[control-plane] Creating static Pod manifest for &quot;kube-controller-manager&quot;&lt;br /&gt;[control-plane] Creating static Pod manifest for &quot;kube-scheduler&quot;&lt;br /&gt;[etcd] Creating static Pod manifest for local etcd in &quot;/etc/kubernetes/manifests&quot;&lt;br /&gt;[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory &quot;/etc/kubernetes/manifests&quot;. This can take up to 4m0s&lt;br /&gt;[apiclient] All control plane components are healthy after 34.004780 seconds&lt;br /&gt;[upload-config] Storing the configuration used in ConfigMap &quot;kubeadm-config&quot; in the &quot;kube-system&quot; Namespace&lt;br /&gt;[kubelet] Creating a ConfigMap &quot;kubelet-config&quot; in namespace kube-system with the configuration for the kubelets in the cluster&lt;br /&gt;[upload-certs] Skipping phase. Please see --upload-certs&lt;br /&gt;[mark-control-plane] Marking the node node01 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]&lt;br /&gt;[mark-control-plane] Marking the node node01 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]&lt;br /&gt;[bootstrap-token] Using token: xua9wk.gwe59et1dix4dw1q&lt;br /&gt;[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles&lt;br /&gt;[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes&lt;br /&gt;[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials&lt;br /&gt;[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token&lt;br /&gt;[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster&lt;br /&gt;[bootstrap-token] Creating the &quot;cluster-info&quot; ConfigMap in the &quot;kube-public&quot; namespace&lt;br /&gt;[kubelet-finalize] Updating &quot;/etc/kubernetes/kubelet.conf&quot; to point to a rotatable kubelet client certificate and key&lt;br /&gt;[addons] Applied essential addon: CoreDNS&lt;br /&gt;[addons] Applied essential addon: kube-proxy&lt;br /&gt;&lt;br /&gt;Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;&lt;br /&gt;To start using your cluster, you need to run the following as a regular user:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&amp;nbsp; mkdir -p $HOME/.kube&lt;br /&gt;&amp;nbsp; sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;&amp;nbsp; sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;Alternatively, if you are the root user, you can run:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;&lt;br /&gt;You should now deploy a pod network to the cluster.&lt;br /&gt;Run &quot;kubectl apply -f [podnetwork].yaml&quot; with one of the options listed at:&lt;br /&gt;&amp;nbsp; https://kubernetes.io/docs/concepts/cluster-administration/addons/&lt;br /&gt;&lt;br /&gt;Then you can join any number of worker nodes by running the following on each as root:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;kubeadm join 192.168.11.201:6443 --token xua9wk.gwe59et1dix4dw1q \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:4775e46c92965e5fc383731aa58429bb1d1246af22e85768bf8474f5869a4666&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;config 設定&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;node01 にて以下のコマンドを実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;mkdir -p $HOME/.kube&lt;br /&gt;sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;以降、node01では &lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;なして &lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;kubectl&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;が実行可能になる&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;ワーカーノードの設定&lt;/h1&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;ワーカーノードのjoin&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;全ワーカーノードに対して、先の &lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;kubeadm init&lt;/span&gt;&lt;/span&gt; コマンド実行結果最後に表示されたコマンドを &lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo &lt;/span&gt;&lt;/span&gt;をつけて実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;sudo kubeadm join 192.168.11.201:6443 --token xua9wk.gwe59et1dix4dw1q \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:4775e46c92965e5fc383731aa58429bb1d1246af22e85768bf8474f5869a4666&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;マスターノードにて &lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;kubectl get nodes&lt;/span&gt;&lt;/span&gt; を実行し、全ワーカーノードがReadyであることを確認（以下、実行例）&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;pi@node01:~ $ &lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;kubectl get nodes&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp; ROLES&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AGE&amp;nbsp;&amp;nbsp;&amp;nbsp; VERSION&lt;br /&gt;node01&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; control-plane&amp;nbsp;&amp;nbsp; 3m7s&amp;nbsp;&amp;nbsp; v1.26.1&lt;br /&gt;node02&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;none&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 111s&amp;nbsp;&amp;nbsp; v1.26.1&lt;br /&gt;node03&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;none&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 74s&amp;nbsp;&amp;nbsp;&amp;nbsp; v1.26.1&lt;br /&gt;node04&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;none&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 72s&amp;nbsp;&amp;nbsp;&amp;nbsp; v1.26.1&lt;br /&gt;pi@node01:~ $&lt;/span&gt; &lt;span style=&quot;color: #2b00fe;&quot;&gt;kubectl get pod -A&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;NAMESPACE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; READY&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp; RESTARTS&amp;nbsp;&amp;nbsp; AGE&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; coredns-787d4945fb-6brdq&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m38s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; coredns-787d4945fb-fm7bs&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m38s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; etcd-node01&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m49s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-apiserver-node01&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m49s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-controller-manager-node01&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m53s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-proxy-254ht&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m38s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-proxy-9dtjv&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2m38s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-proxy-p9qmf&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2m1s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-proxy-q24qn&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 119s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp; kube-scheduler-node01&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3m49s&lt;br /&gt;pi@node01:~ $&lt;/span&gt; &lt;span style=&quot;color: #2b00fe;&quot;&gt;kubectl get ns -A&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp; AGE&lt;br /&gt;default&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Active&amp;nbsp;&amp;nbsp; 4m12s&lt;br /&gt;kube-node-lease&amp;nbsp;&amp;nbsp; Active&amp;nbsp;&amp;nbsp; 4m14s&lt;br /&gt;kube-public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Active&amp;nbsp;&amp;nbsp; 4m14s&lt;br /&gt;kube-system&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Active&amp;nbsp;&amp;nbsp; 4m14s&lt;br /&gt;pi@node01:~ $&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;strike&gt;Flannelのインストール&lt;/strike&gt;&lt;/h2&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;strike&gt;コントロールプレーンノード(node01)上にて、以下のコマンドを実行し最新版の &lt;a href=&quot;https://github.com/flannel-io/flannel#deploying-flannel-manually&quot; target=&quot;_blank&quot;&gt;Flannel &lt;/a&gt;をデプロイする。&lt;/strike&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;strike&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;pi@node01:~ $&lt;/span&gt; &lt;span style=&quot;color: #2b00fe;&quot;&gt;kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;namespace/kube-flannel created&lt;br /&gt;serviceaccount/flannel created&lt;br /&gt;clusterrole.rbac.authorization.k8s.io/flannel created&lt;br /&gt;clusterrolebinding.rbac.authorization.k8s.io/flannel created&lt;br /&gt;configmap/kube-flannel-cfg created&lt;br /&gt;daemonset.apps/kube-flannel-ds created&lt;br /&gt;pi@node01:~ $&lt;/span&gt;&lt;/span&gt;&lt;/strike&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;strike&gt;&lt;u&gt;PodのCIDR指定を10.244.0.0/16以外にした場合、直接kubectl applyしないで、node01上にyamlをcurl保管してネットワーク指定を変更する必要がある&lt;/u&gt;、と&lt;a href=&quot;https://github.com/flannel-io/flannel&quot; target=&quot;_blank&quot;&gt;flannelドキュメント&lt;/a&gt;にかかれている。 &lt;/strike&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;2023/2/15 注記：&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: red;&quot;&gt;ワーカノード（Raspberry Pi 3B+）を参加(&lt;span style=&quot;font-family: courier;&quot;&gt;kubeadm join&lt;/span&gt;)させた状態で、flannelを以下の手順で&lt;span style=&quot;font-family: courier;&quot;&gt;kubectl apply&lt;/span&gt;すると、 OSが突然落ちます&lt;/span&gt;。&lt;span style=&quot;font-family: courier;&quot;&gt;kubectl delete&lt;/span&gt;して、ワーカノードを再起動すると動作します。&lt;/p&gt;&lt;p&gt;flannelは全ワーカノードにコンテナをあげるので、おそらくメモリ1GBだとそれらを上げきることはできないのだとおもいます。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;strike&gt;Swapの再有効化&lt;/strike&gt;&lt;/h2&gt;&lt;p&gt;&lt;strike&gt;Swapを無効化するのは、Kubernetesをインストールする際の前提となっている。しかし今回のワーカノードはRaspberry Pi 3B+なので、メモリが1GBしかない。&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;なのでここでは&lt;u&gt;ワーカノードだけ&lt;/u&gt;Swapを再有効化しておく。&lt;/strike&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;strike&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo vi /var/lib/kubelet/config.yaml&lt;/span&gt;&lt;/span&gt; を実行し、最終行に以下の行を追加、保存&lt;/strike&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;strike&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;failSwapOn: false&lt;/span&gt;&lt;/strike&gt;&lt;/blockquote&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;strike&gt;以下のコマンドを実行する&lt;/strike&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;strike&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;sudo systemctl daemon-reload&lt;br /&gt;sudo systemctl enable dphys-swapfile&lt;br /&gt;sudo systemctl start dphys-swapfile&lt;br /&gt;sudo systemctl restart kubelet&lt;/span&gt;&lt;/span&gt;&lt;/strike&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;2023/2/15 追記：&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: red;&quot;&gt;ワーカノードのSwapを再度有効化した状態でkubeadm joinをかけると&lt;/span&gt;以下のようなエラーがでて&lt;span style=&quot;color: red;&quot;&gt;動作しません&lt;/span&gt;でした。&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;pi@node02:~ $ sudo kubeadm join 192.168.11.201:6443 --token 0hfvvz.63g939bbbv4iuoqz \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:e4fad29f4cadb1fc68464bbae4767e18766365d1fa8c46678301c26a1f0911c7&lt;br /&gt;[preflight] Running pre-flight checks&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING Swap]: swap is enabled; production deployments should disable swap unless testing the NodeSwap feature gate of the kubelet&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING SystemVerification]: missing optional cgroups: hugetlb&lt;br /&gt;[preflight] Reading configuration from the cluster...&lt;br /&gt;[preflight] FYI: You can look at this config file with &#39;kubectl -n kube-system get cm kubeadm-config -o yaml&#39;&lt;br /&gt;[kubelet-start] Writing kubelet configuration to file &quot;/var/lib/kubelet/config.yaml&quot;&lt;br /&gt;[kubelet-start] Writing kubelet environment file with flags to file &quot;/var/lib/kubelet/kubeadm-flags.env&quot;&lt;br /&gt;[kubelet-start] Starting the kubelet&lt;br /&gt;[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...&lt;br /&gt;[kubelet-check] Initial timeout of 40s passed.&lt;br /&gt;[kubelet-check] It seems like the kubelet isn&#39;t running or healthy.&lt;br /&gt;[kubelet-check] The HTTP call equal to &#39;curl -sSL http://localhost:10248/healthz&#39; failed with error: Get &quot;http://localhost:10248/healthz&quot;: dial tcp [::1]:10248: connect: connection refused.&lt;br /&gt;[kubelet-check] It seems like the kubelet isn&#39;t running or healthy.&lt;br /&gt;[kubelet-check] The HTTP call equal to &#39;curl -sSL http://localhost:10248/healthz&#39; failed with error: Get &quot;http://localhost:10248/healthz&quot;: dial tcp [::1]:10248: connect: connection refused.&lt;br /&gt;[kubelet-check] It seems like the kubelet isn&#39;t running or healthy.&lt;br /&gt;[kubelet-check] The HTTP call equal to &#39;curl -sSL http://localhost:10248/healthz&#39; failed with error: Get &quot;http://localhost:10248/healthz&quot;: dial tcp [::1]:10248: connect: connection refused.&lt;br /&gt;[kubelet-check] It seems like the kubelet isn&#39;t running or healthy.&lt;br /&gt;[kubelet-check] The HTTP call equal to &#39;curl -sSL http://localhost:10248/healthz&#39; failed with error: Get &quot;http://localhost:10248/healthz&quot;: dial tcp [::1]:10248: connect: connection refused.&lt;br /&gt;[kubelet-check] It seems like the kubelet isn&#39;t running or healthy.&lt;br /&gt;[kubelet-check] The HTTP call equal to &#39;curl -sSL http://localhost:10248/healthz&#39; failed with error: Get &quot;http://localhost:10248/healthz&quot;: dial tcp [::1]:10248: connect: connection refused.&lt;br /&gt;&lt;br /&gt;Unfortunately, an error has occurred:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; timed out waiting for the condition&lt;br /&gt;&lt;br /&gt;This error is likely caused by:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - The kubelet is not running&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)&lt;br /&gt;&lt;br /&gt;If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &#39;systemctl status kubelet&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &#39;journalctl -xeu kubelet&#39;&lt;br /&gt;error execution phase kubelet-start: timed out waiting for the condition&lt;br /&gt;To see the stack trace of this error execute with --v=5 or higher&lt;/span&gt;&lt;/p&gt;&lt;p&gt;このあとSwap無効化して&lt;span style=&quot;font-family: courier;&quot;&gt;kubeadm reset&lt;/span&gt;したあと、再度&lt;span style=&quot;font-family: courier;&quot;&gt;kubeadm join&lt;/span&gt;したら&lt;span style=&quot;font-family: courier;&quot;&gt;kubectl get node&lt;/span&gt;にReadyで登場するようになりました。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;以上&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Dockerの場合、ネットワークを管理するコンテナを隠しでいれてくれているので、意識しなくても良かったが、Kubernetesの場合はインストールする側がきちんと選んでインストールしないといけない。ドキュメントによると、ネットワークポリシーを適用するCalicoなどがあるが、このあたりはサードパーティ製になるので、Kubernetesの責務の外というかんじのようだ。&lt;/p&gt;&lt;p&gt;CloudStackやOpenStack、Docker (Swarm)と学習していると、オーケストレーションを実現する思想的なものの違いがなんとなく見えてくる。こういったソフトウェアの責任範囲の切り分けがどこにあるかを見極められると、理解が少し早くなるのだと思う。&lt;/p&gt;&lt;p&gt;&amp;nbsp;再度書きますが、Raspberry Pi 3B+ をkubernetesクラスタに加えることは、ほぼできないと考えておいたほうが良いです。インストールはできますが、それまでです。書籍の学習でちょっとうごかしてみよう的な環境でも落ちるかもしれません。そうしたらsyslogやjouralctlとにらめっこが始まってしまい、学習は中断..という風になるでしょう。そういう場合はDocker Desktop(いつまでKubernetesが動くか..)や&lt;a href=&quot;https://speakerdeck.com/coolerking/play-with-kubernetes-hazimeniyarukoto&quot; target=&quot;_blank&quot;&gt;play with kubernetes 環境&lt;/a&gt;(いつまで..再び)を使いましょう。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/1118392674195796582/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/1118392674195796582' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/1118392674195796582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/1118392674195796582'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2023/02/raspberry-pi-os-bullseye64bit-kubernetes.html' title='Raspberry Pi OS bullseye/64bit を使って Kubernetes クラスタを構築'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNDWqZQjCgxFl1ckPxE8K-C_rj3CMuIcI4-h6o-Qn-EMD8DBCzXq_PWbBUZ29DDBoDx6Cotb_CDD9ot8VVMYASIoAKTutLJsW-XYZmqGsAL0YxRAM3JTsrWxcfqtB8mJcm3MLim0j3tpYB5xY51WAIJNkig6lyjRaCafeWqJWtGp2KX7aLI28TBYBrpg/s72-c/k8s_pi_hardwares.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-5186804900942679203</id><published>2023-01-26T15:09:00.040+09:00</published><updated>2023-02-21T11:38:30.933+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Kubernetes"/><title type='text'>Play with Kubernetes 上でPodをcreateしてもPendingのままになる</title><content type='html'>&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;nbsp;Kubernetes を勉強す&lt;span style=&quot;font-family: courier;&quot;&gt;るとき、Docker DesktopをローカルPCにいれたり、Minikubeをインストールしたりするが、会社のルールでローカルPCにDockerや仮想マシンをインストール出来ない場合がある。&lt;br /&gt;&lt;br /&gt;そういったときにPlay with Kubernetes &lt;a href=&quot;https://labs.play-with-k8s.com/&quot;&gt;https://labs.play-with-k8s.com/&lt;/a&gt; を使う（&lt;br /&gt;ログインするにはGitHubもしくはDockerHubのアカウントを作成しておく必要がある）。&lt;br /&gt;&lt;br /&gt;Loginした状態になると、記事執筆時点(2023/1/26)では４時間だけ使用可能な環境が与えられる。&lt;br /&gt;&lt;br /&gt;ADD NEW INSTANCE を押すと以下のメッセージが表示されたコンソール画面が表示される。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WARNING!!!!&lt;br /&gt;&lt;br /&gt;&amp;nbsp;This is a sandbox environment. Using personal credentials&lt;br /&gt;&amp;nbsp;is HIGHLY! discouraged. Any consequences of doing so, are&lt;br /&gt;&amp;nbsp;completely the user&#39;s responsibilites.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;You can bootstrap a cluster as follows:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;1. Initializes cluster master node:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;kubeadm init --apiserver-advertise-address $(hostname -i) --pod-network-cidr 10.5.0.0/16&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;2. Initialize cluster networking:&lt;br /&gt;&lt;br /&gt;kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/kubeadm-kuberouter.yaml&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;3. (Optional) Create an nginx deployment:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx-app.yaml&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The PWK team.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;（日本語訳）&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 警告!!!!&lt;br /&gt;&lt;br /&gt;&amp;nbsp;これはサンドボックス環境です。個人の認証情報を使用することは非常にお勧めできません。そうすることで生じるいかなる結果も、完全にユーザの責任となります。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;以下の手順でクラスタをブートストラップできます。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;1. クラスタマスタノードを初期化します。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;kubeadm init --apiserver-advertise-address $(hostname -i) --pod-network-cidr 10.5.0.0/16&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;2. クラスタネットワーキングを初期化します。&lt;br /&gt;&lt;br /&gt;kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/kubeadm-kuberouter.yaml&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;3.オプション）nginxのDeploymentを作成します。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx-app.yaml&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PWKチーム&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3はオプションになっているけど、nginxが動作した状態になるので、きちんとKubernetes環境がPlay with Kubernetes上に作れているかを確認する場合は3も実行する。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;だがノードを１つ作成し、そのまま手順に従って１から３の順にコマンドをコピペ実行して &lt;span style=&quot;font-family: courier;&quot;&gt;kubectl get pod &lt;/span&gt;してみるが、3で作成されたはずのnginxがPendingのままになる..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;これはmasterノードだけしか作成されていないためで、別途workerノードを1つ以上つくっておかないといけない。&lt;br /&gt;&lt;br /&gt;なのでログインしたら、&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ADD NEW INSTANCE を押し、node1を作成&lt;/li&gt;&lt;li&gt;ADD NEW INSTANCE を押し、node2を作成&lt;/li&gt;&lt;li&gt;node1のコンソール画面で1を実行(ex. kubeadm init --apiserver-advertise-address $(hostname -i) --pod-network-cidr 10.5.0.0/16)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;:&lt;/span&gt; &lt;br /&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;[addons] Applied essential addon: CoreDNS&lt;br /&gt;[addons] Applied essential addon: kube-proxy&lt;br /&gt;&lt;br /&gt;Your Kubernetes control-plane has initialized successfully!&lt;br /&gt;&lt;br /&gt;To start using your cluster, you need to run the following as a regular user:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mkdir -p $HOME/.kube&lt;br /&gt;&amp;nbsp; sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;&amp;nbsp; sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;&lt;br /&gt;Alternatively, if you are the root user, you can run:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; export KUBECONFIG=/etc/kubernetes/admin.conf&lt;br /&gt;&lt;br /&gt;You should now deploy a pod network to the cluster.&lt;br /&gt;Run &quot;kubectl apply -f [podnetwork].yaml&quot; with one of the options listed at:&lt;br /&gt;&amp;nbsp; https://kubernetes.io/docs/concepts/cluster-administration/addons/&lt;br /&gt;&lt;br /&gt;Then you can join any number of worker nodes by running the following on each as root:&lt;br /&gt;&lt;br /&gt;kubeadm join 192.168.0.X:6443 --token XXXX...XXX \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:XXXX...XXX &lt;br /&gt;Waiting for api server to startup&lt;br /&gt;Warning: resource daemonsets/kube-proxy is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.&lt;br /&gt;daemonset.apps/kube-proxy configured&lt;br /&gt;No resources found&lt;br /&gt;[node1 ~]$ &lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;（日本語訳）&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;:&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;Kubernetesのコントロールプレーンが正常に初期化されました!&lt;br /&gt;&lt;br /&gt;クラスタの利用を開始するには、一般ユーザで以下を実行する必要があります。&lt;br /&gt;&lt;br /&gt;&amp;nbsp; mkdir -p $HOME/.kube&lt;br /&gt;&amp;nbsp; sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br /&gt;&amp;nbsp; sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;br /&gt;&lt;br /&gt;また、rootユーザの場合は、以下のように実行します。&lt;br /&gt;&lt;br /&gt;&amp;nbsp; export KUBECONFIG=/etc/kubernetes/admin.conf を実行します。&lt;br /&gt;&lt;br /&gt;これで、クラスタにポッドネットワークがデプロイされました。&lt;br /&gt;kubectl apply -f [podnetwork].yaml &quot;を、以下に記載されているいずれかのオプションで実行します。&lt;br /&gt;&amp;nbsp; https://kubernetes.io/docs/concepts/cluster-administration/addons/&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: red;&quot;&gt;次に、ワーカーノード上でrootとして以下を実行することで、任意の数のワーカーノードに参加することができます。&lt;br /&gt;&lt;br /&gt;kubeadm join 192.168.0.X:6443 --token XXXX....XXXX \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:XXXX...XXX&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;apiサーバーの起動を待っています&lt;br /&gt;警告: リソース daemonsets/kube-proxy には、kubectl apply で必要とされる kubectl.kubernetes.io/last-applied-configuration アノテーションがありません。kubectl apply は kubectl create --save-config または kubectl apply によって declaratively に作成したリソースに対してのみ使用されるべきものです。不足するアノテーションは自動的にパッチが適用されます。&lt;br /&gt;daemonset.apps/kube-proxyが設定されています。&lt;br /&gt;リソースが見つかりません &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;実行メッセージ内の以下の箇所をコピー&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;kubeadm join 192.168.0.X:6443 --token XXXXXXX...XXX \&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --discovery-token-ca-cert-hash sha256:XXXXXX....XXXX&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;node2 のコンソール画面に移動し、コピーした&lt;span style=&quot;font-family: courier;&quot;&gt;kubeadm&lt;/span&gt;コマンドを実行&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;&amp;nbsp;[node2 ~]$ &lt;span style=&quot;color: #01ffff;&quot;&gt;kubeadm join 192.168.0.X:6443 --token XXX...XXX&amp;nbsp; --discovery-token-ca-cert-hash sha256:XXXXXX....XXXXX&lt;/span&gt;&lt;br /&gt;Initializing machine ID from random generator.&lt;br /&gt;[preflight] Running pre-flight checks&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING Service-Docker]: docker service is not active, please run &#39;systemctl start docker.service&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING IsDockerSystemdCheck]: detected &quot;cgroupfs&quot; as the Docker cgroup driver. The recommended driver is &quot;systemd&quot;. Please follow the guide at https://kubernetes.io/docs/setup/cri/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables does not exist&lt;br /&gt;[preflight] The system verification failed. Printing the output from the verification:&lt;br /&gt;KERNEL_VERSION: 4.4.0-210-generic&lt;br /&gt;DOCKER_VERSION: 20.10.1&lt;br /&gt;OS: Linux&lt;br /&gt;CGROUPS_CPU: enabled&lt;br /&gt;CGROUPS_CPUACCT: enabled&lt;br /&gt;CGROUPS_CPUSET: enabled&lt;br /&gt;CGROUPS_DEVICES: enabled&lt;br /&gt;CGROUPS_FREEZER: enabled&lt;br /&gt;CGROUPS_MEMORY: enabled&lt;br /&gt;CGROUPS_PIDS: enabled&lt;br /&gt;CGROUPS_HUGETLB: enabled&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING SystemVerification]: this Docker version is not on the list of validated versions: 20.10.1. Latest validated version: 19.03&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [WARNING SystemVerification]: failed to parse kernel config: unable to load kernel module: &quot;configs&quot;, output: &quot;&quot;, err: exit status 1&lt;br /&gt;[preflight] Reading configuration from the cluster...&lt;br /&gt;[preflight] FYI: You can look at this config file with &#39;kubectl -n kube-system get cm kubeadm-config -o yaml&#39;&lt;br /&gt;[kubelet-start] Writing kubelet configuration to file &quot;/var/lib/kubelet/config.yaml&quot;&lt;br /&gt;[kubelet-start] Writing kubelet environment file with flags to file &quot;/var/lib/kubelet/kubeadm-flags.env&quot;&lt;br /&gt;[kubelet-start] Starting the kubelet&lt;br /&gt;[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...&lt;br /&gt;&lt;br /&gt;This node has joined the cluster:&lt;br /&gt;* Certificate signing request was sent to apiserver and a response was received.&lt;br /&gt;* The Kubelet was informed of the new secure connection details.&lt;br /&gt;&lt;br /&gt;Run &#39;kubectl get nodes&#39; on the control-plane to see this node join the cluster.&lt;br /&gt;&lt;br /&gt;（日本語訳）&lt;br /&gt;このノードはクラスタに参加しました。&lt;br /&gt;* 証明書署名要求が apiserver に送信され、応答が受信されました。&lt;br /&gt;* Kubeletに新しいセキュアな接続の詳細が通知されました。&lt;br /&gt;&lt;br /&gt;control-plane の &#39;kubectl get nodes&#39; を実行して、このノードがクラスタに参加したことを確認します。 &lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;node1 にもどり &lt;span style=&quot;font-family: courier;&quot;&gt;kubectl get nodes&lt;/span&gt; でmaster以外のノードnode2が追加されていることを確認&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;このあとnode1で2と3を実行し &lt;span style=&quot;font-family: courier;&quot;&gt;kubectl get pod&lt;/span&gt; すれば Pending ではなく Ready になる。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;[node1 ~]$ kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/kubeadm-kuberouter.yaml&lt;br /&gt;configmap/kube-router-cfg created&lt;br /&gt;daemonset.apps/kube-router created&lt;br /&gt;serviceaccount/kube-router created&lt;br /&gt;clusterrole.rbac.authorization.k8s.io/kube-router created&lt;br /&gt;clusterrolebinding.rbac.authorization.k8s.io/kube-router created&lt;br /&gt;[node1 ~]$ kubectl get nodes&lt;br /&gt;NAME&amp;nbsp;&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ROLES&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AGE&amp;nbsp;&amp;nbsp;&amp;nbsp; VERSION&lt;br /&gt;node1&amp;nbsp;&amp;nbsp; NotReady&amp;nbsp;&amp;nbsp; control-plane,master&amp;nbsp;&amp;nbsp; 12m&amp;nbsp;&amp;nbsp;&amp;nbsp; v1.20.1&lt;br /&gt;node2&amp;nbsp;&amp;nbsp; NotReady&amp;nbsp;&amp;nbsp; &amp;lt;none&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5m1s&amp;nbsp;&amp;nbsp; v1.20.1&lt;br /&gt;[node1 ~]$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx-app.yaml&lt;br /&gt;service/my-nginx-svc created&lt;br /&gt;deployment.apps/my-nginx created&lt;br /&gt;[node1 ~]$ kubectl get nodes&lt;br /&gt;NAME&amp;nbsp;&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp; ROLES&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VERSION&lt;br /&gt;node1&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; control-plane,master&amp;nbsp;&amp;nbsp; 12m&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v1.20.1&lt;br /&gt;node2&amp;nbsp;&amp;nbsp; Ready&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;none&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5m28s&amp;nbsp;&amp;nbsp; v1.20.1&lt;br /&gt;[node1 ~]$ kubectl get pod&lt;br /&gt;NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; READY&amp;nbsp;&amp;nbsp; STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp; RESTARTS&amp;nbsp;&amp;nbsp; AGE&lt;br /&gt;my-nginx-66b6c48dd5-kwx58&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34m&lt;br /&gt;my-nginx-66b6c48dd5-qw9zf&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34m&lt;br /&gt;my-nginx-66b6c48dd5-r7n5p&amp;nbsp;&amp;nbsp; 1/1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Running&amp;nbsp;&amp;nbsp; 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34m&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt; Play with Kubernetes環境は、使用中もとても遅くなることがあり、Pendingになっている時間が結構かかる場合もある。なのでゆっくりめのトイレタイムをあけて再度kubectl get podすると動いている場合がある。自分はだめな場合と判断しているのは、２トイレタイムくらい間を空けてだめなときだ。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;Play with Kubernetes 環境はおそすぎてADD NEW INSTANCEしても無視することがある。そういった場合はセッションをCLOSEしてしばらく待ってから再度Loginしてみる。&lt;/div&gt;&lt;div&gt;３０分後くらいには普通の動作に戻ることもあるし、１日だめなばあいもある。&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;いらいらいすることもあるけど、無料で使わせていただいている身なので、ありがたく使わせていただいている。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ｐｓ&lt;/p&gt;&lt;p&gt;Speaker Deckに「&lt;a href=&quot;https://speakerdeck.com/coolerking/play-with-kubernetes-hazimeniyarukoto&quot; target=&quot;_blank&quot;&gt;Play with Kubernetesはじめにやること&lt;/a&gt;」というスライドを投稿しました。初心者でもできるように一挙手一投足をスライドにしています。ご笑覧ください。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;ｐs2&lt;/p&gt;&lt;p&gt;..にしてもよく落ちる..&lt;/p&gt;&lt;p&gt;Killacodaの&lt;a href=&quot;https://killercoda.com/kubecon&quot; target=&quot;_blank&quot;&gt;k8s playground&lt;/a&gt;にしようかな..&amp;nbsp;&lt;/p&gt;&lt;p&gt;でも、こっちはexposeしたサービスを外部からみれないし、60分だし..&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/5186804900942679203/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/5186804900942679203' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5186804900942679203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/5186804900942679203'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2023/01/docker-desktoppcminikubepcdocker-play.html' title='Play with Kubernetes 上でPodをcreateしてもPendingのままになる'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2816846411346017602.post-652653585916529428</id><published>2022-12-29T10:40:00.001+09:00</published><updated>2022-12-29T10:40:50.964+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Geo JSON"/><category scheme="http://www.blogger.com/atom/ns#" term="geopandas"/><category scheme="http://www.blogger.com/atom/ns#" term="GISデータ"/><category scheme="http://www.blogger.com/atom/ns#" term="GML"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="地理空間データ"/><category scheme="http://www.blogger.com/atom/ns#" term="基盤地図情報"/><title type='text'> 国土地理院 基盤地図情報数値標高モデルをGeoJSON化する</title><content type='html'>&lt;p style=&quot;text-align: left;&quot;&gt;国土地理院は、日本のすべての測量の基礎となる基本測量を行う国交省の特別機関です。&lt;br /&gt;国土地理院ではいろんなデータを公開しているのですが、そのなかでも地図作成の基本となるデータ「基盤地図情報」がダウンロード可能になっています。&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5sCA6BlkNm7U5rFcNOjHm3jQ6z_Hl790XLjlUySkDQu-K-lrbgzVyfmROHyKJHBgDO1oR5LQQGmN0dd-LfpIucBQ5zCelR5WPc8jsmYZjV_8QQfnCXdccfwV_DeRtv5NPX-8dsCHht6S1oWVtsQ45pknSR6xihmbG-j4NYOMWF90FYX5Ndf5RJn6qMA/s500/site.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;399&quot; data-original-width=&quot;500&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5sCA6BlkNm7U5rFcNOjHm3jQ6z_Hl790XLjlUySkDQu-K-lrbgzVyfmROHyKJHBgDO1oR5LQQGmN0dd-LfpIucBQ5zCelR5WPc8jsmYZjV_8QQfnCXdccfwV_DeRtv5NPX-8dsCHht6S1oWVtsQ45pknSR6xihmbG-j4NYOMWF90FYX5Ndf5RJn6qMA/s320/site.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;br /&gt;Google MapやYahoo地図だけでなくOpenStreetMapなどXYZタイルをWeb APIで取得できるようになっているので、正直地図をイチから作成することはあまりなかったことですが、近年の機械学習のヒットで地図情報も入力データとして扱うようになってきました。&lt;br /&gt;&lt;br /&gt;ただ基盤地図情報からダウンロードできるデータは、GML、XML、Shape、ASCIIといった形式で、TensorFlow/PyTorchの入力データ化するには、事前の処理としてのパースがどうしても必要になります。&lt;br /&gt;&lt;br /&gt;基盤地図情報は以下の３つの種類にわかれています。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;基本項目&lt;/li&gt;&lt;li&gt;数値標高モデル&lt;/li&gt;&lt;li&gt;ジオイド・モデル&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;このうち、一番利用されるのが基本項目。道路や鉄道、海取り口の境界線、建物などがGML形式になっています。ダウンロードできるファイルの種類が多く、それぞれの種類で比空間データの属性がことなるため厄介です。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHe6fJ1Ik4zQMsaI3O4PIOfzY6bUoyewpcqhZ-RreyOWxrJ-GDcq8LjcyNXnc-Jlb02UvuYCk7waPOVPGRgqaqUuHN_F5JVgUly26OmrL5h0F6wug7ienAUII8pVENUg9gZZoMMhvvlJtW5VFG4Cn9IQ3dCrv1vqLPeAZYaFmoKGwcAS6S-en7kfGGMA/s1197/basic_kinds.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;594&quot; data-original-width=&quot;1197&quot; height=&quot;159&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHe6fJ1Ik4zQMsaI3O4PIOfzY6bUoyewpcqhZ-RreyOWxrJ-GDcq8LjcyNXnc-Jlb02UvuYCk7waPOVPGRgqaqUuHN_F5JVgUly26OmrL5h0F6wug7ienAUII8pVENUg9gZZoMMhvvlJtW5VFG4Cn9IQ3dCrv1vqLPeAZYaFmoKGwcAS6S-en7kfGGMA/s320/basic_kinds.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;ただ、Python geopandasにある&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;read_file()&lt;/span&gt;&lt;/span&gt;を使えば簡単に&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;GeoDataFrame&lt;/span&gt;&lt;/span&gt;化できるので、パースは簡単です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9d9WTcy9QkCFn4LILZEhfAkcDO2M7J1aL2ciLpy5JkDUlTkghT8Oj3kViuUX1PBQZj0Ed5J7BZKXzxB5F03A6XPOGNtP5eWdj4IazUdMGHm-jmXMGFM08iGSL6RB9wkpQLoP70vCL7Iiu9ViGjaN3U0v3FXTMtyCJ-ado7NG2-QUXcqaE4MuLFFEtWA/s1154/basic.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;507&quot; data-original-width=&quot;1154&quot; height=&quot;141&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9d9WTcy9QkCFn4LILZEhfAkcDO2M7J1aL2ciLpy5JkDUlTkghT8Oj3kViuUX1PBQZj0Ed5J7BZKXzxB5F03A6XPOGNtP5eWdj4IazUdMGHm-jmXMGFM08iGSL6RB9wkpQLoP70vCL7Iiu9ViGjaN3U0v3FXTMtyCJ-ado7NG2-QUXcqaE4MuLFFEtWA/s320/basic.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;ジオイド・モデルはXMLかASCIIかのどちらかで、どちらも独自のパースが必要ですが、ASCII形式のデータが固定長なので、比較的実装はしやすいので、こちらも問題ないとおもいます。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuifIpc1CpbSu4OjbgwRfdbM3WsmT8AqqqQ_VtR-44jthTNUZ68BDr5pIXjDib3jfopsQsXkzzuuLr44v5mrLOBQO2iUDP3FW3h5346MGcyT8VhjNPFRGnLPuMYuhnh9TCPIQUZydzsOuaAEjZ1WUQO2mVQ9jtCuamzyYaMu8mUPH7JQ7JCQ9O9JjofQ/s764/geojson_sample.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;443&quot; data-original-width=&quot;764&quot; height=&quot;186&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuifIpc1CpbSu4OjbgwRfdbM3WsmT8AqqqQ_VtR-44jthTNUZ68BDr5pIXjDib3jfopsQsXkzzuuLr44v5mrLOBQO2iUDP3FW3h5346MGcyT8VhjNPFRGnLPuMYuhnh9TCPIQUZydzsOuaAEjZ1WUQO2mVQ9jtCuamzyYaMu8mUPH7JQ7JCQ9O9JjofQ/s320/geojson_sample.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;ただ、ジオイド・モデルの特性上、GPSの生データの標高補正か球体にテクスチャを貼り付けて地球の球面を表示する場合くらいにしか使い道がないので、必要になればその時実装すればいいだけだとおもいます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1m0HYB2q3JWlbF9y2x9R2ZydMFCU_kQytlvaa8DPqWcLhEfXop6qRQEmkhNHpDR2SPK0bNNSbVsYyFAGFLMoWIl6aDhQUdxzMM30ebUvEZfU8sHL4HvoUO7R6Z4CgQo0_SMorvvxtv54nzVegqCNrPRSgppWnWR3zVxpHZnbr-SghlxcAIpuR782WJQ/s682/geoid.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;682&quot; data-original-width=&quot;622&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1m0HYB2q3JWlbF9y2x9R2ZydMFCU_kQytlvaa8DPqWcLhEfXop6qRQEmkhNHpDR2SPK0bNNSbVsYyFAGFLMoWIl6aDhQUdxzMM30ebUvEZfU8sHL4HvoUO7R6Z4CgQo0_SMorvvxtv54nzVegqCNrPRSgppWnWR3zVxpHZnbr-SghlxcAIpuR782WJQ/s320/geoid.png&quot; width=&quot;292&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;数値標高モデルは、いわゆるDEM: Digital Elevation Model というやつで、日本の国土の地面の標高(m)を5m/10mメッシュ単位にまとめたもので、XML形式でダウンロードできます。&lt;br /&gt;この数値標高モデルのXMLはGMLベースですが、標高が格納されている要素内に直列でならんでいたり、ほかの要素や属性値を使わないときちんとデータとして使用できないので、しっかり仕様を読み込んでパース処理を実装しなくてはなりません。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieFadL-BK-zKtUozJBrELXstCmmc8J_Q4-Ns11tIM0QMH9mdNmf7-YjZO7waS2Ktftps623HNu-mg-hkJ5mYrod8EUW-sVe2DQZ70a6L-njSJQFK1laKtt2sFo67f9XbJIvamGL2d4N3b06Ag8XzUteWX2EtASZpkcFpvMxSV46wRhA1RUn9xjYITZ2Q/s1277/dem.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;641&quot; data-original-width=&quot;1277&quot; height=&quot;161&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieFadL-BK-zKtUozJBrELXstCmmc8J_Q4-Ns11tIM0QMH9mdNmf7-YjZO7waS2Ktftps623HNu-mg-hkJ5mYrod8EUW-sVe2DQZ70a6L-njSJQFK1laKtt2sFo67f9XbJIvamGL2d4N3b06Ag8XzUteWX2EtASZpkcFpvMxSV46wRhA1RUn9xjYITZ2Q/s320/dem.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;そこで、DEM(XMLファイル)を読み込み、GeoJSON化して出力する変換プログラムを作成しました。&lt;br /&gt;&lt;br /&gt;以下のGitHubリポジトリにおいてあるコードをおきました。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/coolerking/basemap/tree/main/dem&quot; target=&quot;_blank&quot;&gt;[GitHub] coolerking/basemap DEM&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;まず実行環境を作成します。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;conda create -n geo python numpy geopandas &lt;br /&gt;conda activate geo&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;リポジトリのクローンします。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;cd hogehoge&lt;br /&gt;git clone https://github.com/coolerking/basemap&lt;br /&gt;cd basemap/dem&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;download &lt;/span&gt;&lt;/span&gt;ファイルを作成し、基盤地図情報ダウンロードサイトから取ってきた数値標高モデルを取得、展開して対象のXMLをここに格納します。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;mkdir download&lt;br /&gt;# XMLファイルをdownloadディレクトリに格納する&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;models.py&lt;/span&gt;&lt;/span&gt; を実行します。&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;omit_no_data&lt;/span&gt;&lt;/span&gt;オプションをつけると、&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;-9999.0&lt;/span&gt;&lt;/span&gt;のデータをすべて削除します。&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&lt;blockquote&gt;python models.py --omit_no_data&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;作成されたGeoJSONはoutputディレクトリに格納されます。&lt;br /&gt;&lt;br /&gt;GeoJSONを確認したい場合は下図のように QGIS などの統合GISソフトウェアで読み込ませるか、GeoPandasの&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;GeoDataFrame&lt;/span&gt;&lt;/span&gt;化してから、&lt;span style=&quot;color: #01ffff;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;plot()&lt;/span&gt;&lt;/span&gt;すれば表示できます。&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil60fx6gz5aduFc20By2zu_emm27zBi3mCgmIcdMB-cSp0PuAixwG0f8X0faMxe7tLeb0VEX2lTQjU8FMovfdbfVeI947GjyIWyFuX3eZ3P7nEHlwQHUMfPE4ij34k1O9an_xeZM33EnvivxxwybXBRNOXg6ZtlbSy9mVpcgKTXcqdFWWTzWD6SyvMgA/s1917/qgis_dem_sample.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1036&quot; data-original-width=&quot;1917&quot; height=&quot;173&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil60fx6gz5aduFc20By2zu_emm27zBi3mCgmIcdMB-cSp0PuAixwG0f8X0faMxe7tLeb0VEX2lTQjU8FMovfdbfVeI947GjyIWyFuX3eZ3P7nEHlwQHUMfPE4ij34k1O9an_xeZM33EnvivxxwybXBRNOXg6ZtlbSy9mVpcgKTXcqdFWWTzWD6SyvMgA/s320/qgis_dem_sample.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;p.s.&lt;/p&gt;&lt;p&gt;国土地理院基盤地図情報については国土地理院サイトもしくは、以下のスライドを参考にしてみてください。&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/coolerking/guo-tu-di-li-yuan-ji-pan-di-tu-qing-bao-gis-detanoji-ben&quot; target=&quot;_blank&quot;&gt;国土地理院 基盤地図情報 ～GISデータの基本&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;複数の入手元から複数GISデータを統合してデータ分析する場合、測地座標系をあわせるという作業がとても厄介です。基盤地図情報はJGD2011v2.1(本記事執筆時点)ですが、GPSの測地系であるWGS84とは完全に一致しません。地図の世界では表示する縮尺によりこの精度を無視することがありますが、データ分析でどうするかはどのくらい誤差があるか、そもそもWGS84とはなにでJGD2011とはどうちがうのか、がわからないと正確に扱うことはできません。&lt;/p&gt;&lt;p&gt;まあ３０年くらい前の車載GPSのように海岸線を走っているのに画面では海の上にいることになっていたりするかもですが、そのあたりどう&quot;目をつぶるか&quot;がGISデータの取り回しする人間の裁量になってくるのでしょう。&amp;nbsp; &lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://fight-tsk.blogspot.com/feeds/652653585916529428/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/2816846411346017602/652653585916529428' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/652653585916529428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2816846411346017602/posts/default/652653585916529428'/><link rel='alternate' type='text/html' href='http://fight-tsk.blogspot.com/2022/12/geojson.html' title=' 国土地理院 基盤地図情報数値標高モデルをGeoJSON化する'/><author><name>ton</name><uri>http://www.blogger.com/profile/10940565614747629853</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5sCA6BlkNm7U5rFcNOjHm3jQ6z_Hl790XLjlUySkDQu-K-lrbgzVyfmROHyKJHBgDO1oR5LQQGmN0dd-LfpIucBQ5zCelR5WPc8jsmYZjV_8QQfnCXdccfwV_DeRtv5NPX-8dsCHht6S1oWVtsQ45pknSR6xihmbG-j4NYOMWF90FYX5Ndf5RJn6qMA/s72-c/site.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>