OpenShift 4.3のRouterのデフォルトエラー画面はカスタマイズできないという話

# いきなりまとめ

OpenShiftを使っているとおなじみの画面があります。これです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/0f4f650b-d7e4-e862-b9ba-beed59f37809.png)

これは、Routeに存在しないURLを指定した場合や、該当PodがReadyではない場合に表示されます。

機械的な画面なので、商用サイトではユーザーフレンドリーな画面にしたいと思うのが人情だと思ったとします。

しかし、OpenShift 4.3ではこの画面はカスタマイズできないとサポートより回答がありましたので、正攻法では諦めてください。

ちなみにOpenShift 3系ではカスタマイズが可能です。

> https://docs.ukcloud.com/articles/openshift/oshift-how-customise-error-page.html

なお、この話はRed Hat OpenShift on IBM Cloud 4.3で検証した結果です。オンプレ版や他社のマネージドサービスでは事情が異なる可能性がありますのでご了承ください。

# 仕組み

このエラー画面を誰がどのように表示しているかという話ですが、正体はRouterのPodです。

```
$ oc get pods -n openshift-ingress
NAME                              READY   STATUS    RESTARTS   AGE
router-default-6fd75fdf69-2p27m   1/1     Running   0          2d20h
router-default-6fd75fdf69-9c5xl   1/1     Running   0          2d20h
```

このPodはDeploymentで管理されています。

```
$ oc get deployments -n openshift-ingress
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
router-default   2/2     2            2           24d
```

ではこのDeploymentは誰に管理されているかというと、IngressControllerというOperatorのようです。

```
$ oc get ingresscontrollers -n openshift-ingress-operator
NAME      AGE
default   24d
```

さて、エラー画面ですが、Pod内のerror-page-503.httpで定義されています。

```
$ oc rsh -n openshift-ingress router-default-6fd75fdf69-2p27m ls -l /var/lib/haproxy/conf
total 128
-rw-rw-r--. 1 root root   454 May 15 08:27 cert_config.map
-rw-r--r--. 1 root root  2035 Apr 20 06:57 default_pub_keys.pem
-rw-r--r--. 1 root root  3278 Apr 20 06:57 error-page-503.http
-rw-r--r--. 1 root root 34848 Apr 20 06:57 haproxy-config.template
-rw-rw-r--. 1 root root 30660 May 15 08:27 haproxy.config
-rw-rw-r--. 1 root root  2613 May 15 08:27 os_edge_reencrypt_be.map
-rw-rw-r--. 1 root root   178 May 15 08:27 os_http_be.map
-rw-rw-r--. 1 root root  1072 May 15 08:27 os_route_http_redirect.map
-rw-rw-r--. 1 root root     0 May 15 08:27 os_sni_passthrough.map
-rw-rw-r--. 1 root root  1179 May 15 08:27 os_tcp_be.map
-rw-rw-r--. 1 root root     0 May 15 08:27 os_wildcard_domain.map

$ oc rsh -n openshift-ingress router-default-6fd75fdf69-2p27m cat /var/lib/haproxy/conf/error-page-503.http
HTTP/1.0 503 Service Unavailable
Pragma: no-cache
Cache-Control: private, max-age=0, no-cache, no-store
Connection: close
Content-Type: text/html

<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
（略）
```

このファイルを差し替えることができればエラー画面をカスタマイズできるはずなのですが、そう簡単にはいきません。このファイルはPod内の実ファイルですので、手動で編集してもPodが再起動したら元に戻ってしまいます。ではファイルをConfigMapにしてDeploymentにボリュームマウントしてみると、なんと、Operatorの力でDeploymentの定義が瞬時に元に戻されてしまいます。

というわけでOperatorで変更できないかとIBM Cloudのサポートに問い合わせたのですが、できないという結論になりました。

先述のとおりOpenShift 3.xではカスタマイズ可能なのですが、これは、3.xのRouterはOperatorではなくDeploymentConfigで管理されているためです。

# 対応策

## デフォルトのRouterを削除してカスタマイズしたRouterをデプロイする

マネージドサービスではサポートの話があるのでやめた方がいいでしょう。オンプレ版では自己責任で可能と思われます。

## 外部のロードバランサーでエラー画面を差し替える

OpenShiftクラスターとクライアントの間に外部ロードバランサーがいた場合の話ですが、もしそのロードバランサーがL4-7レベルを話せるなら、HTTPの戻り値が503の際にカスタムページを表示することは可能な場合があります。

IBM Cloudであればサイトを外部公開する際にCloud Internet Servicesを使用する場合が多いと思いますので、次の記事が参考になるかもしれません。

> [Cloud Internet ServicesのEdge FunctionとCloud Object Storageでアプリケーションエラー時にSorryページを返す](https://qiita.com/teruq/items/45cbb7ef1f40d5fa85ec)