OCI コンテナ・インスタンスでNginxコンテナを実行する

本ブログは、[オラクル・クラウドの個人ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

# 初めに
2022年12月に、<strong>OCI コンテナ・インスタンス</strong>という新サービスがリリースされました。これは、サーバーを管理せずに迅速かつ簡単にコンテナを実行できるサーバーレス・コンピュート・サービスです。コンテナ化されたアプリケーションは、Kubernetes よりも簡単な方法で実行できます。

前回の[ブログ](https://qiita.com/liu-wei/items/4ec173280cb32fb5e31a)では、OCI Computeインスタンスで Nginx コンテナを利用する方法を紹介しました。今回はOCIコンテナ・インスタンスを作成し、その上でNginx コンテナを実行する方法を紹介します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/e8d211c2-9eec-d198-44d3-46136d39931c.png", width="650">

__目次__

- [1. 事前準備](#1-事前準備)
  - [1-1. 認証トークンの生成](#1-1-認証トークンの生成)
  - [1-2. IAMポリシー](#1-2-iamポリシー)
  - [1-3. レポジトリの作成](#1-3-レポジトリの作成)
  - [1-4. Dockerイメージを OCI レジストリにプッシュ](#1-4-dockerイメージを-oci-レジストリにプッシュ)
- [2. コンテナ・インスタンスの作成](#2-コンテナインスタンスの作成)
- [3. Nginxへの接続](#3-nginxへの接続)

# 1. 事前準備
## 1-1. 認証トークンの生成
Docker イメージを OCI レジストリにプッシュするには、事前に認証トークンを生成する必要があります。 生成方法は、[ドキュメント](https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionsgenerateauthtokens.htm)をご参考ください。

## 1-2. IAMポリシー
a) 管理者以外のユーザーを利用し、コンテナ・レジストリにイメージを<strong>PUSH</strong>する場合、以下のようなポリシーを作成します。

テナンシ・レベルの場合：
```
Allow group OCIR-Repo-Group to use repos in tenancy
```
コンパートメント・レベルの場合：

```
Allow group OCIR-Repo-Group to use repos in compartment <Compartment_Name>
```
※、対象ユーザーをOCIR-Repo-Groupに追加します。

b) コンテナ・インスタンスがコンテナ・レジストリからイメージを<strong>PULL</strong>できるように、動的グループとIAMポリシーを作成します。

__動的グループ__
```
ALL {resource.type='computecontainerinstance'}
```

__IAMポリシー__
テナンシ・レベルの場合：
```
Allow dynamic-group ContainerInstanceDynamicGroup to read repos in tenancy
```

コンパートメント・レベルの場合：
```
Allow dynamic-group ContainerInstanceDynamicGroup to read repos in compartment <Compartment_Name>
```

:::note
この例では<strong>プライベート・リポジトリ</strong>を利用するため、上記のように動的グループとポリシーを作成する必要があります。パブリック・リポジトリを利用する場合は、b)のステップは不要です。
:::


## 1-3. レポジトリの作成
メニュー → 開発者サービス → コンテナとアーティファクト → コンテナ・レジストリ → 「レジストリの作成」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/f1426770-eb52-a71f-859a-e90a7df9c957.png)
リポジトリ名を入力し、「レジストリの作成」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/49e594e1-0a4a-7cc8-40ae-a914c70dc1b8.png", width="450">
作成後、以下のようになります。<strong>ユーザー</strong>と<strong>ネームスペース</strong>をメモしておいてください（後ほど使います）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/4371233a-874f-0b0a-0512-58d8563cdda4.png)

## 1-4. Dockerイメージを OCI レジストリにプッシュ
この例では、dockerfile を使用して、Dockerイメージをビルドします。 このステップは、OCI 
Computeインスタンスで実行されます。 なお、テストのために Nginx のウェルカム・ページを置き換えます。 イメージが作成されたら、それをOCI レジストリにプッシュします。

もし、Computeインスタンスに docker がインストールされていない場合は、まずそれをインストールしてください。 (以前のブログの [Step-1](https://qiita.com/liu-wei/items/4ec173280cb32fb5e31a#1-docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) をご参照)

:::note
dockerをインストールした後、起動する必要がありますので忘れないで下さい。
:::

__a) dockerfile の準備__
```bash
[opc@linux8-nginx ~]$ cat dockerfile
FROM nginx
RUN mkdir -p /usr/share/nginx/html
RUN echo "<h1>Hello Nginx</h1>" > /usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html
EXPOSE 80
[opc@linux8-nginx ~]$
```
__b) イメージのビルド__
dockerファイル名を指定したい場合、引数`-f <file_name>`を追加してください。
```
[opc@linux8-nginx ~]$ sudo docker build -t nginx_demo .
[+] Building 9.6s (7/7) FINISHED
 => [internal] load build definition from dockerfile                                                                                        0.0s
 => => transferring dockerfile: 250B                                                                                                        0.0s
 => [internal] load .dockerignore                                                                                                           0.0s
 => => transferring context: 2B                                                                                                             0.0s
 => [internal] load metadata for docker.io/library/nginx:latest                                                                             2.1s
 => [1/3] FROM docker.io/library/nginx@sha256:6650513efd1d27c1f8a5351cbd33edf85cc7e0d9d0fcb4ffb23d8fa89b601ba8                              5.3s
......
 => [2/3] RUN mkdir -p /usr/share/nginx/html                                                                                                0.7s => [3/3] RUN echo "<h1>Hello Nginx</h1>" > /usr/share/nginx/html/index.html                                                                0.9s
 => exporting to image                                                                                                                      0.6s
 => => exporting layers                                                                                                                     0.6s
 => => writing image sha256:19735e14b0a66d10d4b268c01b9da10110823f4e9619fd9fddfb2e573054d067                                                0.0s
 => => naming to docker.io/library/nginx_demo                                                                                               0.0s
[opc@linux8-nginx ~]$ sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx_demo   latest    19735e14b0a6   7 minutes ago   142MB
[opc@linux8-nginx ~]$
```

dockerを起動
```
sudo docker run --rm -d -p 80:80 --name web nginx_demo
sudo docker ps
```

curl コマンドで確認します。 （Webブラウザでも構いません。）

```bash
[opc@linux8-nginx ~]$ curl localhost:80
<h1>Hello Nginx</h1>
[opc@linux8-nginx ~]$
```

__c) イメージのタグ付け__
```bash
[opc@linux8-nginx ~]$ sudo docker tag 19735e14b0a6 nrt.ocir.io/<namespace>/repo-nginx:latest
[opc@linux8-nginx ~]$ sudo docker images
REPOSITORY                            TAG       IMAGE ID       CREATED          SIZE
nginx_demo                            latest    19735e14b0a6   19 minutes ago   142MB
nrt.ocir.io/<namespace>/repo-nginx    latest    19735e14b0a6   19 minutes ago   142MB
[opc@linux8-nginx ~]$
```

__d) OCI コンテナ・レジストリにログイン__
コマンド： <font color="blue">docker login</font> `<region-key>.ocir.io`
\<region-key>: 東京リージョンの場合、<font color=blue>nrt</font> となります。その他のリージョンについては、こちらの[一覧](https://docs.oracle.com/ja-jp/iaas/Content/General/Concepts/regions.htm)を参照してください。

コマンドを実行すると、ユーザー名とパスワードの入力が求められます。

<strong>ユーザー名</strong>：OCI コンテナ・レジストリの画面に表示されている<strong>ネームスペース</strong>と<strong>ユーザー名</strong>を入力 （[Step 1-2](#1-2-レポジトリの作成) をご参照ください。それらの間の「<font color=blue>/</font>」を忘れずに。）
<strong>パスワード</strong>：[Step 1-1](#1-1-認証トークンの生成) で生成された認証トークンを入力
```bash
[opc@linux8-nginx ~]$  sudo docker login nrt.ocir.io
Username: <namespace>/<user>
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[opc@linux8-nginx ~]$
```

__e) Docker イメージのプッシュ__
<strong>コマンド</strong>：`docker push <target-tag>`
<strong>例</strong>: `docker push nrt.ocir.io/<namespace>/repo-nginx:latest`
```bash
[opc@linux8-nginx ~]$ sudo docker push nrt.ocir.io/<namespace>/repo-nginx
Using default tag: latest
The push refers to repository [nrt.ocir.io/<namespace>/repo-nginx]
......
latest: digest: sha256:bc5ca8e3ea4715e7ab4141542cc9c3e30b51358c62f0ae8aa6412c00c0315775 size: 1983
[opc@linux8-nginx ~]$
```

プッシュ後、コンテナ・レジストリの中身を確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/50e50df1-a6ca-63e6-2e6f-327fa63be8dd.png)

# 2. コンテナ・インスタンスの作成
コンテナ・インスタンス → 「コンテナ・インスタンスの作成」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/cc94c591-0d72-6374-33d5-bbb8cf41cc15.png)

コンテナ・インスタンス名を入力し、可用性ドメインとシェイプはデフォルトのままにします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/d86ab63f-2086-6ad9-be53-b5426cb78066.png", width="650">

VCNとサブネットを指定し、「次へ」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/1fc95ca0-5049-9370-56de-d31aa925cb08.png", width="650">

コンテナ名（任意）を入力し、「イメージの選択」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/0fe4f4cf-af8c-98d0-3ff5-d24669c49eb3.png", width="550">

「<font color=blue>OCIコンテナ・レジストリ</font>」タブで、リポジトリとイメージを選択し、「イメージの選択」ボタンをクリックして戻ります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/8e4300de-f9ee-668e-00df-6834b0fe61ba.png", width="650">

イメージの URL は次のようになります。 「次へ」をクリックして詳細情報を確認します。
例：`<region-id>.ocir.io/<namespace>/<repo-name>:<tag>`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/bf5c6de1-f10e-32c3-f053-0621cc56baa9.png", width="650">

情報を確認した上、「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/7915924c-dae7-6872-f8f5-0416f181ae5e.png)
コンテナ・インスタンスはすぐに作成されます。<font color=blue>ACTIVE</font> になったら、<strong>パブリック IP</strong> をコピーしておいてください（接続用）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/fb23ccf0-7c61-b171-38b2-50e2f526852d.png)

# 3. Nginxへの接続
Web ブラウザーを開き、URL ボックスにコンテナ・インスタンスの<strong>パブリック IP</strong> を入力します。(例：`http://XXX.XXX.210.138`)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/6d50f241-5c96-704b-5fac-659a3f8df832.png", width="450">

Computeインスタンスから接続してみます。 
コマンド：`curl <public_ip>`、或いは`curl <public_ip>:80`
```
[opc@linux8 ~]$ curl XXX.XXX.210.138
<h1>Hello Nginx</h1>
[opc@linux8 ~]$
```

ここまで、Nginxの動作確認は完了です。OCI ロードバランサーの<strong>バックエンド・サーバ</strong>としても動作できます。コンテナ・インスタンスを LB のバックエンドに追加する時、<strong>LB作成後</strong>、コンテナ・インスタンスの<strong>IPアドレス</strong>を指定してください（詳細を省略）。

以上

----
__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[OCIでNginxのDockerイメージを利用する](https://qiita.com/liu-wei/items/4ec173280cb32fb5e31a)
[OCI コンテナ・インスタンスと標準VMでのコンテナの実行の違い](https://qiita.com/liu-wei/items/41421b785f87b9429207)

----
__オフィシャル・リンク__
[製品サイト](https://www.oracle.com/jp/cloud/cloud-native/container-instances/)
[公式ドキュメント](https://docs.oracle.com/ja-jp/iaas/Content/container-instances/home.htm)
[Announcing the availability of OCI Container Instances](https://blogs.oracle.com/cloud-infrastructure/post/announcing-the-availability-of-oci-container-instances) （英語）
[Getting started with OCI Container Instances](https://blogs.oracle.com/cloud-infrastructure/post/getting-started-with-oci-container-instances)（英語）
[Container Instancesに関するよくある質問](https://www.oracle.com/jp/cloud/cloud-native/container-instances/faq/)
[コンテナ・インスタンスのIAMポリシー](https://docs.oracle.com/ja-jp/iaas/Content/container-instances/permissions/policy-reference.htm)