Red Hat OpenShift on IBM Cloud使用上の各種のTipsまとめ

# はじめに
当記事では、Red Hat OpenShift on IBM Cloud（ROKS）を使用するうえでの各種のTips、テンプレートを備忘録としてまとめています。


# 前提環境

- Red Hat OpenShift on IBM Cloud (OpenShiftバージョン：4.10.17_1524、VPCクラスターとして作成）


# IBM Cloud Container Registryからコンテナイメージをpullするための設定
ROKSはContainer Registryとセットで利用することが多いですが、default以外のプロジェクトでContainer Registryにあるイメージをpullするには、以下の設定が必要となります

default プロジェクトのSecret「all-icr-io」を、対象プロジェクトにコピーします。

```bash
oc get secret all-icr-io -n default -o yaml | sed 's/default/<target-project>/g' | oc create -n <target-project> -f -
```

コピーしたSecretを以下のいずれかの方法で使用します。``oc new-app``でアプリケーションをデプロイする場合は方法2を使用することになります。

- 方法1：Deploymentのマニフェストに以下を追加する

```yaml
# 追加場所 ： spec.template.spect.imagePullSecrets
      imagePullSecrets:
        - name: all-icr-io
```

- 方法2：対象プロジェクトのデフォルトのServiceAccountである default と all-icr-io をリンクさせる

```bash
oc secrets link default all-icr-io --for=pull
```


# コンテナイメージ指定のユーザ(UID)でのコンテナ実行
Apacheなどのように80ポートを使用するコンテナではroot権限が必要となります。しかし、OpenShiftで実行されるコンテナは、OpenShiftがランダムに割り当てたUIDで実行されるため、80ポートを使用することができません。

これを解決するため、対象プロジェクトのServiceAccount「default」に対してanyuid SCCを付与し、ランダムなUIDではなく、コンテナイメージのDockerfileのUSERインストラクションで指定されているユーザでコンテナを実行できるようにする必要があります。

対象プロジェクトにおいて以下のコマンドを実行し、anyuid SCCを付与します。

```bash
oc adm policy add-scc-to-user anyuid -z default
```


# 再認証不要でocコマンドを使えるようにする
ocコマンドを実行するには事前に``oc login``が必要となりますが、ROKSではOpenShiftのWebコンソールでTokenを取得し、そのTokenを用いて``oc login --token=xxxxx``でログインする必要があります。Tokenは一定時間で無効になるため、その時間が過ぎると再度WebコンソールにアクセスしてTokenを取得する必要があります。

これを省略し、再認証不要でocコマンドを使用できるようにする場合、以下を実行します。

まず、IBM Cloud CLIでIBM Cloudにログインします。
```bash
ibmcloud login
```

次に、``ibmcloud oc cluster config``コマンドで、OpenShiftの構成データ、証明書をダウンロードし、kubeconfigファイルに反映します。``--cluster``オプションで指定するOpenShiftクラスターの名前（またはID）は、IBM Cloudのコンソールで当該クラスターの情報を表示することで確認できます。``--admin``オプションも必要です。

```bash
ibmcloud oc cluster config --cluster <OpenShiftクラスターの名前、または、ID> --admin
```

- 参考：[Red Hat OpenShift on IBM CloudのWebコンソールにアクセスできないときにocコマンドを実行したい場合の対処法](https://qiita.com/hisato_imanishi/items/23a45e5411f89fd71c15)
- 参考：[ibmcloud oc cluster configコマンド](https://cloud.ibm.com/docs/openshift?topic=openshift-kubernetes-service-cli#cs_cluster_config)


# 内部レジストリに外部からアクセスできるようにする
別記事「[Red Hat OpenShift on IBM Cloudで、内部レジストリに外部からアクセスする](https://qiita.com/hisato_imanishi/items/dda647871837262c765c)」を参照ください。


# マニフェストファイルのテンプレート
OpenShiftでは``oc new-app``コマンド、``oc expose``コマンドなどで、お手軽にアプリをデプロイし、外部に公開する（Routeを作成する）ことが可能になっています。

ただ、Infrastructure as Code、GitOpsの観点で、マニフェストファイルを作成し、それに基づいてデプロイを実施する方が好ましいケースが多々あります（特に本番運用を想定した場合）。

いざマニフェストファイルを書こうとしたとき、``oc new-app``、``oc expose``に慣れてしまっているとマニフェストファイルをさっと作れないため、備忘録としてマニフェストファイルのテンプレートを記載します。

以下ではDeployment、Service、Route、Secret、ConfigMap、Jobのテンプレートを示します。Job以外のリソースはお互いに関連し合う内容になっています。

## Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
spec:
  selector:
    matchLabels:
      app: sample-app
  replicas: 1
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: sample-app
          image: <コンテナイメージ>
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          ports:
            - containerPort: 8080
          env:
            - name: TZ
              value: Asia/Tokyo
            - name: DATABASE_NAME
              valueFrom:
                configMapKeyRef: # 後述のConfigMapを参照している
                  key: database-name
                  name: sampledb-configmap
            - name: DB_USERNAME
              valueFrom:
                secretKeyRef:    # 後述のSecretを参照している
                  key: username
                  name: sampledb-secret
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:    # 後述のSecretを参照している
                  key: password
                  name: sampledb-secret
            - name: DB_JDBC_URL
              valueFrom:
                secretKeyRef:
                  key: url
                  name: sampledb-secret
      imagePullSecrets:
        - name: all-icr-io
```


## Service

```yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-app
spec:
  selector:
    app: sample-app
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
```

## Route

```yaml
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: sample-app
  name: sample-app
spec:
  port:
    targetPort: 8080
  to:
    kind: Service
    name: sample-app
```

## Secret

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: sampledb-secret
type: Opaque
data:
  username: xxx
  password: xxx
  url: xxx
```

Secretの値はBase64でのエンコードが必要です。エンコードは以下のコマンドで実行します。

```bash
echo -n '対象文字列' | base64
```


## ConfigMap

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: sampledb-configmap
data:
  database-name: Sample Database
```

## Job

```yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: sample-batch
spec:
  completions: 1
  parallelism: 3
  template:
    spec:
      containers:
        - name: sample-batch
          image: debian
          command: ["echo"]
          args: ["Hello, World"]
      restartPolicy: Never
```

以上です。