routeros-container について
MikroTik 管理者向けの RouterOS コンテナー運用ガイドです。デプロイ、ネットワーク、ストレージ、ライフサイクルに加え、バージョン差やローカルイメージの制約も説明します。
主な機能
- 01コンテナー機能の有効化と導入
- 02VETH、ブリッジ、NAT の設定
- 03環境変数とマウントの設定
- 04イメージの取得またはインポート
- 05ライフサイクルと REST API の管理
- 06バージョン別のプロパティと制約
活用シーン
- 01MikroTik デバイスへのコンテナー導入
- 02コンテナーのネットワークとポート転送の設定
- 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 独自の実装であり、大きな違いがあります。
要件:
containerextra 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.20 | list= を追加 | 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 ファイルに関する特定の要件があります。
- 単一レイヤーのみ — 複数レイヤーのイメージはサポートされていません
- gzip 圧縮なし — レイヤーは圧縮されていない tar である必要があります
- 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)を使用してください。
| プロパティ | 説明 |
|---|---|
interface | VETH インターフェイス |
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-list | CPU コアのアフィニティ |
memory-high | RAM 使用量の上限(バイト単位) |
アーキテクチャの対応付け
レジストリからプルする場合やイメージをビルドする場合は、RouterOS のアーキテクチャを Docker のプラットフォームに対応付けます。
RouterOS architecture-name | Docker プラットフォーム |
|---|---|
arm | linux/arm/v7 |
arm64 | linux/arm64 |
x86 | linux/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 のドキュメントやプロパティの検索には、
rosettaMCP サーバーのツール(routeros_search、routeros_get_page、routeros_search_properties)を使用してください
外部ドキュメント:
- MikroTik 公式ドキュメント:https://help.mikrotik.com/docs/spaces/ROS/pages/84901929/Container