Docker Hubで配布されているDocker ImageをGoogle Container Registry に push してそのImageを元にVMを起動する

## 注意

本記事は自分用のメモの為、体裁が整っていません。ご了承ください。

## 記事を書く動機

以下のようなケースに対処する必要があり、手順などをアウトプットするため。

- Digdag, Embulk サーバー構築用の Docker Image を（Docker Hubで）共有してもらい、
- それを用いてGCPのVMを立ててサーバー構築する

## 参考ページ

- [Container Registry のクイックスタート](https://cloud.google.com/container-registry/docs/quickstart)
    - このドキュメントは 「Container Registry にローカルで用意したDocker Imageをpushする方法」と逆に「Container Registry からDocker Imageをpullする方法」が書かれている
    - 本記事では、前者の箇所を参考にした
- [Google Cloud での Container Registry の使用](https://cloud.google.com/container-registry/docs/using-with-google-cloud-platform)
- [Cloud-Config 経由で Docker コンテナを開始する](https://cloud.google.com/container-optimized-os/docs/how-to/run-container-instance?hl=ja#starting_a_docker_container_via_cloud-config)
- [インスタンスの作成と構成](https://cloud.google.com/container-optimized-os/docs/how-to/create-configure-instance)

## 始める前に

1. Cloud Console のプロジェクト [セレクタページ](https://console.cloud.google.com/projectselector2/home/dashboard)で、Cloud プロジェクトを選択または作成します。
2. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。（[参考](https://cloud.google.com/billing/docs/how-to/modify-project)）
3. [Container Registry API](https://console.cloud.google.com/flows/enableapi) を有効にします。
4. [Cloud SDK をインストール](https://cloud.google.com/sdk/docs)して初期化します。
5. [Docker をインストール](https://docs.docker.com/install/linux/docker-ce/ubuntu/)します。
    1. Ubuntu, debianなどの場合は、`sudo usermod -a -G docker ${USER}`＋再起動により、`sudo`なしで`docker`コマンドを実行できるようにしましょう

## 手順一覧

1. Docker Imageを Docker Hub から pullする
2. (pullした)Docker Image を Container Registry にpushする
3. Container Registry に push したDocker Imageを元にVMを起動する
4. 課金されないようにクリーンアップ

## 1. Docker Imageを Docker Hub から pullする

今回は例として、busyboxを使います。

```bash
docker pull busybox:latest
# check image
docker image ls
REPOSITORY  TAG     IMAGE ID      CREATED       SIZE
busybox     latest  6d5fcfe5ff17  8 months ago  1.22MB
```

## 2. (pullした)Docker Image を Container Registry にpushする

### 2.1. gcloud コマンドライン ツールを認証ヘルパーとして使用するように docker を構成する

以下、参考ページより引用

> イメージを push または pull するには、gcloud コマンドライン ツールを使用して Container Registry へのリクエストを認証するように Docker を構成する必要があります。これを行うには、次のコマンドを実行します（実行する必要があるのは一度だけです）。

```bash
gcloud auth configure-docker
```

### 2.2. イメージにレジストリ名をタグ付けする

`docker push` は通常だとDocker Hubにpushします。特定の場所にpushしたい場合は、レジストリ名のタグを書き換えることで制御するようです。

参考ページより引用
> Docker イメージを Container Registry に push する前に、そのイメージにレジストリ名をタグ付けする必要があります。Docker イメージにレジストリ名をタグ付けすると、イメージを特定の場所に push するように docker push コマンドが構成されます。このクイックスタートでは、ホストの場所は gcr.io です。Docker イメージにタグを付けるには、次のコマンドを実行します。

```bash
docker tag busybox gcr.io/[PROJECT-ID]/busybox:v1
# check img
REPOSITORY                   TAG  IMAGE ID      CREATED       SIZE
gcr.io/[PROJECT-ID]/busybox  v1   6d5fcfe5ff17  8 months ago  1.22MB
```

### 2.3. イメージを Container Registry に push する

```bash
docker push gcr.io/[PROJECT-ID]/busybox:v1
```


## 3. Container Registry に push したDocker Imageを元にVMを起動する

<font color=red>※一旦GUIでVM起動するケースを考える</font>

GCPのダッシュボード画面から `ComputeEngine->VMインスタンス` という流れでVMインスタンス起動画面に移行する。

VM起動画面において、コンテナイメージからインスタンス生成する旨を入力する（下図）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181972/207ea2ec-59ab-1627-72ea-a6db995a8b1f.png)

`コンテナイメージ`には、例に記載されたように事前にpushしたコンテナイメージのパスを記載する。
ContainerRagistryに保存しているコンテナイメージを指定する際は、`gcr.io/...` というパスになる。

※本VMと同一プロジェクト内のGCRに保存されているイメージに対してはデフォルトでpullする権限が与えられているのでアクセス権限周りは調整する必要はない。そうでない場合は、イメージをpullしようとするサービスアカウントに対して、コンテナイメージを格納しているGCSバケットに対して適切なアクセス権限を付与する必要がある。
（[参考](https://cloud.google.com/container-registry/docs/using-with-google-cloud-platform?hl=ja#compute)）

あとはVMインスタンス作成ボタンを押すだけ。

## 4. 課金されないようにクリーンアップ

### 4.1. ContainerRegistryのクリーンアップ

[Google Cloud での Container Registry の使用](https://cloud.google.com/container-registry/docs/using-with-google-cloud-platform)によれば、

```bash
gcloud container images delete gcr.io/[PROJECT-ID]/busybox:v1 --force-delete-tags
```

で実行できるとのことだが、以下のエラーにより`gcloud`コマンドからのDocker Image 削除ができなかった。

```bash
ERROR: (gcloud.container.images.delete) [gcr.io/[PROJECT-ID]/busybox:v1] is not a valid name. Expected tag in the form "base:tag" or "tag" or digest in the form "sha256:<digest>"
```

（現在調査中……）

今回は、Google Cloud ConsoleよりGCRの該当イメージを削除する。

つもりが、見当たらない。。。。（？）

### 4.2. ComputeEngineのクリーンアップ

Google Cloud Console でVMインスタンスを削除します。