まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2023/02

自分が作るアプリの中でユーザー認証/登録といった機能が必要な場合、自分の場合は自作することはほとんどなく、IDaaS 等と呼ばれている SaaS 系専用サービスを使って実装しています。具体的には(資料が充実しているという理由ですが) Auth0AppID を使うことが多いです。単なるユーザー認証だけでなく、(実装する場合に面倒な)オンラインサインアップやパスワード再設定、パスワード忘れ時のリセット機能などをサービスが既にセキュアな形で組み込まれていて、自分ではほぼ実装を意識することなく使えて便利※です。

※もう少しちゃんと説明すると、Auth0 の場合であれば認証自体は OAuth を使って auth0.com で行い、認証情報が正しければコールバックで受け取った情報を使ってアクセストークンを取得できる、というロジックを簡単に実装できます。


この Auth0 を使ってアプリを作った場合、ユーザー名(表示名)やそのアイコン画像は(特定のルールに基づいて)登録時に決まります。ユーザー名はともかく、特にアイコン画像は自動生成されたものではなく自分で気に入っているものを使いたいと感じることが多いと思っています。が、現状ユーザー本人が直接変更することはできません。登録時に決まったものを使い続ける、ということになるので、こだわりを持ったユーザー名やユーザーアイコンへの変更ができないことを問題と感じていました。

で、Auth0 を調べたところ「変更用の API 自体は提供されている」ことが分かりました。要はユーザーが直接変更する機能は提供されていないが、その機能を自分で自分のアプリ内に作る方法は提供されている、ということになります。これを Node.js で早速試してみたのが今回のブログエントリのテーマです。


【プロフィール画像変更 API】
例えばプロフィール画像を変更する API 自体はこのように提供されています(下図は Node.js のサンプル):
2023022001


この上図で言うところの USER_ID 部分に画像を変更したいユーザーの ID(Auth0 上での User.id)を指定し、また変更後の画像 URL を picture の値として指定した上で上述の REST API を実行すればよい、ということになります。

特に Node.js の場合は同様の処理をより簡単に実行できるような SDK も提供されており、こちらを使った場合は ManagementClient クラスの update メソッドに必要なパラメータを渡して実行するだけです。

なおどちらの例もユーザーのアイコン画像(picture)だけを変更する例として紹介されていますが、実際には picture 以外にも nickname(表示名)や firstName, lastName など他の多くの属性を変更することも可能です。 実装そのものは後者(SDK)の方が簡単なので、以下こちらを使って説明を続けます。


【client_id と client_secret の準備】
この API を実行するには Auth0 の認証アプリを作る時と同様に client_id と client_secret (と domain)情報が必要です。ただ多くの場合、取得し直しが必要になる点に注意が必要です。以下は Auth0.com にログインし、メニューから Applications - Applications を選択した後に "Create Application" を実行した時の画面です:
2023022004


Auth0 を使って自分のアプリに認証機能を付加する場合、そのアプリの種類によって "Native(スマホ向けネイティブアプリ)", "Single Page Web Application(SPA)", "Regular Web Applications(その他のいわゆる「ウェブアプリ」)" のいずれかから1つ選んで(Auth0 の)アプリケーションを登録することが多いはずです:
2023022002


ですが、今回の機能を実現するためには "M2M(Machine to Machine)Applications" の client_id と client_secret が必要になります。そのため、まだ M2M アプリを作ったことがない場合は Machine to Machine Applications を選択して、新たに1つ追加登録してください:
2023022003


次の画面で対象 API を選択しますが、M2M アプリの場合は "Auth Management API" の1つしか選択肢がないので、これを選択します:
2023022006


最後に API の許可スコープを指定します。今回はユーザー管理機能を実装するので、検索バーに "users" と入力し、そこで見つかる全てのスコープにチェックを入れて、最後に "Authorize" ボタンをクリックするとアプリケーション登録が完了します:
2023022007


こうして Auth0.com に作成(追加)した M2M アプリケーションの Client ID、Client Secret(と Domain ですが、Domain は他のアプリ登録時に取得したものと同じはずです)が必要になります。利用時にすぐ取得できるようコピー&ペースト等で準備しておいてください:
2023022005


【実装】
ここまでの準備ができたら実装してみましょう。Node.js の場合は auth0 という便利なクライアントライブラリの SDK があるので、これを使って実装します。なお最後にサンプルアプリ・ソースのリンクを載せておくので、興味ある方はそちらをダウンロード後に実際に動作確認してみてください。

まず auth0 をインスタンス化します:
//. Auth0 Management API
var ManagementClient = require( 'auth0' ).ManagementClient;
var auth0 = new ManagementClient({
  domain: 'xxxx.auth0.com',       // domain の値
  clientId: 'client_id',          // client_id の値
  clientSecret: 'client_secret',  // client_secret の値
  scope: 'create:users read:users update:users'
});


auth0 の ManagementClient を取得し、domain, client_id, client_secret の3つの値と、スコープとして 'create:users read:users update:users' を指定してインスタンス化します(今回はプロフィール画像 URL を更新するため、これら全てがスコープとして必要になります)。繰り返しになりますが、重要なのはここで指定する client_id や client_secret は通常のネイティブアプリケーション/ウェブアプリケーションのものではなく、M2M アプリケーションとして登録したアプリケーションのものを使う必要がある、という点です。

そして実際に user_id = 'abcabc' のユーザーのプロフィール画像 URL を変更する場合は、以下のような処理を行います:
var params = { user_id: 'abcabc' };  // ユーザーIDが 'abcabc' の人が対象
var metadata = { picture: 'https://manholemap.juge.me/imgs/logo.jpg' };  // プロフィール画像を指定 URL のものに変更する
auth0.users.update( params, metadata, function( err, user ){
  if( err ){
    console.log( { err } );
        :  // エラー時の処理
  }else{
    console.log( { user } );
        :  // 成功時の処理
  }
});


実行する関数は auth0.users.update() で、この実行時パラメータとして第一パラメータに対象ユーザーの情報、第二パラメータに変更内容を指定します。実行後にエラーか成功かを識別して処理を続けます。

上の例だとプロフィール画像だけを変更していますが、複数の属性を同時に変更することも可能です。例えば以下の例は対象ユーザーのプロフィール画像(picture)と表示名(nickname) を同時に変更しています:
var params = { user_id: 'abcabc' };
var metadata = { nickname: '俺', picture: 'https://manholemap.juge.me/imgs/logo.jpg' };
auth0.users.update( params, metadata, function( err, user ){
  if( err ){
    console.log( { err } );
        :
  }else{
    console.log( { user } );
        :
  }
});


参考になれば、と思って実際に動くサンプルアプリを用意しました:
https://github.com/dotnsf/auth0-userpicture


サンプルアプリを実際に動かす場合は Auth0 に(M2M ではない通常の Web)アプリケーションも登録し、その client_id, client_secret, domain を取得し、また OAuth のコールバックURL(callback_url) を実行時の環境変数に登録する必要があります。実行時の環境変数登録時は同リポジトリ内の .env ファイルにその内容を記載することでも代替可能です。



参照していただくとわかるのですが、実際にユーザーの属性を変更しようとすると対象ユーザーの ID が必要になります。ユーザー ID は OAuth でログイン後にわかるので、実際のアプリケーションでは普通の(通常のウェブの)アプリケーションと、ユーザー管理用の M2M アプリケーションの2つを登録する必要があり、それぞれの client_id と client_secret の両方を使って実装することになります。詳しくはソースコード内を参照ください。


以前のブログエントリで OpenShift 関連の以下2つの紹介をしていました:
IBM Cloud の VPC(Virtual Private Cloud) でプライベート OpenShift クラスタ環境を構築する
IBM Cloud の仮想プライベートクラウド OpenShift 上にデプロイしたコンテナアプリに HTTP パブリックアクセスを許可する


前者は IBM Cloud の VPC(Virtual Private Cloud) 環境を使って、プライベートな OpenShift クラスタ環境を作る手順(と VPN を使ったプライベート OpenShift へのアクセス手順)を紹介しました。 また後者ではこのプライベート環境を使ってデプロイしたプライベートなアプリケーションに対して、VPN なしでパブリックインターネットアクセスを(HTTPS ではなく、HTTP で)行うための設定手順を紹介しました。

今回のブログエントリではこの最終形ともいえる「デプロイしたアプリケーションに対する HTTPS によるアクセス」を実現するための手順を紹介します。上で紹介した2つのエントリの、後者に近い内容ではありますが、純粋な続きというわけではありません。前者の環境が構築済みであるという前提のもとで、oc CLI を使ったアプリケーションのデプロイと、プライベートアクセスを可能にするための手順を紹介していきます。


【3通りの方法】
今回のブログエントリの結論めいたことを最初に紹介します。この「プライベートクラウドにデプロイしたアプリケーションにパブリックにアクセスする」には目的や制約に応じた3通りの方法があります(うち(1)は前回説明済み):
(1)HTTP でパブリックアクセスする(前回説明
(2)HTTPS でパブリックアクセスする(自己証明書を使う場合)
(3)HTTPS でパブリックアクセスする(有効な証明書を使う場合)

要は「HTTP でいいのか? HTTPS が必要か?」「HTTPS の場合、自己証明書でいいか?NGか?」という2つの考慮点があり、その要件によって選択肢を選ぶ必要がある、ということです。「この中でどれか?と言われたら(3)でしょ?」と思うかもしれませんが、それぞれに制約事項があったりして(例えば(1)、(2)は IBM Cloud 内の設定のみで実現できますが、(3)の場合はカスタムドメインが別途必要になります)、検証目的なのか本運用なのか、といった背景によっても選択肢は変える必要が生じるものだと思います。

以下では、最終的には(3)を実現する前提として、(1)から順に実現手順を紹介します。なお(1)と同じことを前回紹介しているのですが、(3)まで行うことを考えると(1)も少し手順を変える必要があるので、改めて(1)から実現手順を、以下で順に紹介します。


【0. 事前準備】
まず事前準備としてプライベートクラウドでの OpenShift クラスタ環境と、同環境にアクセスするための VPN が必要です。これらの構築手順はシリーズ初回で紹介しているので、こちらの手順を参照してプライベートクラウドの OpenShift クラスタと、同クラスタにアクセスするための VPN 環境を作っておいてください。

ここまでが完了している前提で以下の説明を続けます。


【1. プライベート OpenShift クラスタにアプリケーションをデプロイし、パブリックアクセスのパスを定義する】

2023020205


以前にも紹介した内容ですが、今回は HTTPS でのアクセスまでを考慮した手順を紹介します。そのため、HTTP でアクセスするこの部分から以前とは異なる、oc CLI コマンドと yaml ファイルを使ってアプリケーションをデプロイする手順を紹介します。

まず前提として、以下のようなプライベート OpenShift クラスタ環境が IBM Cloud 内に作られているものと仮定します:

OpenShift クラスタ名: kkimura-mycluster-jp-osa-2-priv
2023020101


Ingress が定義したサブドメイン名: kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud
2023020102


アプリケーションをデプロイする OpenShift プロジェクト(ネームスペース): default

OpenShift にデプロイするアプリ:DockerHub 上の ibmcom/guestbook:v1
2023020103


※ちなみにこの ibmcom/guestbook をデプロイしてウェブブラウザでアクセスするとこのような↓画面が表示されます。この画面が表示されればデプロイとアクセスが成功している、と判断してください:
2023020101



以下では上述の名称や設定を前提として説明します。適宜自分の環境での名称や設定に読み替えてください。

では実際に oc CLI を使って、アプリケーションをプライベート OpenShift クラスタにデプロイします。まずはプライベート環境へアクセスする VPN を有効にした上で「OpenShift Web コンソール」を開きます(VPN が有効でないと開けません):
2023020104


OpenShift Web コンソールが開きます。今回は oc CLI と呼ばれるコマンドラインツールを使ってアプリケーションのデプロイや設定変更を行うので、まだこのツールをインストールしていない場合は導入が必要です。OpenShift Web コンソール画面上部のクエスチョンマークをクリックし、コンテキストメニューから「コマンドラインツール」を選択して、自分の PC 環境にあった oc CLI ツールをダウンロード&インストールしておいてください:
2023020108


同様にして ibmcloud CLI コマンドも(未導入の場合は)インストールしておきます:
https://cloud.ibm.com/docs/cli?topic=cli-install-ibmcloud-cli&locale=ja


oc CLI ツールと ibmcloud CLI ツールがインストールできている状態で、改めて OpenShift Web コンソール画面右上の名前部分をクリックしてコンテキストメニューを開き、「ログインコマンドのコピー」を選択します:
2023020105


新しいウィンドウが開くと、"Display Token" とだけ表示されているので、この部分をクリックしてトークン情報を参照します:
2023020106


するとトークン情報が書かれたページが表示されます。この中の "Log in with this token" で書かれた部分を(この後ペーストするので)コピーします:
2023020107


ターミナルを開き、さきほどコピーした内容をペーストして Enter キーを押すと、ターミナル画面で IBM Cloud の OpenShift 環境にログインできます:
2023020109


同様にして ibmcloud CLI ツールからも IBM Cloud へのログインを行っておきます:
$ ibmcloud login


ではここからプライベート OpenShift クラスタ内にアプリケーションをインストールします。改めて以下のような内容の yaml ファイル(guestbook_deployment.yaml)を用意します:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: guestbook
  labels:
    app: guestbook
spec:
  replicas: 1
  selector:
    matchLabels:
      app: guestbook
  template:
    metadata:
      labels:
        app: guestbook
    spec:
      containers:
      - name: guestbook
        image: ibmcom/guestbook:v1
        imagePullPolicy: Always
        env:
          - name: NODE_ENV
            value: production
---
apiVersion: v1
kind: Service
metadata:
  name: guestbook-svc
  labels:
    app: guestbook
spec:
  type: ClusterIP
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: guestbook
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None


この yaml ファイルは Deployment, Service, Route を1つずつ含んでいて、これ一つでアプリケーションをデプロイして、クラスタ外に公開して、ホスト名でアクセスできるようなルーティングを設定しています。数か所ある太字部分を補足します。

まず Deployment 内の image 名で ibmcom/guestbook:v1 と記載している部分、これがデプロイするアプリケーションのイメージです。別のイメージを使う場合はここを変えてください。

また数か所ある 3000 という数字、これは ibmcom/guestbook アプリが内部的に待ち受けるポート番号です。使うアプリイメージによって変わるので、ここもそのアプリ向けの正しい値を指定してください。

最後に Route 内の host 名、ここは (アプリ固有の名).(Ingress サブドメイン) を指定します。今回の例ではアプリ固有の名として guestbook とし、Ingress サブドメインは上記で調べた値(kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud)を使っています。

では用意した yaml ファイルを使って実際にプライベート OpenShift にデプロイします:
$ oc apply -f guestbook_deployment.yaml

成功したら上述の host 名に HTTPS でアクセスし、期待通りに動作することを確認します(この時点でプライベートクラウドへはデプロイできました):
2023020101


次にこのアプリケーションをパブリッククラウドから(最初は HTTP で)アクセスできるように設定します。大まかな手順としては以下のことを行います:
・OpenShift 内にパブリック・ルーター(の Pod)とパブリック・ロードバランサーを作成し、
・パブリック・ロードバランサー → パブリック・ルーター を経由して、アプリケーションだけにアクセスできるようなパスを通し、
・パブリック・ロードバランサーの外部ホスト名でアプリケーションを公開できるよう DNS を変更する


では順に実行していきます。ロードバランサーを OpenShift のパブリックネットワーク側に作りたいのですが、その際の(パブリックネットワーク用の)サブドメインを決める必要があります。まずは以下の ibmcloud コマンドを実行します:
$ ibmcloud oc nlb-dns ls --cluster kkimura-mycluster-jp-osa-2-priv
(最後のパラメータは OpenShift クラスタ名)

(以下、実行結果例)
OK
Subdomain                                                                                          Target(s)                            SSL Cert Status   SSL Cert Secret Name                                             Secret Namespace    Status
kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud   59aa36c3-jp-osa.lb.appdomain.cloud   created           kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000   openshift-ingress   OK

この実行結果例では1行しか表示されていませんが、複数行表示されることもあります。で、この結果の Subdomain を見ると "i000" と表示されている部分があります。この "i" で始まって数字が3桁続くサブドメインはプライベートネットワークであることを示しています。

新たにパブリックなサブドメインを追加したいのですが、その名称は、
・↑の方法でプライベートネットワークのサブドメインのうち、"i" 以降の数字が最も大きいもの(今回であれば "000")を探して、
・その数字に1を追加し、"i" をゼロ(0)にしたもの(今回であれば "0001")
にします。つまり今回の例であれば、
kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud

をパブリック用のサブドメインとします。

パブリック用のサブドメインが決まったら、以下のような yaml ファイル(ingresscontroller.yaml)を作って実行し、パブリックネットワークにパブリックルーターとパブリックロードバランサーを作ります(太字部分はパブリック用サブドメイン):
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: public
  namespace: openshift-ingress-operator
spec:
  replicas: 2
  domain: kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud
  endpointPublishingStrategy:
    loadBalancer:
      scope: External
    type: LoadBalancerService
$ oc apply -f ingresscontroller.yaml

そして以下を実行し、結果の "EXTERNAL-IP" を参照します:
$ oc get svc router-public -n openshift-ingress

NAME            TYPE           CLUSTER-IP       EXTERNAL-IP                          PORT(S)                      AGE
router-public   LoadBalancer   172.21.191.252   5ca5ada9-jp-osa.lb.appdomain.cloud   80:31127/TCP,443:30992/TCP   32h

この例では EXTERNAL-IP は "5ca5ada9-jp-osa.lb.appdomain.cloud" となっています。これがパブリックロードバランサーのホスト名となります。

このサービスのパブリック VPC ホスト名を DNS に登録します。以下のコマンドを実行します:
$ ibmcloud oc nlb-dns create vpc-gen2 --cluster (OpenShiftクラスタ名) --lb-host (ロードバランサーホスト名) --type public

※今回の例だと、
 OpenShift クラスタ名: kkimura-mycluster-jp-osa-2-priv
 ロードバランサーホスト名: 5ca5ada9-jp-osa.lb.appdomain.cloud

最後にアプリのサービスをパブリックルーターで expose します:
$ oc expose svc/guestbook-svc --name guestbook-public --hostname guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud

これでサービス(guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud)がパブリックネットワーク上で HTTP で公開されました。いったん VPN を切ってから、パブリックホスト名(http://guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud)に HTTP でアクセスできることを確認してみましょう:
2023020201


【2. プライベート OpenShift クラスタにアプリケーションをデプロイし、自己証明書の HTTPS アクセスができるよう定義する】

2023020206


1. で説明した作業の続きとして、パブリックロードバランサー名(今回であれば "5ca5ada9-jp-osa.lb.appdomain.cloud")で自己証明書を使った HTTPS アクセスを可能にします。

そのためにはアプリケーションのデプロイ時に使った yaml ファイル(guestbook_deployment.yaml)を少し改良します。具体的には以下の青字部分を(自分の環境のホスト名やパブリックロードバランサー名を使って)追加します:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: guestbook
  labels:
    app: guestbook
spec:
  replicas: 1
  selector:
    matchLabels:
      app: guestbook
  template:
    metadata:
      labels:
        app: guestbook
    spec:
      containers:
      - name: guestbook
        image: ibmcom/guestbook:v1
        imagePullPolicy: Always
        env:
          - name: NODE_ENV
            value: production
---
apiVersion: v1
kind: Service
metadata:
  name: guestbook-svc
  labels:
    app: guestbook
spec:
  type: ClusterIP
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: guestbook
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: 5ca5ada9-jp-osa.lb.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None

これによりパブリックロードバランサー(5ca5ada9-jp-osa.lb.appdomain.cloud)への HTTPS アクセスが可能になります。ただ証明書が自己証明書のため、アクセス制約がかかります。この yaml ファイルでデプロイしなおします(VPN を切ったままの場合は再接続してから):
$ oc apply -f guestbook_deployment.yaml


そしてブラウザでアクセスしてみます。具体的には以下のようになります。VPN を切断後にブラウザで https://5ca5ada9-jp-osa.lb.appdomain.cloud にアクセスすると、以下のような画面になります。「詳細設定」をクリックします:
2023020202


証明書が自己証明書なので安全ではない、というメッセージが表示されます。安全ではないことを理解した上でアクセスしてみます:
2023020203


すると、(保護はされていないけれど)一応 HTTPS でアクセスできることが確認できます:
2023020204


このパブリックロードバランサーのドメインは OpenShift 環境から自動発行されたもので、内部的に使うぶんにはこれで問題ないのですが、ユーザーが直接使う場合はちょっと気になる部分ではあります:
2023020205


後述の手順で正しい証明書を使った HTTPS アクセス方法を紹介しますが、こちらにも別の制約事項があるので、両方理解した上でどちらを使うべきか検討してください。


【3. プライベート OpenShift クラスタにアプリケーションをデプロイし、カスタムドメインの証明書を使って HTTPS アクセスができるよう定義する】

2023020207


最後のケースは HTTPS としては完成形のような位置づけですが、これまでのケースにはない制約事項が1つあります。それは「カスタムドメインを使う」必要がある点です。2. では IBM Cloud 発行のドメインを使って HTTPS ができなかったのを、自前のドメインを使うことで回避する方法になります。

例えば "pi314.jp" というカスタムドメインを使うことにして、2. までに説明してきたアプリケーションを "guestbook.pi314.jp" というホスト名で HTTPS アクセス可能にする、という想定で以下の説明を行います。

まずカスタムドメインの DNS を設定します。契約したドメイン会社や DNS 移管先によって具体的な設定手順は異なりますが、guestbook という CNAME に対して、パブリックロードバランサー名を設定します(下図は CloudFlare.com を使った場合のスクリーンショット):
2023020206


更にデプロイ用の guestbook_deployment.yaml をもう一度改良して、赤字部分を更に追加します:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: guestbook
  labels:
    app: guestbook
spec:
  replicas: 1
  selector:
    matchLabels:
      app: guestbook
  template:
    metadata:
      labels:
        app: guestbook
    spec:
      containers:
      - name: guestbook
        image: ibmcom/guestbook:v1
        imagePullPolicy: Always
        env:
          - name: NODE_ENV
            value: production
---
apiVersion: v1
kind: Service
metadata:
  name: guestbook-svc
  labels:
    app: guestbook
spec:
  type: ClusterIP
  ports:
  - port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: guestbook
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-i000.jp-osa.containers.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.kkimura-mycluster-jp-osa-6fe57c7eaf38abe6232341d97eae54c0-0001.jp-osa.containers.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: 5ca5ada9-jp-osa.lb.appdomain.cloud
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: guestbook-route
  labels:
    app: guestbook
spec:
  host: guestbook.pi314.jp
  to:
    kind: Service
    name: guestbook-svc
    weight: 100
  port:
    targetPort: 3000
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None

この yaml ファイルを(VPN が切れている場合は再接続してから)再度適用します:
$ oc apply -f guestbook_deployment.yaml

そして VPN を切断し、ブラウザでカスタムドメイン側に登録した名前(guestbook.pi314.jp)に HTTPS アクセスしてみましょう:
2023020207


警告などが表示されることなく、ちゃんと HTTPS でパブリックアクセスできることが確認できるはずです。


以上、コンテナ環境を運用する上で
・コンテナ管理はプライベートネットワークで運用し、
・デプロイしたアプリはパブリックネットワークから利用する

という要件はあってもおかしくなさそうですが、今回紹介したような方法で実現できそうです。自己証明書を使うページはスマホから利用するのが難しいのですが、カスタムドメインという高めのハードルを越えることができればその問題もなくなります。利用環境や目的に応じて検討してください。


マンホール関係者枠(?)で、映画 "#マンホール" (読み方は「はっしゅたぐまんほーる」)のオンライン試写に参加させていただきました:

00



この映画の存在は SNS で以前から知っており、また好きな女優さんの一人である奈緒さんが出演されることもわかったので気になっていました。このたびマンホールマニア(笑)枠でこの映画の試写に参加させていただいた経緯でございます。「#マンホール」は 2/10 から一般公開されますが、一足早く鑑賞させていただきました。関係者の皆様、本当にありがとうございました。

実を言うと試写を見る前(苦笑)から、こんな感想を書くつもりでいました:
あんなオチが用意されているとは、とても奥の深い作品でした。マンホールだけに


・・・で、実際に観た感想ですが、、、いやあ舐めてました。ごめんなさい。まずタイトルの「ハッシュタグ・マンホール」について。自分のようなマンホール蓋愛好家の立場では「#マンホール」って確かにしょっちゅう検索に使ってるけど、事前の予告を観た限りではそういう話とは思えない。「ハッシュタグ」ってどういうことよ!? と思ってましたが、なるほど SNS を駆使してストーリーが展開していく様子をタイトルに含めていたんですねー。

あと、この映画は「マンホール内に閉じ込められた男性がタイムリミットまでの脱出を試みる」話なので、どうしても一人芝居が多くなるだろうな、と予想していました。もしかするとつまらないと感じる時間が長くなってしまうかも・・・ という不安もありました(実際、大半が一人芝居だったように思います)が、自分も普段 SNS を使っていることもあり、SNS やネット素材をこれでもかというほど活用(悪用?)して知らない人との連帯で展開されていく様子は一人であって一人でないような、気が付くと引き込まれているような、痛快さと怖さを感じる映画でもありました。

そして終盤、「ここまで追い詰められてどうやって解決するんだろ?」と不安になってしまいました。試写時の約束でオチについては触れられないことになっていますが、、うーん、、深い!(謎) これは実際に観てのお楽しみということで。


ちなみに、作品内で「マンホール蓋のデザインから地名を特定する」シーンがありましたが、これは我々マニアの得意分野でもあります。 σ(^o^) 最近のマンホール蓋は地域の文化に関わる意匠がデザインされることも多く、そういうのは見ればだいたいわかります。今回の作品で出てきた蓋そのものは全国共通のいわゆる「JIS 規格」モノだったように思いますが、この蓋は中央に市区町村章がデザインされていることが多いので、そこで特定可能です。ただ自分も全ての市区町村章を暗記しているわけではないので、あのスピードで特定できるのは相当なマニアがいたように感じました。 (^^;

そんなマンホール蓋マニアや愛好家が多く集まるのがツイッターの #manhotalk ハッシュタグと、全国の(実際には世界中の)マンホール蓋デザインとその位置情報が集まるマンホール SNS 「マンホールマップ」です。映画を通じてマンホール蓋デザインに興味を持った方がいらっしゃったら、ぜひこれらも覗いてみてください。そして是非地元のマンホール蓋を撮影して、マンホールマップに投稿してください。お待ちしております:
banner



このたびは貴重な試写の機会をいただき、ありがとうございました。マンホーラー冥利に尽きる機会でした。

最後に改めて感想を:
あんなオチが用意されているとは、本当にとても奥の深い作品でした。マンホールだけに


このページのトップヘ