2019年7月22日月曜日

Docker で Keycloak に入門する

Keycloak の Getting Started Guide をやっていく。

前提

  • OS: Windows 10 Pro
  • Docker: Docker version 18.09.2, build 6247962
    • 使用イメージ: debian:buster-slim
  • Keycloak: 6.0.1

事前準備

コンテナ起動

docker run -it --rm -p "80:80" -p "8080:8080" -p "9080:9080" debian:buster-slim
  • 80: アプリケーションサーバーポート
  • 8080: keycloak ポート
  • 9080: アプリケーションサーバー管理用ポート

必要なパッケージを取得

apt-get update
apt-get upgrade -y
mkdir -p /usr/share/man/man1
apt-get install -y curl openjdk-11-jdk

※ openjdk は、 headless だとサンプルアプリのデプロイでエラーが発生するため、今回は普通のものをインストールする。

keycloak の準備

keycloak のインストール

ダウンロード

curl -L https://downloads.jboss.org/keycloak/6.0.1/keycloak-6.0.1.tar.gz -O

配置

tar xf ./keycloak-6.0.1.tar.gz -C /opt

初期設定

初期ユーザー作成

ユーザー mikoto を追加。

root@dd4775da3619:/# /opt/keycloak-6.0.1/bin/add-user-keycloak.sh -u mikoto
Press ctrl-d (Unix) or ctrl-z (Windows) to exit
Password:
Added 'mikoto' to '/opt/keycloak-6.0.1/standalone/configuration/keycloak-add-user.json', restart server to load user

すでに keycloak サーバーを起動してしまっている場合は、サーバーを再起動するとユーザーが有効になる。

keycloak の起動

/opt/keycloak-6.0.1/bin/standalone.sh -Djboss.bind.address=0.0.0.0 -Djboss.http.port:8080 -Djboss.https.port=8523 -Djboss.bind.address.management=0.0.0.0 -Djboss.management.http.port=9000 -Djboss.management.https.port=9443

各引数の意味はこんな感じ。

  • -Djboss.bind.address=0.0.0.0: keycloak の listen アドレス。今回は Docker を使っているので、どこからでもアクセスできるように 0.0.0.0 を設定。
  • -Djboss.http.port=8080, -Djboss.https.port=8523: keycloak 接続ポート
  • -Djboss.bind.address.management=0.0.0.0: keycloak が動いている WildFly の管理用ページ(?) の listen アドレス。今回は Docker を使っているので、どこからでもアクセスできるように 0.0.0.0 を設定。
  • -Djboss.management.http.port=8080, -Djboss.management.http.port=9443: keycloak が動いている WildFly の管理用ポート

その他、ポート番号はオフセットで指定することもできる。こっちのほうが楽そう。

  • -Djboss.socket.binding.port-offset=10000

Realm とユーザーの追加

http://localhost:8080 に接続し、 Realm とユーザーを追加する。

Realm の追加

  1. 左上の Master のドロップダウンを選択
  2. Add realm ボタン押下
  3. realm の設定を入力
    1. Name: demo
    2. Enabled: ON
    3. Create 押下
    4. 左上のドロップダウンが Demo に変わっているのを確認

Realm に対するユーザーの追加

  1. 左のサイドメニューの Users を選択
  2. Add user ボタン押下
  3. ユーザー情報の追加
    1. Username: demo_user
    2. User Enabled: ON
    3. Save 押下
  4. Credentials タブを選択
  5. パスワード設定
    1. New Password, Password Confirmation を設定
    2. Reset Password 押下
    3. Change password 押下

アプリケーションの準備

アプリケーション用 WildFly のインストール

WildFly のダウンロードと展開

curl -L https://download.jboss.org/wildfly/17.0.1.Final/wildfly-17.0.1.Final.tar.gz -O
tar xf wildfly-17.0.1.Final.tar.gz

WildFly OpenID Connect adapter のダウンロード・展開

curl -L https://downloads.jboss.org/keycloak/6.0.1/adapters/keycloak-oidc/keycloak-wildfly-adapter-dist-6.0.1.tar.gz -O
tar xf keycloak-wildfly-adapter-dist-6.0.1.tar.gz -C wildfly-17.0.1.Final

WildFly OpenID Connect adapter のインストール

cd ./wildfly-17.0.1.Final/bin
./jboss-cli.sh --file=adapter-install-offline.cli

WildFly の実行

./standalone.sh -Djboss.bind.address=0.0.0.0 -Djboss.http.port=80 -Djboss.https.port=443 -Djboss.bind.address.management=0.0.0.0 -Djboss.management.http.port=9080 -Djboss.management.https.port=9523

keycloak を利用するアプリケーションの準備

keycloak を利用する側のアプリを準備。 keycloak の quickstarts のアプリを使う。

ソース取得

apt-get install -y git maven
git clone https://github.com/keycloak/keycloak-quickstarts

ビルド・デプロイ

cd keycloak-quickstarts/app-profile-jee-vanilla
mvn clean wildfly:deploy -Dwildfly.port=9080 -Dmaven.compiler.target=11 -Dmaven.compiler.source=11

demo_user がまだ許可されていないことを確認

http://localhost/vanilla にアクセス。

LOGIN ボタンを押すと、 BASIC 認証ダイアログが表示される。demo_user のユーザー名・パスワードでログインできないことを確認。

アプリケーションと demo Realm の紐づけ

アプリケーションと demo Realm を紐づけて、 demo Realm の情報でログインできるようにする。

keycloak 側の設定

  1. demo realm -> Clients を選択
  2. Create 押下
  3. クライアント情報入力
    1. Client ID: vanilla
    2. Client Protocol: openid-connect
    3. Root URL: http://localhost/vanilla
    4. Save 押下
  4. Installation タブ選択
    1. Format Option: Keycloak OIDC JBoss Subsystem XML

アプリケーションサーバー側の設定

/wildfly-17.0.1.Final/standalone/configuration/standalone.xml を編集する。

<subsystem xmlns="urn:jboss:domain:keycloak:1.1"/> を探して、以下のように修正する。

<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
    <secure-deployment name="vanilla.war">
        <realm>demo</realm>
        <auth-server-url>http://localhost:8080/auth</auth-server-url>
        <public-client>true</public-client>
        <ssl-required>EXTERNAL</ssl-required>
        <resource>vanilla</resource>
    </secure-deployment>
</subsystem>

アプリケーションサーバーを再起動すると、この設定が有効になる。

demo_user でログインできることを確認

http://localhost/vanilla にアクセス。

LOGIN ボタンを押すと、 keycloak のログイン画面が表示される。

demo_user のユーザー名・パスワードでログインできることを確認。 初回ログインなのでパスワードの更新を求められる。

ログインが完了すると、次のような画面が表示される。

以上。

アプリケーションサーバー管理用ポートを開けて、サンプルアプリケーションのビルド・デプロイはホスト側でやるというのもありですね。

参考資料

2019年7月19日金曜日

GitLab Runner で Azure Container Registry を使う

GitLab Runner が使うイメージを管理するのに Azure Container Registry を使いたい。

諸事情により GitLab Container Repository が使えない。

前提

Azure CLI 用のコンテナ準備

Azure CLI 用のコンテナを起動し、 Docker をインストールする。 必要に応じてこの作業の結果をイメージ化するのが良さそう。

Azure CLI 用のコンテナ起動

docker run -it --rm -v "/var/run/docker.sock:/var/run/docker.sock" microsoft/azure-cli

Docker のインストール

apk update
apk add docker

Azure 側の準備

  1. Azure へログイン
  2. リソースグループの作成
  3. コンテナレジストリ作成
  4. サービスプリンシパルの作成

GitLab Runner から Azure Container Registry を使用するためには「4.」が必須となる。 (対話的に push, pull するだけなら「3.」までで良い)

Azure へログイン

# az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code xxxxxxxxx to authenticate.
[
  {
    "cloudName": "AzureCloud",
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "isDefault": true,
    "name": "Pay-As-You-Go",
    "state": "Enabled",
    "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "user": {
      "name": "USER@COMPANY.onmicrosoft.com",
      "type": "user"
    }
  }
]

https://microsoft.com/devicelogin へアクセスして code を入力する。

リソースグループの作成

# az group create --name MyGitLab --location japaneast
{
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MyGitLab",
  "location": "japaneast",
  "managedBy": null,
  "name": "MyGitLab",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": null
}

コンテナレジストリの作成

# az acr create --resource-group MyGitLab --name ContainerRegistryForGitLab --sku Basic
{
  "adminUserEnabled": false,
  "creationDate": "2019-07-14T12:29:14.193071+00:00",
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MyGitLab/providers/Microsoft.ContainerRegistry/registries/ContainerRegistryForGitLab",
  "location": "japaneast",
  "loginServer": "containerregistryforgitlab.azurecr.io",
  "name": "ContainerRegistryForGitLab",
  "networkRuleSet": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "MyGitLab",
  "sku": {
    "name": "Basic",
    "tier": "Basic"
  },
  "status": null,
  "storageAccount": null,
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries"
}

サービスプリンシパルの作成

# az ad sp create-for-rbac --name GitLabRunner
Changing "GitLabRunner" to a valid URI of "http://GitLabRunner", which is the required format used for service principal names
Retrying role assignment creation: 1/36
Retrying role assignment creation: 2/36
Retrying role assignment creation: 3/36
{
  "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "displayName": "GitLabRunner",
  "name": "http://GitLabRunner",
  "password": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

appIdpassword をメモしておく。

az ad sp list --display-name GitLabRunner で、作成したサービスプリンシパルの情報を確認できる。

サービスプリンシパルへのロール設定

ロール設定

GitLab Runner は、読み込み権限しか必要ないはずなので、 AcrPull のロールを割り当てる。

次のコマンドで、 新規ロール(AcrPull)の追加とデフォルトのロール(Contributor)の削除を行う。

az role assignment create --assignee APP_ID --role AcrPull
az role assignment delete --assignee APP_ID --role Contributor
  • APP_ID: メモした appId

az role assignment list で、結果の確認ができる。

ロール設定の確認

docker login した後に docker push で失敗することを確認。

# docker login containerregistryforgitlab.azurecr.io
# docker push containerregistryforgitlab.azurecr.io/hello-world
The push refers to repository [containerregistryforgitlab.azurecr.io/hello-world]
6f9c9be2140a: Layer already exists
errors:
denied: requested access to the resource is denied
unauthorized: authentication required

docker login 時の UsernamePassword には、先ほどメモした appIdpassword を使用する。

使用するイメージを作成・プッシュ

Dockerfile 作成

FROM debian:buster-slim

LABEL maintainer "mikoto2000 <mikoto2000@gmail.com>"
LABEL version="v1.0.0"
LABEL description "print 'Hello, World!!!'"

CMD ["echo", "Hello, World!!!"]

ビルド

docker build -t containerregistryforgitlab.azurecr.io/hello-world .

Push

現在は、リードオンリーなサービスプリンシパルでログインしている状態なので、 いったんログアウトして az acr login でログインしなおす。

az acr login --name ContainerRegistryForGitLab
docker push containerregistryforgitlab.azurecr.io/hello-world

az acr login で失敗する場合には、 az login からやり直すと良いかもしれない。

GitLab Runner の設定

GitLab に環境変数を登録

DOCKER_AUTH_CONFIGFile タイプとして作成し、以下の JSON 文字列を設定する。

{
    "auths": {
        "containerregistryforgitlab.azurecr.io": {
            "auth": "BASE64ED_USERNAME:PASSWORD"
        }
    }
}
  • containerregistryforgitlab.azurecr.io: 作成した Azure Container Registry の URL
  • BASE64ED_USERNAME:PASSWORD: サービスプリンシパルを作成した時にメモした appIdpassword: で繋げた文字列を BASE64 変換した文字列

PowerShell での Base64 への変換方法参考

以下コマンドで変換可能。

$text_byte = ([System.Text.Encoding]::Default).GetBytes("ここに変換したい文字列を入れる")
[Convert]::ToBase64String($text_byte)

Azure Container Registry から Pull する設定を gitlab-ci.yml へ記載

.gitlab-ci.ymlimage で Azure Container Registry のイメージを指定するだけ。

image: containerregistryforgitlab.azurecr.io/hello-world

stages:
    - hello

print_hello:
    stage: hello
    tags:
        - test
    script:
        - echo Hello, World!

.gitlab-ci.ymlpush すると、GitLab Runner による CI が実行される。

検証の後片付け

各リソースの消し方確認もかねて、丁寧に一つずつ削除していく。

サービスプリンシパルの削除

az ad sp delete --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  • --id: サービスプリンシパルを作成した時にメモした appId を指定

Azure Container Registry の削除

az acr delete  --resource-group MyGitLab --name ContainerRegistryForGitLab

リソースグループの削除

az group delete --name MyGitLab

以上。

参考資料

更新履歴

日付 更新内容
2019/7/19 新規作成
2019/7/19 割り当てるべきロールの種類を間違えていたのを修正(Reader -> AcrPull)

2019年7月8日月曜日

Theia と vscode-java で Java 開発環境を整える

theia-ide/theia を試す。

theia-ide/theia-apps にいろんな Dockerfile があるので、それを参考に Java 開発環境を構築していく。

前提

Visual Studio Code プラグインが使えるようなのでそれを使う。

必要なファイルの作成

theia-ide/theia-apps/theia-go-docker に VS Code プラグインを有効にしたいときの参考になる Dockerfile, package.json がある。

それを参考に作って、同じディレクトリに格納する。

Dockerfile

ARG NODE_VERSION=10
FROM node:$NODE_VERSION
WORKDIR /home/theia
ADD package.json ./package.json
ARG GITHUB_TOKEN

# OpenJDK12 をダウンロード・配置・環境変数設定
RUN mkdir -p /opt/java && \
    curl -L https://download.java.net/java/GA/jdk12.0.1/69cfe15208a647278a19ef0990eea691/12/GPL/openjdk-12.0.1_linux-x64_bin.tar.gz -o /tmp/openjdk-12.0.1_linux-x64_bin.tar.gz && \
    tar xf /tmp/openjdk-12.0.1_linux-x64_bin.tar.gz -C /opt/java/ && \
    rm /tmp/openjdk-12.0.1_linux-x64_bin.tar.gz
ENV JAVA_HOME=/opt/java/jdk-12.0.1
ENV PATH=${JAVA_HOME}/bin:${PATH}

RUN yarn --pure-lockfile && \
    NODE_OPTIONS="--max_old_space_size=4096" yarn theia build && \
    yarn --production && \
    yarn autoclean --init && \
    echo *.ts >> .yarnclean && \
    echo *.ts.map >> .yarnclean && \
    echo *.spec.* >> .yarnclean && \
    yarn autoclean --force && \
    yarn cache clean

# See : https://github.com/theia-ide/theia-apps/issues/34
RUN adduser --disabled-password --gecos '' theia && \
    chmod g+rw /home && \
    mkdir -p /home/project && \
    chown -R theia:theia /home/theia && \
    chown -R theia:theia /home/project;
USER theia

# configure Theia
ENV SHELL=/bin/bash \
    THEIA_DEFAULT_PLUGINS=local-dir:/home/theia/plugins

EXPOSE 3000
ENTRYPOINT [ "node", "/home/theia/src-gen/backend/main.js", "/home/project", "--hostname=0.0.0.0" ]

package.json

{
    "private": true,
    "dependencies": {
        "@theia/git": "next",
        "@theia/editor-preview": "next",
        "@theia/getting-started": "next",
        "@theia/json": "next",
        "@theia/plugin-ext-vscode": "next",
        "@theia/preview": "next",
        "@theia/textmate-grammars": "next"
    },
    "devDependencies": {
        "@theia/cli": "next",
        "@theia/debug": "next"
    },
    "scripts": {
        "postinstall": "download-debug-adapters"
    },
    "adapterDir": "plugins",
    "adapters": {
        "vscode-java": "https://redhat.gallery.vsassets.io/_apis/public/gallery/publisher/redhat/extension/java/0.46.0/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
    }
}

ポイントは以下三点。

  • scripts/postinstall: プラグインダウンロードに使うスクリプト、 adapterDir, adapters でプラグインを導入する場合必須
  • adapterDir: プラグインを入れるディレクトリ
  • adapters: インストールするプラグイン(vsix)を列挙

イメージビルド

Dockerfilepackage.json のあるディレクトリでビルドコマンドを実行。

docker build -t mikoto2000/theia-java:latest .

コンテナ実行

docker run --rm -p "3000:3000" mikoto2000/theia-java:latest

ブラウザで接続

localhost:3000 にアクセス。プラグインを確認すると、 vscode-java が入っているのがわかる。

以上。

参考資料