インストールしたSONiCを更新したい
SONiCの初期インストールにはONIEを使います。環境をきっちりセットアップすれば自動的にインストールさせることもできますし、そうじゃなければONIEのコンソールからコマンドを叩けばインストールできます。SONiCのインストールイメージはサーバに置いたりUSBメモリに入れてスイッチ本体に挿したりといった感じ。
では、SONiCがインストールされたスイッチに対して、新しいイメージに置き換えたい場合、どうするのがいいでしょうか?
公式wikiに示された手順
# sh ./sonic-broadcom.bin
上記はBroadcom用イメージの場合ですが、他のプラットフォームであってもファイル名が異なるだけで手順としては同じです。要するに、スイッチで動いているSONiC(この場合Linuxと読み替えていい)から参照できるファイルシステム上に更新用のイメージファイルを配置し、shに食わせれば更新される、というものです。
しかしこれはよろしくない。どこがよろしくないかというと、IPアドレスなどの設定が丸ごと初期化されてしまうのです。つまり、更新というより再インストールに近いということになります。
どうしようもないときの手順
なんらかの不具合でSONiCの操作ができないようなケースでは、初期インストール時と同様にONIEを使ってインストール済みイメージを削除し、再度インストールすることになります。当然設定は初期化されます。再インストールです。
どこにもドキュメントがないがおそらく推奨すべき手順
sonic_installer
コマンドというものが用意されていて、これを使います。(Pythonで書かれています)
$ sudo sonic_installer install -y ./sonic-broadcom.bin
このコマンドは現在の設定内容(config_db.json
)をバックアップするようになっています。SONiCは起動時に、バックアップされた設定が存在するかチェックして、あればその設定を使うようになっているため、更新後も設定が引き継がれます。
それでも引き継がれないssh host key
config_db.json
に描かれた設定はsonic_installer
を使うことで更新後も引き続き利用することができます。が、ssh host keyはバックアップ対象外のため、SONiCを更新するとhost keyは別の値に差し変わってしまいます。つまり更新後にsshでログインしようとするとエラーを食らい。やむなくssh-keygen -R ホスト名
を実行することになってしまいます。
patchを書いてみた
(2020年2月10日追記: 下記のpatchは、現時点のmasterでは当たらなくなっています。代替手段についてはSONiCのconfig-setup hookを使ってみるをご参照ください。)
ssh host keyが引き継がれない問題は、sonic_installer
とSONiCの起動スクリプトrc.local
の合計2か所にパッチを当てることで解決します。
sonic_installer
のパッチ (src/sonic-utilities
で当てます)
diff --git a/sonic_installer/main.py b/sonic_installer/main.py
index b47703c..0caa67e 100644
--- a/sonic_installer/main.py
+++ b/sonic_installer/main.py
@@ -364,6 +364,9 @@ def install(url, force):
run_command("rm -rf /host/old_config")
# copy directories and preserve original file structure, attributes and associated metadata
run_command("cp -ar /etc/sonic /host/old_config")
+ run_command("rm -rf /host/old_ssh")
+ # copy directories and preserve original file structure, attributes and associated metadata
+ run_command("cp -ar /etc/ssh /host/old_ssh")
# Finally, sync filesystem
run_command("sync;sync;sync")
rc.local
のパッチ
diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/
rc.local
index b74e9f40..03445a63 100755
--- a/files/image_config/platform/rc.local
+++ b/files/image_config/platform/rc.local
@@ -236,6 +236,10 @@ if [ -f $FIRST_BOOT_FILE ]; then
else
touch /tmp/pending_config_initialization
fi
+ if [ -d /host/old_ssh ]; then
+ mv -f /host/old_ssh/* /etc/ssh/
+ rmdir /hoe/old_ssh
+ fi
# Notify firstboot to Platform, to use it for reboot-cause
touch /tmp/notify_firstboot_to_platform
どうやってるかは書いてある通りです。