OKE/OCIRでコンテナイメージのセキュリティを高めよう

# はじめに

この記事は、[Oracle Cloud Infrastructure Advent Calendar 2021 その1](https://qiita.com/advent-calendar/2021/oci) Day 21の記事として書かれています。

昨今、従来より増して「セキュリティ」に関する意識が高まっているところだと思います。

この記事では、コンテナセキュリティ強化の一環として、OKEやOCIRを利用して比較的容易に実現できる営みをご紹介したいと思います。
この記事でご紹介するのは以下です。

* OCIRに格納したコンテナイメージの脆弱性スキャン
* OCIRでのコンテナイメージに対するイメージ署名
* OCIR、OKEでのイメージ署名に対する検証

それでははじめていきます。

# OCIRに格納したコンテナイメージの脆弱性スキャン

まずは、コンテナイメージの脆弱性スキャンから見ていきます。

コンテナイメージの脆弱性をスキャンして、把握することで、コンテナイメージ内のセキュリティホールを埋めることができます。
こちらの機能では、CVEで公開されている脆弱性を対象にスキャンすることができます。

OCIRで脆弱性スキャンを利用するにはAPI/OCI CLIのいずれかを利用します。(現時点でコンソールでの脆弱性スキャンはサポートしておりません)
今回はOCI CLIを利用して行います。

## ポリシーの設定

まずは、脆弱性スキャンを行うためのポリシーを設定していきます。
ポリシーはOCIコンソールから、「アイデンティティとセキュリティ」=>「ポリシー」で辿れます。
![スクリーンショット 2021-12-21 13.36.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/ac1e0ef4-93c2-df2b-0565-9aef5b33aa30.png)

以下のポリシーを作成します。

:::note warn
以下のポリシーの他に、操作対象となるコンパートメント内のフルアクセス権限があることを前提とします。
:::

|ポリシー|説明|
|---|---|
allow service vulnerability-scanning-service to read repos in compartment <コンパートメント名>|脆弱性スキャンサービスがOCIRのコンテナイメージを参照可能にするポリシー
allow service vulnerability-scanning-service to read compartments in compartment <コンパートメント名>|脆弱性スキャンサービスがコンパートメント情報を参照可能にするポリシー

これでポリシーの作成は完了です。

##　OCIRのレポジトリ作成

今回スキャン対象とするレポジトリをOCIRに作成します。

OCIRへは、「開発者サービス」=>「コンテナ・レジストリ」で遷移します。


![スクリーンショット 2021-12-21 15.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/655c3563-cb56-70d0-c84a-1313d3f0e8a9.png)

「レポジトリの作成」をクリックし、以下の情報を入力します。  

|入力項目|説明|
|---|---|
レポジトリ名|scan-test

「レポジトリの作成」をクリックします。


![スクリーンショット 2021-12-21 15.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/21a9cd8e-76cb-0b03-ef8f-619fa5c19015.png)


これで、OCIRのレポジトリ作成は完了です。


## スキャン・レシピとスキャン・ターゲットの作成

今回は、Cloud Shell環境でOCI CLIを実行していきます。

次にスキャン・レシピとスキャン・ターゲットを作成します。

```sh
oci vulnerability-scanning container scan recipe create 
--display-name <スキャン・レシピ名> 
--compartment-id <コンパートメントのOCID> 
--scan-settings '{"scanLevel": "STANDARD"}'
```
`--scan-settings '{"scanLevel": "STANDARD"}'`の部分は、現時点で`STANDARD`しか存在しないので、こちらを利用します。

以下のようなレスポンスが返却されるので、スキャン・レシピのOCID(レスポンスの`id`フィールド)だけ記録しておきます。

```sh
{
  "data": {
    "compartment-id": "ocid1.tenancy.oc1..aaaaaaaa6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxo7prvv7a55asqdzge45nq",
    "defined-tags": {
      "Oracle-Tags": {
        "CreatedBy": "oracleidentitycloudservice/xxxx@gmail.com",
        "CreatedOn": "2021-12-21T05:16:43.785Z"
      }
    },
    "display-name": "scan-recipe",
    "freeform-tags": {},
    "id": "ocid1.vsscontainerscanrecipe.oc1.iad.aaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxww6yag3b2pe24a",
    "lifecycle-state": "ACTIVE",
    "scan-settings": {
      "scan-level": "STANDARD"
    },
    "system-tags": {},
    "time-created": "2021-12-21T05:16:43.956000+00:00",
    "time-updated": "2021-12-21T05:16:43.998000+00:00"
  },
  "etag": "7591b3eaa0034e78c8dc2e6ad82eb89cbe4e866250d665b56f1021935244bd4f",
  "opc-work-request-id": "ocid1.coreservicesworkrequest.oc1..aaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxupdiwfjzlyidoa4ljqjmq"
}
```

続いてスキャン・ターゲットを作成します。

```sh
oci vulnerability-scanning container scan target create --display-name scan-target --compartment-id <コンパートメントのOCID>  
 --container-scan-recipe-id <上記で作成したスキャン・レシピのOCID>  
 --target-registry 
'{"type": "OCIR", "url": "https://<対象のリージョン・コード>.ocir.io","compartmentId": "<コンパートメントのOCID>", "repositories": ["<OCIRのレポジトリ名>"]}'
```

ここで`"repositories": ["<OCIRのレポジトリ名>"]`を指定しないこともでき、その場合は対象のコンパートメント内の全てのイメージがスキャン対象になります。

:::note warn
コンパートメント内の全てのイメージをスキャン対象にする場合も事前にレポジトリの作成が必要になるので、ご注意ください。
:::

実行するとこのような結果が返ってきます。

```sh
{
  "data": {
    "compartment-id": "ocid1.tenancy.oc1..aaaaaaaa6nvbus6xxxxxxxxxxxxxxxxxxxxvv7a55asqdzge45nq",
    "container-scan-recipe-id": "ocid1.vsscontainerscanrecipe.oc1.iad.aaaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxx6yag3b2pe24a",
    "defined-tags": {
      "Oracle-Tags": {
        "CreatedBy": "oracleidentitycloudservice/xxxx@gmail.com",
        "CreatedOn": "2021-12-21T05:32:58.119Z"
      }
    },
    "description": null,
    "display-name": "scan-target",
    "freeform-tags": {},
    "id": "ocid1.vsscontainerscanrecipe.oc1.iad.aaaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxww6yag3b2pe24a",
    "lifecycle-state": "CREATING",
    "system-tags": {},
    "target-registry": {
      "compartment-id": "ocid1.tenancy.oc1..aaaaaaaa6nvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx55asqdzge45nq",
      "repositories": [
        "scan-test"
      ],
      "type": "OCIR",
      "url": "https://iad.ocir.io"
    },
    "time-created": "2021-12-21T05:32:58.389000+00:00",
    "time-updated": "2021-12-21T05:32:58.389000+00:00"
  },
  "etag": "177aaa88f3072f50362c5d9a975fd076349613cbce6ee158299d2130ef79f90e",
  "opc-work-request-id": "ocid1.coreservicesworkrequest.oc1..aaaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxm24jdzhuafngjg7wea"
}
```

ここまでできれば、すでに格納済みのイメージもしくは今後プッシュされるイメージに対して脆弱性スキャンが実行されます。

スキャン実行結果はコンソールから確認できます。

OCIRのコンソールから、scan-testレポジトリに格納されたイメージの「スキャン結果」をクリックします.

![スクリーンショット 2021-12-21 15.13.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/b3b5a326-e1ce-2f05-479f-296b2a8dd505.png)

発見された脆弱性の詳細を見る場合は、右端にあるケバブメニューの「詳細の表示」からアクセスできます。

![スクリーンショット 2021-12-21 15.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/6debcabe-5360-f005-ec69-b67fc7cef745.png)

今回の場合は以下のように表示されました。こちらのリンクをクリックすると、CVEデータベースの詳細な情報を参照することができます。
これをもとに、コンテナイメージのセキュリティホールを事前に対処することができます。

![スクリーンショット 2021-12-21 15.16.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/abbf05e0-615b-2844-129d-60b38579e88b.png)

以上がOCIRでのコンテナイメージの脆弱性スキャンです。

# OCIRでのコンテナイメージに対するイメージ署名

次に、OCIRでのコンテナイメージに対するイメージ署名を実施してみます。

イメージ署名を利用することで、コンテナイメージに対する改竄を防ぎ、信頼できるコンテナイメージとして管理することができます。

:::note warn
イメージの署名を利用するために、ポリシーについては、対象となるコンパートメント内のフルアクセス権限があることを前提とします。
:::

## OCI Vaultでの暗号化キーの作成

イメージ署名に利用するための暗号化キーをOCI Vaultで作成していきます。

OCI Vaultでは、「アイデンティティとセキュリティ」=>「ボールト」をクリックします。

![スクリーンショット 2021-12-21 15.29.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/32d5566d-ee77-a035-ba7e-3426dedc3b35.png)

「ボールトの作成」をクリックします。

以下の情報を入力し、「ボールトの作成」をクリックします。

|入力項目|説明|
|---|---|
名前|image-vault

![スクリーンショット 2021-12-21 15.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/0a4eaffe-df24-fd77-3ca8-fd0f982ee8a9.png)

Vaultがプロビジョニングされるまでしばらく待ちます。

プロビジョニングが完了したら、作成した「image-vault」をクリックし、「キーの作成」をクリックします。

以下の情報を入力し、「キーの作成」をクリックします。

|入力項目|説明|
|---|---|
名前|image-key
キーのシェイプ：アルゴリズム|RSA

:::note warn
イメージの署名で利用する暗号化キーにAESを利用することはできない(利用可能なのはRSAもしくはECDSA非対称キーです)ので、ご注意ください。
:::

![スクリーンショット 2021-12-21 15.40.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/1abea389-0498-da3d-c527-c462bcf6f831.png)


キーがプロビジョニングされるまで待ちます。

プロビジョニングされたら、「image-key」をクリックし、「キー情報」のOCIDと「キーバージョン」のOCIDを記録しておきます。

![スクリーンショット 2021-12-21 15.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/a2502846-1b26-1916-6b12-8754142070c6.png)

以上で、OCI Vaultでの暗号化キーの作成は完了です。

## OCIRでのイメージ署名

続いて、OCIRでのイメージ署名を行います。

コンテナイメージへの署名は、脆弱性スキャンと同様にAPIもしくはOCI CLIを利用します。

今回は、Cloud Shell環境でOCI CLIを実行していきます。

以下のコマンドで署名することができます。

```sh
oci artifacts container image-signature sign-upload --compartment-id <コンパートメントのOCID>
--kms-key-id <上記の「キー情報」のOCID> 
--kms-key-version-id <上記の「キーバージョン」のOCID> 
--signing-algorithm SHA_256_RSA_PKCS_PSS 
--image-id <イメージ署名対象のOCID> 
--description <署名時の説明> 
--metadata '""'
```

`--signing-algorithm`オプションでは、複数のアルゴリズムから選択して利用することができます。
詳細は[こちら](https://docs.oracle.com/ja-jp/iaas/Content/Registry/Tasks/registrysigningimages_topic.htm)をご確認ください。

:::note info
--image-idで指定するコンテナイメージのOCIDはOCIRコンソールから確認できます。
:::

実行すると以下のような結果が返ってきます。

```sh
Obtaining container image metadata by the image ID
Generating signature
Signature: d78iommDRruKEPlvfaCFhxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Uploading signature
Uploaded signature: d78iommDRruKEPlvfaCFhTVlixsDLoLdVS2LuCS5cSEnq3IJK/A5NO0ITOL1fUXPD8HjcHtAPK+DODk0VoyCK0rIs9XNkwVIH6x8TQpd9qQz2MbCsvNS2dKGh/AokSu+3ULn6vQ9EnRreumgla70qWQhzNJYTA/F+/AgBn1Ig9gcx8k0C5+KgRs10nKDki5dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Message: eyJkZXNjcmlwdGlvbiI6ImltYWdlLXNpZ24gZGVtbyIsImltYWdlRGlnZXN0Ijoic2hhMjU2OmJiOWMzZGQwMmYxNDUyOTFjNWQ0ZTIxOGJmMWI1MDVhYzFiMGI0ZjYyYzI1YzEzYTFmZmQyOTNiZDJlZjU1NmEiLCJrbXNLZXlJZCI6Im9jaWQxLmtleS5vYzEuaWFkLmI1cTRjNWxuYWFoaWsuYWJ1d2NsanN2azRzY3B4M3ZrZjU2YTJteTdtaDU3M2pwd2oyamV4ZXBrMnF3am9xcW52M3Q2amNmNjRhIiwia21zS2V5VmVyc2lvbklkIjoib2NpZDEua2V5dmVxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ID: ocid1.containerimagesignature.oc1.iad.0.idwpqivumvev.aaaaaaaaa5msu6tsr5efanzpzjozh3eex4strnw6wa5a3rdu46grtdobwfza
{
  "data": {
    "compartment-id": "ocid1.tenancy.oc1..aaaaaaaa6xxxxxxxxxxxxxxxxxxxxxxxxxt6p3o7prvv7a55asqdzge45nq",
    "created-by": "ocid1.saml2idp.oc1..aaaaaaaain5ck5a6zeo222ajpq5xxxxxxxxxxxxxxxxxxxxxxxxxq/xxxxx.devdays@gmail.com",
    "display-name": "v3t6jcf64a::5slkxvenra::SHA_256_RSA_PKCS_PSS::grtdobwfza",
    "id": "ocid1.containerimagesignature.oc1.iad.0.idwpqivumvev.aaaaaaxxxxxxxxxxx4strnw6wa5a3rdu46grtdobwfza",
    "image-id": "ocid1.containerimage.oc1.iad.0.idwpqivumvev.aaaaaaxxxxxxxxxxlxjd56yhsmjgkk2d75c6no6oxnq",
    "kms-key-id": "ocid1.key.oc1.iad.b5q4c5lnaahik.abuwcljsvk4scpx3vkf56a2my7mh5xxxxxxxxxxv3t6jcf64a",
    "kms-key-version-id": "ocid1.keyversion.oc1.iad.b5q4c5lnaahik.aumomhaxn6yaa.abuxxxxxxxxxxuxv5jbvng5eyolkbhm6y5slkxvenra",
    "message": "eyJkZXNjcmlwdGlvbiI6ImltYWdlLXNpZxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "signature": "d78iommDRruKEPlvfaCFhTVlixsDLoLdVS2LuCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxqRX8A8Q8LE1Kd4hbZNr8D4eTOJ9xg248PRplWsv7hOQ/ZeZzcpwVSEaa6coaZLHJADdT+F+vVlpP7yT/rMerAOkwBkn9WoIP036B8QOWnJrQYOLQ4d6Qk53tzk+PhFEMsQPqiJOUUC6TT7NAUOMOA==",
    "signing-algorithm": "SHA_256_RSA_PKCS_PSS",
    "time-created": "2021-12-21T07:02:58.383000+00:00"
  }
}
```

OCIRのコンソールから対象のイメージを確認すると「(署名済)」と表示され、「署名」タブには署名時に`--description`オプションで指定した文字列(今回の場合は`image-sign demo`)が表示されていることが確認できます。
![スクリーンショット 2021-12-21 16.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/d06db879-9a85-ef30-7f80-81a618c81532.png)




これでイメージ署名は完了です。

# OCIR、OKEでのイメージ署名に対する検証

最後にOCIR、OKEそれぞれでイメージ署名に対する検証を行います。

## OCIRでのイメージ検証

OCIRでのイメージ検証はシンプルかつ一瞬です。

OCIRのコンソールの「署名」タブのケバブメニューから「署名の検証」をクリックします。

![スクリーンショット 2021-12-21 16.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/673578ed-3755-12e5-da7d-1b9036f36814.png)

イメージ検証が正常にできれば、「検証済」と表示されます。

![スクリーンショット 2021-12-21 16.11.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/d3622c4b-7f06-9a47-1670-637e6382759e.png)

これで、OCIRでのイメージ検証は完了です。

## OKEでのイメージ検証

OKEでのイメージ検証ではOKEクラスタが必要になるので、[OCIチュートリアル](https://oracle-japan.github.io/ocitutorials/cloud-native/oke-for-commons/)に沿って作成してください。

OKEでのイメージ検証を有効化すると、指定した暗号化キーで署名されたイメージのみをデプロイすることができます。
（未署名のイメージや検証に失敗したイメージはデプロイされません）

OKEクラスタを作成できたら、イメージの署名を利用可能にするためのポリシーを設定します。

* Allow any-user to use keys in tenancy where request.user.id=<作成したOKEクラスタのOCID>
* Allow any-user to read repos in tenancy where request.user.id=<作成したOKEクラスタのOCID>

:::note info
OKEクラスタのOCIDはOCIコンソールから確認できます。
:::


次に、OKEクラスタのメニューにある「イメージ検証」をクリックします。

![スクリーンショット 2021-12-21 16.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/89bc46cc-a1e6-be05-3ab8-5abdb6c40492.png)

「イメージ検証の編集」をクリックします。

![スクリーンショット 2021-12-21 16.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/551b8368-0892-b560-3467-1df8835e5d4c.png)

「このクラスタでのイメージ検証の有効化」にチェックを入れ、イメージ署名時に作成したボールト名とキー名を選択し、「イメージ検証設定の保存」をクリックします。

![スクリーンショット 2021-12-21 16.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/21707a27-2d28-e6cb-66ff-0aa1bae2b372.png)

OKEクラスタが「更新中」のステータスになるので、「アクティブ」になるまで、10分~20程度待機します。

ここからは、OKEでのイメージ検証の挙動を確認していきます。

まずは、未署名のイメージがOKEにデプロイできないことを確認します。

今回は通常のnginxイメージをデプロイしてみたいと思います。
以下のようなManifestをデプロイしてみます。

```yaml:unsigned_nginx.yaml
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: unsigned-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
```

このファイルをapplyします。

```sh
kubectl apply -f unsigned_nginx.yaml
```

すると、Deploymentリソースは作成されますが、Podが作成されないことが分かります。

```sh
$ kubectl get deploy
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
unsigned-nginx   0/3     0            0           3m
```

これは、nginxコンテナイメージが期待された暗号化キーで署名されていないためです。

次に先ほど署名したコンテナイメージをデプロイしてみます。

デプロイする前にOCIRのクレデンシャルを含めたSecretを作成しておきます。

```sh
kubectl create secret ocir-cred --docker-server=<リージョン・コード>.ocir.io 
--docker-username='オブジェクト・ストレージ・ネームスペース/ユーザ名' 
--docker-password='認証トークン' 
--docker-email='xxx@example.com'
```

:::note info
--docker-emailの値は適当でも問題ありません。
:::


以下のManifestを作成します。

```yaml:signed_nginx.yaml
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: unsigned-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers:
      - name: nginx
        image: iad.ocir.io/idwpqivumvev/scan-test@sha256:bb9c3dd02f145291c5xxxxxxxxxxxxxxxffd293bd2ef556a
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: ocirsecret
```

:::note warn
OKEでイメージの検証を利用する場合は、必ずイメージをダイジェストで指定する必要があります。
イメージのダイジェストはOCIRのコンソール上で確認できます。
:::

このファイルをapplyします。

```sh
kubectl apply -f signed_nginx.yaml
```

結果を確認してみると、署名済みのイメージはPodが作成されていることが分かります。

```sh
$ kubectl get deploy
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
signed-nginx     3/3     3            3           2m54s
unsigned-nginx   0/3     0            0           36m
```

このように、OKEでイメージの検証を行うと、指定された暗号化キーで署名したコンテナイメージのみをデプロイすることができます。

# まとめ

長くなりましたが、OKEやOCIRではコンテナセキュリティを高めるための様々な機能が実装されており、今回その一部を紹介しました。
コンテナでも、セキュリティには十分に注意する必要がありますので、参考にしてみてください。

なお、今回の記事については、2021/12/17(金)に開催された[Oracle Developer Day 2021](https://developer.oracle.com/jp/developer-days-2021-on-demand/)で私が行った「OCIコンテナ関連サービス最新事情〜OKEと周辺サービスの現在地と未来〜」というセッション内でもデモを実施しておりますので、よければご覧ください。（サイト内にアーカイブがあります)

# 参考記事

https://docs.oracle.com/ja-jp/iaas/scanning/using/scanning-images.htm

https://docs.oracle.com/ja-jp/iaas/Content/Registry/Tasks/registrysigningimages_topic.htm

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengenforcingsignedimagesfromocir.htm

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengpullingimagesfromocir.htm#Pulling_Images_from_Registry_during_Deployment