🔐

Docker-Composeを使用した際のKeyCloakのデータを外部DBに依存させる方法

2023/06/01に公開

はじめに

研修中にKeyCloakを使用してOpenID Connectを自作アプリに導入する機会があり、KeyCloakを触ったこともなく非常に混乱した部分だったので、備忘録として記録したいと思います。 KeyCloakにはもともとH2というRDBMS(DBを管理するシステム)が含まれていて、デフォルトの設定ではこちらを使用して腹持ちのDBを利用する形が取られています。 ここで、状況によっては外部DBを持っておいて、冗長性を持たせたいケースが出てくるときがあると思います。 KeyCloakには外部DBを参照させられる設定があるので今回はこちらをDockerを利用してやってみました。

KeyCloakってなんですか

KeyCloakというのは、皆さんインターネットを利用する上で必ずつきまとう認証システムをやってくれるOSS(OpenSourceSoftware)の一つです。 SAML認証とOpenID Connectが可能なのですが、最近はOpenID Connectがよく使われています。 OpenID Connectは例えばGoogleのアカウントが存在することを保証して、ChatGPTにログインできたりできる機能です。 アカウント作成の時にGoogleアカウントやTwitterアカウントで作るというところがあるのがそれです。 パスワードを各サービスごとに作らなくていいので結構便利です。
今は、パスワードレスにしようみたいな動きが活発ですが

動作環境

使ったもの バージョン
MacOS Ventura 13.3.1(a)
Docker 4.19.0
KeyCloak 21.0.2
MySQL 8.0.33

今回はMySQLでのやり方を記載していますが、他主要DBでも可能です。

手順

Step1 Dockerをインストールしましょう

Dockerとは何かというと、仮想環境をローカルのPCに生み出せるコンテナツールです。
詳しくは、googleで調べてもらえるとわかりやすく解説してくれている記事があると思います。

https://www.docker.com/
上記のURLに飛んで、自分の環境にあったDockerをインストールしてもらえるといいかと思います。

Step2 Docker-composeを利用して、Docker上にKeyCloakとMySQLのサーバーを立てる

Docker-Composeは設定ファイルなのですが、Dockerで複数個のコンテナを一緒に立てたい時にとても有効です。 実際に私が作成してみたDocker-Composeファイルはこちらになります。

version: '3.8'

volumes:
  mysql_data:
      driver: local

services:
  mysql:
      image: mysql:8.0.33
      container_name: mysql
      volumes:
        - mysql_data:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: keycloak
        MYSQL_USER: keycloak
        MYSQL_PASSWORD: password
      ports:
        - 3306:3306

  keycloak:
      image: quay.io/keycloak/keycloak:21.0.2
      container_name: keycloak
      environment:
        KEYCLOAK_ADMIN: admin
        KEYCLOAK_ADMIN_PASSWORD: admin
        KC_DB : mysql
        KC_DB_URL: jdbc:mysql://mysql:3306/keycloak
        KC_DB_URL_DATABASE: keycloak
        KC_DB_USERNAME: keycloak
        KC_DB_PASSWORD: password
      ports:
        - 8080:8080
      command:
        - start-dev

Docker-composeの詳細については、こちらの記事がまとめてくれているので参照していただけるとよいと思います。
https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04

この例では、「mysql_data」ボリュームがそれにアタッチされています。MySQLコンテナで生成されたデータは、コンテナ内の「/var/lib/mysql」ディレクトリに保存され、ホストマシンの「mysql_data」ボリュームにマッピングされます。
さらに、environmentでMySQLとKeyCloakの環境変数をそれぞれ設定しています。
※imageでmysql:8.0.33の後続のバージョン指定の部分をlatestとすると、最新バージョンが取得可能なのですが、明示的にしたほうが管理面で良いと思うのでなるべく数字で示せるなら、数字のほうが良いと思います。
KeyCloakの立ち上げ時のコマンドとして今回は、start-devを使用しています。 こちらは開発環境としての起動になっていて特段何もオプションを付けずとも動いてくれるものです。 他にもstartがあります。 これは、本番環境として立ち上げる場合が想定されており、オプションとしてホスト名、サーバー証明書のパス、証明書の秘密鍵のパスの指定が必須となっており、これらなしでは動いてくれません。 また、buildコマンドでサーバーのイメージを作成することも必要であり、小難しい設定が必要となるので今回は使用を控えさせていただきました。

こちらのファイルが存在するディレクトリに移動して

docker-compose up -d

とするとmysqlとkeycloakのコンテナが立ち上がります。
閉じるときは同じディレクトリで

docker-compose down

です。

Step3 KeyCloakが立ち上がっているかどうかの確認

ここまでできたら、しっかり立ち上がってくれているかどうかを確認しましょう。
KeyCloakのコンテナは8080ポートで立てたので、
http://localhost:8080
でアクセスすることができると思うので、KeyCloakの環境変数で設定したadminとそのパスワードでログインしてみて動いているか確認しましょう。

このような画面ができたら、administration ConsoleにいくとKeyCloakの管理画面へのログイン画面が出るのでDocker-Composeにて設定したKEYCLOAK_ADMINとKEYCLOAK_ADMIN_PASSWORDをそれぞれ入力して、成功すると

このようなページが出ればKeyCloakの起動は完璧です。

Step4 MySQLに接続して、KeyCloakのデータが保存されているかどうか確認

ここで、本命のDBの確認です。
MySQLを立てたコンテナに入って、きちんとテーブルができているかどうか確認しましょう。
コンテナ内への入り方は

docker exec -it コンテナ名 mysql -u{ユーザー名} -p{パスワード}

でmysqlサーバーのmysqlに接続することができます。
今回はkeycloakという名前のデータベースにデータを保存するように設定しているので

docker exec -it mysql mysql -ukeycloak -ppassword keycloak

といれれば、データベースをkeycloakに指定して入ることができます。

さあ、無事に入ることができたら

show tables;

と入力してみましょう。
KeyCloakのREALMやらCLIENTやらのテーブルがあれば接続成功です。

終わりに

今回はあまり難しいことはせずに、簡単な接続の説明で終わりにしたいと思います。
もっと冗長性を持たせようとすると、NginxをロードバランサーとしておいてKeyCloakを二台構成にして、この2台に対して外部DBを接続するような構成にもできるのですが、それはまた次回の機会にしたいと思います。

ここまで読んでくれてありがとうございます。

EMP Tech Blog

Discussion