OpenShift on IBM Cloud で IBM Cloud Container Registry にあるイメージを使う

## やりたいこと

OpenShift (on IBM Cloud) でアプリケーションを公開するときに、既存のコンテナイメージを使いたい。
コンテナレポジトリーとして IBM Cloud Container Registry を使いたい。

## ImagePullSecretの設定

### `default`プロジェクトではデフォルトで使える

`default`プロジェクトにはImagePullSecretがクラスター作成時に一緒に作られています。

```sh
$ oc get secret -n default | grep icr
NAME                   TYPE                                  DATA   AGE
default-au-icr-io      kubernetes.io/dockerconfigjson        1      124d
default-de-icr-io      kubernetes.io/dockerconfigjson        1      124d
default-icr-io         kubernetes.io/dockerconfigjson        1      124d
default-jp-icr-io      kubernetes.io/dockerconfigjson        1      124d
default-uk-icr-io      kubernetes.io/dockerconfigjson        1      124d
default-us-icr-io      kubernetes.io/dockerconfigjson        1      124d
```

`default`プロジェクトにアプリをデプロイする場合は、後述のマニフェストファイルへの記載やService Accountへの追加などをしなくてもイメージを指定すればpullできるようになっています。


### `default`プロジェクト以外でも使えるようにする

すでにある`default`プロジェクトのImagePullSecretをコピーしてしまいましょう。
今回は`demo`プロジェクトを作成し、ここに設定することにします。

```sh
$ oc get secret default-jp-icr-io -o yaml -n default | sed 's/default/demo/g' | oc -n demo create -f -
secret/demo-jp-icr-io created
```
> 上記は東京リージョンのレジストリーに対するImagePullSecretを作成しています。
> 他のリージョンで実行したい場合は`default-jp-icr-io`の`jp`部分を変えてください。

上記コマンド実行後、確認してみるとコピーされています。

```sh
$ oc get secret | grep icr
demo-jp-icr-io        kubernetes.io/dockerconfigjson        1      35s
```

## ImagePullSecretを使ってアプリをデプロイする

以下の2種類の方法があります。

- マニフェストファイルにImagePullSecretを記載する
- Service AccountにImagePullSecretを追加する

### マニフェストファイルにImagePullSecretを記載する

`spec.imagePullSecrets`を追加し、ImagePullSecretを記載します。
この方法だと毎回マニフェストファイルに記載する必要がありますが、プロジェクト内のすべてのPodにレジストリーへのアクセスをさせたくない場合には有効です。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: mytodo
      image: jp.icr.io/kishida/mytodo:1.0
  imagePullSecrets:
    - name: demo-jp-icr-io
```

### Service AccountにImagePullSecretを追加する

`default`という名前のService AccountにImagePullSecretを追加します。
この方法だとImagepullSecretがPod作成時に自動で付与されるようになるので、いちいちマニフェストファイルで指定する必要はありません。

まずは初期状態のService Account `default`の中身を確認してみましょう。

```sh
$ oc describe sa default
Name:                default
Namespace:           demo
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-xzfhd
Mountable secrets:   default-token-hcxjk
                     default-dockercfg-xzfhd
Tokens:              default-token-hcxjk
                     default-token-wwlw2
Events:              <none>
```

ここにImagePullSecretを追加します。

```sh
$ oc patch -n demo sa/default --type='json' \
-p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"demo-jp-icr-io"}}]'
serviceaccount/default patched
```

追加できたか確認してみます。

```sh
$ oc describe sa default
Name:                default
Namespace:           demo
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-xzfhd
                     demo-jp-icr-io           ← 追加されたImagePullSecret
Mountable secrets:   default-token-hcxjk
                     default-dockercfg-xzfhd
Tokens:              default-token-hcxjk
                     default-token-wwlw2
Events:              <none>
```

これでService AccountにImagePullSecretが追加されたので、あとは通常通りイメージを指定するだけでpullできるようになっています。

## 参考リンク

https://cloud.ibm.com/docs/openshift?topic=openshift-images