はじめに
この記事はCAPで作ったサービスをKyma runtimeにデプロイシリーズの3回目です。以下のチュートリアルを参考にしつつ、
- CAPで作ったアプリをKymaにデプロイするにはどのような仕組みが使われているか
- 一からアプリを作成してKymaにデプロイするには何が必要か
について確認することを目的としています。
3回目の今回は、前回作成した基本的なCAPサービスに認証を追加します。
CAPサービスに認証を追加
ステップ
- アクセスコントロールを追加
- XSUAAを追加
- Helmの設定
- ビルド、Dockerイメージのプッシュ
- Kyma runtimeにデプロイ
- デプロイ結果の確認
1. アクセスコントロールを追加
srv/cat-service.cdsを以下のように変更します。これにより、Booksエンティティを照会するのにViewerのロールが必要になります。
using my.bookshop as my from '../db/data-model';
service CatalogService {
@readonly
entity Books @(restrict : [{
grant : ['READ'],
to : ['Viewer']
}]) as projection on my.Books;
}
試しにcds watch
でサービスをローカル実行し、Booksを開こうとすると以下の画面になります。
ローカルで実行するため、.cdsrc.jsonに以下のエントリを追加します。
{
"[development]": {
"auth": {
"passport": {
"strategy": "mock",
"users": {
"viewer01": {
"password": "initial",
"ID": "viewer01",
"roles": [
"Viewer"
]
}
}
}
}
}
}
シークレットウインドウでURLを開くとログインを求められるので、上で設定したユーザ、パスワードを入力するとデータを照会できます。
2. XSUAAを追加
以下のコマンドを実行します。
cds add xsuaa --for production
package.jsonのcds
配下にauth
セクションが追加されます。
xs-security.jsonファイルが追加され、サービス定義をもとにスコープとロールテンプレートの定義が設定されます。
{
"scopes": [
{
"name": "$XSAPPNAME.Viewer",
"description": "Viewer"
}
],
"attributes": [],
"role-templates": [
{
"name": "Viewer",
"description": "generated",
"scope-references": [
"$XSAPPNAME.Viewer"
],
"attribute-references": []
}
]
}
3. Helmの設定
chart/values.yamlを見てみると、以下の部分が追加されています。
また、chartフォルダにxs-security.jsonがコピーされています。
これらをもとにどのようなリソースが作られるのかをhelm template capkyma ./chart
で見てみると、前回の基本的なCAPサービスから増えたものは以下です。
リソース | 何をするものか |
---|---|
ServiceBinding (xsuaa) | CAPのサービスにxsuaaのシークレットをバインド |
ServiceInstance (xsuaa) | xsuaaのサービスインスタンスを登録。ロールを生成 |
生成されたyamlの関連部分は以下のようになっています。ServiceInstanceの定義の中にxs-security.jsonで設定したスコープ、ロールの定義が持ち込まれているのがわかります。
---
# Source: capkyma/charts/srv/templates/service-binding.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
name: capkyma-srv-auth
labels:
helm.sh/revision: "1"
helm.sh/chart: srv-0.1.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: srv
app.kubernetes.io/instance: capkyma
spec:
serviceInstanceName: capkyma-xsuaa
---
# Source: capkyma/templates/xsuaa.yaml
apiVersion: services.cloud.sap.com/v1alpha1
kind: ServiceInstance
metadata:
name: capkyma-xsuaa
namespace: capkyma
labels:
helm.sh/chart: capkyma-1.0.0
app.kubernetes.io/name: xsuaa
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/instance: capkyma
app.kubernetes.io/version: 1.0.0
spec:
serviceOfferingName: xsuaa
servicePlanName: application
externalName: capkyma-capkyma-xsuaa
parameters:
attributes: []
role-templates:
- attribute-references: []
description: generated
name: Viewer
scope-references:
- $XSAPPNAME.Viewer
scopes:
- description: Viewer
name: $XSAPPNAME.Viewer
xsappname: capkyma
4. ビルド、Dockerイメージのプッシュ
前回と同様の手順でビルド、Dockerイメージのプッシュを行います。
5. Kyma runtimeにデプロイ
前回と同様、以下のコマンドでKyma runtimeにデプロイします。
helm upgrade <リリース名> <chartフォルダのパス> --install
# 例
helm upgrade capkyma ./chart --install
以下のメッセージが表示されればデプロイは成功です。
The release "capkyma" is installed in namespace "capkyma".
Your services are available at:
- https://capkyma-srv-capkyma.a2985eb.kyma.shoot.live.k8s-hana.ondemand.com
Booksエンティティにアクセスしてみると、以下のエラーになります。
6. デプロイ結果の確認
Kyma runtimeにServiceInstanceを作成すると、Cloud Foundry側にもサービスインスタンスが登録されます。ただし、Cloud Fondryで作ったインスタンスと違い、ここから操作したりサービスキーを見ることはできません。
ロールテンプレートで定義したロールもできています。
Kyma runtime側から見ると以下のようにXSUAAのサービスインスタンスが登録されています。また、サービスバインディングをドリルダウンしていくとシークレットを見ることもできます。
Kyma runtimeにStandalone Approuterを立てる
認証されていないユーザはBooksエンティティにアクセスできなくなりました。次回の記事でUI5アプリを作成し、BTPのLaunchpad経由でCAPサービスにアクセスします。このときは、LaunchpadのManaged Approuterが認証を行ってくれます。
今回はManaged Approuterではなく、Standalone Approuterを使用して認証を行ってみます。
Standalone ApprouterのためのDocker Imageが最近(2022年8月)公開されたため、これを使用してみます。
SAPブログ
今回は以下の手順を参考に、Kyma runtimeにStandalone Approuterを立ててApprouter経由でCAPサービスにアクセスしてみます。
前提
前のステップで作成したXSUAAサービスインスタンスは、xs-security.jsonにtenant-mode
の指定がないためデフォルトで"shared"になるようです。このままだとApprouterをデプロイしたときに"TENANT_HOST_PATTERNの指定がない"というエラーになってしまうため、"dedicated"と明示する必要があります。また、認証後にリダイレクトする先としてoauth2-configuration.redirect-uris
にApprouterのURLを追加します。
【備忘】Launchpadから実行する際は、oauth2-configuration.redirect-uris
にLaunchpadのURLを追加する必要があります。
{
"tenant-mode": "dedicated",
"scopes": [
{
"name": "$XSAPPNAME.Viewer",
"description": "Viewer"
}
],
"attributes": [],
"role-templates": [
{
"name": "Viewer",
"description": "generated",
"scope-references": [
"$XSAPPNAME.Viewer"
],
"attribute-references": []
}
],
"oauth2-configuration": {
"redirect-uris": [
"https://my-approuter.a2985eb.kyma.shoot.live.k8s-hana.ondemand.com/**",
"http://localhost:5000/**"
]
}
}
tenant-modeを変える場合、XSUAAサービスインスタンスを一旦削除して再登録する必要があります。以下のコマンドでデプロイしたものを全て削除することができます。
helm uninstall <リリース名>
# 例
helm uninstall capkyma
そのうえで、再度デプロイします。
ステップ
- DestinationとRouteの設定を作成する
- Approuterをデプロイする
- APIRuleによりApprouterを公開する
- ApprouterからCAPサービスにアクセスする
Approuter関連の設定ファイルを格納するため、プロジェクトのルートにapprouter
というフォルダを作成しました。
1. DestinationとRouteの設定を作成する
config.yamlを以下の内容で作成します。{CLUSTER_DOMAIN}の部分には、自分のkyma runtimeのドメインを指定します。(例:a2985eb.kyma.shoot.live.k8s-hana.ondemand.com
)
apiVersion: v1
kind: ConfigMap
metadata:
name: destinations
data:
destinations: >-
[
{
"name": "capkyma-srv",
"url": "https://capkyma-srv-capkyma.{CLUSTER_DOMAIN}",
"forwardAuthToken": true
}
]
---
apiVersion: v1
data:
xs-app.json: |-
{
"authenticationMethod": "route",
"sessionTimeout": 10,
"login" : {
"callbackEndpoint": "/catalog"
},
"routes": [
{
"source": "^/catalog/(.*)$",
"target": "/catalog/$1",
"destination": "capkyma-srv",
"authenticationType": "xsuaa",
"csrfProtection": false
},
{
"source": "^/(.*)$",
"destination": "capkyma-srv",
"target": "/",
"authenticationType": "xsuaa"
}
]
}
kind: ConfigMap
metadata:
name: xs-app
以下のコマンドでデプロイします。(以降も同様です)
kubectl apply -f approuter/config.yaml
2. Approuterをデプロイする
deployment.yamlを以下の内容で作成し、デプロイします。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-approuter
spec:
host: my-approuter
trafficPolicy:
loadBalancer:
consistentHash:
httpCookie:
name: JSESSIONID
path: /
ttl: 0s
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: my-approuter
name: my-approuter
spec:
replicas: 1
selector:
matchLabels:
app: my-approuter
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: my-approuter
spec:
volumes:
- name: xs-app
configMap:
name: xs-app
- name: capkyma-srv-auth
secret:
secretName: capkyma-srv-auth
containers:
- image: sapse/approuter:11.3.2
name: my-approuter
imagePullPolicy: Always
ports:
- containerPort: 5000
resources: {}
volumeMounts:
- name: xs-app
mountPath: /app/xs-app.json
subPath: xs-app.json
readOnly: true
- name: capkyma-srv-auth
mountPath: /etc/secrets/sapcp/xsuaa/capkyma-xsuaa
readOnly: true
env:
- name: destinations
valueFrom:
configMapKeyRef:
name: destinations
key: destinations
status: {}
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: my-approuter
name: my-approuter
spec:
ports:
- port: 5000
protocol: TCP
targetPort: 5000
selector:
app: my-approuter
status:
loadBalancer: {}
3. APIRuleによりApprouterを公開する
api-rule.yamlを以下の内容で作成し、デプロイします。
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
labels:
app: my-approuter
name: my-approuter
spec:
gateway: kyma-gateway.kyma-system.svc.cluster.local
service:
host: my-approuter
name: my-approuter
port: 5000
rules:
- path: /.*
methods: ["GET", "POST", "PUT", "DELETE"]
accessStrategies:
- handler: noop
mutators:
- handler: header
config:
headers:
x-forwarded-host: "my-approuter.{CLUSTER_DOMAIN}"
4. ApprouterからCAPサービスにアクセスする
Kyma runtimeのダッシュボードを開き、APIRulesからmy-approuterのURLにアクセスします。
認証の画面が開きます。
認証後、以下の画面が表示されれば成功です。
$metadataは表示できましたが、BooksエンティティにアクセスしようとするとForbiddenとなります。これはまだロールをユーザに割り当てていないためです。
BTPロールコックピットからロールコレクションを作成し、Vierwerのロールを割り当てます。作成したロールコレクションを自分のユーザに割り当てます。
再ログインするとBooksエンティティが表示できます。