mcpField
R
routeros-container

routeros-container

github.com/tikociクラウド・DevOps8348 回インストール5 日前に更新
リポジトリ

routeros-container について

MikroTik 管理者向けの RouterOS コンテナー運用ガイドです。デプロイ、ネットワーク、ストレージ、ライフサイクルに加え、バージョン差やローカルイメージの制約も説明します。

主な機能

  1. 01コンテナー機能の有効化と導入
  2. 02VETH、ブリッジ、NAT の設定
  3. 03環境変数とマウントの設定
  4. 04イメージの取得またはインポート
  5. 05ライフサイクルと REST API の管理
  6. 06バージョン別のプロパティと制約

活用シーン

  1. 01MikroTik デバイスへのコンテナー導入
  2. 02コンテナーのネットワークとポート転送の設定
  3. 03コンテナー導入と管理の自動化

MCP 対応

RouterOS のドキュメントやプロパティの検索には rosetta MCP サーバーを使うと記載されています。このガイド自体は MCP サーバーではありません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tikoci/routeros-skills --skill routeros-container

インストール後、Claude Code で/routeros-containerを入力して読み込まれたか確認します。

詳細

RouterOS コンテナーサブシステム

概要

RouterOS 7.x には、MikroTik のハードウェア上で OCI 互換のコンテナーイメージを直接実行するコンテナーサブシステム(/container)が含まれています。Docker ではありません。MikroTik 独自の実装であり、大きな違いがあります。

要件:

  • container extra package がインストールされた RouterOS 7.x
  • device-mode が有効であること(初回設定には物理的なアクセスが必要です)
  • 十分なストレージ(外部 USB ディスクを推奨。100 MB/s 以上、ランダム IOPS 10K 以上)
  • ARM、ARM64、または x86 アーキテクチャ(コンテナーでは MIPS はサポートされていません)

Device-Mode — 物理的なアクセスが必要です

コンテナーのサポートは device-mode によって制限されています。有効にするには、物理的な確認(リセットボタンの押下または電源の再投入)が必要です。

# Enable container mode
/system/device-mode/update mode=advanced container=yes

# After executing: physically confirm within activation-timeout
# - Press reset button, OR
# - Power cycle the device

device-mode はコンテナー専用ではなく、RouterOS 全般のセキュリティ機能です。デバイスごとの工場出荷時のデフォルト設定を持つ 4 つのモード(home、basic、advanced、rose)で、スケジューラー、fetch、スニファーなど、多くの機能を制限します。

機能の全一覧、モード、更新プロパティ、物理的な確認の詳細については、routeros-fundamentals スキルの Device-mode リファレンスを参照してください。

モードスクリプトによる回避(7.22 以降): netinstall 中に、モードスクリプト(-sm)で初回起動時の device-mode を設定でき、自動的に再起動がトリガーされます。routeros-netinstall スキルを参照してください。

Container パッケージのインストール

# Check if container package is already installed
/system/package/print where name=container

方法 1:.npk ファイルをアップロードして apply-changes を実行する(オフライン)

# Upload via SCP (or Winbox drag-and-drop, or WebFig file upload)
scp container-7.22-arm64.npk admin@router:/
# Apply changes (triggers reboot AND activates — /system/reboot does NOT work!)
/system/package/apply-changes

⚠️ 重要:/system/package/apply-changes は RouterOS 7.18 で追加されました。 7.18 以降では、必ずこれを使用してください。単に /system/reboot を実行すると、アップロードしたパッケージは破棄されます。7.18 未満では、/system/reboot が正しい(かつ唯一の)方法です。(ラボで検証済み:7.22.1 では apply-changes を使用し、7.10 では再起動が必要です。バージョンは rosetta コマンドツリーで確認してください。)

方法 2:オンラインでパッケージを更新する(インターネット接続が必要です)

/system/package/update check-for-updates
/system/package/update install

これにより、追加パッケージを含む、利用可能なすべての更新がダウンロードおよびインストールされます。アップロード済みで有効化されていない特定のパッケージを有効にするには、/system/package/enable container を実行し、その後 /system/package/apply-changes を実行します。

ネットワーク設定

VETH(仮想イーサネット)

コンテナーは VETH インターフェイスを介して RouterOS のネットワークに接続します。

# Create VETH pair
/interface/veth/add name=veth-myapp address=172.17.0.2/24 gateway=172.17.0.1

# The VETH name IS the container's interface name (RouterOS 7.21+)
ブリッジの設定
# Create a bridge for containers
/interface/bridge/add name=containers

# Add VETH to the bridge
/interface/bridge/port/add bridge=containers interface=veth-myapp

# Assign IP to bridge (acts as gateway for containers)
/ip/address/add address=172.17.0.1/24 interface=containers
NAT/ファイアウォール
# Masquerade container traffic for internet access
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24

# Port forwarding from host to container
/ip/firewall/nat/add chain=dstnat action=dst-nat \
  dst-port=8080 protocol=tcp to-addresses=172.17.0.2 to-ports=80

# Allow container bridge in interface list (if firewall restricts)
/interface/list/member/add list=LAN interface=containers
レイヤー 2 ネットワーク(ブリッジモード)

コンテナーを物理インターフェイスと同じ L2 ネットワーク上に置く必要がある場合(例:netinstall):

# Add both physical port and VETH to the same bridge
/interface/bridge/port/add bridge=mybridge interface=ether5
/interface/bridge/port/add bridge=mybridge interface=veth-netinstall

これにより、コンテナーは ether5 上のデバイスに L2 で直接アクセスできます。

環境変数とマウント

コンテナーに環境変数とマウントを割り当てる方法は 2 通りあります(7.21 以降)。

インライン(7.21 以降で推奨)

/container/add に env= と mount= を直接設定します。コンテナーを自己完結型にできます。

# Inline env vars and mount (7.21+)
/container/add remote-image=pihole/pihole:latest interface=veth1 \
  env="TZ=Europe/Riga,WEBPASSWORD=secret" \
  mount="src=disk1/pihole,dst=/etc/pihole" \
  root-dir=disk1/images/pihole logging=yes

これは、内部で /app YAML が動作する仕組みでもあります。インライン設定は最新のパターンであり、管理する別個のリンク済みオブジェクトがないため、自動化にも適しています。

名前付きリスト(すべてのバージョンで使用可能)

環境変数とマウントを別個のオブジェクトとして作成し、名前で参照します。

# Create named env list (7.20+ — the 'list=' property groups envs together)
/container/envs/add list=MYAPP key=TZ value="Europe/Riga"
/container/envs/add list=MYAPP key=WEBPASSWORD value="secret"

# Create named mount
/container/mounts/add name=appdata src=disk1/appdata dst=/data

# Reference from container (7.20+ uses 'envlists=', pre-7.20 used 'envlist=')
/container/add file=myimage.tar interface=veth1 \
  envlists=MYAPP mountlists=appdata root-dir=disk1/myapp

ベストプラクティス: コンテナーボリュームは必ず外部ディスク(disk1/)に配置し、内部フラッシュストレージには配置しないでください。

プロパティ名の変遷

環境変数/マウントの参照プロパティ名は、バージョンの境界で変更されています。

バージョン環境変数リストのグループ化(/container/envs/add)コンテナーの環境変数参照(/container/add)コンテナーのマウント参照
7.20 より前key=、value= のみ(グループ化プロパティなし)(環境変数参照プロパティなし)(利用不可)
7.20list= を追加envlists=(複数形)を追加(利用不可)
7.21 以降list=envlists= とインラインの env=mountlists= とインラインの mount=

バージョンに関する注意: 7.20 以降のプロパティ名は、/console/inspect のコマンドツリーデータで確認されています。7.20 より前の /container/envs/add には key と value しかなく、グループ化の仕組みはありませんでした。また、/container/add に環境変数の参照プロパティはありませんでした。インラインの env= と mount= は 7.21 で追加されました。

コンテナイメージ形式

RouterOS は、次の形式のコンテナイメージを受け入れます。

オプション A:レジストリからプルする
/container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/pull
/container/add remote-image=library/alpine:latest interface=veth-myapp
オプション B:ローカルの tar ファイルをインポートする

Docker v1 の tar ファイルをルーターにアップロードし、次を実行します。

/container/add file=myimage.tar interface=veth-myapp
ローカルインポート用の OCI イメージ要件

RouterOS のコンテナローダーには、ローカルの tar ファイルに関する特定の要件があります。

  1. 単一レイヤーのみ — 複数レイヤーのイメージはサポートされていません
  2. gzip 圧縮なし — レイヤーは圧縮されていない tar である必要があります
  3. Docker v1 マニフェスト形式 — manifest.json + config.json + layer.tar
myimage.tar
├── manifest.json    # [{"Config":"config.json","RepoTags":["name:tag"],"Layers":["layer.tar"]}]
├── config.json      # {"architecture":"arm64","os":"linux","config":{...},"rootfs":{...}}
└── layer.tar        # Uncompressed tar of the full filesystem

これらの制約が標準的な OCI イメージとの主な違いです。パブリックレジストリのほとんどのベースイメージは、レジストリからプルすることで要件 1 と 2 をすでに満たします。ローカルでビルドした tar は、3 つすべての要件を満たす必要があります。

コンテナのライフサイクル

CLI
# Create container (7.21+ inline syntax)
/container/add file=myimage.tar interface=veth-myapp \
  env="MY_VAR=hello" mount="src=disk1/appdata,dst=/data" \
  root-dir=disk1/myapp logging=yes

# Start
/container/start [find tag~"myapp"]

# Stop
/container/stop [find tag~"myapp"]

# View status
/container/print

# View logs (if logging=yes)
/log/print where topics~"container"

# Remove (must be fully stopped first)
/container/remove [find tag~"myapp"]
REST API
const base = "http://192.168.1.1/rest";
const auth = { headers: { Authorization: `Basic ${btoa("admin:")}` } };

// List containers
const containers = await fetch(`${base}/container`, auth).then(r => r.json());

// Start container by ID
await fetch(`${base}/container/start`, {
  method: "POST", ...auth,
  headers: { ...auth.headers, "Content-Type": "application/json" },
  body: JSON.stringify({ ".id": "*1" }),
});

// Check status — .running field is "true"/"false" (strings!)
const status = await fetch(`${base}/container/*1`, auth).then(r => r.json());
if (status.running === "true") { /* container is running */ }

// Stop container
await fetch(`${base}/container/stop`, {
  method: "POST", ...auth,
  body: JSON.stringify({ ".id": "*1" }),
});

// Delete — must be fully stopped. Poll .running and retry.
async function deleteContainer(id) {
  for (let i = 0; i < 5; i++) {
    const c = await fetch(`${base}/container/${id}`, auth).then(r => r.json());
    if (c.running === "false") {
      await fetch(`${base}/container/${id}`, { method: "DELETE", ...auth });
      return;
    }
    await new Promise(r => setTimeout(r, 3000));
  }
  throw new Error("Container did not stop in time");
}
コンテナの REST API に関する注意点
  • .running フィールドがステータスを示します。値はブール値ではなく、文字列 "true" / "false" です
  • .stopped フィールドはありません — .running のみを確認してください
  • 停止中に削除すると HTTP 400 が返されます — DELETE の前に、.running が "false" になるまでポーリングする必要があります
  • ローカル tar には file=、レジストリからのプルには remote-image= を使用します
  • コンテナの envlists=(複数形、7.20 以降)は、env リスト名を参照します。複数形である点に注意してください。7.20 より前は envlist=(単数形)を使用していました。上記の env/mount のバージョン履歴を参照してください。

コンテナのプロパティ(7.22 以降)

/container/add のプロパティを一部紹介します。これはすべてを網羅した一覧ではありません。特定のバージョンでの全一覧については、rosetta MCP ツール(/container/add の routeros_command_tree)を使用してください。

プロパティ説明
interfaceVETH インターフェイス
envインライン環境変数(7.21 以降)。KEY=value のペアをカンマ区切りで指定
envlists名前付き env リストの参照(7.20 以降)。上記の env/mount セクションを参照
mountインラインのボリュームマウント(7.21 以降)。src=host/path,dst=/container/path
mountlists名前付きマウントリストの参照(7.21 以降)。上記の env/mount セクションを参照
root-dirコンテナのファイルシステムの保存場所
fileコンテナの tar ファイル(ローカルインポート)
remote-imageコンテナイメージ名(レジストリからのプル)
cmdコンテナの CMD を上書き
entrypointコンテナの ENTRYPOINT を上書き
hostnameコンテナのホスト名
dnsコンテナ用の DNS サーバー
loggingコンテナの stdout/stderr を RouterOS ログに記録(yes/no)
start-on-bootデバイス起動時にコンテナを自動起動(yes/no)
workdir作業ディレクトリを上書き
nameコンテナ名([find where name=...] 用)
devices物理デバイスをパススルー(7.20 以降)
cpu-listCPU コアのアフィニティ
memory-highRAM 使用量の上限(バイト単位)

アーキテクチャの対応付け

レジストリからプルする場合やイメージをビルドする場合は、RouterOS のアーキテクチャを Docker のプラットフォームに対応付けます。

RouterOS architecture-nameDocker プラットフォーム
armlinux/arm/v7
arm64linux/arm64
x86linux/amd64

ルーターのアーキテクチャを確認します。

const resource = await fetch(`${base}/system/resource`, auth).then(r => r.json());
const arch = resource["architecture-name"]; // "arm64", "arm", "x86"

/app システム(7.21+/7.22+)

RouterOS 7.21 で /app パス(組み込みアプリ一覧)が導入されました。YAML によるアプリの完全な作成(/app/add)は 7.22 で追加されました。YAML の仕様全体については、routeros-app-yaml スキルを参照してください。

/app と手動でのコンテナ設定

netinstall、DHCP リレー、その他の未加工の L2 ワークフローなど、VETH/ブリッジ/L2 を完全に制御する必要がある場合は、手動で /container を設定してください。RouterOS のアプリ向けネットワークおよびポートフォワーディングの規約に適合する標準的な複数コンテナアプリケーションには、/app YAML を使用してください。

追加リソース

関連スキル:

  • ネットインストールとデバイスモードの自動化については、routeros-netinstall スキルを参照してください
  • /app YAML 形式については、routeros-app-yaml スキルを参照してください
  • RouterOS の一般的な基礎(CLI、REST、スクリプト)については、routeros-fundamentals スキルを参照してください

MCP ツール:

  • RouterOS のドキュメントやプロパティの検索には、rosetta MCP サーバーのツール(routeros_search、routeros_get_page、routeros_search_properties)を使用してください

外部ドキュメント:

コメント