はじめに
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2025 (一枚目) の 15 日目として投稿しています。
2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2019年版: https://qiita.com/advent-calendar/2019/cisco
2020年版: https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
2021年版: https://qiita.com/advent-calendar/2021/cisco
2021年版(2枚目): https://qiita.com/advent-calendar/2021/cisco2
2022年版(1,2): https://qiita.com/advent-calendar/2022/cisco
2023年版: https://qiita.com/advent-calendar/2023/cisco
2024年版: https://qiita.com/advent-calendar/2024/cisco
2025年版: https://qiita.com/advent-calendar/2025/cisco <--ここ
免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。
Cisco Modeling Lab (CML)
Cisco が提供する CML は広く使用されており、ネットワークシミュレーションや簡易的にサーバを用意するだけでも非常に便利です。バージョンアップを重ね、Virtual Machine の基盤としても色々な機能が追加されており、ネットワークエンジニアの中には日々の業務に欠かせないと言った方もおられるかと思います。
本年 2025 年には CML 2.9.x が公開され、コンテナが正式にサポートされました。これにより、Reference Platform ディスクにもコンテナイメージが含まれており、使用可能です。コンテナ起動の特徴の一つとしてノードの起動が非常に速く、可能な限り活用したい機能です。
イメージ
デフォルトで Reference Platform に含まれているものを引用します。
| Container | Description |
|---|---|
| chrome | Chrome web browser, which can be accessed via the VNC console in CML |
| dnsmasq | DNS (default), DHCP (off by default) and TFTP (off by default). |
| firefox | Firefox web browser, which can be accessed via the VNC console in CML. |
| freeradius | A service container with FreeRADIUS |
| frr | A Free Range Routing (FRR) container |
| net-tools | A container with a variety of network troubleshooting tools |
| nginx | A service container for the nginx web server |
| splunk | A service container with Splunk Enterprise |
| syslog | A service container with syslog-NG |
| tacplus | A service container with TACACS+ |
| thousandeyes-ea | A service container with a ThousandEyes Enterprise agent |
これらは CML 上に配置するだけで、すぐに使用することが可能です。しかしながら、使いたい機能が含まれていない場合など、カスタムイメージを作りたい場合があります。
本記事では、カスタムコンテナイメージの作り方と CML での使用方法をまとめたいと思います。
コンテナイメージの作成
CML 上で動作するコンテナイメージであっても、一般的なコンテナイメージと同じです。Dockerfile を作成し、docker build (や docker buildx) を使用して作成することができます。
FROM ubuntu:24.04
COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
CMD ["/entrypoint.sh"]
#!/bin/bash
while true :
do
sleep 5
done
そのディレクトリで以下のコマンドを実行し、イメージをビルドします。名前に test-ubuntu、タグに 1.0 を付加しました。
$ docker build -t test-ubuntu:1.0 .
x86_64 ではない Mac (arm64) などの上でビルドする場合は、CML が動作する Linux 上で動作する様、以下の様に platform 指定が必要です。
$ docker build -t test-ubuntu:1.0 --platform linux/amd64
完成したイメージは、ローカルのリポジトリに登録されていますので、ファイルへ出力します。
$ docker save test-ubuntu:1.0 -o test-ubuntu_1.0.tar
コンテナイメージのIDを控える
CML へイメージの登録を行う際、コンテナイメージのハッシュIDが必要になりますので、確認しておきます。
$ docker image inspect test-ubuntu:1.0 -f '{{.Id}}'
sha256:4302efca3a0da7fb763a3f6ac6c667440237f440691b4a3547d4f64d8950f5bd
イメージのアップロード
CML 上で使用するため、tar ファイルを登録します。以下どちらの方法でも可能ですが、圧縮して tar.gz ファイルとして登録する場合は、scp を使用してください。
- GUI 上からブラウザを使ってアップロード
- scp を使用して、CML サーバへアップロード 参照
CML 2.9.1 の GUI 上では、tar.gz のアップロードも可能な表記がありますが、現在選択することが出来ません。
今回は GUI 上から、tar ファイルのままアップロードします。
Node Definition の作成
作成したイメージは、新規作成した Node Definition に紐付けますので、先に作成します。
General
| 項目 | 今回の値 | 説明 |
|---|---|---|
| ID | my-custom-image | このノードの内部的な名前 |
| Description | (自由) | このノード種別の説明 |
| Nature | server | ノード種別 |
User Interface
| 項目 | 今回の値 | 説明 |
|---|---|---|
| Visible | True | UI上で見えたり、操作可能かどうか |
| Description | (自由) | UI上で見えるノードの説明 |
| Prefix | my-custom- | ノードを配置した際に、表示される文字列。一つ目は my-custom-0 となる |
| Icon | Server | UI 上でのアイコン |
| Label | my-custom | ラベル |
Linux Native Simulation
| 項目 | 今回の値 | 説明 |
|---|---|---|
| Domain Driver | Docker | 今回のキモで、Dockerを使用する |
| Simulation Driver | Server | |
| Disk Driver | - | 別のディスクは使用しないため、何も選択しない |
| Memory | 512 | 付与するメモリサイズ(MB) |
Interfaces
| 項目 | 今回の値 | 説明 |
|---|---|---|
| Has a Loopback Interface | False | この例ではサーバであるため、Loopbackインターフェースは不要。ルータなどで必要な場合は設定する |
| Number of Serial Ports | 1 | シリアルポートの数 |
| Default Number of Physical Interfaces | 1 | コンテナに接続されるインターフェースの数 |
| Interface 0 | eth0 | インターフェース名 |
Boot
| 項目 | 今回の値 | 説明 |
|---|---|---|
| Timeout | 30 | Startしてから起動完了とするまでの秒数 |
Provisioning
| 項目 | 今回の値 | 説明 |
|---|---|---|
| Enable Provisioning | True | Dockerコンテナで使用する場合、現状必須 |
| Media Type | RAW | |
| Configuration Disk Volume Name | cfg | |
| Name | config.json | Docker コンテナイメージに必須 |
| Content | 以下参照 | docker-shim に渡される設定内容 |
{
"docker": {
"image": "test-ubuntu:1.0",
"mounts": [
],
"misc_args": [
"--security-opt","seccomp=unconfined"
]
},
"privileged": true,
"shell": "/bin/sh",
"busybox": false
}
Image Definition の紐付けは行われますが、現時点では config.json で指定されたイメージが使用されるようです。つまり、各ノードの Config としてイメージ名が決まるわけですが、本来の CML のデザインとは違うため、今後実装変更される可能性があります。
Image Definition の作成
- Node Definition: 先ほど作成した my-custom を指定
- Disk Image: アップロードされたファイル名を選択
- Disk Hash: 控えておいたHashを入力
起動してみる
作成したノードを配置します。
Startをクリックしたところ、無事起動できました!しかし、コンテナの起動コマンド (PID=1) である entrypoint.sh では sleep しており、コンソールへは何も表示されません。
代わりに PID=1 をシェルにして、作り直してみます。
イメージ作りなおし (PID=1 をシェルにする)
$ cat entrypoint.sh
#!/bin/bash
bash
$ docker build -t test-ubuntu:1.1 --platform linux/amd64 .
$ docker save test-ubuntu:1.1 -o test-ubuntu_1.1.tar
$ docker image inspect test-ubuntu:1.1 -f '{{.Id}}'
sha256:f3e67ba9c9d26ba5520f79724c22ad47b42bf09ff1ed4403ac5a4331c1555a58
新しいイメージを使って再度CML上で起動すると、無事シェルが表示されました!
ただし、まだ問題があります。PID=1がシェルですので、exit するとコンテナが終了してしまいます。
イメージの作り直し (PID=1 シェルの無限再起動)
シェルが終了した時に、PID=1となるプロセスが終了することが問題ですので、以下の様に書き換えます。
$ cat entrypoint.sh
#!/bin/bash
while true :
do
bash
echo "Session ended. Restarting..."
sleep 1
done
$ docker build -t test-ubuntu:1.2 --platform linux/amd64 .
$ docker save test-ubuntu:1.2 -o test-ubuntu_1.2.tar
$ docker image inspect test-ubuntu:1.2 -f '{{.Id}}'
sha256:5fc63715fda36828376a2978c5e25533e64c487c17fd725c718fb0b3b198416a
シェルを exit で終了した場合も、ノードは起動したままで、次のシェルが起動する様になりました。
イメージの作り直し (認証付き)
この際ログインも可能な様にします。
user = cisco, pass = cisco でハードコードしています。
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y login --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN useradd -m -s /bin/bash cisco && echo "cisco:cisco" | chpasswd
COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
CMD ["/entrypoint.sh"]
bash の代わりに、/bin/login を起動します。
#!/bin/bash
while true :
do
/bin/login
echo "Session ended. Restarting..."
sleep 1
done
ここまでで、ある程度使用可能なレベルまで完成したと思います。
ネットワークへ接続
ping コマンド等を追加して、接続性の確認をしてみます。
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y iproute2 util-linux iputils-ping net-tools login --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN useradd -m -s /bin/bash cisco && echo "cisco:cisco" | chpasswd
COPY entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
CMD ["/entrypoint.sh"]
下記は External Connector (NAT)を eth0 へ接続し、www.cisco.com へping を行ってみた様です。問題なくインターフェースの接続も使用できることが確認出来ました。
まとめ
記事では、CML 2.9.x 以降で正式サポートされたコンテナ機能に向けて、独自のコンテナイメージを作成し、CML 上で利用可能にするまでの手順を紹介しました。
ここまでの手順(Docker イメージのビルド、CML へのアップロード、Node Definition の作成)を踏むことで、標準で用意されているイメージ以外にも、自分が必要とするツールやサービスを自由に CML トポロジーへ組み込めるようになります。
従来の VM ベースのノードと比較してコンテナは起動が非常に高速であり、リソース消費も抑えられるため、大規模な検証環境や頻繁なスクラップ&ビルドを行うシーンでは特に重宝するかと思います。
ぜひ、用途に合わせたカスタムイメージを作成して、CML での検証環境をより便利に活用してみてください。













