[GCP]Artifact Registryまとめ

Artifact RegistryへDockerイメージを保存する際に調査した情報を、自分用にやさしくまとめた記事。

# 1. 概要
Argifact Registry(略称: GAR)は、アーティファクトを保存して管理できるサービス。
アーティファクトとしてサポートされる形式は、Dockerイメージ、各言語のパッケージ、OSのパッケージである。
具体的には[サポートされている形式](https://cloud.google.com/artifact-registry/docs/supported-formats?hl=ja)に記載されている。

# 2. リポジトリ
GAR上にあらかじめアーティファクトの保存場所になるリポジトリを作成する必要がある。
リポジトリの作成時には、保存対象の形式が何であるかを指定する必要がある。
また、リポジトリのモードを以下の3つから指定する必要がある。
- 標準リポジトリ
- リモートリリポジト
- 仮想リポジトリ

参考: [リポジトリの概要](https://cloud.google.com/artifact-registry/docs/repositories?hl=ja)

## 2.1. 標準リポジトリ
アーティファクトの実体をGCP上に直接保存、管理する通常のリポジトリ。

## 2.2. リモートリポジトリ
読み取り専用のリポジトリであり、GCP外部のリポジトリに存在するアーティファクトを管理するためのプロキシ。
アーティファクトのバージョンを外部リポジトリからダウンロードする際にキャッシュが生成・保存され、次回以降のダウンロードで高速化が期待できる。

## 2.3. 仮想リポジトリ
読み取り専用のリポジトリであり、複数の標準リポジトリ、リモートリポジトリ上のアーティファクトをGCP上で一元管理するためのアクセスポイント。
上流のリポジトリはアップストリームリポジトリと呼ばれる。
複数のアップストリームリポジトリにアーティファクトが存在する場合に備え、アップストリームリポジトリの優先度を設定できる。

## 所感
ググった感じ、リモートリポジトリと仮想リポジトリについてはあまり情報がなく、少なくとも日本での採用事例は少なそう(2024/7/17時点)。


# 3. Dockerイメージの標準リポジトリを扱う
## 3.1. 完全名
Google Cloud API(を使うgloud CLI等のツール)を介してDockerイメージの標準リポジトリを操作する際には、リポジトリおよびDockerイメージの完全名について、命名規則を意識しておく必要がある。

### 3.1.1. リポジトリの完全名
**命名規則**
```
<リポジトリのロケーション(リージョン or マルチリージョン)>-docker.pkg.dev/<プロジェクトID>/<リポジトリ名>
```

例. ロケーション: us-west1, プロジェクトID: my-project, リポジトリ名: my-repo の場合  
```
us-west1-docker.pkg.dev/my-project/my-repo 
```
### 3.1.2. コンテナイメージの完全名
**命名規則**
以下のいずれか
```
<リポジトリの完全名>/<イメージ名>
<リポジトリの完全名>/<イメージ名>:<タグ>
<リポジトリの完全名>/<イメージ名>@<ダイジェスト>
```

**例**
```
us-west1-docker.pkg.dev/my-project/my-repo/my-image
us-west1-docker.pkg.dev/my-project/my-repo/my-image:v1.2.3
us-west1-docker.pkg.dev/my-project/my-repo/my-image@sha256:4d11e24ba8a615cc85a535daa17b47d3c0219f7eeb2b8208896704ad7f88ae2d
```

#### 補足
**ダイジェスト**
イメージ固有のsha256ハッシュ。自動生成され変更不可。

**タグ**
イメージにつけるラベル。手動で設定可能。タグはあるイメージの1バージョンを指すもので、リポジトリ内でユニーク。

タグの挙動: 
- 何もタグを指定せずにイメージをpushするとArtifact Registry上でlatestタグが付く。
- 再度タグを指定せずにイメージをpushするとArtifact Registry上でlatestタグが後にpushしたイメージへ移動する。
- タグを指定してイメージをpushするとArtifact Registry上でそのタグが付く。
- 再度タグを指定してイメージをpushするとArtifact Registry上でそのタグが後にpushしたイメージへ移動する。

### 参考
- [Artifact Registry ロケーション](https://cloud.google.com/artifact-registry/docs/repositories/repo-locations?hl=ja)
- [リポジトリ名とイメージ名](https://cloud.google.com/artifact-registry/docs/docker/names?hl=ja)
- [Container concepts](https://cloud.google.com/artifact-registry/docs/container-concepts)

## 3.2. ローカルのDockerイメージを標準リポジトリへPUSHする
### 3.2.1. 前提
- コンテナイメージの標準リポジトリを作成しておく
- PUSH対象のArtifact Regstryリポジトリリソース、またはプロジェクト の `roles/artifactregistry.writer`ロール に対して PUSH可能なメンバーをバインディングしておく
- 操作するマシン上でDockerをインストールしておく
- Dockerの認証設定を済ませておく
- ローカルのコンテナイメージが存在する

### 3.2.2. 手順
```
# ローカルイメージにArtifact Registryの標準リポジトリ上でのタグを設定する
docker tag <ローカルイメージのID or 名前> <リポジトリの完全名>/<リポジトリ上でのイメージ名>:<タグ>

# 標準リポジトリへpushする
## latestタグがついているローカルイメージをpush
docker push <リポジトリの完全名>/<リポジトリ上でのイメージ名>

## 自身でつけたタグがついているローカルイメージをpush
docker push <リポジトリの完全名>/<リポジトリ上でのイメージ名>:<タグ>
```

## 参考
[イメージを push および pull する](https://cloud.google.com/artifact-registry/docs/docker/pushing-and-pulling?hl=ja)
[Dockerの認証設定](https://cloud.google.com/artifact-registry/docs/docker/authentication?hl=ja)
[[GCP]Artifact Registryへのログイン](https://qiita.com/WisteriaWave/items/27bd24292a5a5f94e45f)