OCI Container Instancesで利用するコンテナレジストリの資格情報をOCI Vaultから取得してみる

# はじめに

昨年末にContainer Instancesというサーバレスのコンテナ実行基盤がリリースされました。

こちらの記事でContainer Instancesを利用してWordPress環境を構築する方法が紹介されています。

https://qiita.com/cyberblack28/items/8a3924acc42224b954b6

Container Instanceでは、プライベートなコンテナレジストリからもイメージをPullできるようになっており、コンソールから資格情報を入力することができるようになっています。

しかし、OCI Vaultを利用することで、資格情報をよりセキュアに保管したり、再利用性を高めたりすることができます。

この記事では、Container Instancesで利用するコンテナレジストリの資格情報をOCI Vaultを利用して管理、利用する方法を見ていきます。

# 事前準備

いくつか事前準備があるので、そちらを実施していきます。

## OCIRへのイメージの登録

今回は、プライベートなコンテナレジストリとしてOCIRを利用します。

OCIRにDocker HubからPullしてきたNGINXイメージをPushし、以降の手順で利用していきます。
OCIRにPushしたイメージはデフォルトでプライベートになります。
（もちろん、ユーザが意図的にパブリックにすることもできます）

まずは、Docker HubからNGINXイメージをPullします。

```sh
docker image pull nginx
```

Pullされたことを確認します。

```sh
docker image ls
REPOSITORY                                             TAG         IMAGE ID      CREATED       SIZE
docker.io/library/nginx                                latest      448a08f1d2f9  13 days ago   147 MB
```

これをOCIRにPushします。

まずは、OCIRにログインします。
今回は東京リージョンを利用します。

```sh
docker login nrt.ocir.io
```

この際に入力するクレデンシャルは以下の通りです。
これを後ほどOCI Vaultに登録し、Container Instancesから利用します。

- username: `OCIで利用するアカウントユーザ`
- password: `認証トークン`

上記の詳細は、下記のドキュメントをご確認ください。

https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionslogintoocir.htm

ログインしたら、先ほどPullしたNGINXイメージをPushします。
まずはOCIRへPushするためにタグを作成します。

```sh
docker image tag nginx nrt.ocir.io/<オブジェクトストレージネームスペース>/nginx
```

`<オブジェクトストレージネームスペース>`はこちらでご確認ください。

https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/understandingnamespaces.htm

```sh
docker image push nrt.ocir.io/<オブジェクトストレージネームスペース>/nginx
```

先ほど記載した通り、OCIRへPushしたイメージはデフォルトでプライベートになっているので、このイメージは資格情報がなければPullすることができません。

これでOCIRへのイメージの登録は完了です。

## OCI Vaultへのコンテナレジストリの資格情報の登録

OCI Vaultを作成します。

OCIコンソール画面から、「アイデンティティとセキュリティ」 => 「ボールト」をクリックします。

![スクリーンショット 2023-05-17 15.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/dcba3df8-31eb-5b1b-8714-f455cd8214c1.png)


遷移した画面で「ボールトの作成」をクリックします。

![スクリーンショット 2023-05-17 15.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/31f92752-15da-ac14-71fc-5eae483e0c27.png)

以下のパラメータを入力し、「ボールトの作成」をクリックします。

|  key  | value  |
| ---- | ---- |
|  名前  | container instances  |

![スクリーンショット 2023-05-17 15.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/659b19d8-ab28-4cd0-5086-85a5c99f7c5a.png)

「キーの作成」をクリックします。

![スクリーンショット 2023-05-17 15.23.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/18fdc291-f202-2dcd-9874-15d5c4c41fe1.png)

以下のパラメータを入力し、「ボールトの作成」をクリックします。

|  key  | value  |
| ---- | ---- |
|  名前  | container instances  |

![スクリーンショット 2023-05-17 15.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/b6f31c15-f1f9-ba07-7523-0b7358bea621.png)

画面右端にある「シークレット」をクリックします。

![スクリーンショット 2023-05-17 15.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/29f91416-1fbb-de11-4498-9db85ca30f2a.png)

「シークレットの作成」をクリックします。

![スクリーンショット 2023-05-17 15.48.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/01cb5834-5ecc-d09e-1e51-324de275ff80.png)

以下のパラメータを入力し、「ボールトの作成」をクリックします。

|  key  | value  |　備考 |
| ---- | ---- |---- |
|  名前  | ocir-token  |
|  暗号化キー  | container instances  |
|  シークレットコンテンツ  |  `{"username": "<OCIで利用するアカウントユーザ>", "password": "<認証トークン>"}` | 前手順での`docker login`で利用したクレデンシャル

![スクリーンショット 2023-05-17 15.54.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/d2f8f86b-92b0-2486-f9df-37af3558379a.png)

これで、OCI Vaultへのコンテナレジストリの資格情報の登録は完了です。

## 動的グループ/ポリシーの作成

先ほどOCI Vaultに登録したクレデンシャルをOCI Container Instancesから読み取れる必要があるので、ここではその設定を行なっていきます。

まず、Container Instancesを含んだ動的グループを作成します。
今回は、すべてのContainer InstancesがOCI Vault上のシークレットを読み取れるように設定します。

今回設定する動的グループとポリシーは以下の通りです。

|  key  | value  |　備考 |
| ---- | ---- |---- |
| 動的グループ  | ALL {resource.type='computecontainerinstance'}  |　すべてのContainer　Instancesを含めた動的グループ
|  ポリシー  | allow dynamic-group <動的グループ名> to read secret-bundles in compartment <compartment名>  |　動的グループ（すべてのContainer Instances）がシークレットを読み取り可能にするポリシー

動的グループとポリシーは以下をご確認ください。

https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingdynamicgroups.htm

https://docs.oracle.com/ja-jp/iaas/Content/Identity/policieshow/how-policies-work.htm

これで、事前準備は完了です。

# Container Instancesの作成

Container Instancesを作成します。

今回実施するように、コンテナレジストリの資格情報をOCI Vaultから取得してContainer Instancesを作成する場合、コンソールからの作成はできません。

そのため、OCI CLIを利用してContainer Instancesを作成します。

今回は以下のようなJSONテンプレートを作成したので、こちらをコピーして利用してください。(東京リージョンの想定です)

```json:ci.json
{
  "availabilityDomain": "TGjA:AP-TOKYO-1-AD-1",
  "compartmentId": "<コンパートメントOCID>",
  "containers": [
    {
      "imageUrl": "nrt.ocir.io/<オブジェクトストレージネームスペース>/nginx"
    }
  ],
  "imagePullSecrets": [
    {
      "registryEndpoint": "nrt.ocir.io/<オブジェクトストレージネームスペース>",
      "secretId": "<OCI Vaultに作成したSecretのOCID>",
      "secretType": "VAULT"
    }
  ],
  "shape": "CI.Standard.E3.Flex",
  "shapeConfig": {
    "memoryInGBs": 8.0,
    "ocpus": 1.0
  },
  "vnics": [
    {
      "subnetId": "<サブネットOCID>"
    }
  ]
}
```

このJSONファイルを利用して以下のコマンドを実行します。

```sh
oci container-instances container-instance create --from-json file://ci.json
```

結果が以下のようになればプロビジョニングされている状態です。

```json
{
  "data": {
    "availability-domain": "TGjA:AP-TOKYO-1-AD-1",
    "compartment-id": "ocid1.compartment.oc1..aaaaaaaaw4afdxxxxxxxxxxxxxxxxmrzgdq",
    "container-count": 1,
    "container-restart-policy": "ALWAYS",
    "containers": [
      {
        "container-id": "ocid1.computecontainer.oc1.ap-tokyo-1.anxhiljrssl65iqaxxxxxxxxxxxxx7syrwgwjalivikfa",
        "display-name": "computecontainer-dcc86a86-02c9-4b73-8696-7b72e7bc2b6c"
      }
    ],
    "defined-tags": {},
    "display-name": "computecontainerinstance-57683e2f-c9cc-43b9-9d98-549808ee0a28",
    "dns-config": null,
    "fault-domain": null,
    "freeform-tags": {},
    "graceful-shutdown-timeout-in-seconds": 0,
    "id": "ocid1.computecontainerinstance.oc1.ap-tokyo-1.anxhiljrssl65iqa24bztzxxxxxxxxxxxxxxxsuoj7x33vcpa",
    "image-pull-secrets": [
      {
        "registry-endpoint": "nrt.ocir.io/<オブジェクトストレージネームスペース>",
        "secret-id": "ocid1.vaultsecret.oc1.ap-tokyo-1.amaaaaaassl65iqarvs76xxxxxxxxxxxxxxxkygo54hq",
        "secret-type": "VAULT"
      }
    ],
    "lifecycle-details": "Creating",
    "lifecycle-state": "CREATING",
    "shape": "CI.Standard.E3.Flex",
    "shape-config": {
      "memory-in-gbs": 8.0,
      "networking-bandwidth-in-gbps": 1000.0,
      "ocpus": 1.0,
      "processor-description": "2.25 GHz AMD EPYC\u2122 7742 (Rome)"
    },
    "system-tags": {},
    "time-created": "2023-05-18T04:55:54.370000+00:00",
    "time-updated": "2023-05-18T04:55:54.370000+00:00",
    "vnics": [
      {
        "vnic-id": null
      }
    ],
    "volume-count": 0,
    "volumes": []
  },
  "etag": "1edc7d56b78194b5db33469xxxxxxxxxdcafb23b52539ac24f6e",
  "opc-work-request-id": "ocid1.computecontainerworkrequest.oc1.ap-tokyo-1.abxhiljrjmk6wl5uzfoczgtthuxxxxxxxxxxxxdmi4zdmkwelr3adq"
}
```

コンソールから確認してみましょう。

![スクリーンショット 2023-05-18 14.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/b86c27d3-9613-ccec-e172-b6f8f11f3705.png)

コンテナイメージの情報が表示され、先ほどPushしたコンテナイメージが取得できていることが確認できます。

![スクリーンショット 2023-05-18 14.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/fe1171bf-9bfc-239d-adca-a528e446a922.png)


このようにOCI Vaultに格納されているシークレットの情報を利用してOCIRのコンテナイメージを取得することができました。

# まとめ

この記事ではContainer Instances作成時に利用するコンテナレジストリの資格情報をOCI Vaultで管理、利用するという方法を紹介しました。
これを利用して、セキュアかつ再利用性の高い形でコンテナレジストリの資格情報を管理していきましょう！！

# 参考情報

https://docs.oracle.com/ja-jp/iaas/Content/container-instances/vault-secrets-image-authorization.htm