やること
- ECS on Fargateにkeycloakをクラスタ構成でデプロイする
構成図
keycloakのDockerイメージをECRにPush
-
以下のDockerfileをECRにPushする。
(参照:https://qiita.com/s-takino/items/c666c0a1fce10dd30843)# ビルド環境の準備 FROM quay.io/keycloak/keycloak:latest as builder WORKDIR /opt/keycloak # 検証環境のため簡易的な証明書を作成 RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore # Keycloakのビルドスクリプトを実行して、Keycloakをビルド RUN /opt/keycloak/bin/kc.sh build # 本番環境の設定 FROM quay.io/keycloak/keycloak:latest # ビルドステージから生成されたファイルをコピー COPY --from=builder /opt/keycloak/ /opt/keycloak/ # JARファイルの追加 ADD --chown=keycloak:keycloak https://repo1.maven.org/maven2/org/jgroups/aws/jgroups-aws/2.0.1.Final/jgroups-aws-2.0.1.Final.jar /opt/keycloak/providers/jgroups-aws-2.0.1.Final.jar ADD --chown=keycloak:keycloak https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-core/1.12.410/aws-java-sdk-core-1.12.410.jar /opt/keycloak/providers/aws-java-sdk-core-1.12.410.jar ADD --chown=keycloak:keycloak https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-s3/1.12.410/aws-java-sdk-s3-1.12.410.jar /opt/keycloak/providers/aws-java-sdk-s3-1.12.410.jar ADD --chown=keycloak:keycloak https://repo1.maven.org/maven2/joda-time/joda-time/2.12.2/joda-time-2.12.2.jar /opt/keycloak/providers/joda-time-2.12.2.jar # エントリーポイント(kc.sh)の設定 ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
- 検証目的のため簡易的な自己証明書を利用(実運用環境では適切な証明書を使用すること)
- 環境変数はFargate側で設定するためDockerfileでは未定義
- keycloakのクラスタリングに必要なjarファイルをダウンロードして追加
- UDPの使用がデフォルト設定だが、AWSでは対応していないため、「S3_ping」を使用する
-
ECRにPush
- ECRの作成手順は本記事では割愛
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <アカウント名>.dkr.ecr.ap-northeast-1.amazonaws.com docker build -t <任意のイメージ名> . docker tag <任意のイメージ名>:latest <アカウント名>.dkr.ecr.ap-northeast-1.amazonaws.com/<リポジトリ名>:latest docker push <アカウント名>.dkr.ecr.ap-northeast-1.amazonaws.com/<リポジトリ名>:latest
周辺リソースの環境構築
-
VPCの作成
VPCを一つと、パブリックサブネット、プライベートサブネットを二つずつ作成する。 -
セキュリティグループの作成
▷ ALB用SGルール タイプ プロトコル ポート ソース インバウンド HTTP TCP 80 0.0.0.0/0 HTTPS TCP 443 0.0.0.0/0 アウトバウンド すべてのトラフィック すべて すべて 0.0.0.0/0 ▷ コンテナ用SG
ルール タイプ プロトコル ポート ソース インバウンド MYSQL/Aurora TCP 7800 コンテナ用SGのID MYSQL/Aurora TCP 8080 ALB用SGのID アウトバウンド すべてのトラフィック すべて すべて 0.0.0.0/0 ▷ DB用SG
ルール タイプ プロトコル ポート ソース インバウンド MYSQL/Aurora TCP 3306 コンテナ用SGのID アウトバウンド すべてのトラフィック すべて すべて 0.0.0.0/0 -
DB(RDS)の構築
Cloud9や踏み台サーバをRDSと同一VPC内にデプロイし、以下のコマンドを実行# mysqlログイン mysql --user=admin --password -h <RDSのエンドポイント> # DB作成 MySQL [(none)]> create database keycloak character set utf8 collate utf8_unicode_ci; # ユーザ作成 MySQL [(none)]> create user 'dbuser' identified by 'dbpass'; # ユーザにDBへの権限付与 MySQL [(none)]> grant all privileges on keycloak.* to 'dbuser';
-
S3バケットの作成
keycloakクラスタメンバーのリストの格納先となるS3バケットを作成しておく -
ドメイン名、証明書の取得
keycloakサーバ用へのアクセスをHTTPS化するためドメインと証明書を取得する。
証明書は自己証明書を使うと500エラーが発生するためACM経由で発行する。 -
ALBの作成
コンテナの前段に配置するALBを作成する。
▷ターゲットグループ# ## 基本的な設定 ターゲットタイプの選択 IP ターゲットグループ名 任意の名称 プロトコル : ポート HTTP: 8080 IP アドレスタイプ IPv4 VPC 作成済みのVPCを選択 プロトコルバージョン HTTP1 ヘルスチェック ヘルスチェックプロトコル HTTP ヘルスチェックパス /auth/admin ▷ロードバランサー
# ## ロードバランサータイプ Application Load Balancer 基本的な設定 ロードバランサー名 任意の名称 スキーム インターネット向け ネットワークマッピング VPC 作成済みのVPCを選択 VPC 作成済みのVPCを選択 マッピング パブリックサブネットを二つ選択する セキュリティグループ 作成済みのSGを選択 リスナーとルーティング リスナー プロトコル:HTTPS/ポート:443/ターゲットグループ:作成済みのターゲットグループを選択 セキュアリスナーの設定 セキュリティポリシー ポリシー名:ELBSecurityPolicy-TLS13-1-2-2021-06 デフォルト SSL/TLS サーバー証明書 作成済みのACM証明書を選択 -
レコードセット登録
Route53にてエイリアスレコードを使用して、作成したドメインとALBを紐づける。
Fargateの作成
-
クラスター作成
インフラストラクチャにAWS Fargateを選択して作成。
# ## 基本的な設定 ターゲットタイプの選択 IP デフォルトの名前空間 任意の名称 インフラストラクチャ AWS Fargate -
タスク定義作成
- タスクロールは以下のポリシーを付与して作成する
- AmazonEC2ContainerServiceRole
- AmazonS3FullAccess
- タスク実行ロールは以下のポリシーを付与して作成する
- AmazonECSTaskExecutionRolePolicy
# ## タスク定義の設定 タスク定義ファミリー名 任意の名称 インフラストラクチャの要件 起動タイプ AWS Fargate OS、アーキテクチャ、ネットワークモード Linux/X86_64 ネットワークモード awsvpc(既定) タスクサイズ CPU:.5vCPU/メモリ:3GB タスクロール 作製したロールを選択 タスク実行ロール 作製したロールを選択 コンテナ - 1 コンテナの詳細 名前:任意の名称/イメージ URI:PushしたECRイメージURI/必須コンテナ:はい プライベートレジストリ認証 いいえ ポートマッピング コンテナポート:8080/プロトコル:TCP/ポート名:http/アプリケーションプロトコル:HTTP コンテナポート:7800/プロトコル:TCP/ポート名:none/アプリケーションプロトコル:None 読み取り専用 いいえ 環境変数 下記表を参照 ログ収集の使用 はい(値はデフォルト) ストレージ- オプション 量 30 環境変数
キー 値 説明 JAVA_OPTS_APPEND -Djgroups.s3.region_name=ap-northeast-1 -Djgroups.s3.bucket_name=<バケット名> JGroups S3_PINGプロトコル用の追加Javaオプション KC_HOSTNAME < keycloak サーバのドメイン名> Keycloakのホスト名 KC_ADMIN_HOSTNAME < keycloak サーバのドメイン名> 管理コンソール用のホスト名 KC_DB_URL jdbc:mysql://:3306/<作成したDB名> MySQLデータベースのJDBC接続URL KC_DB_USERNAME <作成したDBユーザ名> DB接続に使用するユーザ名 KC_DB_PASSWORD <作成したDBユーザのパスワード> DB接続に使用するパスワード KC_CACHE ispn KeycloakのキャッシュプロバイダーとしてInfinispanを使用 KC_CACHE_STACK ec2 Infinispanキャッシュの設定スタックをEC2用に設定 KC_DB mysql 使用するDBの種類 KC_HEALTH_ENABLED true ヘルスチェックエンドポイントを有効化 KC_HOSTNAME_STRICT false リクエストのホスト名検証を無効化 KC_HTTP_ENABLED true HTTPプロトコルを有効化 KC_HTTP_PORT 8080 HTTP接続のポートを指定 KC_PROXY edge 前段にALBを配置するためEdgeプロキシ設定を有効化 KEYCLOAK_ADMIN admin 初期管理者ユーザ名 KEYCLOAK_ADMIN_PASSWORD admin 初期管理者ユーザのパスワード - タスクロールは以下のポリシーを付与して作成する
-
サービス作成
- タスクロールは以下のポリシーを付与して作成する
- タスク実行ロールは以下のポリシーを付与して作成する
# ## 環境 既存のクラスター 作成済みのクラスターを選択 コンピューティングオプション キャパシティープロバイダー戦略 キャパシティープロバイダー戦略 カスタムを使用 (アドバンスト) キャパシティープロバイダー:FARGATE/ベース:1/ウェイト:1 プラットフォームバージョン LATEST デプロイ設定 アプリケーションタイプ サービス タスク定義 作成済みのタスク定義を選択 サービス名 任意の名称 サービスタイプ レプリカ ネットワーキング VPC 作成済みのVPCを選択 サブネット 作成済みのプライベートサブネットを選択 セキュリティグループ 作成済みのSGを選択 パブリックIP いいえ ロードバランシング ロードバランサーの種類 Application Load Balancer コンテナ 8080:8080 ロードバランサー 作成済みのALBを選択 ヘルスチェックの猶予期間 60 リスナー 作成済みのリスナーを選択 ターゲットグループ ターゲットグループ名:/作成済みのターゲットグループを選択/ヘルスチェックパス:/auth/admin/ヘルスチェックプロトコル:HTTPS
動作確認
実際にアクセスしてみる。
コンテナの環境変数で指定した初期管理者ユーザ名/パスワードにてログインする。
realmを作成してみる。画像赤枠の「Create realm」を押下。
Realm nameに任意の名前を記入して作成。
作製したrealmは先程の選択タブより切り替え可能
続けてUserを作成する。
Usersメニューより「Add User」ボタンを押下。
任意の名前を記載し、Create。
最後にkeycloakが正常にクラスタ構成で動作しているか確認する。
ECSのサービスを確認するとタスクが二つ作成されていることが分かる。
S3に格納されたlistファイルも確認する。
中身を見るとタスクのプライベートIPが表示されているため、正常にクラスタ構成にて動作していることが確認できる。
DBでも確認。(見づらいのでメモ帳経由で添付)
▷MySQL [keycloak]> select * from USER_CONSENT;
▷MySQL [keycloak]> select * from USER_ENTITY;
最後に
Fargateは非常にやさしくアプリケーションをデプロイできるので助かりますね。
参考資料
https://qiita.com/s-takino/items/c666c0a1fce10dd30843
https://qiita.com/wadahiro/items/0837729e7c57becbfd06