2. チュートリアル

2.1. 本チュートリアルについて

本チュートリアルでは、お客さまにCNAPサービスを利用したコンテナアプリケーションのデプロイ方法をご理解いただくことを目的としています。

CNAPサービスをはじめてご利用いただく際、CNAPの使い方を習得いただくため、まず最初にチュートリアルを実施いただくことを推奨しています。

本チュートリアルは以下の内容を含んでいます。

  • Deploy Keyをお客さまのGithubリポジトリに登録する

  • アプリケーションのマニフェストをGithubリポジトリに保存し、アプリケーションとクラウドリソースをデプロイする

  • アプリケーションのデプロイ後、DNSレコードが自動登録されていることを確認する

  • TLSの設定方法について、マネージドTLS証明書と、セルフマネージド証明書を利用する2つの方式を実施する

  • アプリケーションのマニフェストを登録するGitリポジトリを追加登録する

  • Kubernetesクラスタに任意のNamespaceを追加作成する

  • Grafanaダッシュボードを利用する

  • 本チュートリアルで作成したリソースを削除する

本チュートリアルでは、インターネットからアクセスできるWebサービスを作成します。このサービスはWebアプリケーションとマネージドRDBから構成されます。

チュートリアルのアプリケーションアーキテクチャ

2.2. 対象読者と前提知識

本チュートリアルの想定する対象読者は以下のとおりです。

  • これからCNAPを使う方

  • CNAPサービス上で稼働するアプリケーションの設計・開発・運用に関わる方

本チュートリアルを進めるにあたり、必要となる前提知識は以下のとおりです。

  • Gitの基本的な仕組みを理解し、Gitコマンドを利用した経験がある

  • Kubernetesの基本概念を理解し、kubectlコマンドを利用した経験がある

  • クラウドコンソールを操作し、リソースを作成・確認することができる

  • ネットワークに関する基本的な用語(TLS、DNSなど)がわかる

CNAPでは、本来記述すべきKubernetesやマネージドクラウドサービスのコードを大幅に縮小した、ローコードによりマニフェストを記述可能です。

ただしローコードとはいえ、コードでインフラを記述しデプロイする作業は必要となるため、YAMLの基本的な書き方についての知識があると内容がより理解し易いです。

2.3. あらかじめご用意いただくもの

このチュートリアルを進めるにあたり、以下の情報、およびリソースがお手元にあることをご確認ください。

  • CNAPでご提供したKubernetesクラスタ

  • お客さまリポジトリ用Deploy Key

お客さまリポジトリ用Deploy Keyは、あらかじめ弊社から提供している英数字と記号から構成される文字列です。サンプルは以下の通りです。

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAMIX+oD5Imr1huwc7qerYcZsTZXNF3Soa4wp05m8sSF msp12345678 Deploykey

CodeCommit などをご使用の場合には、ssh-rsa で始まる長い文字列になります。

また、以下のCLIツールが利用可能であることをご確認ください。詳細については、各CLIツールの開発元のドキュメントをご確認ください。

  • git

  • kubectl

参考:

2.4. 事前準備:Deploy Keyの登録

CNAPでは、お客さまのアプリケーションの一貫性と信頼性を保つため、GitOpsを採用しています。 お客さまにアプリケーションのマニフェストを作成いただき、Gitリポジトリにpushしていただくと、CNAPのシステムが自動で変更を検知し、各種リソースとアプリケーションをデプロイします。

このため、まず、GitリポジトリとCNAPを連携させるため、お客さまのGitリポジトリにDeploy Keyの登録を行う必要があります。

以下では、Github、AWS CodeCommitでの設定方法について説明します。 それ以外のGitリポジトリをご利用の場合には、サポートにご相談ください。

2.4.1. Github

GithubリポジトリにDeploy Keyを登録します。

  1. リポジトリ上部メニューの settings をクリックしてください

../_images/github-settings.png
  1. 左メニューの Deploy keys をクリックし、右上の Add deploy key をクリックしてください

../_images/github-add-deploykey.png
  1. 任意の タイトル を設定し、 Key 欄にDeploy Keyを入力してください。弊社から提供した文字列の一部ではなく、先頭から末尾まで全て入力してください。 コンテナイメージの自動更新 の機能を利用する場合は Allow write access チェックボックスのチェックが必要です。

../_images/github-input-deploykey.png
  1. 緑色の Add key ボタンをクリックしてください

../_images/github-push-addkey.png

以上でDeploy Keyがお客さまのリポジトリに登録されました。

2.4.2. AWS CodeCommit

CNAPからAWS CodeCommitリポジトリに接続するためにDeploy Keyを登録します。

  1. CodeCommit アクセスに使用するIAMユーザーを作成します。

IAMサービスの「ユーザー」メニューで、IAMユーザーを作成します。

  1. 作成したIAM ユーザーに、 AWSCodeCommitPowerUser ポリシーをアタッチします。

作成したIAMユーザーを開き、 「アクセス権限タブ」で「アクセス権限の追加」ボタンを押します。 既存のポリシーから AWSCodeCommitPowerUser を選択します。

../_images/codecommit-policy.png
  1. 作成したIAMユーザーにSSHパブリックキーを設定します。

作成したIAMユーザーを開き、「認証情報」タブで「AWS CodeCommit の SSH キー」の項目の「SSHパブリックキーをアップロード」ボタンを押します。 ウィンドウが開いたらDeploy Keyを貼り付けて「SSHパブリックキーをアップロード」ボタンを押します。

  1. SSH キー IDを取得します。

「認証情報」タブで「AWS CodeCommit の SSH キー」の項目の「SSH キー ID」を取得します。 取得した「SSH キー ID」を、法人テクニカルサポートWebにおいて、CNAP申し込み時のケースでご連絡ください。

../_images/codecommit-ssh-key-id.png

2.5. クラウドコンソールへのアクセス

クラウドコンソールへのアクセスに特別な操作が必要なものについて説明します。

2.5.1. AWS

CNAP申し込み時に作成したIAMユーザで AWS Management Console にサインインしてクラウドリソースを参照・操作するためには、 cnap_customer ロールにロール切り替えを行う必要があります。

ロール切り替えは下記の手順で行います。

IAMユーザで AWS Management Console にサインインし、右上のナビゲーションバーのユーザー名を選択します。 (通常は username@account_ID_number_or_alias のように表示されます。) [アカウント ID] が表示されているので、コピーしておきます。 [ロールの切り替え] を選択します。このオプションを選択するのが初めての場合、詳細な情報がページに表示されます。情報を読んだ後、[ロールの切り替え] を選択します。 [ロールの切り替え] ページで、[アカウント] にコピーしておいたアカウント IDを入力し、[ロール]に cnap_customer を入力しロール切り替えを行います。

2.6. アプリケーションの構築

これから、サンプルのアプリケーションを構築していきます。

本チュートリアルでは、以下の2つのアプリケーションをサンプルとして構築していきます。

  • kanboard というwebアプリケーションと、kanboardのデータを保存するマネージドRDBサービス

  • 自身で作成したカスタムImageを利用したwebアプリケーション

2.6.1. Kanboardを利用したサンプルアプリケーションの構築

kanboard というwebアプリケーションと、kanboardのデータを保存するマネージドRDBサービスを構築します。

CNAPでは、ユーザーが kubernetes およびクラウドサービスにインフラ環境を構築するためのパッケージを提供します。 サンプルアプリケーションでは、webアプリケーション部分を basic-deployment パッケージ、マネージRDBサービスを RDB パッケージでデプロイします。

CNAPで各種パッケージをデプロイするためには、 Application カスタムリソースのマニフェストでデプロイしたいパッケージやそのバージョン、設定を定義します。

チュートリアルで作成するアプリケーションとCNAPパッケージ

アプリケーションの構築は、GitOpsに基づいて実施します。

GitOpsではアプリケーションの信頼性と一貫性を保つため、Gitリポジトリを信頼できる唯一の情報源として扱います。 アプリケーションとインフラの望ましい状態を宣言的に記述したマニフェストを保存し、記述された通りにアプリケーションとインフラを維持します。 CNAPでは、Gitリポジトリにお客さまのアプリケーションのマニフェストを登録いただくことで、CNAPのシステムが自動的にマニフェストに基づきクラウドリソースとアプリケーションをデプロイします。

RDBサービスの構築

  1. マネージドRDBサービスのマニフェストを作成します。

まずは RDB パッケージを使用してマネージドRDBサービスを構成するマニフェストを作成します。マネージドRDBサービスをデプロイするクラウドベンダーに合わせてマニフェストをコピーし、お客さまのローカルgitリポジトリに保存してください。

YAML形式であるマニフェストはインデントに意味を持つため、各行正しい位置になるようご注意ください。

保存した後、各マニフェストで使用するパッケージのバージョンを編集します。spec.chart.version: <latest> と記載されている箇所を編集し、最新バージョンを入力してください。各パッケージの最新バージョンは、HELM ユーザー用パッケージ より、使用されるパッケージのリファレンスのChange Logを確認してください。

パッチを自動的に適用させる場合には、バージョンの末尾の番号(パッチバージョン)は x と設定してください。 パッケージの最新バージョンが 1.2.12 の場合、パッチバージョンを自動適用させるためには「1.2.x」と設定します。 パッケージのパッチバージョンアップでは、お客さまの操作に影響が無い範囲でのバグ修正や小規模な改善が行われるため、自動適用することを推奨します。

入力例: パッケージ「RDB」のバージョン 1.2.x を指定する場合

# ~~~省略~~~
spec:
  chart:
    name: rdb
    version: 1.2.x
# ~~~省略~~~

Azure

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata: 
  name: postgres
  namespace: staging
spec:
  chart:
    name: rdb
    version: <latest>
  settings:
    databaseType: postgres
    instance:
      create: true
      name: postgres-cnap-<customer id>-instance
      location: japaneast
      machineType: Standard_D2s_v3
      engineVersion: "16"
      tier: GeneralPurpose
    network:
      azure:
        firewallRules:
          - name: allow-azure-services
            # すべてのネットワークアクセスを許可する設定のため
            # チュートリアル後に削除、もしくは設定の変更をすることをおすすめします
            startIpAddress: 0.0.0.0
            endIpAddress: 255.255.255.255
    databases:
      - name: staging-db
    users:
      - name: maintainer
        secret:
          key: rdb-secret

Google Cloud

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: mysql
  namespace: staging
spec:
  chart:
    name: rdb
    version: <latest>
  settings:
    databaseType: mysql
    instance:
      create: true
      name: mysql
      version: "8.0"
      location: asia-northeast1
      machineType: db-g1-small
      availability:
        highAvailability: false
      backup:
        gcp:
          enabled: true
    databases:
      - name: staging-db
        charset: UTF8
    users:
      - name: kanboard
        secret:
          key: kanboard

AWS

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: mysql
  namespace: staging
spec:
  chart:
    name: rdb
    version: <latest>
  settings:
    databaseType: mysql
    instance:
      name: mysql
      machineType: db.t3.micro
      location: ap-northeast-1
      engineVersion: "8.4"
      storage:
        type: gp2
        size: 20
      backup:
        retentionPeriod: 7
        aws:
          startTime: 16:00
          endTime: 17:00
      availability:
        highAvailability: true
    network:
      aws:
        subnets:
          - <customer subnet1>
          - <customer subnet2>
        securityGroups:
          - <customer securityGroup1>
    databases:
      - name: staging
    users:
      - name: admin
        secret:
          key: rdb-admin
          property: password

(参考:HELM ユーザー用パッケージ RDB)

このマニフェストでは、お客さまのアプリケーションで使用するRDBサーバの構成について記述しています。CNAPはこのマニフェストに従い、お客さまの契約されたクラウドサービスのマネージドRDBサービスを利用して、RDBサーバを構築します。

Azure環境にマニフェストをデプロイする場合は、 .spec.settings.instance.name<customer id> を、お客さまがCNAP開通時に弊社のヒアリングシートに記載したMSP契約番号に置き換えてください。この項目はDBのホスト名に使われるので全Azureアカウントで一意である必要があります。 またsqlserverでは、 .spec.settings.instance.owner.azure.resourceGroup.name を、お客さまのデプロイ先となるリソースグループ名に置き換えてください。

AWS環境にマニフェストをデプロイする場合は、 .spec.settings.network.aws.subnets<customer subnet1> および <customer subnet2> を、お客さまがRDBインスタンスをデプロイするサブネットのIDに置き換えてください。 また .spec.settings.network.aws.securityGroups<customer securityGroup1> を、お客さまがデプロイするRDBインスタンスに設定するセキュリティグループのIDに置き換えてください。

  1. お客さまがご利用のクラウドサービスが提供するシークレットストアサービスに、DBの認証情報を登録します。

Azureの場合は初期開通時に作成されている cnap-<MSP契約番号> のキーコンテナに、 .spec.settings.users[0].secret.key に指定した値をキー名として、任意のDBアクセス用パスワードを保存してください。

Google Cloudの場合はSecretManagerに kanboard という名前のシークレットを作成し、任意のDBアクセス用パスワードを保存してください。

AWSの場合はSecretManagerのシークレットのタイプからその他のシークレットのタイプを選択してDBの認証情報を登録します。 .spec.settings.users[0].secret.key に指定した値がSecrets Managerのシークレット名、 .spec.settings.users[0].secret.property に指定した値がシークレット内のキー名に対応します。 前述のマニフェストの場合は、 rdb-admin シークレットの password というキーに対応する値として任意のDBアクセス用パスワードを保存してください。

注釈

一般的に、データベースサーバに接続する際はパスワードなどの機密情報を使用する必要があります。CNAPでは、お客さまの機密情報を各クラウドサービスが提供するシークレットストアサービスに保管します。

シークレットストアサービスからパスワードなどの機密情報を取得し、Podに渡す流れは以下の通りです。

ESOのアーキテクチャ

Secret Storeリソースによりシークレットストアサービスへ認証が行われ、取得した資格情報をExternal Secretが利用してパスワードを取得・Secretリソースに格納します。

SecretリソースをPodにマウントすることでPodからRDBにアクセス可能になります。

なお、External SecretリソースはRDBパッケージもしくはbasic-deploymentパッケージから作成され、Secret StoreはVaultパッケージから作成されます。

CNAPではデフォルトのSecret Store(name: default)が作成されており、本チュートリアルではデフォルトのSecret Storeを利用するためVaultパッケージは利用せずにパスワードを取得します。

シークレットストアサービスのアクセス制限をしたいといった理由でデフォルトのSecret Storeを利用したくない場合は、Vaultパッケージを使って別途Secret Storeを作成してください。

  1. アプリケーションのマニフェストをコミットし、リモートのGitリポジトリにpushしてください。

git add . && git commit -m "add rdb manifest"
git push
  1. マニフェストからリソースが正常に作成されたことを確認します。

Application カスタムリソースが適用されたことを確認します。以下のコマンドを入力し、 mysql-application もしくは postgres-application という名前のリソースが存在し、READYのステータスがTrueになっていることを確認してください。

kubectl get helmrelease -n staging

READYのステータスがFalseとなっている場合デプロイに失敗しているため、インデントが間違ってないか、chartのversionが正しいかなど、YAMLの記載内容を確認してください。

デプロイに成功したらマネージドRDBが作成されたことを確認します。ご利用のクラウドベンダーのポータル画面にログインし、マネージドRDBのインスタンスが存在することを確認してください。

Azure, AWSの場合は、作成したマネージドRDBのエンドポイントを控えてください。

Azureの場合、RDBはNamespaceと同名のリソースグループ(サンプルでは staging)に作成されます。

別のリソースグループにクラウドリソースを構築したい場合には、RDBマニフェストに .spec.settings.instance.owner.azure.resourceGroup.name の設定を追加し対象のリソースグループ名を指定します。 また、事前に、 Azure リソースグループの追加 を参考に UserConfig を使用してリソースグループを作成しておく必要があります。

RDBへの接続確認

RDBへの接続確認は、次の手順で行います。

AzureおよびAWSの場合
  1. kubectlコマンドを使用して、RDBに接続するPodを起動します。以下のコマンドを入力してください。

MySQLの場合:

kubectl run --rm --tty rdb-client --image=mysql:8.0 --namespace=staging --command -- bash

PostgreSQLの場合:

kubectl run --rm --tty rdb-client --image=postgres:16 --namespace=staging --command -- bash
  1. Pod内からRDBに接続します。以下のコマンドを入力してください。

MySQLの場合:

mysql -h <db hostname> -u admin -p -e "SELECT 1;"

PostgreSQLの場合:

psql -h <db hostname> -U admin -d postgres -c 'select 1;'

<db hostname> には、マネージドRDBのホスト名を入力してください。AWSの場合は、前述で控えておいたエンドポイントを指定してください。

パスワードの入力を求められたら、前述の手順でシークレットストアサービスに登録したDBアクセス用パスワードを入力してください。

  1. RDBから切断し、Podを終了します。以下のコマンドを入力してください。

exit
Google Cloudの場合

Google Cloudの場合はCloud Shellを使用して接続確認を行います。 ポータルのCloud SQL のページから作成したインスタンスを選択し、 概要ページの このインスタンスとの接続 から gcloud を使用して接続するには Cloud Shellを開く を選択し、接続のテストを行ってください。 gcloud sql connect mysql-techdoc --user=root --quiet というコマンドを実行しようとするので、 root の部分を設定したユーザー名( kanboard )に変更して実行します。 パスワードの入力を求められたら、前述の手順でシークレットストアサービスに登録したDBアクセス用パスワードを入力してください。

Webアプリケーションの構築

  1. 次に、basic-deploymentパッケージを使用してWebアプリケーションを構成するマニフェストを作成します。アプリケーションをデプロイするクラウドベンダーに合わせて下記のマニフェストをコピーし、お客さまのローカルのgitリポジトリに保存してください。

Azure

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: kanboard
  namespace: staging
spec:
  chart:
    name: basic-deployment
    version: <latest>
  settings:
    image:
      repository: kanboard/kanboard
      pullPolicy: IfNotPresent
      tag: "latest"
    network:
      domain: kanboard.<customer domain>
      service:
        ports:
          - name: kanboard
            containerPort: 80
            servicePort: 80
    env:
      - name: DB_DRIVER
        value: postgres
      - name: DB_USERNAME
        value: maintainer
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: rdb-user-rdb-secret-maintainer-postgres-cnap-<customer id>-instance
            key: password
      - name: DB_HOSTNAME
        value: postgres-cnap-<customer id>.postgres.database.azure.com
      - name: DB_NAME
        value: staging-db
    timeout: 10m

Google Cloud

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: kanboard
  namespace: staging
spec:
  chart:
    name: basic-deployment
    version: <latest>
  settings:
    image:
      repository: kanboard/kanboard
      pullPolicy: IfNotPresent
      tag: "latest"
    network:
      domain: kanboard.<customer domain>
      service:
        ports:
          - name: kanboard
            containerPort: 80
            servicePort: 80
    env:
      - name: DB_DRIVER
        value: mysql
      - name: DB_USERNAME
        value: kanboard
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: rdb-user-kanboard-kanboard-mysql
            key: password
      - name: DB_HOSTNAME
        value: "127.0.0.1"
      - name: DB_NAME
        value: staging-db
    preConnectRdb:
      - gcp:
          instance: mysql
          port: 3306
          location: asia-northeast1
    auth:
      gcp:
        roles:
        - name: roles/cloudsql.client
      serviceAccount:
        create: true
    timeout: 10m

AWS

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: kanboard
  namespace: staging
spec:
  chart:
    name: basic-deployment
    version: <latest>
  settings:
    image:
      repository: kanboard/kanboard
      pullPolicy: IfNotPresent
      tag: "latest"
    network:
      domain: kanboard.<customer domain>
      service:
        ports:
          - name: kanboard
            containerPort: 80
            servicePort: 80
    mountSecrets:
      - remoteRef:
          key: rdb-admin
        property: password
        env: DB_PASSWORD
    env:
      - name: DB_DRIVER
        value: mysql
      - name: DB_USERNAME
        value: admin
      - name: DB_HOSTNAME
        value: <db hostname>
      - name: DB_NAME
        value: staging
    timeout: 10m

(参考:HELM ユーザー用パッケージ basic-deployment)

このマニフェストでは、 kanboardのdeploymentリソースと、アプリケーションにアクセスするためのDNSレコードが作成されます。

.spec.settings.network.domain<customer domain> は、お客さまがCNAP開通時に弊社のヒアリングシートに記載したゾーン名に置き換えてください。例として、example.comをヒアリングシートに記載された場合、初期開通時にあらかじめ example.com というゾーンがマネージドDNSサービスに登録されています。その中に kanboard.example.com というAレコードが作成されます。

Azureの場合は .spec.settings.env 内の <customer id> を、お客さまがCNAP開通時に弊社のヒアリングシートに記載したMSP契約番号に置き換えてください。

AWSの場合は .spec.settings.env 内の <db hostname> を、先ほど控えておいたマネージドRDBのエンドポイントに置き換えてください。

また、AzureおよびGoogle Cloudの場合には .spec.settings.env[3].valueFrom.secretKeyRef.namerdb-user-<RDBマニフェストの.spec.settings.users[0].secret.key>-<RDBマニフェストの.spec.settings.users[0].name>-<RDBマニフェストの.spec.settings.instance.name> となるので確認してください。

  1. アプリケーションのマニフェストをコミットし、リモートのGitリポジトリにpushしてください。

git add . && git commit -m "add application manifest"
git push
  1. マニフェストからリソースが正常に作成されたことを確認します。

Application カスタムリソースが適用されたことを確認します。以下のコマンドを入力し、 kanboard という名前のリソースがあることを確認してください。

kubectl get application -n staging

アプリケーションの Deployment リソースが作成されたことを確認します。以下のコマンドを入力し、 kanboard-application-basic-deployment という名前のリソースが存在し、READYが1/1になっていることを確認してください。

kubectl get deployment -n staging

マネージドDNSのレコードが作成されたことを確認します。ご利用のクラウドベンダーのポータル画面にログインし、マネージドDNSゾーンとレコードが存在することを確認してください。

  1. 作成されたアプリケーションにブラウザからアクセスし、アプリケーションが利用可能であることを確認します。

.spec.settings.network.domain で指定したURLにブラウザでアクセスしてください。以下のような画面が表示されれば、アプリケーションのデプロイは成功しています。

../_images/sample-kanboard.png

一般公開 Helm チャートのデプロイ

Application マニフェストでは CNAP の提供する Helm チャート以外にも ArtifactHub などで公開されている Helm チャートの CD にも対応しています。

以下の例では Web UI を持つ Helm チャートの設定を行っています。

---
apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: kiali-sample
  namespace: staging
spec:
  type: public                          # public を指定する。
  repository:
    name: kiali                         # 任意の名前を指定 (同一 namespace 内ではユニークになるように設定する)
    url: https://kiali.org/helm-charts  # helm リポジトリの URL
    type: default                       # 通常の helm リポジトリの場合は default を指定する。OCI の場合は oci を指定する。
  chart:
    name: kiali-server                  # インストールする chart 名を指定
    version: X                          # インストーするバージョンを指定
  settings:                             # chart の values で指定したいパラメータを指定する
    server:
      web_fqdn: kiali.example.com
      web_schema: https
      web_root: /kiali
    deployment:
      secret_name: kiali-sample
      logger:
        log_level: trace

一般公開されている Helm チャートを利用する際、istio のルーティング設定を行う VirtualService リソースが作成されません。 クラスタ外のネットワークに公開する場合は以下のような VirtualService リソースを追加します。

ルーティングする先の Service が不明な場合は、一旦 VirtualService なしの状態でインストールを行い、 実際に作成された Service の内容を確認して設定を行います。

---
# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/networking.istio.io/virtualservice_v1.json
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: kiali-sample
  namespace: staging
spec:
  gateways:
  - istio-system/istio-ingress
  hosts:
  - kiali.example.com         # fqdn を指定する
  - kiali
  http:
  - route:
    - destination:            # ルーティング先の Service リソースを指定
        host: kiali
        port:
          number: 20001
    headers:                  # ルーティング先が 443 以外のポートの場合はヘッダー情報を付与する
      request:
        set:
          X-Forwarded-Host: kiali.example.com
          X-Forwarded-Port: "443"
          X-Forwarded-Proto: https

重要

ルーティングは istio によって行われるため ingress のインストールを同時に行う helm チャートを 利用する場合は、ingress 関連のリソースがインストールされないように設定してください。

補足 kanboardのdeploymentリソースをAzureのMySQLと接続する場合

Azureにおいて Application カスタムリソース の名前を mysql と設定した場合には追加の設定が必要です。

AzureのMySQLサーバへ接続する場合、Azureの提供する証明書を用いて接続を暗号化する必要があります。

証明書をインストールし、データベースへの接続時にその証明書を使用するように設定することで、kanboardアプリケーションを立ち上げることが可能です。

postgres の場合と異なる設定は .spec.settings.env[5] .spec.settings.sharedMounts .spec.settings.initContainers です。

apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: kanboard
  namespace: staging
spec:
  chart:
    name: basic-deployment
    version: <latest>
  settings:
    image:
      repository: kanboard/kanboard
      pullPolicy: IfNotPresent
      tag: "latest"
    network:
      domain: kanboard.<customer domain>
      service:
        ports:
          - name: kanboard
            containerPort: 80
            servicePort: 80
    env:
      - name: DB_DRIVER
        value: mysql
      - name: DB_USERNAME
        value: maintainer
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef:
            name: rdb-user-rdb-secret-maintainer-mysql-cnap-<customer id>-instance
            key: password
      - name: DB_HOSTNAME
        value: mysql-cnap-<customer id>.mysql.database.azure.com
      - name: DB_NAME
        value: staging-db
      - name: DB_SSL_CA
        value: /var/cert/DigiCertGlobalRootCA.crt.pem
    sharedMounts:
      - /var/cert
    initContainers:
      - name: getcert
        image:
          repository: alpine
          tag: latest
        workingDir: /var/cert
        command:
          - wget
          - https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem
    timeout: 10m

2.6.2. カスタムイメージを利用したwebアプリケーション

Kanboardは既存のサービスですが、自身で作成したアプリケーションを構築するには、Container Registryを作成し、カスタムイメージを登録する必要があります。 Container Registryの作成からカスタムイメージの登録までの流れを説明します。

カスタムイメージの格納先としてContainer Registryを作成する

カスタムイメージを使用する場合、イメージをコンテナレジストリに保管する必要があります。

CNAPでは、Container Registryの作成をサポートしています。

以下はご利用のクラウドベンダーごとの作成例です。

CNAP クラスタからリポジトリへのアクセスは初期状態で許可されているため、アクセス許可設定は不要です。 下記は、 Container Registry を作成するマニフェストの例です。acl(AccessControlList) のセクションでコンテナレジストリにアクセスできるユーザやグループなどを設定できます。 また、お手元のPCでDockerがインストールされ、起動している必要があります。

Azure (ACR)
apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: my-acr
  namespace: staging
spec:
  chart:
    name: container-registry
    version: <latest>
  settings:
    # Azureではコンテナレジストリ名に「-」などの記号は使用できません
    name: myregistryname
    location:
      name: japaneast
    acl:
      readWrite:
        - name: <ユーザーグループなどのObject ID>
          type: objectId
    keepOnDelete: true
Google (Artifact Registry)
apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: my-artifact-registry
  namespace: staging
spec:
  chart:
    name: container-registry
    version: <latest>
  settings:
    name: my-registry-name
    location:
      name: asia-northeast1
    acl:
      readWrite:
        - name: user@example.com
          type: user
    keepOnDelete: true
AWS (ECR)
apiVersion: managed.msp.sbopsv/v1alpha1
kind: Application
metadata:
  name: my-ecr
  namespace: staging
spec:
  chart:
    name: container-registry
    version: <latest>
  settings:
    name: my-registry-name
    location:
      name: ap-northeast-1
    acl:
      readWrite:
        - name: cnap_customer
          type: role
    keepOnDelete: true

Container RegistryにカスタムイメージをPushする

本手順では、カスタムイメージをContainer RegistryにPushし、それをCNAPのアプリケーションとしてデプロイする流れを説明します。

説明の便宜上、各クラウドにおけるコンテナイメージのパス(タグを含まない部分)を <registry_image_path> と表記します。 ご利用の環境に合わせて、以下のように読み替えてください。

各クラウドの <registry_image_path> の構成

  • Azure (ACR):

    <registry_name>.azurecr.io/<image_name>

  • Google Cloud (Artifact Registry):

    <location>-docker.pkg.dev/<project_id>/<registry_name>/<image_name>

  • AWS (ECR):

    <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<image_name>


1. Container Registryへのログイン

まず、Push先のレジストリに対して認証(ログイン)を行います。

Azure (ACR)

az acr login --name <registry_name>

Google Cloud (Artifact Registry)

gcloud auth configure-docker <location>-docker.pkg.dev

AWS (ECR)

aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com

2. イメージのタグ付けとPush

手元のDockerイメージに、先ほど確認した <registry_image_path> を付与してPushします。 この手順はすべてのクラウドで共通です。

  1. イメージにタグを付けます。

# <local_image> は手元にあるビルド済みのイメージ名です
docker tag <local_image> <registry_image_path>:<tag>
  1. イメージをPushします。

docker push <registry_image_path>:<tag>

3. マニフェストの設定 (デプロイ)

Pushしたイメージを利用してアプリケーションをデプロイします。 マニフェストの settings.image セクションには、Push時に使用した <registry_image_path><tag> をそのまま指定してください。

settings:
  image:
    repository: <registry_image_path> # Pushしたパス (タグを含まない)
    tag: "<tag>" # Pushしたタグ

2.6.3. 補足 Applicationカスタムリソースのタイムアウト値の設定について

Application カスタムリソースでは .spec.settings.timeout にタイムアウトの値を設定することが可能です。 設定する場合は 10m1h のように数値と単位を組み合わせた形式で指定してください。

Application カスタムリソースによって作成されるリソース群は 作成時間がタイムアウト値に設定した値を超えるとエラーとなり作成が中断される場合があります。

そのため、アプリケーションマニフェストなど作成に時間がかからないリソースはタイムアウト値を短めに、RDBマニフェストなど作成に時間がかかるリソースはタイムアウト値を長めに設定することを推奨します。

2.7. セルフマネージドTLS証明書の設定方法

セルフマネージドTLS証明書利用時のアーキテクチャ

CNAPでは、https通信に利用するTLS証明書については、以下の2つの方式に対応しています。

  • マネージドTLS証明書を利用する方式

    • Let's Encrypt で発行した DV 証明書をCNAPが自動的に設定します。

    • 証明書の更新は自動で行われます。

  • セルフマネージドTLS証明書を利用する方式

    • 外部の認証機関が発行した証明書を設定します。

    • 証明書の自動更新は行われないため、期限が切れる前に証明書を更新する必要があります。

セルフマネージドTLS証明書を利用する方式では、お客さまにてクラウドベンダーの暗号化キーマネージメントサービスへの登録・更新を実施していただく必要があるため、以下にて設定手順を説明します。

2.7.1. 登録方法

ご利用のクラウドベンダーごとに以下の手順で登録作業を行います。

Azure

Azure ポータルからキーコンテナに証明書を格納する場合、改行が崩れて証明書を正しい形式で登録することができません。 そのため CLI 経由で証明書を登録します。

  1. 秘密鍵ファイルの登録

以下のコマンドを実行します。

az keyvault secret set --vault-name "cnap-[顧客 Id]" --name "[cluster名]-ingress-key-1" --file "<秘密鍵ファイルのパス> "
  1. 証明書ファイルの登録

以下のコマンドを実行します。

az keyvault secret set --vault-name "cnap-[顧客 Id]" --name "[cluster名]-ingress-crt-1" --file "<証明書ファイルのパス>"

※ [顧客 Id] とは、 MSP契約番号を小文字にした 「msp1234567」のような文字列になります。MSP契約番号は、MSP開通通知書に記載されてます。

Google Cloud

クラウドコンソールでの登録
  1. 秘密鍵ファイルの登録

Portal の Secret Manager メニューにて シークレットを作成 を選択します。

名前[cluster名]-ingress-key-1 を設定し、 シークレットの値 にて 秘密鍵ファイルをアップロードし、 シークレットを作成 をクリックします。

  1. 証明書ファイルの登録

Portal の Secret Manager メニューにて シークレットを作成 を選択します。

名前[cluster名]-ingress-crt-1 を設定し、 シークレットの値 にて 証明書ファイルをアップロードし、 シークレットを作成 をクリックします。

gcloud cli での登録
  1. 秘密鍵ファイルの登録

以下のコマンドを実行します。

gcloud secrets create "[cluster名]-ingress-key-1" --data-file "<秘密鍵ファイルのパス> "
  1. 証明書ファイルの登録

以下のコマンドを実行します。

gcloud secrets create "[cluster名]-ingress-crt-1" --data-file "<証明書ファイルのパス> "

AWS

マネージドコンソールでの登録
aws cli での登録
  1. 秘密鍵ファイルの登録

以下のコマンドを実行します。

aws secretsmanager create-secret --name [cluster名]-ingress-key-1 --secret-string file://<秘密鍵ファイルのパス>
  1. 証明書ファイルの登録

以下のコマンドを実行します。

aws secretsmanager create-secret --name [cluster名]-ingress-crt-1 --secret-string file://<証明書ファイルのパス>

2.7.2. 更新方法

ご利用のクラウドベンダーごとに以下の手順で更新作業を行います。

Azure

  1. 秘密鍵ファイルの更新

以下のコマンドを実行します。

az keyvault secret set --vault-name "cnap-[顧客 Id]" --name "[cluster名]-ingress-key-1" --file "<秘密鍵ファイルのパス> "
  1. 証明書ファイルの更新

以下のコマンドを実行します。

az keyvault secret set --vault-name "cnap-[顧客 Id]" --name "[cluster名]-ingress-crt-1" --file "<証明書ファイルのパス>"

※ [顧客 Id] とは、 MSP契約番号を小文字にした 「msp1234567」のような文字列になります。MSP契約番号は、MSP開通通知書に記載されてます。

Google Cloud

  1. 秘密鍵ファイルの更新

Portal の Secret Manager メニューにて [cluster名]-ingress-key-1 を選択します。

新しいバージョン を選択し、秘密鍵ファイルをアップロードし、 新しいバージョンを追加 をクリックします。

  1. 証明書ファイルの更新

Portal の Secret Manager メニューにて [cluster名]-ingress-crt-1 を選択します。

新しいバージョン を選択し、証明書ファイルをアップロードし、 新しいバージョンを追加 をクリックします。

AWS

  1. 秘密鍵ファイルの更新

以下のコマンドを実行します。

aws secretsmanager put-secret-value --secret-id [cluster名]-ingress-key-1 --secret-binary file://<秘密鍵ファイルのパス>
  1. 証明書ファイルの更新

以下のコマンドを実行します。

aws secretsmanager put-secret-value --secret-id [cluster名]-ingress-crt-1 --secret-binary file://<証明書ファイルのパス>

2.8. Gitリポジトリ・Namespace・Azure リソースグループの追加方法

ユーザー設定 用マニフェスト UserConfig の使用方法。

2.8.1. Gitリポジトリの追加

CNAPでは、アプリケーションのマニフェストを登録するGitリポジトリをお客さま自身で追加することが可能です。

本節末尾の マニフェスト例 を参考に UserConfig カスタムリソースが記載されたマニフェストを作成するか、 すでにCNAPに反映済の UserConfig カスタムリソースが記載されたマニフェストが存在している場合は当該マニフェストにGitリポジトリの設定を追記してください。

Gitリポジトリの情報は UserConfig カスタムリソースの .spec.repositories に記載してください。

作成もしくは設定を追記したマニフェストをCNAPと連携済みのGitリポジトリに登録することで追加のGitリポジトリへCNAPがアクセスするためのDeoploy Key(公開鍵)が発行されます。

なお、作成されたDeploy KeyはKubernetesクラスタ上で以下のコマンドを実行することで取得することができます。

kubectl get secret -n flux-system <metadata.name に設定した値>-userconfig-<spec.repositories[].name に設定した値>-user-repo -o=jsonpath='{.data.identity\.pub}'| base64 --decode

例として、本章末尾の例のようにマニフェストを設定した場合、コマンドは以下となります。

sample-repo1 用の Deoploy key を取得する
kubectl get secret -n flux-system uc-userconfig-sample1-user-repo -o=jsonpath='{.data.identity\.pub}'| base64 --decode

sample-repo2 用の Deoploy key を取得する
kubectl get secret -n flux-system uc-userconfig-sample2-user-repo -o=jsonpath='{.data.identity\.pub}'| base64 --decode

Windows などbase64コマンドが使えない環境の場合は、以下のようなコマンドでDeploy Keyを取得してください。

kubectl get secret -n flux-system <metadata.name に設定した値>-userconfig-<spec.repositories[].name に設定した値>-user-repo -o=jsonpath='{.data.identity\.pub}' > encoded.txt
certutil -decode encoded.txt decoded.txt
# decoded.txt  Deploy Key が出力されます

取得したDeploy Keyをお客さまのGitリポジトリに登録することでCNAPとの連携が完了します。

2.8.2. Namespaceの追加

また、CNAPでは、提供したKubernetesクラスタに任意のNamespaceをお客さま自身で追加することが可能です。

本節末尾の マニフェスト例 を参考に UserConfig カスタムリソースが記載されたマニフェストを作成するか、 すでにCNAPに反映済の UserConfig カスタムリソースが記載されたマニフェストが存在している場合は当該マニフェストにNamespaceの設定を追記してください。

Namespaceの情報は UserConfig カスタムリソースの .spec.namespaces に記載してください。

作成もしくは設定を追記したマニフェストをすでにCNAPと連携済みのGitリポジトリに登録することでKubernetesクラスタ上に追加のNamespaceが作成されます。

Azureでご利用の場合、CNAPは、KubernetesクラスタのNamespaceに対応した同名のリソースグループを作成します。 Namespaceを削除しても、作成されたリソースグループは削除されません(お客さまのクラウドリソースを保護するためです)。

その他、設定可能な値についてはユーザ設定の章をご参照ください。

2.8.3. Azure リソースグループの追加

CNAPでは、Azure サブスクリプション にKubernetes Namespace に対応した同名のリソースグループを自動的に作成します。 これ以外に任意のリソースグループをお客さま自身で追加することができます。以下では追加方法を示します。

本節末尾の マニフェスト例 を参考に UserConfig カスタムリソースが記載されたマニフェストを作成してください。 Azure リソースグループの情報は UserConfig カスタムリソースの .spec.azure.resourceGroups に記載してください。

作成もしくは設定を追記したマニフェストをすでにCNAPと連携済みのGitリポジトリに登録することでリソースグループが作成されます。 その他、設定可能な値についてはユーザ設定の章をご参照ください。

作成したリソースグループにRDBなどのクラウドリソースを作成するには、RDBパッケージなどにおいてリソースグループを指定してください。 指定しない場合には、Application をインストールしたNamespace と同名のリソースグループに作成されます。

注釈

マニフェストからAzure リソースグループの情報を削除しても、Azureサブスクリプションからリソースグループは削除されません(お客さまのクラウドリソースを保護するためです)。 また、CNAP以外で作成されたリソースグループを扱いたい場合、上記と同様に UserConfig カスタムリソースでリソースグループを定義してください。

apiVersion: managed.msp.sbopsv/v1alpha1
kind: UserConfig
metadata:
  name: uc
  namespace: staging
spec:
  namespaces: 
    - name: namespace1
      create: true
  repositories:
    - name: sample1
      url: ssh://git@github.com/organization/sample-repo1
      branch: master
      path: ./
    - name: sample2
      url: ssh://git@github.com/organization/sample-repo2
      branch: master
      paths:
        - ./app1
        - ./app2
  azure:
    resourceGroups:
      - name: sample-rg1
        location: japaneast
      - name: sample-rg2
        location: japaneast

注釈

1つのKubernetesクラスタにつき1つの UserConfig カスタムリソースが有効になります。2つ目以降の UserConfig カスタムリソースの内容はKubernetesクラスタに反映されません。ご注意ください。

2.9. リソースモニタリングの利用方法

CNAPでは、リソースの使用状況を確認できるダッシュボード機能およびアラート機能を提供しており、クラスタおよびお客さまのコンテナアプリケーションのリソース使用状況を把握することが可能です。

AWS、Azureを利用している場合、モニタリングツールとしてGrafanaを利用します。Grafanaはクラウドベンダが提供するマネージドサービスで構築されます。 Google Cloudを利用している場合、モニタリングツールとしてGoogle Cloud Monitoringを利用します。

ユーザーチュートリアルでは、各モニタリングツールへのアクセス方法と、ダッシュボード・アラートのサンプルについて説明します。

なお、ダッシュボードやアラートの作成方法・機能については、Grafanaの公式ドキュメント Grafana documentationGoogle Cloud Monitoring のドキュメント等を 各データソースごとのクエリの構成方法については、 Prometheusの公式ドキュメント QUERYING PROMETHEUS ならびに 各クラウドベンダの監視機能のドキュメントを参照ください。

また、 Grafana のバージョンアップにより画面構成が変わることが考えられます。 以下の説明のメニュー名など実際のUIと異なることもありますので、その場合は公式ドキュメントを確認してください。

2.9.1. モニタリングツールへのアクセス方法

ご利用のクラウドベンダによって、アクセス方法が異なります。

AWS

AWSを利用している場合、Grafanaは Amazon Grafana で構築されます。 マネジメントコンソールにアクセスし、 Amazon Grafana から、作成されているGrafana WorkspaceのURLへアクセスしてください。

ログイン画面が表示されますので、 事前にヒアリングシートの Grafana用 IAM Identity Center アカウント にて 作成を依頼したユーザーと構築時に連携されたパスワードを利用してログインしてください。

警告

2023年1月現在、Amazon Grafanaのバグにより、 Grafana用 IAM Identity Center アカウント を一度削除すると、ユーザーを再作成してもログイン不可となります。 削除したユーザーを再作成したい場合には、管理者権限のある他のユーザーでログインし、Grafanaの管理画面上から該当ユーザーを削除するワークアラウンドを実施してください。

Azure

Azureを利用している場合、Grafanaは Azure Managed Grafana で構築されます。

CNAP-customerグループに所属しているアカウントを利用して、Azure portalにアクセスし、 リソースグループ managed-grafana-rg 内に作成されているGrafanaのURLへアクセスしてください。ログインは自動的に実施されます。

Prometheus Data Sourceの登録

Azure Managed Grafanaでは、データの取得元であるPrometheus Data Sourceがデフォルトで登録されていないため、以下の手順で登録を行います。

  1. Azure Monitor Workspaceのクエリエンドポイントの確認

Portal の Azure Monitor ワークスペース メニューにて [MSP契約番号]-[Kubernetesクラスタ名]-ws のワークスペースを選択します。 左メニューの 概要 を選択し、 クエリエンドポイント のURLを控えてください。

../_images/grafana-amw.png
  1. Prometheus Data Sourceの登録

リソースグループ managed-grafana-rg 内に作成されているGrafanaのURLへアクセスしてください。

../_images/grafana-endpoint.png

Grafanaへアクセス後、左メニューの Connections -> Data sources を選択し、Add new data source ボタンをクリックします。

../_images/grafana-top-page.png

Prometheus を選択し、以下の情報を入力します

../_images/grafana-datasource.png
  • Connection -> Prometheus server URL1. で控えた クエリエンドポイント を入力します

  • Authentication -> Authentication methods -> Authentication methodAzure auth に選択します

  • 後はデフォルト選択のまま最下部の Save & test ボタンを押してData Sourceを作成します

../_images/grafana-datasource-setting.png

Google Cloud

Google Cloudを利用している場合、Google Cloud Monitoringを利用します。

Google Cloud コンソールの「モニタリング」メニューからアクセスしてください。

2.9.2. ダッシュボードの利用

各モニタリングツールではダッシュボード作成して、各種メトリクス・ログを可視化することができます。 本チュートリアルでは、ダッシュボードの新規作成とサンプルダッシュボードのインポートについて説明します。

新規ダッシュボードの作成

ユーザーが自分自身でダッシュボードを作成・カスタマイズして作ることができます。

CNAPでは、以下にてダッシュボードの作成方法についてサンプルを用意しています。

なお、ダッシュボードの詳細な作成方法、クエリの作成方法等については、各モニタリングツールの公式ドキュメントを参照してください。

サンプルダッシュボードのインポート

ユーザーが自分自身で既に用意されているダッシュボードをインポートして利用することができます。

CNAPでは、以下のGrafanaサンプルダッシュボードを用意しています。 Google Cloud Monitoringを利用している場合も、Grafanaダッシュボードのインポート機能を利用して、JSONファイルをインポートすることが可能です。

また、CNAPで用意しているサンプルダッシュボードの他に、Grafanaが公式で提供しているサンプルダッシュボードもインポートして利用が可能です。

Grafanaのダッシュボードページ へアクセスしてダッシュボードを選択し、 Download JSON からjsonファイルを取得してください。 インポート方法は上記記載のCNAPで提供しているjsonファイルのインポート方法と同様です。

データソースの設定 (Grafana)

Grafana ではユーザーが自分自身でダッシュボードのデータ取得元となるデータソースを設定できます。

CNAP では各ベンダごとに以下のデータソースが予め設定済みです。

  • Azure

    • Managed Prometheus、Azure Monitor

  • AWS

    • Managed Prometheus、Amazon CloudWatch

なお、データソースの設定に関しては、データソースごとに認証などの仕組みが異なりますので、 予め設定されているデータソースを新規に設定する場合は、Grafana の公式ドキュメントを参照してください。

2.9.3. アラートの利用

各モニタリングツールではメトリクス・ログに基づいてアラートを作成したり、アラートを通知したりすることができます。 本チュートリアルでは、アラートの作成、通知先の作成、アラートと通知先の紐づけの方法について説明します。

アラートの設定

Grafanaでは、ユーザーが自分自身でアラートを作成することができます。

CNAPでは、以下にてアラートの設定方法についてサンプルを用意しています。

なお、アラートの詳細な条件の作成方法等については、Grafana の公式ドキュメントを参照してください。

通知先(コンタクトポイント)の設定

Grafanaでは、ユーザーが自分自身でコンタクトポイントという、アラートの通知先の設定を行うことができます。

CNAPでは、以下にて通知先の設定方法についてサンプルを用意しています。

なお、その他の通知先の設定方法については、 CNAP の基盤側での設定変更が必要な場合がありますので、サポートにご相談ください。

アラートと通知先の紐づけ

Grafanaでは、ユーザーが自分自身でアラートと通知先の紐づけの設定を行うことができます。

作成したアラートと通知先は紐付けは、 Alerting メニューの Notification policies から行う事ができます。

Default policy の右端の ︙ から「Edit」を選択し、 Default contact point に設定した通知先を選択し、 Update default policy を選択して保存することで、 アラート発生時に設定した通知先へ通知を送付することができます。

また、アラートのタグ等に応じて複数の通知先を使い分けたいときには、 New nested policy を選択して設定します。

2.10. 作成したリソースの削除

アプリケーションのマニフェストファイルを削除しコミット・pushすることで、作成したリソースを削除できます。または、ファイルの中のYAMLを全行コメントアウトした上でコミット・pushしても削除可能です。

なお、誤操作によるインスタンスの削除を防ぐため、RDBサービスでは keepOnDelete の値がデフォルトで true に設定されています。

true の状態でパッケージをアンインストールしてもデータベースインスタンスは残るため、実際に削除する際は、以下の通り keepOnDeletefalse に更新し、一度コミット・pushした後で、削除を行ってください。

# ~~~省略~~~
spec:
  chart:
    name: rdb
    version: <latest>
  settings:
    keepOnDelete: false
# ~~~省略~~~

2.11. Tips: Chat GPTを利用したCNAPマニフェストの作成支援

CNAPでは、CNAP for Mobius をご利用のお客様に対し、CNAPのマニフェスト作成を支援するカスタムGPTsを公開しています。詳細は こちら

なお、Azure 生成AIパッケージをご利用のお客様におきましても、本カスタムGPTsを利用可能です。利用をご希望のお客様はお問い合わせください。