Container-Optimized OS を利用して GCE上にコンテナを構築する

# はじめに
GC上でデータ移行を行うためにそれの仕組みを検討した結果、GCEでコンテナを利用することになりました。
その際のGCEとその中でのコンテナ起動を試します。
※デプロイ方法及びCI/CDによるコンテナリリース方法は以下で記載
https://qiita.com/hirosait/items/f5580384ac1c89dcc9f7

# 経緯
そもそもなんでそれを利用するのか、、を軽く経緯説明

## ざっくり検討
案件の都合でデータ移行が必要となりデータ移行で利用するインフラ構成を検討した。
案としてかっこいいものだと以下2点

- Cloud Batch
- Cloud Run

ただこれらはVPC内のプライベートリソースへのアクセスができなかったり、
処理時間に懸念があったりと、お互いが合体すれば要件にマッチしたが今回はマッチしない
悩ましいけど確実なGCE(コンテナは使わない)でいくことになった

## 少し細かく検討
GCEを使うにあたって頭を悩ませたのがツールリリースした際のデプロイ方法。
GCEに対して、Cloud Build でやろうとして記事をさがすと無理やりscpで静的コンテンツをリリースしたり、git cloneしてゴニョゴニョしたりと、どうもスッキリ行く方法がなく、一時的な環境に対して、Jenkinsを新たにたてるのも違うとなり、、思いついたのが、GCE上にコンテナを構築するという方法で「Container-Optimized OS」なるものの記事を見つけました、、

# Container-Optimized OS 
やっと本題

https://cloud.google.com/compute/docs/containers

## Container-Optimized OS というものがあることを知る
上記したURLにありますが、以下がシンプルでまさにそのとおりでした。
> Container-Optimized OS は、 Docker コンテナの実行用に最適化された、 Compute Engine VM 用のオペレーティング システム イメージです。Container-Optimized OS を使用すると、Google Cloud Platform で Docker コンテナを迅速、効率的、かつ安全に起動できます。

## 起動するにはGCEで何がいるか

https://cloud.google.com/compute/docs/containers

それでは作成画面で見ていきます。赤枠にコンテナ設定箇所があります。
![スクリーンショット 2022-12-17 1.20.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/08d48766-32b3-6d30-d364-0830c2979526.png)


「DEPLOY CONTAINER」を開くと以下のような設定箇所があります。
![スクリーンショット 2022-12-17 2.05.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/c1d42344-37c8-0440-7b34-7dca74817960.png)

イメージはもちろんですが、こちらで特権ユーザを設定したり、環境変数を設定したり、データを永続化するためにボリュームをマウントしたりすることも可能です。

これらを設定してVMを作成するとVMの起動と併せてコンテナが起動します。

## 起動結果
以下のような形でSSH接続し、docker ps で コンテナの状態を確認できます。
```
h_saito@h-saito-test-container ~ $ docker ps
CONTAINER ID   IMAGE                                                                             COMMAND                  CREATED          STATUS          PORTS     NAMES
61ad2c0a5339   gcr.io/articulate-sol-739/h-saito-test:161f568516d2f40ac722ddd62495c69365ce5443   "php artisan serve -…"   55 seconds ago   Up 54 seconds             klt-h-saito-test-container-ecce
aae3b3c7cdf7   gcr.io/stackdriver-agents/stackdriver-logging-agent:1.9.8                         "/entrypoint.sh /usr…"   56 seconds ago   Up 55 seconds             stackdriver-logging-agent
```
もちろんdocker execでコンテナの中にも入れます。
```
h_saito@h-saito-test-container ~ $ docker exec -it klt-h-saito-test-container-ecce bash
bash-4.2#
```
今回Laravelの入ったコンテナを起動しているのですが、ポートのLISTEN状態も見てみます。
他にもでてますが、dockerfile内でEXPOSEしたポートが空いています。
※EXPOSEしないとうまく公開できないみたいです、、
```
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN
```
当たり前ですが、外部からこのポートでアクセスしたい場合、GCEのExternalIPに対する対象ポートをFWのインバウンド許可をしておく必要があります。
試しにcurlでアクセスすると以下の通り見れていることがわかります(一部抜粋)。
※GCEでなくてもローカルの端末で動いていれば動くのは当たり前ですが、、、
```
h_saito@h-saito-test-container ~ $ curl http://127.0.0.1:8000
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
```
試しに外部からアクセスしてみます。
![スクリーンショット 2022-12-17 2.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/85cdf2b8-63e5-3a7b-fd8a-24c4fec90857.png)

特に問題なくアクセスできました。

## 気になる点を1つ試す

仮にGCE上のコンテナのリソースが圧迫した場合、Webサービスなどであれば、instance templateを組みスケールことで解消できそうです。
が、今回はデータ移行目的ということもあり、そういった対応はできないため、インスタンスタイプを増強するとなった場合、dockerのリソースはどう考えればいいか？と思い、試しにインスタンスタイプを変えて状態を確認しました。

**以下が最初の状態**
![スクリーンショット 2022-12-16 19.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/bd785d63-8566-af52-4910-77cbfa387c12.png)

**以下がインスタンスタイプ変更後の状態**
![スクリーンショット 2022-12-16 19.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1720034/580b666b-b31b-97ef-9355-bb2c436d585f.png)


docker statsで確認したところ、変更後ではLimitsの値が増加しており、増強したものもdockerへ割り当てられていることがわかりますので、今後、変更時も安心できました。

# 所感
本当はCI/CDまで書こうと思いましたが、ちょっと長くなってしまったので、起動までとします。

※記載済み
https://qiita.com/hirosait/items/f5580384ac1c89dcc9f7

dockerを起動するからといって、dockerを入れる必要もなく、dockerのリソース変更も必要なく、気にするのはdocker imageの内容くらいで良さそうで、さすがだな、と思いました。
今回はデータ移行でしたが、これ以上にWebシステムなどで、スケールをコントロールしたかったり、マネージドに頼りたい場合などは、GKEやCloud Run 、内容によってはたまた App Engine など検討する必要があるかな、と思いましたが、CI/CDを気にしたり、簡易的にコンテナで動かしたい場合、Container-Optimized OS はとてもメリットあるな、と思いました。