はじめに
当記事では、OpenShiftのOAuthサーバーを認証プロバイダとするLibertyをOperatorとしてデプロイする方法を記述します。
環境はOpenShift4.6です。
下記の記事の続編になります。
この記事ではAnsibleベースのOperator SDKを使用してOperatorをビルドしていますので、
合わせて下記を参照ください。
上記の記事によって、
静的な設定を通して、OpenShiftのOAuth Serverを認証プロバイダとして設定できている状況が前提とします。
環境をOperatorとしてデプロイして、デプロイされたOpenShiftのOAuthサーバーを認証プロバイダとするためには、
環境に依存する設定値を動的に設定する必要になります。
下記が、OperatorのAPI動作時に環境に合わせて動的に設定する情報です。
- ServiceAccountを作成する、アノテーションに、リダイレクトURLを設定する
- Oauth認証のためのClusterRole やClusterRole Bindingを作成し、ServiceAccountに関連付ける
- authorizationEndpointやtokenEndpointを環境に応じて、動的に取得する
- ServiceAccountのToken情報を取得する
- APIサーバーのSSL証明書をOpenLibertyが動作するJVMのキーストアにロードする
設定について
ServiceAccountを作成する、アノテーションに、リダイレクトURLを設定する
- name: Get downloadapp route
community.kubernetes.k8s_info:
api_version: route.openshift.io/v1
kind: route
name: downloadapp
namespace: "{{ ansible_operator_meta.namespace }}"
register: downloadappinfo
- debug:
msg: downloadapp info is {{downloadappinfo.resources[0].spec.host}}
- name: Create service account
community.kubernetes.k8s:
state: present
definition:
api_version: v1
kind: ServiceAccount
metadata:
name: downloadapp-sa
namespace: "{{ ansible_operator_meta.namespace }}"
annotations:
serviceaccounts.openshift.io/oauth-redirecturi.first: https://{{downloadappinfo.resources[0].spec.host}}/ibm/api/social-login/redirect/openshiftLogin
Oauth認証のためのClusterRole やClusterRole Bindingを作成し、ServiceAccountに関連付ける
- name: Create ClusterRole Binding
community.kubernetes.k8s:
state: present
definition:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: downloadapp-role
rules:
- apiGroups:
- authentication.k8s.io
resources:
- subjectaccessreviews
- tokenreviews
verbs:
- create
- name: Create ClusterRoleBinding Binding
community.kubernetes.k8s:
state: present
definition:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: donwloadapp-rb
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: downloadapp-role
subjects:
- kind: ServiceAccount
name: downloadapp-sa
namespace: "{{ ansible_operator_meta.namespace }}"
authorizationEndpointやtokenEndpointを環境に応じて、動的に取得する
authorizationEndpointやtokenEndpointを環境に応じて、動的に取得する方法については、OpenShiftのマニュアルに記載がありますので、下記に情報を紹介します。
- name: get oauth info
uri:
url: https://openshift.default.svc/.well-known/oauth-authorization-server
method: GET
return_content: yes
validate_certs: false
status_code: 200
body_format: json
register: oauth_info
- debug:
msg: authorization_endpoint is {{oauth_info.json.authorization_endpoint}}
- debug:
msg: token_endpoint is {{oauth_info.json.token_endpoint}}
ServiceAccountのToken情報を取得する
Podのデフォルトにおいて、コンテナの/run/secrets/kubernetes.io/serviceaccount
というディレクトリに、
ServiceAccountのTokenが、ファイルという形にマウントされます。
VARIABLE_SOURCE_DIRS
という環境変数に、このディレクトリを指定することで、
ファイル名をLibertyの環境変数、ファイルの内容と環境変数の値として読み込むことができます。
この仕組みによって、OAuthサーバーにアクセスするためのservice accountのtoken情報を、Libertyに渡します。
参考
APIサーバーのSSL証明書をOpenLibertyが動作するJVMのキーストアにロードする
Libertyから、OpenShift上のOauthサーバーにアクセスするにあたり、
SSL証明書が、Libertyが使用するキーストアにロードされていないと、エラーが発生します。
そのエラーを防ぐために、以下の変数をserver.envに指定することで、
Liberty起動時に、Pod上のコンテナにマウントされた証明書を、キーストアにロードします。
cert_defaultKeyStore=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
参考
Libertyのserver.xmlとAnsibleベースのオペレータでのPodの設定
OpenShiftのOAuthサーバーを認証プロバイダーに設定するために必要な変数と取得についての要約です。
変数 | 補足 |
---|---|
serviceAccount | オペレータのステップで作成し、Libertyに引き渡す |
token | VARIABLE_SOURCE_DIRS から、Pod上のファイル内容を、Libertyに引き渡す |
authEndpointUrl | オペレータのステップでOpenShitに対するRestAPIで動的取得 |
tokenEndpointUrl | オペレータのステップでOpenShitに対するRestAPIで動的取得 |
userApiUrl | 固定値 |
VARIABLE_SOURCE_DIRS | serviceaccountのtoken情報を取得するために必要。固定値。コンテナ上のserviceaccount情報 |
cert_defaultKeyStore | OpenShiftのAPIサーバーのSSL証明書をVMにロードするための情報。固定値。コンテナ上のserviceaccount情報 |
Libertyのserver.xmlとAnsibleベースのOperatorの設定の抜粋です。
<!-- These variables are updated by OpenShift/Kubernetes Environment Variable when creating a pod /-->
<variable name="serviceAccount" defaultValue="system:serviceaccount:default:xxxxxxx" />
<variable name="token" defaultValue="Token for Service Account specified in serviceAccount variable"/>
<variable name="authEndpointUrl" defaultValue="https://oauth-openshift.apps.xxx.com/oauth/authorize" />
<variable name="tokenEndpointUrl" defaultValue="https://oauth-openshift.apps.xxx.com/oauth/token" />
<variable name="userApiUrl" defaultValue="https://openshift.default.svc/apis/authentication.k8s.io/v1/tokenreviews" />
<oauth2Login id="openshiftLogin"
scope="user:info"
clientId="${serviceAccount}"
clientSecret="${token}"
authorizationEndpoint="${authEndpointUrl}"
tokenEndpoint="${tokenEndpointUrl}"
userNameAttribute="username"
groupNameAttribute="groups"
userApiToken="${token}"
userApiType="kube"
userApi="${userApiUrl}">
</oauth2Login>
- name: Create pod for collecting the tar file
community.kubernetes.k8s:
state: present
definition:
kind: Pod
apiVersion: v1
metadata:
name: downloadapp
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app: downloadapp
spec:
restartPolicy: Always
containers:
- resources: {}
name: download-app
ports:
- containerPort: 9080
protocol: TCP
- containerPort: 9443
protocol: TCP
imagePullPolicy: Always
volumeMounts:
- name: storage
mountPath: /app/upload
image: quay.io/xxxx/download-app:latest
env:
- name: downloadBaseDir
value: "/app/upload"
- name: authEndpointUrl
value: "{{oauth_info.json.authorization_endpoint}}"
- name: tokenEndpointUrl
value: "{{oauth_info.json.token_endpoint}}"
- name: serviceAccount
value: "system:serviceaccount:{{ansible_operator_meta.namespace}}:downloadapp-sa"
- name: VARIABLE_SOURCE_DIRS
value: "/run/secrets/kubernetes.io/serviceaccount"
serviceAccount: downloadapp-sa
volumes:
- name: storage
persistentVolumeClaim:
claimName: pvc-supportfiles
まとめ
上記の設定によって、
OpenShiftのOAuthサーバーを認証プロバイダーとする、OpenShiftのコンテナで動作するLiberty上のJavaアプリケーションを、
Operatorでデプロイすることができます。
忘備録に近い記述で恐縮ですが、誰かの役に立てば幸いです。