目次


#TryIBMDev

バックエンド処理をサーバーサイド Swift の Kitura と Kubernetes でデプロイし、ショップで使える会員アプリ(iOS 版)を作る

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: #TryIBMDev

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:#TryIBMDev

このシリーズの続きに乞うご期待。

IBM Code Patternsこちらのシナリオをもとにちょっと改変したアプリを作成し、気づいた点や構築にあたって気をつけるべき点などを書いて見たいと思います。

どんなアプリ?

名前は「しょっぷあっぷセブン」。いわゆるショップの会員アプリです。
Swiftで書かれた簡単なステップトラッカーiOSアプリケーションをもとに作成します。ユーザーに対し、ポイントの保有数を確認でき、ポイントに応じて買い物ができる、といった良くあるユースケースを想定しているアプリです。アプリの画面イメージは以下の通りです。

ユーザー情報の画面、ユーザーの持っているポイントでのランキング画面、ポイントで購入できる買い物画面となっています。
それぞれ持っているデータの形は以下の通り非常にシンプルです。

ユーザー
ユーザーID、名前、ポイント、画像イメージ

買い物
商品ID、商品名、在庫数、価格(ポイント)

このアプリケーションのバックエンドは、Swift のサーバーサイド Web フレームワークである Kitura を使用しています。ですので、フロントエンドとバックエンドの両方を 1 つの言語で記述したい iOS 開発者にとって面白いシナリオではないかと思います。
3 つのシンプルな Kitura マイクロサービスを、コンテナオーケストレーションプラットフォームである Kubernetes にデプロイします。

このアプリを一通り作成すると、以下のことを理解することができます。

  • Kitura を使ってサーバーサイドの Swift アプリケーションを構築する
  • Swift Kuery で Kitura を使用してデータベースに接続する
  • Kubernetes に Kitura マイクロサービスを導入する
  • iOS アプリケーションと Kitura バックエンドを統合する
  • Kubernetes を TLS でパブリックドメインで利用できるようにする

アプリ構成図

必要な環境

以下の環境を準備しておく必要があります。少し面倒ですが、全てサービス作成、インストールなどを済ませておきましょう!

※1 IBM Cloud での kubernetes クラスタの作成
プランはスタンダードでロケーションを AP North から tok(東京)を選びます。

実装してみる

1. リポジトリのダウンロード

先ずはこれからですね。git コマンドでサクッと Clone してください。もちろん zip でダウンロードして展開しても OK です。

$ git clone https://github.com/IBM/kitura-on-kubernetes
$ cd kitura-on-kubernetes

2. Kitura のマイクロサービス作成とデプロイ

環境変数に dockerhub のユーザー名を入れましょう。
その後、docker のイメージを作っていきます。

$ export DOCKERHUB_USERNAME=<your-dockerhub-username>

$ docker build -t $DOCKERHUB_USERNAME/kitura-users:latest containers/users/
$ docker build -t $DOCKERHUB_USERNAME/kitura-shop:latest containers/shop/
$ docker build -t $DOCKERHUB_USERNAME/kitura-leaderboards:latest containers/leaderboards/

$ docker push $DOCKERHUB_USERNAME/kitura-users:latest
$ docker push $DOCKERHUB_USERNAME/kitura-shop:latest
$ docker push $DOCKERHUB_USERNAME/kitura-leaderboards:latest

Kubernetes のマニフェストファイルがmanifestsフォルダの中にあるので編集します。

  • leaderboard.yaml
  • shop.yaml
  • users.yaml

ここで注意です。

今回参考にしている GitHub では leaderboad のマニフェストファイルleaderboard.yamlの中にあるイメージファイル名がkitura-leaderboardになっていますが、一つ前の手順で作成したイメージファイル名はkitura-leaderboardsと"s"が付いていますの注意して下さい。また、バージョンもここではlatestを指定してイメージを作っているので、そのとおり書き換えます。
私はここでハマりました。s のつけ忘れと、バージョン指定を 1.0 にしていたので、次の手順のkubectl applyでフェイルしてました。

例) manifests/leaderboard.yaml
...
    image: anthonyamanse/kitura-leaderboard:1.0
       ↓ 以下に書き換える
    image: <自分の dockerhub のアカウント名>/kitura-leaderboards:latest
...

はい、これで各マイクロサービスの YAML 作成は完了です。非常に簡単ですね。
次に PostgreSQL の YAML を編集していきます。

## クレデンシャルを作成し、PostgreSQL をデプロイします

$ kubectl create cm postgres-cm --from-env-file=postgres-config.env
$ kubectl apply -f manifests/postgres.yaml

## postgres コンテナが running になっていることを確認します。
$ kubectl get pods

先ほど作成した 3 つのマイクロサービスの YAML もここでデプロイしていきましょう。

$ kubectl apply -f manifests/leaderboard.yaml
$ kubectl apply -f manifests/shop.yaml
$ kubectl apply -f manifests/users.yaml

## Make sure the 3 of them are running
$ kubectl get pods

3. Kubernetes Ingress でアプリを公開する

デプロイしたバックエンドを公開して、iOS アプリがそのアプリケーションと通信できるようにしたいとします。 Kubernetes Ingress を使用すると、これらのマイクロサービスを公開することができます。 IBM Cloud Kubernetes Service に付属の Ingress サブドメインを使用することができます。

$ bx cs cluster-get <IBM Cloud に作成したクラスタ名>

次の 2 つの項目の値を確認し控えておきます。後ほど使用します。

..
Ingress Subdomain:	XXXXXXXXXXXXX
Ingress Secret:		XXXXXX
..

manifests/ingress.yaml を編集して、上記のサブドメインを設定します。

...
spec:
  tls:
  - hosts:
    - YOUR_INGRESS_SUBDOMAIN
    secretName: YOUR_INGRESS_SECRET
  backend:
    serviceName: users
    servicePort: 8080
  rules:
  - host: YOUR_INGRESS_SUBDOMAIN
...

Kubernetes Ingress をデプロイします。

$ kubectl apply -f manifests/ingress.yaml

Kitura が起動しているかを確認します。

$ export URL=https://YOUR_INGRESS_SUBDOMAIN

## ユーザー機能の初期データを投入
$ curl -X POST -H 'Content-type: application/json' -d "$(curl $URL/users/generate)" $URL/users

{"name":"Gisk Igofrow","userId":"6A213D99-7C08-4BF2-A250-D24E3310236B","stepsConvertedToFitcoin":0,"image":"..." ...}

## ユーザーデータを確認
$ curl $URL/users

[{"name":"Gisk Igofrow","userId":"6A213D99-7C08-4BF2-A250-D24E3310236B" ...}]

## ショップページに表示する products の初期データを投入
curl -X POST -H 'Content-type: application/json' -d "$(cat sampleProducts/smartwatch.json)" $URL/shop/products
curl -X POST -H 'Content-type: application/json' -d "$(cat sampleProducts/runningshoes.json)" $URL/shop/products
curl -X POST -H 'Content-type: application/json' -d "$(cat sampleProducts/smartbodyscale.json)" $URL/shop/products

## products データを確認
$ curl $URL/shop/products

[{"productId":"smartwatch","price":20,"quantity":100,"name":"Smart Watch"},{"productId":"shoes","price":50,"quantity":25,"name":"Running Shoes"},{"productId":"bodyScale","price":5,"quantity":50,"name":"Body Scale"}]

iOS アプリケーション作成

Xcode のワークスペースを開きます。

$ open iOS/KituraStepTracker/KituraStepTracker.xcworkspace

Controllers 配下の 4 つのファイルと、AppDelegate.swift の以下の行を自分の Ingress Subdomain の URL に置き換えます。

let KituraBackendUrl = "https://anthony-dev.us-south.containers.mybluemix.net"

オリジナルの手順には無いですが、UI の日本語化と会員アプリを想定しているので、会員番号から QR コードを自動生成する機能を追加します。UserViewController.swift に以下の通り Function を追加します。

UserViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view, typically from a nib.
        initImageView()
        
        〜中略〜
    }

        〜中略〜

    private func initImageView(){
        //会員番号を取得
        let memberid = getMemberId()
        
        // NSString から NSData へ変換
        let data = memberid.data(using: String.Encoding.utf8)!
        
        // QR コード生成のフィルター
        // NSData 型でデーターを用意
        // inputCorrectionLevel は、誤り訂正レベル
        let qr = CIFilter(name: "CIQRCodeGenerator", withInputParameters: ["inputMessage": data, "inputCorrectionLevel": "M"])!
        
        
        let sizeTransform = CGAffineTransform(scaleX: 10, y: 10)
        let qrImage = qr.outputImage!.transformed(by: sizeTransform)
       
        // UIImage インスタンスの生成
        // UIImageView 初期化
        let uiimage = UIImage(ciImage:qrImage)
        let imageView = UIImageView(image:uiimage)
        
        // 画面の横幅を取得
        let screenWidth:CGFloat = view.frame.size.width
        let screenHeight:CGFloat = view.frame.size.height
        
        // 画像の中心を画面の中心に設定
        imageView.center = CGPoint(x:screenWidth/2, y:screenHeight/1.5)
        
        // UIImageView のインスタンスをビューに追加
        self.view.addSubview(imageView)
        
    }
    
    private func getMemberId() -> String {
        // 会員番号を生成するロジックを適宜実装して下さい。
        // ここではリテラルで返します。
        let memberid = "HRQ01-34345-9FH0J1-11111"
        
        return memberid
    }
}

UI の日本語化の部分は Storyboard を書き換えるだけです。

これで全て完了です。
Xcode でアプリをビルド・実行するとエミュレータでアプリが起動します。もちろん、実機にビルドしても OK です。
iOS アプリから kubernetes の各マイクロサービスへ通信し、各ページのコンテンツとして動作することを確認できました。

最後に

今回の実装で、オリジナルの GitHub から私が編集して実装したバージョンは、私の GitHub に置いてありますので、必要に応じご参照下さい。

今回は、iOS アプリケーションのバックエンドでコンテナ(kubernetes)を使ってマイクロサービス化する、という例をやってみました。IBM Cloud で非常に簡単にバックエンド(サーバーサイド)のアプリが作成出来ることが実感頂けたと思います。このアプリでのポイントは、iOS アプリから直接各マイクロサービスと通信するために Ingress を使っているところです。各サービスを NodePort にして iOS アプリからはそれぞれの NodePort の URL を呼び出すようにしてみても良いかもしれませんね。

ではでは。


ダウンロード可能なリソース


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development
ArticleID=1063401
ArticleTitle=#TryIBMDev: バックエンド処理をサーバーサイド Swift の Kitura と Kubernetes でデプロイし、ショップで使える会員アプリ(iOS 版)を作る
publish-date=11142018