CAPで作ったサービスをKyma runtimeにデプロイ(1) 事前準備編

## はじめに
この記事は chillSAP [夏の自由研究2022](https://note.com/chillsap/n/n62740563aee0)、8/20の記事として執筆しています。

最近、以下のチュートリアルを実施してCAPで作ったサービスをKyma runtimeにデプロイしてみました。色々とつまずきはあったものの、最後まで実施することができました。

https://developers.sap.com/mission.btp-deploy-cap-kyma.html

チュートリアルをやっている間はステップを追うことに専念していたので、この記事では以下を確認したいと思います。

- CAPで作ったアプリをKymaにデプロイするにはどのような仕組みが使われているか
- 一からアプリを作成してKymaにデプロイするには何が必要か

上記のチュートリアルでは、いくつかの操作を事前に用意されたスクリプトを使用して自動的に行っていました（おそらく時間短縮とエラー回避のため）。それゆえに、裏で何が行われているかわかりにくかったので、この記事ではそれらの操作をマニュアルで実施してみます。

### シリーズの目次
1. 事前準備（この記事）
1. [基本的なCAPアプリを作成してKyma  runtimeにデプロイ](https://qiita.com/tami/items/90e353b0a62d0771b502)
1. [認証を追加](https://qiita.com/tami/items/bac04b92414af5dc46a2)
1. [UIを追加してLaunchpadにデプロイ](https://qiita.com/tami/items/143d44f15043d5e40a5d)

## CAPで作ったサービスをKyma runtimeにデプロイする仕組み
### Kyma runtimeへのデプロイの基本的な流れ
Kyma runtimeへデプロイするための基本的な流れは以下のとおりです。

1. 作成したプロジェクトと実行環境をセットにしたDockerファイルを作成
1. Dockerイメージを作成してDocker Hubなどのレジストリにプッシュ
1. Dockerイメージを参照するデプロイ用のyamlファイルを作成
1. yamlファイルを使用してKyma runtimeにデプロイ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/d08b6e82-ca67-c6be-6b76-2dd51c97887d.png)

以下はKyma runtimeの[Community Code Challenge](https://qiita.com/tami/items/8ffad45ef1ee0f54e8c4)で作成した簡単なサービスのデプロイ用yamlファイルです（CAPではありません）。中を見ると、`---`で区切られた3つのリソース（Deployment, Service, APIRule）から構成されていることがわかります。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-service2
  labels:
    app: my-service2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-service2
  template:
    metadata:
      labels:
        app: my-service2
    spec:
      containers:
      - name: my-service2
        image: docker.io/miyasuta/my-service:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        resources:
            limits:
              ephemeral-storage: 256M
              memory: 256M
              cpu: 100m
            requests:
              cpu: 100m
              ephemeral-storage: 256M
              memory: 256M
      imagePullSecrets:
      - name: regcred
status: {}
      
---
apiVersion: v1
kind: Service
metadata:
  name: my-service2
spec:
  selector:
    app: my-service2
  ports:
  - port: 8081
    targetPort: 8080
    protocol: TCP

---

apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
  name: my-service2
spec:
  gateway: kyma-gateway.kyma-system.svc.cluster.local
  service:
    name: my-service2
    port: 8081
    host: my-service2
  rules:
    - path: /.*
      methods: ["GET"]
      accessStrategies:
        - handler: noop
          config: {}
```
このファイルを使ってデプロイすると、DeploymentをもとにPodができ、またPodを参照するService、Serviceを参照するAPIRuleができます。

- Pod: アプリケーションを動かすための最小単位。一つまたは複数のDockerコンテナで構成される
- Service: Podで稼働するサービスを公開するためのもの。（Podは複数作成できるが、一つのサービスとして透過的にアクセスできるようにする）
- APIRule: Serviceに対してアクセスポリシーなどを設定し、外部から利用できるようにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4f23d1bd-08fe-3ddc-85d7-3420457da095.png)

### CAPの場合
CAPの場合、データベース（HANA Cloud）へのアクセスや認証のためのXSUAAサービスインスタンスなど、追加のリソースが必要になります。それらをデプロイするためのyamlファイルを毎回手で作成するのは大変なので、[Helm](https://helm.sh/)というツールを使います。

Helmを使用するために、yamlファイルを作成するためのテンプレートと、テンプレートに値を設定するためのvalues.yamlというファイル用意する必要があります。CAPでは`cds add helm`というコマンドで自動的にテンプレートとvalues.yamlファイルを生成できます。開発者が設定するのはvalues.yamlファイルのみです。設定ができたらHelmのコマンドでKubernetes（Kyma runtime）にデプロイします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ccae521e-c767-b525-4751-86b545193b77.png)

## 一からアプリを作成してKymaにデプロイしてみる（事前準備編）
**開発環境**
- VS Code
- BTPトライアルアカウント（Kyma runtimeを有効化済）

**事前準備のステップ**
1. 環境設定
1. HDIコンテナおよびシークレットの作成

### 1. 環境設定
以下のチュートリアルに沿って必要なツールのインストールやKyma runtimeの設定を行います。

https://developers.sap.com/tutorials/btp-app-kyma-prepare-dev-environment.html

概要は以下です。

**インストールするもの**
- @sap/cds-dkと@sap/cds-dkの最新バージョン（いずれも6.0.1以上）
- kubectl
- kubelogin
- helm
- pack
- Docker Desktop
- Rancher Desktop（DockerかRancherを選択する）

**ローカルでの設定**
- Kyma runtimeから接続用のコンフィグファイルをダウンロード


**Kyma runtimeでの設定**
- サービスをデプロイするためのnamespaceを作成
- Dockerレジストリにアクセスするためのシークレットを作成

※今回namespaceは`capkyma`という名前で作成しました。

### 2. HDIコンテナおよびシークレットの作成
xsuaaやdestinationのサービスインスタンスはKyma runtimeからも作ることができますが、HANA CloudのHDIコンテナは作ることができません。そこで、Cloud FoundryでHDIコンテナのサービスインスタンスを作成しておき、Kyma runtimeからアクセスできるようにシークレットをKyma側に作成します。
[チュートリアル](https://developers.sap.com/tutorials/btp-app-kyma-hana-cloud-setup.html)ではスクリプトを使って実施していましたが、ここでは何をしているのかわかるようにマニュアルで実施してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/795b0c1b-65a8-1a6d-76e6-3d25f791958e.png)

#### 2.1. HDIコンテナの作成
CLIでCloud Foundryにログインし、以下のコマンドでHDIコンテナを作成します。（前提として、HANA Cloudのサービスインスタンスが起動していること）

```
cf create-service hana hdi-shared <サービス名>

例
cf create-service hana hdi-shared capkyma-db
```
#### 2.2. サービスキーの作成

```
cf create-service-key <サービス名> <サービスキー名>

例
cf create-service-key capkyma-db capkyma-db-key
```

#### 2.3. シークレットの作成
##### 2.3.1. サービスキーの表示
以下のコマンドで作成したサービスキーを表示します。

```
cf service-key <サービス名> <サービスキー名>

例
cf service-key capkyma-db capkyma-db-key
```
##### 2.3.2. yamlファイルの作成
サービスキーの内容を参照して、以下のようなyamlファイルを作成します。ファイル名は何でもよいです。`type`と`label`は固定値(hana)で、その他はサービスキーから設定します。

```yaml:secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: capkyma-db
type: Opaque
stringData:
  type: hana
  label: hana
  url: jdbc:sap://d6b507e7-ef9c-46ad-9269-22a2b982188c.hana.trial-eu10.hanacloud.ondemand.com:443?encrypt=true&validateCertificate=true&currentschema=32A9C5EA390F49C4A19410B001541306
  certificate: |
    -----BEGIN CERTIFICATE-----
    MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
    ...
    YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
    CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
    -----END CERTIFICATE-----
  database_id: d6b507e7-ef9c-46ad-9269-22a2b982188c
  driver: com.sap.db.jdbc.Driver
  hdi_password: xxxxxx
  host: d6b507e7-ef9c-46ad-9269-22a2b982188c.hana.trial-eu10.hanacloud.ondemand.com
  hdi_user: 32A9C5EA390F49C4A19410B001541306_AMSMNC2G4WVWQUPJ9C1NA82OY_DT
  password: xxxxxx
  port: "443"
  schema: 32A9C5EA390F49C4A19410B001541306
  user: 32A9C5EA390F49C4A19410B001541306_AMSMNC2G4WVWQUPJ9C1NA82OY_RT  
```

yamlファイルを作成する際の注意点が2つあります。
- portの443はクォーテーションで囲む
- certificateは改行して設定する
サービスキーには以下のように1行でcertificateが設定されていますが、"\n"のところで改行して設定する必要があります。

```
"-----BEGIN CERTIFICATE-----\nMIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nxxxx-----END CERTIFICATE-----"
```
Terapadで改行を入れることができます。
①"\n"を"あ"などcertificateにない文字に置換する。"\n=改行"のチェックボックスは外しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/ea04ab2d-339e-9350-b747-dfd9b78438bd.png)
②"あ"を"\n"に置換する。"\n=改行"のチェックボックスをつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c2af6204-3ca0-c91f-6836-f4708c566cfd.png)
結果、以下のような形になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/edd7bf14-9065-56b2-8609-6e2cca6c84f5.png)

##### 2.3.3. Kyma runtimeにシークレットを作成
以下のコマンドでシークレットを作成します。

```
kubectl apply -f <ファイル名>
```

以下のメッセージが出れば成功です。

```
secret/capkyma-db created
```

Kyma runtimeに作成したnamespaceにシークレットができていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/040ec243-2fd1-037f-1682-4ac3f22effd5.png)

事前準備は以上です。次回は基本的なCAPアプリを作成してKyma runtimeにデプロイしてみます。