Azure PAYG SLES15 SP1でコンテナ内zypperが使えない(container-suseconnect-zypp)原因と対処法

Azure の SLES15 SP1(PAYG) で Docker イメージをビルドすると、コンテナ内の zypper が「There are no enabled repositories defined」となり更新できないことがあります。原因は plugin:/susecloud と container-suseconnect-zypp の前提条件不足であるケースが多く、確認ポイントと回避策をまとめます。

目次

今回の症状:ホストでは見えるのに、コンテナ内だけ zypper が空になる

Azure の SLES15 SP1(従量課金 / PAYG)では、ホスト OS 上の zypper がクラウド登録(SUSEConnect)と連携し、クラウド固有の “プラグイン経由リポジトリ” を使って更新できる構成になっていることがあります。ところが Dockerfile でホスト同様に plugin:/susecloud?... を使って repo を追加しても、コンテナ内で次のように「リポジトリ 0」と判断され、追加パッケージのインストールや update が止まるケースがあります。

zypper ref -s && zypper update -y
Refreshing service 'container-suseconnect-zypp'...
Warning: Skipping service 'container-suseconnect-zypp' ...
Warning: There are no enabled repositories defined.

ここで重要なのは、あなたが追加した repo が無いのではなく、zypper が “サービス(service)” を更新できず、その結果として repo が 0 扱いになっている点です。表示上は「No repositories defined」「There are no enabled repositories defined」と出ますが、根っこは container-suseconnect-zypp の呼び出し失敗にあります。

結論:plugin:/ はコンテナ内でも使えるが、前提条件が欠けると必ず失敗する

質問ポイントへの回答を先にまとめます。

質問結論補足
plugin:/ で始まる URI はコンテナ内で使っても問題ない?前提条件が揃っていれば利用可能plugin:/ は “実体の https URL を生成する仕組み” なので、プラグインと登録情報が必要です。
Azure の PAYG SLES15 であることが原因?原因になり得るPAYG は自動登録に依存するため、登録が壊れる/クローンで不整合が出ると repo が消えたように見えます。
RMT の SSL 証明書を別途準備する必要がある?通常は不要公式の更新先を使う限り、追加の証明書準備は不要。
ただし社内 RMT を自前証明書で運用している場合は、コンテナ側に CA 取り込みが必要です。

plugin:/susecloud と container-suseconnect-zypp を正しく理解する

SLES の zypper は、通常は https:// で始まるリポジトリ URL を参照します。一方で Azure の PAYG などクラウド連携が入る環境では、実際の更新先を動的に解決するために plugin:/ スキームが登場します。

plugin:/ の正体

  • plugin:/... は zypper が認識する “特殊な URI スキーム” で、プラグインを呼び出してリポジトリ情報を生成します。
  • 見た目は URI ですが、実体は「このプラグインを動かして、適切な repo 定義(URL、認証情報、リージョン別のエンドポイント等)を取ってきてね」という指示です。
  • したがって、プラグインが動かない=repo が生成できない=repo 0 扱いになりやすい構造です。

container-suseconnect-zypp が担っていること

container-suseconnect-zypp は、zypper の “サービス(service)プラグイン” として動き、SUSEConnect(クラウド登録)と連携して、SLES の公式リポジトリを参照できる状態を整えます。つまり、次のような役割をまとめて引き受けています。

  • ホスト(PAYG)の登録状態を前提に、コンテナが更新できるための repo 情報を供給する
  • モジュールや拡張(例:Server Applications、Containers など)の有効化状況に応じた repo を提示する
  • クラウド環境固有の認証や接続先の違いを吸収する

この仕組みが “クラウド自動登録” と密結合しているため、PAYG で登録が崩れた瞬間に、コンテナ内の zypper も一緒に崩れたように見える、というのが今回の落とし穴です。

zypper の「サービス」と「リポジトリ」を分けて考えると理解が早い

zypper には大きく分けて service と repo の2種類の入口があります。今回のように container-suseconnect-zypp が絡むケースでは、repo そのものより “service が repo を生成できるか” が核心になります。

要素格納場所の例zypper コマンド今回のポイント
サービス(service)/etc/zypp/services.d/zypper lscontainer-suseconnect-zypp がここ。ここが壊れると repo を生成できず “repo 0” になりやすい
リポジトリ(repo)/etc/zypp/repos.d/zypper lr -uservice の refresh 成功後に repo が見える/増えることがある

まずホストとコンテナの両方で、次の2つを必ず取っておくと、どこで差が出ているかが一気に見えます。

# サービス一覧
zypper ls

# repo 一覧(URL 付き)

zypper lr -u

コンテナ内で repo が 0 扱いになる主な原因と、最短で切り分ける方法

「Skipping service ‘container-suseconnect-zypp’」が出た時点で、zypper はサービス更新に失敗し、結果として “有効な repo が無い” と判定しています。ここからは、原因を再現性高く切り分けるための観点を整理します。

よくある原因典型的なサイン確認コマンド(例)対処の方向性
ホストの登録状態が壊れている/期限切れホストでも repo が少ない、更新が不安定、SUSEConnect がエラーSUSEConnect --status-text zypper lr -uクラウド登録の再実行、登録情報のクリーンアップ、必要な拡張の再アタッチ
コンテナから SUSEConnect 連携先に到達できないhost network でないと失敗、プロキシ環境で失敗、NSG/Firewall で外に出られないdocker build --network=host . # あるいはコンテナ内で curl -I https://updates.suse.com/ビルド時のネットワーク設定、プロキシ環境変数の引き継ぎ、到達性の担保
container-suseconnect-zypp のプラグイン/サービス定義が不整合サービス更新で即スキップ、ログに Python/権限/依存関係エラーls -l /usr/lib/zypp/plugins/services/ ls -l /etc/zypp/services.d/ zypper -vvv ref -s必要パッケージの導入、ファイル権限の修復、ログから依存関係を解消
コンテナに必要な情報が引き継がれていないホストは OK だがコンテナだけ失敗、ビルド環境を変えると直るcat /etc/zypp/services.d/*.service env | grep -i proxyビルド時の環境変数、必要な設定の受け渡し(ただし機密情報の扱いに注意)
時刻ずれ・証明書検証で失敗TLS エラー、証明書期限エラー、curl も失敗timedatectl curl -v https://updates.suse.com/NTP 同期、CA 証明書の更新、プロキシでの TLS 中間証明書対応

推奨トラブルシュート手順

闇雲に Dockerfile をいじるより、ホスト登録 → プラグインの健全性 → コンテナの到達性の順で潰すと、最短で原因にたどり着けます。

ホスト側:登録と repo の状態を先に確定させる

  • 登録状態の確認:SUSEConnect --status-text で “有効な登録” になっているかを見る
  • リポジトリの可視化:zypper lr -u で、想定モジュール(例:Containers、Server Applications など)が有効か確認
  • ホスト単体で更新が通るか:zypper ref -s と zypper update が安定して成功する状態を作る

ここが不安定だと、コンテナ側は高確率で崩れます。PAYG の場合、VM を複製(OS ディスクのコピーやイメージ化)したタイミングで登録連携が崩れることがあるため、“新規に Marketplace から作った素の VM” と挙動比較するのが効果的です。

ホスト側:container-suseconnect-zypp と関連コンポーネントを点検する

サービスがスキップされる時は、たいていログにヒントがあります。まずは zypper を冗長ログで動かし、次に systemd / ログを確認します。

# まずは zypper を冗長ログで
zypper -vvv ref -s

# サービスとプラグインの所在
zypper ls
ls -l /usr/lib/zypp/plugins/services/
ls -l /etc/zypp/services.d/

# systemd / 全体ログ(環境によりユニット名は異なる場合があります)
journalctl -b | grep -i suseconnect
journalctl -b | grep -i container

特に、プラグイン本体が無い、実行権限が無い、依存パッケージが足りない、といった基本的な不整合は早めに潰しておくと後が楽です。

ビルド側:コンテナが “ホストと同じ前提” で動けるかを確認する

PAYG のクラウド連携系プラグインは、ホスト側の連携サービスにアクセスする前提になっていることがあります。Docker build の RUN ステップがデフォルトの NAT ネットワークのままだと、ホストの 127.0.0.1 にアクセスできず失敗することがあるため、まずは --network=host を試す価値があります。

DOCKER_BUILDKIT=1 docker build --network=host -t my-sap-sles-image:latest .

すでに --network=host を付けているのに失敗する場合は、次を重点的に疑います。

  • プロキシ環境で、ホストは通るがビルドコンテキストでは環境変数が渡っていない
  • ホスト側の “連携サービス” が起動していない/別ポートで待ち受けている
  • ホスト側で登録が壊れていて、連携サービスが正常に repo を生成できない

ログの取り方:成功したホストと、失敗するコンテナの差分を取る

「Warning: Skipping service …」の背後には、ほぼ必ず具体的な失敗理由があります。zypper の冗長ログと標準ログをセットで取ると、サポート問い合わせ時も通りが良くなります。

  • zypper 冗長ログ:zypper -vvv ref -s(サービス更新の直前直後が出ます)
  • zypper ログファイル:/var/log/zypper.log
  • 履歴:/var/log/zypp/history
  • systemd ログ:journalctl -b と、関連ユニットの journalctl -u ...

コンテナはビルド中にログが流れて消えやすいので、再現性が低いときは一度 “デバッグ用の一時コンテナ” を起動し、手で zypper を叩いてログを残すのが確実です。

# 例:ホストネットワークで一時コンテナを起動して確認(イメージ名は環境に合わせて)
docker run --rm -it --network=host your-base-image:15sp1 /bin/bash

# コンテナ内で
zypper -vvv ref -s
zypper lr -u
cat /etc/zypp/services.d/*.service
tail -n 200 /var/log/zypper.log

containerbuild-regionsrv を使う構成での注意点

質問文にある通り、ホストで containerbuild-regionsrv を起動している場合でも、コンテナ側がそのサービスにアクセスできなければ意味がありません。典型的には次のどれかでつまずきます。

  • Docker build が host network で実行されていない(ビルド時の RUN からホストの 127.0.0.1 に届かない)
  • サービスは起動しているが、待ち受けが想定と違う(ポート/バインド先)
  • 登録状態が壊れていて、regionsrv が “repo 生成に必要な情報” を返せない

まずホストで “本当に待ち受けているか” を確認します(ポート番号は環境差があるため、プロセス名で探すと確実です)。

systemctl status containerbuild-regionsrv
ss -lntp | grep -i regionsrv

Dockerfile の書き方でハマりやすいポイント

同じ SLES15 SP1 でも、ベースイメージが “何の前提を持っているか”で結果が変わります。次のポイントを押さえると、再現性の高い Dockerfile になります。

RUN の直前に “現状確認” ステップを入れて、壊れ方を見える化する

ビルドが通らない時は、いきなり zypper update を実行するより、repo/サービスの一覧と状態を出してから更新すると原因が絞れます。

RUN zypper -n --gpg-auto-import-keys lr -u && \
    zypper -n -vvv ref -s || (echo "zypper refresh failed" && exit 1)

プラグイン依存の repo 追加は “サービスが成功している前提” でしか成立しない

zypper ar 'plugin:/susecloud?...' が書けたとしても、それは “登録情報やプラグインが動く” ことを保証しません。refresh でサービスが生成する repo が本体なので、まず refresh が成功する状態が必要です。

機密情報を Dockerfile に焼き込まない

回避策として SCC の登録コード(レジストレーションコード)をコンテナに入れて更新する方法もありますが、Dockerfile に平文で埋め込むのは避けるべきです。CI/CD で実施するなら、BuildKit の secret マウントなどを使い、イメージに残さない形にします。

どうしても急ぐときの回避策

本番運用では “クラウド連携の正攻法” で直すのが理想ですが、SAP 向けカスタムイメージのビルドが止まっている場合、現実的には回避策が必要になることもあります。代表的な選択肢をまとめます。

回避策メリットデメリット/注意点向いているケース
BYOS(自前サブスク)でコンテナを登録して更新クラウド連携に依存せず repo を確実に使える登録情報の取り扱いが難しい(秘密情報の混入、ライセンス管理)CI 上で一時的にビルドだけ通したい
RMT で社内ミラーを立て、コンテナは https repo を参照外部到達性に依存せず安定、帯域や監査にも強いRMT 運用コスト。自前証明書の場合はコンテナへ CA 取り込みが必要閉域・プロキシ必須・大規模環境
SUSE のコンテナ向けベースイメージ(BCI 等)を採用コンテナ前提の整備が進んでおり、依存関係の罠が減るベースイメージのポリシーに合わせた設計が必要新規のコンテナ設計、長期運用を見据える

RMT の SSL 証明書は本当に不要なのか

公式リポジトリ(SUSE の公開更新サーバ)へ出ていく構成であれば、基本的に追加の証明書準備は不要です。一方で、次のような構成では “証明書が原因で zypper が落ちる” ことが起こり得ます。

  • 社内 RMT を立て、社内 CA(自己署名またはプライベート PKI)で TLS 終端している
  • 透過型プロキシが TLS を中間者として終端し、独自の中間証明書を挿入している

この場合は、コンテナ内に CA 証明書を入れて信頼ストアを更新する必要があります。つまり「RMT の証明書が不要」というのは、“公式をそのまま参照している限り”の話であり、ネットワーク設計によって前提が変わります。

Azure Marketplace 版 SLES15 SP1 で「No repositories defined」となる場合

2つ目の症状(/etc/zypp/repos.d/ が空、zypper pchk で「No repositories defined」)は、コンテナではなくホストそのものが repo を持っていない状態です。この場合はほぼ例外なく、自動登録(または登録の引き継ぎ)が失敗していることが原因です。

まず確認すること:PAYG か BYOS かで “正しい登録手順” が変わる

項目PAYG(従量課金)BYOS(自前サブスク)
登録の基本Azure 側の課金・連携情報を使った自動登録が前提SUSE Customer Center の登録コードで手動登録
repo が空になる典型自動登録が走っていない/失敗している/複製で崩れた登録未実施/登録コード間違い/期限切れ
よく効く対処クラウド登録ツールの再実行、VM 作り直しで比較SUSEConnect で再登録、拡張の付け直し
コンテナビルドへの影響ホスト登録が崩れると container-suseconnect-zypp も巻き込まれやすいコンテナ内登録方式を設計しやすいが、秘密情報管理が必須

登録状態の確認と、再登録の大枠

まずはホストで登録状態を確認します。

SUSEConnect --status-text
zypper lr -u
ls -l /etc/zypp/repos.d/

ここで未登録・期限切れ・repo 0 の場合は、環境に合わせて再登録が必要です。操作はイメージ種別や運用(PAYG/BYOS)で異なりますが、次の流れで進めると安全です。

  1. クラウド登録ツールや SUSEConnect のヘルプを確認し、“今の VM が想定する登録方式”を特定する
  2. 必要に応じて登録情報をクリーンアップ(例:登録の解除や再初期化)
  3. 再登録を実行し、/etc/zypp/repos.d/ に repo ファイルが生成されることを確認
  4. zypper refresh が通るまで、ネットワーク(プロキシ/NSG/DNS)と時刻を点検

特に Azure でありがちなのが、VM 作成後に OS ディスクをコピーして別 VM を作ったケースです。この場合、登録の一意性が崩れ、自動登録がスキップされて repo が生成されないことがあります。最短の切り分けは、同じ Marketplace イメージから新規 VM を作って比較し、差分をログで追うことです。

現場で使えるチェックリスト

最後に、現場で “やること” が一目で分かるようにチェックリスト化します。コンテナ問題でも Marketplace repo 0 問題でも、ここを順に潰せば原因が浮かびます。

チェック項目見る場所OK の目安NG のときの次アクション
SUSEConnect の登録状態ホストstatus が有効、製品/拡張が想定通り再登録(PAYG はクラウド登録、BYOS は登録コード)
repo の生成ホスト/etc/zypp/repos.d に repo が作られている自動登録ログ確認、VM 複製の有無確認
container-suseconnect-zypp の健全性ホスト/コンテナサービス更新がスキップされないプラグイン実体・権限・依存関係・ログを確認
ネットワーク到達性(更新先/プロキシ)ホスト/コンテナcurl で外部へ到達、DNS が解決HTTP(S)_PROXY の引き継ぎ、NSG/Firewall/DNS を見直す
時刻と証明書ホスト/コンテナ時刻が正しい、TLS エラーが出ないNTP 同期、CA 更新、社内 CA を信頼ストアへ追加

よくある質問

ホストでは zypper が動くのに、なぜコンテナだけダメなの?

ホストはクラウド登録の状態と連携サービス(プラグイン)が揃っている一方、コンテナはビルドの実行環境・ネットワーク・引き継がれる設定が異なります。plugin:/ は “動的生成” なので、わずかな前提差で repo が 0 扱いになりやすいのが理由です。

plugin:/ を https:// に置き換えれば解決する?

置き換えで直るケースもありますが、PAYG の恩恵(自動的な認証・課金連携)を捨てることになります。自前で SCC 認証や RMT を用意する必要が出るため、短期回避としては有効でも、運用設計としては慎重に判断してください。

最終的にどこへ問い合わせるのが早い?

ホストの登録が怪しい/Marketplace で repo が空、といった “クラウド連携そのもの” の問題は、SUSE 側と Azure 側の境界にまたがります。ログ(SUSEConnect の状態、zypper の冗長ログ、systemd ログ、ネットワーク到達性の結果)を揃えた上で、SUSE サポートまたは Azure のサポートに投げると解決が早いことが多いです。

まとめ

  • plugin:/susecloud はコンテナ内でも使えるが、動的生成のため前提条件が欠けると repo 0 扱いになりやすい
  • 「Skipping service ‘container-suseconnect-zypp’」が出たら、まずホストの登録状態とプラグインの健全性を確定させる
  • Marketplace 版で /etc/zypp/repos.d/ が空なら、ほぼ確実に自動登録の失敗。PAYG/BYOS を見極めて再登録する
  • 急ぎなら BYOS 登録や RMT、BCI の採用など回避策もあるが、ライセンスと秘密情報の取り扱いを含めて設計する

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次