1 はじめに
Harborには、コンテナイメージの脆弱性スキャンを行う Trivy(トリビー)が標準で組み込まれています。本記事では、Harbor に統合された Trivy を利用してコンテナイメージをスキャンする方法や、その基本的な使い方を説明します。
Harbor のインストール手順は、以下のページをご覧ください。
Trivy を Harbor のスキャナーとして利用するためのアダプタの公式 GitHub リポジトリは以下です。
2 検証環境
2.1 ネットワーク構成
検証環境は、VMware Workstation Pro上に構築した3台の仮想マシンでKubernetesクラスタを構成しています。各仮想マシンはブリッジ接続により、PCと同じネットワーク(192.168.1.0/24)に接続されています。
一方、10.244.0.0/16 は、CalicoのCNIプラグインによってクラスタ内に作成されるPodネットワークです。各Podにはこのアドレス帯からIPアドレスが割り当てられ、異なるノード上のPod同士が相互に通信する際に使用されます。Calicoは各ノードに経路を設定することで、Pod間通信を透過的に実現しています。
+--- control ---+ +--- worker1 ---+ +--- worker2 ---+
|AlmaLinux 10.2 | |AlmaLinux 10.2 | |AlmaLinux 10.2 |
| | | | | |
| Pod | | Pod | | Pod |
| | | | | | | | |
| 10.244.x.0/24 | | 10.244.y.0/24 | | 10.244.z.0/24 |
| ------------- | | ------------- | | ------------- |
| | | | | |
+-------+-------+ +-------+-------+ +-------+-------+
|.19 |.20 |.22
| | |
| 192.168.1.0/24 | |
+--------------------------------------------------------+
| VMware Workstation Pro(Bridged networking) |
+--------------------------------------------------------+
|
+---------------+
| |
| PC |
| |
+---------------+
それぞれの役割は以下のとおりです。
1台をコントロールノード、2台をワーカーノードとして使用します。
| ホスト名 | 名称 | 役割 |
|---|---|---|
| control | コントロールノード | クラスタ(control、worker1、worker2)の状態を管理し、Pod をどのノードで実行するかを決定するノード |
| worker1 | ワーカーノード | Pod を実行するノード |
| worker2 | ワーカーノード | Pod を実行するノード |
2.2 ソフトウェアのバージョン
各ノードのAlmaLinuxバージョンは以下のとおりです。
[root@control ~]# cat /etc/redhat-release
AlmaLinux release 10.2 (Lavender Lion)
各ノードのカーネルバージョンは以下のとおりです。
[root@control ~]# uname -r
6.12.0-211.7.3.el10_2.x86_64
Kubernetesのバージョンは以下のとおりです。
[root@control ~]# kubectl version
Client Version: v1.36.2
Kustomize Version: v5.8.1
Server Version: v1.36.2
2.3 ノードのリソース
各ノードには4GBのメモリを割り当てています。
[root@control ~]# free -h
total used free shared buff/cache available
Mem: 3.6Gi 1.3Gi 1.0Gi 5.8Mi 1.5Gi 2.3Gi
Swap: 0B 0B 0B
各ノードは 4コアのCPU(4 vCPU) を搭載しています。
[root@control ~]# lscpu -xe
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
0 0 0 0 0:0:0:0 yes
1 0 1 1 1:1:1:1 yes
2 0 2 2 2:2:2:2 yes
3 0 3 3 3:3:3:3 yes
lscpuコマンドの詳しい使い方は、以下のページをご覧ください。
3 スキャナー情報の確認
Harbor では、脆弱性スキャンや SBOM 生成を担当する「スキャナー」の情報を確認できます。ここでは、現在登録されているスキャナーや、そのバージョン、対応している機能を確認します。確認するには、Harbor の管理画面で次の順にクリックします。
Administration → Interrogation Services → Scanners
Scanner セクションには、現在登録されているスキャナー名やベンダー、バージョンなどの情報が表示されます。以下の例では、スキャナーが Trivy、スキャナー開発元が Aqua Security、Trivy のバージョンが v0.70.0 であることが確認できます。
Scanner:
Name: Trivy
Vendor: Aqua Security
Version: v0.70.0
Capabilities セクションには、Trivy で利用できる機能が表示されます。以下の例では 2 つの Type が登録されており、Trivy がこれら 2 つの機能に対応していることがわかります。
| Type | 概要 |
|---|---|
| Vulnerability | コンテナイメージに含まれるソフトウェアやライブラリに既知の脆弱性がないかを検査する機能です。 |
| SBOM(Software Bill of Materials) | ソフトウェアに含まれるパッケージやライブラリを一覧化した「ソフトウェア部品表(SBOM)」を生成する機能です。イメージの構成要素を可視化できるため、脆弱性が発見された際の影響範囲の特定やライセンス管理などに役立ちます。 |
4 コンテナイメージのスキャン
コンテナイメージのスキャンは、イメージ内に含まれるソフトウェアやライブラリを調査し、既知の脆弱性(CVE)が含まれていないかを確認する機能です。スキャンを実行すると、検出された脆弱性の件数や重大度、対応状況などを確認できます。
Harbor で手動スキャンを行うには、対象イメージのチェックボックスを選択し、「SCAN VULNERABILITY」ボタンをクリックします。

以下はスキャン実行中の画面です。「Vulnerabilities」列に「Scanning」と表示されており、コンテナイメージの脆弱性スキャンが実行中であることがわかります。

以下はスキャン完了後の画面です。スキャン結果の詳細を確認するため、赤枠内をクリックします。

以下はスキャン完了後の画面です。スキャン結果の詳細を確認するため、赤枠内のリンクをクリックします。

この例では、Potential Mitigations(対策)項目が空欄になっていることから、2026年7月18日時点では、この CVE に対する修正パッチや回避策が Trivy 側のデータベースに登録されていないことがわかります。アップストリームで対策が公開されると、この欄にパッチのバージョンやワークアラウンドなどが表示される場合があります。
*5 データベースのアップデート
Trivy は脆弱性スキャンの際、脆弱性データベースを参照し、コンテナイメージに含まれるソフトウェアやライブラリに既知の脆弱性がないかを確認します。このデータベースは定期的に更新され、新たに公開された脆弱性情報が反映されます。本章では、Trivy が使用する脆弱性データベースの更新タイミングと、Harbor の画面上から更新状況を確認する方法を説明します。なお、検証環境の Harbor は UTC で動作しているため、本章に記載する時刻はすべて UTC です。日本時間(JST)に換算する場合は、9時間加えてください。
今回の検証環境では、Trivy の設定は以下のとおりで、自動更新が有効になっています。
env.SCANNER_TRIVY_SKIP_UPDATE: false
スキャン前の Properties セクションのデータベース更新日時は、以下のとおりです。
vulnerability-database-next-update-at: 7/19/26, 4:19 PM
vulnerability-database-updated-at: 7/18/26, 4:19 PM
ここで、まだ脆弱性スキャンを実行していない別の nginx コンテナイメージに対してスキャンを実行します。

スキャンを実行した結果、Properties セクションのデータベース更新日時が、以下のように変化しました。
harbor.scanner-adapter/vulnerability-database-next-update-at:7/21/26, 4:44 PM
harbor.scanner-adapter/vulnerability-database-updated-at:7/20/26, 4:44 PM
vulnerability-database-updated-at が 7/18 から 7/20 に更新されており、スキャンの実行にあわせて脆弱性データベースが最新の状態に更新されたことがわかります。あわせて vulnerability-database-next-update-at も翌日の同時刻(7/21, 4:44 PM)に更新されており、次回の自動更新予定が新たにスケジュールされていることが確認できます。
6 自動スキャン
自動スキャンは、プロジェクト(本記事では library)へコンテナイメージを push するたびに、これまで手動で「SCAN VULNERABILITY」ボタンをクリックして実行していた脆弱性スキャンを自動的に実行する機能です。
設定するには、Harbor の Web UI で以下の順にクリックします。
Projects → library → Configuration
「Vulnerability scanning」セクションにある「Automatically scan images on push」にチェックを入れると、自動スキャンが有効になります。

動作確認のため、Docker Hub から新しいバージョンの nginx イメージを取得します。
[root@control ~]# podman pull docker.io/library/nginx:1.28
イメージの一覧を確認します。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.30 f91c43d45520 4 days ago 165 MB
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
取得したイメージを Harbor に push できるように、Harbor 用のタグ(別名)を付けます。
[root@control ~]# podman tag docker.io/library/nginx:1.28 harbor.home.lab/library/nginx:1.28
再度イメージ一覧を確認します。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.30 f91c43d45520 4 days ago 165 MB
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
次に、Harbor にログインしているかどうかを確認します。以下の結果より、まだ Harbor にログインしていないことがわかります。
[root@control ~]# podman login --get-login harbor.home.lab
Error: not logged into harbor.home.lab
Harborにログインします。
[root@control ~]# podman login harbor.home.lab
Username: admin
Password:
Login Succeeded!
Harborへコンテナイメージをアップロードします。
[root@control ~]# podman push harbor.home.lab/library/nginx:1.28
コンテナイメージの Harbor へのアップロードが完了すると、自動的にイメージの脆弱性スキャンが実行されていることが確認できます。イメージ一覧の「Vulnerabilities」列にスキャン結果が表示されます。

*7 脆弱性の深刻度によるイメージ取得制御
「Prevent vulnerable images from running」は、指定した深刻度以上の脆弱性を含むコンテナイメージの pull を拒否する機能です。これにより、深刻な脆弱性を含むコンテナイメージが本番環境などで誤って利用されることを防止できます。本章では、この機能を無効にした場合と有効にした場合の挙動を比較し、実際にイメージの pull がどのように制御されるかを確認します。
(1) 事前準備
現在のイメージ一覧を確認します。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.30 f91c43d45520 4 days ago 165 MB
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
検証のため、ローカルにある nginx:1.30 のイメージを一度削除しておきます。
[root@control ~]# podman rmi harbor.home.lab/library/nginx:1.30
Untagged: harbor.home.lab/library/nginx:1.30
Deleted: f91c43d45520959a835dfeb3d9e62ec52610b983c6c20ea409b2f212b2d38fb0
イメージ一覧から、nginx:1.30 が削除されたことを確認します。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
(2) デプロイ防止ポリシー無効の場合
まず、「Prevent vulnerable images from running」を無効にした状態で動作を確認します。

ポリシーが無効な状態で、nginx:1.30 を pull します。
[root@control ~]# podman pull harbor.home.lab/library/nginx:1.30
Trying to pull harbor.home.lab/library/nginx:1.30...
Getting image source signatures
Copying blob e226c5634adb done |
Copying blob 22b1b3aae7d1 done |
Copying blob 6307db16215e done |
Copying blob d98b66041796 done |
Copying blob 74da90576f8d done |
Copying blob bb9460f4024e done |
Copying blob a0e1f1b23e48 done |
Copying config f91c43d455 done |
Writing manifest to image destination
f91c43d45520959a835dfeb3d9e62ec52610b983c6c20ea409b2f212b2d38fb0
ポリシーが無効な状態では、深刻度の高い脆弱性が検出されているイメージであっても、問題なく pull できることが確認できます。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.30 f91c43d45520 4 days ago 165 MB
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
(3) デプロイ防止ポリシー有効の場合
続いて、「Prevent vulnerable images from running」を有効にし、しきい値を「High」に設定して動作を確認します。
まず、先ほど pull した nginx:1.30 を再度削除しておきます。
[root@control ~]# podman rmi harbor.home.lab/library/nginx:1.30
Untagged: harbor.home.lab/library/nginx:1.30
Deleted: f91c43d45520959a835dfeb3d9e62ec52610b983c6c20ea409b2f212b2d38fb0
イメージ一覧から、nginx:1.30 が削除されたことを確認します。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
Harbor のプロジェクト設定画面で、ポリシーを有効化し、しきい値を「High」に設定します。

この状態で、再度 nginx:1.30 を pull します。
[root@control ~]# podman pull harbor.home.lab/library/nginx:1.30
Trying to pull harbor.home.lab/library/nginx:1.30...
WARN[0000] Failed, retrying in 1s ... (1/3). Error: initializing source docker://harbor.home.lab/library/nginx:1.30: reading manifest 1.30 in harbor.home.lab/library/nginx: unknown: current image with 340 vulnerabilities cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of "High" or higher from running.' To continue with pull, please contact your project administrator to exempt matched vulnerabilities through configuring the CVE allowlist.
WARN[0001] Failed, retrying in 1s ... (2/3). Error: initializing source docker://harbor.home.lab/library/nginx:1.30: reading manifest 1.30 in harbor.home.lab/library/nginx: unknown: current image with 340 vulnerabilities cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of "High" or higher from running.' To continue with pull, please contact your project administrator to exempt matched vulnerabilities through configuring the CVE allowlist.
WARN[0002] Failed, retrying in 1s ... (3/3). Error: initializing source docker://harbor.home.lab/library/nginx:1.30: reading manifest 1.30 in harbor.home.lab/library/nginx: unknown: current image with 340 vulnerabilities cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of "High" or higher from running.' To continue with pull, please contact your project administrator to exempt matched vulnerabilities through configuring the CVE allowlist.
Error: unable to copy from source docker://harbor.home.lab/library/nginx:1.30: initializing source docker://harbor.home.lab/library/nginx:1.30: reading manifest 1.30 in harbor.home.lab/library/nginx: unknown: current image with 340 vulnerabilities cannot be pulled due to configured policy in 'Prevent images with vulnerability severity of "High" or higher from running.' To continue with pull, please contact your project administrator to exempt matched vulnerabilities through configuring the CVE allowlist.
エラーメッセージの通り、nginx:1.30 には 340 件の脆弱性が検出されており、「High」以上の脆弱性を含むイメージの pull を禁止するポリシーによって pull が拒否されました。また、CVE allowlist を設定することで、特定の脆弱性を例外として許可できることも示されています。
イメージ一覧を確認すると、pull に失敗したため nginx:1.30 が追加されていないことがわかります。
[root@control ~]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor.home.lab/library/nginx 1.29 5dfe511714e1 2 months ago 165 MB
harbor.home.lab/library/nginx 1.28 fda7399e8104 3 months ago 164 MB
docker.io/library/nginx 1.28 fda7399e8104 3 months ago 164 MB

