Help us understand the problem. What is going on with this article?

ニフクラのHatoba(β)でdapr + マイクロサービスを動かしてみた

この記事は、 富士通クラウドテクノロジーズ Advent Calendar 202014日目の記事です。

13日目@morisatoru さんの M5Stack とニフクラ mobile backend でお菓子カウンターを作る でした!
ニフクラ mobile backend + M5Stack を使えば数行のコードを追加するだけでIoT化することができそうですね:yum:
アイデア次第でさまざまなライフハックができそうなので僕もやってみたい…!

磁石が内蔵されているのも便利なので、玄関のドアに貼り付け、外出時に天気予報を配信するモノとか作ってみたいな〜とおもいました!眠っているM5Stackを引っ張りだして来なければ…

🌞 はじめに

改めましてこんにちは!DDD + Clean Architecture でAPIを開発している @kzmake と申します。
2日目daprでつくるマイクロサービス に引き続き、今回は実際にそのサービスをニフクラのマネージドKubernetesサービスであるHatoba(β)を利用して動かしてみたいとおもいます!

📖 Hatoba(β)とは

Hatoba(β)とは、ニフクラ上でマネージドkubernetesクラスターを作成することができるサービスです。
2019/03/26からβ版としてリリースされているサービスで、現在(2020/12/13)はなんと無料で試すことができます!

※Hatoba(β)はユーザーの評価・検証利用を目的として提供しております。本番サービスでのご利用は想定しておりません。

💡 dapr + 時計サービス:timer:Hatoba(β) で動かしてみる

前回の記事でdaprを使って作成したマイクロサービス
時計サービス:timer: https://github.com/kzmake/dapr-clock
をニフクラのHatoba(β)で動かしていきます。
image.png

kubernetes クラスター作成

kubernetesクラスターを作成します。ユーザーガイドのHatoba(β):クイックスタートに操作方法を紹介していますのでぜひご利用ください。今回はニフクラ上で作成したサーバーからプライベートLANを経由してリクエストすることを想定し、

  • プライベートLAN: private
    • DHCPサーバー(ルーター + DHCPコンフィグ): router
  • ファイアウォールグループ: fw
    • 6443/tcp
    • 32080/tcp

を事前に作成しました。ファイアウォールグループは、ニフクラ上のサーバーからAPIをリクエストする・daprやkubectl 等で操作するためにINルールを設定しています。

image.png

ニフクラでは、コンパネを利用することで kubernetes クラスターを簡単に作成することができます(今回はノードプールとして medium x 3 を設定しました)。

image.png

上記のように、ステータスが稼働中となりましたらクラスター作成完了です。最後に、作成したクラスターを選択し、[選択したクラスターの操作] -> [クレデンシャル表示] より ~/.kube/config に設定することでkubectlなどでアクセスできるようになります。

docker run --rm -it -v ~/.kube/config:/root/.kube/config quay.io/derailed/k9s

などでkubernetesクラスターに接続できれば問題ないかとおもいます。

kubernetesクラスターに dapr のインストール

マイクロサービスを実行するruntimeとしてdaprをセットアップします。事前に dapr の cli をインストールしてください。

curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash

先程ニフクラ上で作成したkubernetesクラスターに dapr をインストールします。現在(2020/12/13)の安定版である v0.11.3 を利用しています。

dapr init -k --enable-ha=true --enable-mtls=true --runtime-version=0.11.3
$ dapr status -k
  NAME                   NAMESPACE    HEALTHY  STATUS   REPLICAS  VERSION  AGE  CREATED
  dapr-sentry            dapr-system  True     Running  3         0.11.3   26s  2020-12-13 20:53.07
  dapr-dashboard         dapr-system  True     Running  3         0.3.0    25s  2020-12-13 20:53.08
  dapr-placement         dapr-system  True     Running  1         0.11.3   26s  2020-12-13 20:53.07
  dapr-operator          dapr-system  True     Running  3         0.11.3   26s  2020-12-13 20:53.07
  dapr-sidecar-injector  dapr-system  True     Running  3         0.11.3   26s  2020-12-13 20:53.07

(traefikのデプロイ)

何でもいいんですが僕は traefik が好きなので、Helmを利用して IngressRoute を設定できるようにします。今回は type: NodePort32080/tcp で待ち受けさせます。(Hatoba(β)にてクラスター作成時に HTTPロードバランサー利用する に設定し、 NGINX Ingress Controller を利用することも可能です。)

helm repo add traefik https://containous.github.io/traefik-helm-chart
helm repo update
helm install traefik traefik/traefik --set ports.web.nodePort=32080 --set service.type=NodePort

(redisのデプロイ)

  • pub/sub
  • state store

にて利用するためRedisを利用します。
(実際にサービス展開する環境では、高可用になるように Redis cluster や kafka、他のクラウドサービスに差し替えての利用をおすすめします。)

今回はとりあえず試せる程度でいいので、下記のマニフェストを kubernetes 上にセットアップします。

redis.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
    - port: 6379
      targetPort: 6379
  selector:
    app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: master
          image: redis:alpine
          ports:
            - containerPort: 6379
kubectl apply -f manifests/clock/override/develop/redis.yaml

デプロイしたいアプリケーションの準備

今回は前回の記事(daprでつくるマイクロサービス)で作成した https://github.com/kzmake/dapr-clock を利用します。イメージは下記を利用します。

下記を kubectl apply することでアプリケーションのデプロイは完了となります :yum:

git clone https://github.com/kzmake/dapr-clock.git && cd dapr-clock
kubectl apply -k manifests/clock/override/develop

以下は kubectl apply -k manifests/clock/override/develop の要素をピックアップして解説します。

コンポーネントの設定

コード中にて抽象化されているビルディングブロックのために、コンポーネントの定義を設定します。

  • Redis を pub/sub
  • Redis を statestore
  • 1sec毎にをカウントするcron
  • 24h毎に時刻同期するcron
  • サービス間通信でmtls

を利用するために、

pubsub.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
    - name: redisHost
      value: redis.default.svc.cluster.local:6379
    - name: redisPassword
      value: ""
scopes:
  - hour-hand
  - minute-hand
  - second-hand
  - synchronizer
  - ticker
statestore.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
    - name: redisHost
      value: redis.default.svc.cluster.local:6379
    - name: redisPassword
      value: ""
scopes:
  - hour-hand
  - minute-hand
  - second-hand
  - synchronizer
  - ticker
ticker.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: ticker
spec:
  type: bindings.cron
  metadata:
    - name: schedule
      value: "@every 1s"
scopes:
  - ticker
synchronizer.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: synchronizer
spec:
  type: bindings.cron
  metadata:
    - name: schedule
      value: "@daily"
scopes:
  - synchronizer
mtls.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: daprsystem
spec:
  mtls:
    enabled: "true"
    workloadCertTTL: "24h"
    allowedClockSkew: "15m"

を作成し、

kubectl apply -f pubsub.yaml
kubectl apply -f statestore.yaml
kubectl apply -f ticker.yaml
kubectl apply -f synchronizer.yaml

で設定していきます。 dapr では runtime としてこのコンポーネントを元に抽象化されたインターフェースに実装を注入しているようです。

マイクロサービス + dapr-sidecar

dapr を利用するマイクロサービス毎に sidecar として dapr を設定します。clock サービスを例に紹介すると、

clock.yaml
apiVersion: v1
kind: Service
metadata:
  name: clock
  labels:
    app: clock
spec:
  selector:
    app: clock
  ports:
    - port: 80
      targetPort: 3500
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clock
  labels:
    app: clock
spec:
  replicas: 3
  selector:
    matchLabels:
      app: clock
  template:
    metadata:
      labels:
        app: clock
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "clock"
        dapr.io/app-protocol: "grpc"
        dapr.io/app-port: "3000"
        dapr.io/log-as-json: "true"
        dapr.io/log-level: "debug"
    spec:
      containers:
        - name: clock
          image: ghcr.io/kzmake/dapr-clock/clock:latest
          command: ["/go/bin/app"]
          ports:
            - containerPort: 3000
            - containerPort: 3500
          imagePullPolicy: Always

のように spec.template.metadata.annotations を記述し、

kubectl apply -f clock.yaml

で設定することで sidecar として dapr をデプロイできます。(dapr-sidecar-injector がanotationsに対応するdapr-sidecarを展開しているようですね)

IngressRoute の設定

すべてのアプリケーションのデプロイが完了すれば、時計サービス:timer: として動作するはずなので最後に ingress を設定します。

ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: dapr-invoke
spec:
  addPrefix:
    prefix: /v1.0/invoke/clock/method
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: clock-ingress
spec:
  entryPoints:
    - web
  routes:
    - match: Method(`GET`) && Path(`/now`)
      kind: Rule
      middlewares:
        - name: dapr-invoke
      services:
        - name: clock
          port: 80

上記では traefik を利用し、 GET /now のリクエストを GET /v1.0/invoke/clock/method/now に流す設定を行いました!

これを、

kubectl apply -f ingress.yaml

して完了です!

🚀 リクエストしてみる

curl -s http://<NodeのIPアドレス>:32080/now | jq .
{
  "hour": 0,
  "minute": 15,
  "second": 42
}

バッチリ動作しているようですね!

🌜さいごに

どうでしたでしょうか?Hatoba(β) + dapr を利用することで

  • Hatoba(β): マネージドkubernetesクラスターを構築
  • dapr: ビルディングブロックとして抽象化されたアプリケーションの実行環境
  • app: ビジネスロジックに集中して後はつくるだけ :hugging:

とシンプルになった気がします!

dapr には、コンセプトにもあるとおり、Any language, any framework, anywhere であることから Any cloud or edge infrastructure な選択も可能になってます。
pub/subやstatestoreとして他のクラウドベンダーさんのサービスを利用しながら、マネージドkubernetesサービスとしてニフクラのHatoba(β)を利用することもできます。Any cloud なアプローチは今後さらに増えていくことになると思うので期待ですね! :hugging:

ぜひ、マネージドkubernetesサービスとして Hatoba を利用してもらえると嬉しいです :yum:

明日は、1日目のニフクラがTerraformに対応したので使ってみた【基礎編】 に続き、@miyuush さんが ニフクラがTerraformに対応したので使ってみた【応用編】を書いてくれるようです!
お楽しみに!

🔖 参考

kzmake
趣味でArduinoやProcessingを使ったおもちゃを作ってます。
fjct
クラウド・IoT 関連サービスを開発・提供している企業です。(こちらは、富士通クラウドテクノロジーズの有志にて運営しております。)
https://fjct.fujitsu.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away