Red Hat OpenShift on IBM Cloudに自作のOperatorカタログを登録する

# 目的

OpenShiftクラスターにはデフォルトでコミュニティやRed HatのOperatorが登録され、カタログ表示されています。今回はカタログを自作してOpenShiftのWebコンソールから使えるようにしてみます。

# 手順

## 参考

公式のドキュメントが参考になります。

https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/operators/olm-managing-custom-catalogs

## Operator Bundleの作成

検証用のOperator Bundleを作成します。

```
$ mkdir hello-operator
$ cd hello-operator/
$ operator-sdk init --plugins ansible --domain teruq.example.com
$ operator-sdk create api --group apps --version v1alpha1 --kind Hello --generate-role
```

```roles/hello/tasks/main.yml
---
- name: Deployment hello is defined
  community.kubernetes.k8s:
    definition:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: "{{ ansible_operator_meta.name }}-hello"
        namespace: "{{ ansible_operator_meta.namespace }}"
      spec:
        selector:
          matchLabels:
            app: hello
        template:
          metadata:
            labels:
              app: hello
          spec:
            containers:
            - name: hello
              image: ibmcom/hello
```

以下記事を参考にアイコンを設定します（必須ではありません）。
> https://qiita.com/teruq/items/03558220a168d4e75d30

Operatorをビルドしプッシュします。

```
$ make docker-build docker-push IMG=docker.io/teruq/hello-operator:0.0.1
```

Bundleをビルドしプッシュします。

```
$ make bundle IMG=docker.io/teruq/hello-operator:0.0.1

Display name for the operator (required):
> Hello Operator

Description for the operator (required):
> Deploys simple Hello World app.

Provider's name for the operator (required):
> teruq

Any relevant URL for the provider name (optional):
> https://qiita.com/teruq

Comma-separated list of keywords for your operator (required):
> hello

Comma-separated list of maintainers and their emails (e.g. 'name1:email1, name2:email2') (required):
> teruq

$ make bundle-build bundle-push BUNDLE_IMG=docker.io/teruq/hello-operator-bundle:v0.0.1
```

## opm CLIのインストール

下記サイトからダウンロードします。

https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/

```
$ wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/latest-4.8/opm-linux-4.8.13.tar.gz
$ tar zxvf opm-linux-4.8.13.tar.gz
$ sudo cp opm /usr/local/bin/
$ opm version
Version: version.Version{OpmVersion:"597a10a4d", GitCommit:"597a10a4d97180558226ef5dbf5ea9e722a6ddf0", BuildDate:"2021-09-21T10:17:45Z", GoOs:"linux", GoArch:"amd64"}
```

## カタログイメージの作成

```
$ opm index add --bundles docker.io/teruq/hello-operator-bundle:v0.0.1 --tag docker.io/teruq/teruq-operator-catalog:0.0.1 -c docker
INFO[0000] building the index                            bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0000] running /usr/bin/docker pull docker.io/teruq/hello-operator-bundle:v0.0.1  bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0004] running docker create                         bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0005] running docker cp                             bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0005] running docker rm                             bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0006] Could not find optional dependencies file     dir=bundle_tmp065158169 file=bundle_tmp065158169/metadata load=annotations
INFO[0006] found csv, loading bundle                     dir=bundle_tmp065158169 file=bundle_tmp065158169/manifests load=bundle
INFO[0006] loading bundle file                           dir=bundle_tmp065158169/manifests file=apps.teruq.example.com_hellos.yaml load=bundle
INFO[0006] loading bundle file                           dir=bundle_tmp065158169/manifests file=hello-operator-controller-manager-metrics-service_v1_service.yaml load=bundle
INFO[0006] loading bundle file                           dir=bundle_tmp065158169/manifests file=hello-operator-manager-config_v1_configmap.yaml load=bundle
INFO[0006] loading bundle file                           dir=bundle_tmp065158169/manifests file=hello-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml load=bundle
INFO[0006] loading bundle file                           dir=bundle_tmp065158169/manifests file=hello-operator.clusterserviceversion.yaml load=bundle
INFO[0006] Generating dockerfile                         bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0006] writing dockerfile: index.Dockerfile460207887  bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0006] running docker build                          bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
INFO[0006] [docker build -f index.Dockerfile460207887 -t docker.io/teruq/teruq-operator-catalog:0.0.1 .]  bundles="[docker.io/teruq/hello-operator-bundle:v0.0.1]"
```

## カタログイメージのプッシュ

```
$ docker push docker.io/teruq/teruq-operator-catalog:0.0.1
```

## CatalogSourceの作成と登録

```catalogsource.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: teruq-operator-catlog
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: docker.io/teruq/teruq-operator-catalog:0.0.1
  displayName: Teruq Operator Catalog
  publisher: teruq
  updateStrategy:
    registryPoll:
      interval: 30m
```

クラスタに登録します。

```
$ oc create -f catalogsource.yaml
catalogsource.operators.coreos.com/teruq-operator-catlog created
```

Podが起動したことを確認します。

```
$ oc get pods -n openshift-marketplace
NAME                                                              READY   STATUS      RESTARTS   AGE
...
teruq-operator-catlog-cqhz4                                       1/1     Running     0          21s
...
```

Package Manifestを確認します。

```
$ oc describe packagemanifest hello-operator -n openshift-marketplace
Name:         hello-operator
Namespace:    openshift-marketplace
Labels:       catalog=teruq-operator-catlog
              catalog-namespace=openshift-marketplace
              operatorframework.io/arch.amd64=supported
              operatorframework.io/os.linux=supported
              provider=teruq
              provider-url=https://qiita.com/teruq
Annotations:  <none>
API Version:  packages.operators.coreos.com/v1
Kind:         PackageManifest
Metadata:
  Creation Timestamp:  2021-10-09T21:24:56Z
  Self Link:           /apis/packages.operators.coreos.com/v1/namespaces/openshift-marketplace/packagemanifests/hello-operator
Spec:
Status:
  Catalog Source:               teruq-operator-catlog
  Catalog Source Display Name:  Teruq Operator Catalog
  Catalog Source Namespace:     openshift-marketplace
  Catalog Source Publisher:     teruq
  Channels:
    Current CSV:  hello-operator.v0.0.1
    Current CSV Desc:
      Annotations:
        Alm - Examples:  [
  {
    "apiVersion": "apps.teruq.example.com/v1alpha1",
    "kind": "Hello",
    "metadata": {
      "name": "hello-sample"
    },
    "spec": {
      "foo": "bar"
    }
  }
]
        Capabilities:                                   Basic Install
        operators.operatorframework.io/builder:         operator-sdk-v1.12.0+git
        operators.operatorframework.io/project_layout:  ansible.sdk.operatorframework.io/v1
      Apiservicedefinitions:
      Customresourcedefinitions:
        Owned:
          Kind:      Hello
          Name:      hellos.apps.teruq.example.com
          Version:   v1alpha1
      Description:   Deploys simple Hello World app.
      Display Name:  Hello Operator
      Install Modes:
        Supported:  false
        Type:       OwnNamespace
        Supported:  false
        Type:       SingleNamespace
        Supported:  false
        Type:       MultiNamespace
        Supported:  true
        Type:       AllNamespaces
      Keywords:
        hello
      Links:
        Name:    Hello Operator
        URL:     https://hello-operator.domain
      Maturity:  alpha
      Provider:
        Name:  teruq
        URL:   https://qiita.com/teruq
      Related Images:
        gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0
        docker.io/teruq/hello-operator:0.0.1
      Version:      0.0.1
    Name:           alpha
  Default Channel:  alpha
  Package Name:     hello-operator
  Provider:
    Name:  teruq
    URL:   https://qiita.com/teruq
Events:    <none>
```

## 動作確認

OpenShift WebコンソールでOperatorHubを確認します。helloで検索すると自作オペレータが表示されます。

> アイコンを設定しているつもりなのですが、ここでは表示されませんでした。別途調査します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/663890f4-92a2-5c94-9661-e4501a964eb5.png)

Operatorを選択して``Install``をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/91e0b104-1a72-ca29-e7db-c842f893c911.png)

``Install``をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/ece5543e-5a8b-1a6e-7b1c-003694acb038.png)

Operatorのインストールが成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/4b7d0706-cfa2-5705-ed6e-e4955ce49fd4.png)

アプリケーションをインストールしたいプロジェクトを選択して``Installed Operators``を選択します。``Hello Operator``を選択します。

> ここからはアイコンが表示されています。不思議です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/205815b6-f692-e89c-5219-939b1e1bab68.png)

``Create Instance``をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/65180b04-1a2f-17b6-4adf-837fe495780f.png)

``Create``をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/ab0af20c-6cc7-e797-4002-5331d9db2bcb.png)

PodがRunningになったことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/bcd8ad03-a487-4334-1e0e-4d970ffc00fb.png)