はじめに
IBM Cloud上のマネージドなOpenShift環境である Red Hat OpenShift on IBM Cloud では、oc expose
コマンドにより、デプロイしたWeb・APIアプリケーションを外部(インターネット)に簡単に公開することが可能となっています。ただ、デフォルトではHTTPでの公開となっており、実際に利用するうえでは安全性に問題があります。
Red Hat OpenShift on IBM CloudではHTTPSでアプリケーションを公開する方法も用意されています。この記事では、Quarkusで作成したアプリケーションを対象に、HTTPSで公開する手順について記載します。
経路のタイプ
公式ドキュメントに記載されていますが、OpenShiftでは4つのタイプの経路があり、当記事ではそのうちの「パススルー」と「エッジ」について試してみます。
経路のタイプ | 内容 |
---|---|
パススルー(passthrough) | HTTPSの暗号化の終端をアプリケーションPodが担当。Routerは終端処理に関与せず素通しする。 |
エッジ(edge) | HTTPSの暗号化の終端を(OpenShift内の)Routerが担当。RouterからアプリケーションPodまでの経路は暗号化されない。 |
環境
- Red Hat OpenShift on IBM Cloud 4.7.12 (VPC Gen 2環境に作成)
- Quarkus 1.13.6
Quarkusアプリケーションの準備
公開の前提となるQuarkusアプリケーションの作成、アプリケーションのビルド、コンテナイメージのビルド、IBM Cloudのコンテナレジストリ(IBM Cloud Container Registry)へのイメージpushの手順については別記事「IBM Cloud Code EngineにQuarkusのサンプルアプリケーションをデプロイしてみる」内の記述を参照ください。
以降は、IBM Cloud Container RegistryにQuarkusアプリケーションのイメージが登録済みであることを前提として記述します。
パススルーでの公開手順
パススルーの場合、アプリケーションPod側で終端処理を担当する必要があるため、自己署名証明書を作成し、Quarkusアプリケーションのコンテナに含める必要があります。ここではビルド時にコンテナイメージに含めるのではなく、証明書データをSecretとして登録し、SecretをVolumeとしてマウントすることでQuarkusアプリケーションが証明書を使用できるようにします。
まず、アプリケーションをデプロイするプロジェクト(名前空間)を作成します。
oc new-project quarkus-sample
oc project quarkus-sample
作成したプロジェクトでIBM Cloud Container Registryからイメージをpullできるよう、defaultプロジェクトからimagePullSecret(all-icr-io)をコピーします。
oc get secret all-icr-io -n default -o yaml | sed 's/default/quarkus-sample/g' | oc create -n quarkus-sample -f -
自己署名証明書を作成します。cert.pem、key.pemという2つのファイルが作成されます。
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
自己署名証明書のデータをSecretとして登録します。cert.pem、key.pemというファイル名と同名のキーで登録します。
oc create secret generic https-secret --from-file=cert.pem=./cert.pem --from-file=key.pem=./key.pem
QuarkusアプリケーションのコンテナイメージをOpenShiftにデプロイするための Deployment、Service、Routeのマニフェストファイルを作成します。
Deploymentでは主に以下を設定しています。
- 上記で作成したSecretをVolume化してPodにマウント
- HTTPS接続をポート8443で公開
- 「QUARKUS_HTTP_SSL_CERTIFICATE_FILE」「QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE」という環境変数で、cert.pem、key.pemのパスを設定。これにより、Quarkusアプリケーションに自己署名証明書を渡している
「QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE」という環境変数は、本来は「QUARKUS_HTTP_SSL_CERTIFICATE_KEY-FILE」(KEYとFILEの間がアンダーバーではなくハイフン)が正しいはずなのですが、「QUARKUS_HTTP_SSL_CERTIFICATE_KEY-FILE」を使うとなぜかQuarkusが認識しませんでした。「QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE」を使用してQuarkusアプリケーションを起動するとタイポじゃないかという警告メッセージが出るのですが、なぜかHTTPSで正常に公開されます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-getting-started
spec:
selector:
matchLabels:
app: quarkus-getting-started
replicas: 1
template:
metadata:
labels:
app: quarkus-getting-started
spec:
containers:
- name: quarkus-getting-started
image: <IBM Cloud Container Registry上のQuarkusアプリケーションのコンテナイメージ>
resources:
limits:
memory: "256Mi"
cpu: "500m"
ports:
- containerPort: 8443
volumeMounts:
- name: https-secret
readOnly: true
mountPath: /var/run/secrets/kubernetes.io/ssl
env:
- name: QUARKUS_HTTP_SSL_CERTIFICATE_FILE
value: /var/run/secrets/kubernetes.io/ssl/cert.pem
- name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILE
value: /var/run/secrets/kubernetes.io/ssl/key.pem
- name: QUARKUS_HTTP_INSECURE-REQUESTS
value: redirect
- name: QUARKUS_HTTP_SSL-PORT
value: '8443'
- name: QUARKUS_PROFILE
value: prod
imagePullSecrets:
- name: all-icr-io
volumes:
- name: https-secret
secret:
secretName: https-secret
Serviceはポート8443を公開するように設定しています。
apiVersion: v1
kind: Service
metadata:
name: quarkus-getting-started-https
spec:
selector:
app: quarkus-getting-started
ports:
- protocol: TCP
port: 8443
targetPort: 8443
パススルーの設定はRouteに対して実施します。termination
で passthrough
を指定しています。また、insecureEdgeTerminationPolicy
では、HTTPでのアクセスを受けた場合にHTTPSに自動的にリダイレクトするように Redirect
を設定しています。
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: quarkus-getting-started
name: quarkus-getting-started-https
spec:
port:
targetPort: 8443
tls:
termination: passthrough
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
to:
kind: Service
name: quarkus-getting-started-https
weight: 100
作成したマニフェストファイルをOpenShiftに反映します。
oc apply -f deployment.yaml
oc apply -f service.yaml
oc apply -f route-passthrough.yaml
作成されたRouteを確認し、Routeに設定されているホスト名にHTTPSでアクセスできることを確認します。
oc get route
エッジでの公開手順
エッジの場合、アプリケーションPod側はHTTPSを意識することなく、自己署名証明書は不要です。RouterでTLS接続の終端処理が行われ、証明書はRed Hat OpenShift on IBM Cloud側で自動的に用意・設定されます。
プロジェクトの作成、imagePullSecretのコピーはパススルーの手順と同じです。
oc new-project quarkus-sample
oc project quarkus-sample
oc get secret all-icr-io -n default -o yaml | sed 's/default/quarkus-sample/g' | oc create -n quarkus-sample -f -
QuarkusアプリケーションのコンテナイメージをOpenShiftにデプロイするための Deployment、Service、Routeのマニフェストファイルは以下の通りです。
Deploymentでは、パススルーの場合にあった環境変数などの設定は不要です(Deploymentは終端処理に関わらないため)。
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-getting-started
spec:
selector:
matchLabels:
app: quarkus-getting-started
replicas: 1
template:
metadata:
labels:
app: quarkus-getting-started
spec:
containers:
- name: quarkus-getting-started
image: <IBM Cloud Container Registry上のQuarkusアプリケーションのコンテナイメージ>
resources:
limits:
memory: "256Mi"
cpu: "500m"
ports:
- containerPort: 8080
imagePullSecrets:
- name: all-icr-io
apiVersion: v1
kind: Service
metadata:
name: quarkus-getting-started
spec:
selector:
app: quarkus-getting-started
ports:
- protocol: TCP
port: 8080
targetPort: 8080
エッジの設定をRouteに対して行います。termination
では edge
を指定します。その他はパススルーの場合と同じです。
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
app: quarkus-getting-started
name: quarkus-getting-started-https
spec:
port:
targetPort: 8080
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
to:
kind: Service
name: quarkus-getting-started
weight: 100
作成したマニフェストファイルをOpenShiftに反映します。
oc apply -f deployment.yaml
oc apply -f service.yaml
oc apply -f route-edge.yaml
作成されたRouteを確認し、Routeに設定されているホスト名にHTTPSでアクセスできることを確認します。
oc get route
以上です。