この記事は、 富士通クラウドテクノロジーズ Advent Calendar 2020 の14日目の記事です。
13日目は @morisatoru さんの M5Stack とニフクラ mobile backend でお菓子カウンターを作る でした!
ニフクラ mobile backend + M5Stack を使えば数行のコードを追加するだけでIoT化することができそうですね
アイデア次第でさまざまなライフハックができそうなので僕もやってみたい…!
磁石が内蔵されているのも便利なので、玄関のドアに貼り付け、外出時に天気予報を配信するモノとか作ってみたいな〜とおもいました!眠っているM5Stackを引っ張りだして来なければ…
🌞 はじめに
改めましてこんにちは!DDD + Clean Architecture でAPIを開発している @kzmake と申します。
2日目の daprでつくるマイクロサービス に引き続き、今回は実際にそのサービスをニフクラのマネージドKubernetesサービスであるHatoba(β)を利用して動かしてみたいとおもいます!
📖 Hatoba(β)とは
Hatoba(β)とは、ニフクラ上でマネージドkubernetesクラスターを作成することができるサービスです。
2019/03/26からβ版としてリリースされているサービスで、現在(2020/12/13)はなんと無料で試すことができます!
※Hatoba(β)はユーザーの評価・検証利用を目的として提供しております。本番サービスでのご利用は想定しておりません。
💡 dapr + 時計サービス
を Hatoba(β) で動かしてみる
前回の記事でdaprを使って作成したマイクロサービス
時計サービス https://github.com/kzmake/dapr-clock
をニフクラのHatoba(β)で動かしていきます。
kubernetes クラスター作成
kubernetesクラスターを作成します。ユーザーガイドのHatoba(β):クイックスタートに操作方法を紹介していますのでぜひご利用ください。今回はニフクラ上で作成したサーバーからプライベートLANを経由してリクエストすることを想定し、
- プライベートLAN:
private
- DHCPサーバー(ルーター + DHCPコンフィグ):
router
- DHCPサーバー(ルーター + DHCPコンフィグ):
- ファイアウォールグループ:
fw
6443/tcp
32080/tcp
を事前に作成しました。ファイアウォールグループは、ニフクラ上のサーバーからAPIをリクエストする・daprやkubectl 等で操作するためにINルールを設定しています。
ニフクラでは、コンパネを利用することで kubernetes クラスターを簡単に作成することができます(今回はノードプールとして medium
x 3 を設定しました)。
上記のように、ステータスが稼働中となりましたらクラスター作成完了です。最後に、作成したクラスターを選択し、[選択したクラスターの操作] -> [クレデンシャル表示] より ~/.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: NodePort
で 32080/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 上にセットアップします。
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 を利用します。イメージは下記を利用します。
- ghcr.io/kzmake/dapr-clock/clock
- ghcr.io/kzmake/dapr-clock/hour-hand
- ghcr.io/kzmake/dapr-clock/minute-hand
- ghcr.io/kzmake/dapr-clock/second-hand
- ghcr.io/kzmake/dapr-clock/ticker
- ghcr.io/kzmake/dapr-clock/synchronizer
下記を kubectl apply
することでアプリケーションのデプロイは完了となります
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
を利用するために、
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
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
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: ticker
spec:
type: bindings.cron
metadata:
- name: schedule
value: "@every 1s"
scopes:
- ticker
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: synchronizer
spec:
type: bindings.cron
metadata:
- name: schedule
value: "@daily"
scopes:
- synchronizer
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
サービスを例に紹介すると、
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 の設定
すべてのアプリケーションのデプロイが完了すれば、時計サービス として動作するはずなので最後に ingress を設定します。
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: ビジネスロジックに集中して後はつくるだけ
とシンプルになった気がします!
dapr には、コンセプトにもあるとおり、Any language, any framework, anywhere であることから Any cloud or edge infrastructure な選択も可能になってます。
pub/subやstatestoreとして他のクラウドベンダーさんのサービスを利用しながら、マネージドkubernetesサービスとしてニフクラのHatoba(β)を利用することもできます。Any cloud なアプローチは今後さらに増えていくことになると思うので期待ですね!
ぜひ、マネージドkubernetesサービスとして Hatoba を利用してもらえると嬉しいです
明日は、1日目のニフクラがTerraformに対応したので使ってみた【基礎編】 に続き、@miyuush さんが ニフクラがTerraformに対応したので使ってみた【応用編】を書いてくれるようです!
お楽しみに!