はじめに
Kubernetes上でメッセージングのサービスが使いたくて、NATSを動かしてみました。
最初はHelmのChartを探したのですが見当たらず、NATS公式のGithubアカウントにOperatorを見つけたので、こちらを試してみました。
NATS Operator
https://github.com/nats-io/nats-operator
NATSとは
NATSは、シンプルかつ高性能なオープンソースのメッセージングサービスで、Kubernetesと同じくCNCF(Cloud Native Computing Foundation)傘下のプロジェクトです。公式ページの見解によれば、クラウドネイティブなアプリケーション、IoTメッセージング、マイクロサービスアーキテクチャ向けに作られています。
NATSサーバ自体はGo言語で実装されていて、NATSクライアントは様々な言語で実装されたものが存在します。
NATS
https://nats.io/
Operatorとは
Operatorは、CoreOS社が提唱するKubernetesのカスタムリソースの仕組みを通じてKubernetes APIを拡張し、複雑なステートフルアプリケーションのインスタンスを作成、構成、管理するための運用の知見を組み込んだアプリケーション固有のコントローラです。Operatorを用いることで、(Deployment、ReplicaSet等の)Kubernetesの組み込みリソースと同様に、宣言的な設定により複雑なステートフルアプリケーションの作成、構成、管理を行うことができます。
Introducing Operators: Putting Operational Knowledge into Software
https://coreos.com/blog/introducing-operators.html
Operators
https://coreos.com/operators/
Operatorの実装例としては、etcdクラスタを作成、設定、管理するためのetcd OperatorやPrometheusクラスタを作成、構成、管理するためのPrometheus Operatorがあります。
etcd Operator
https://github.com/coreos/etcd-operator
Prometheus Operator
https://github.com/coreos/prometheus-operator
NATS Operatorのデプロイ
何はともあれ、GKE上にKubernetesクラスタを作成します。
$ gcloud container clusters create nats-cluster \
--zone asia-northeast1-a
自身のユーザーにAuthorizationを許可するためにcluster-admin
の権限を付与します。
NATS OperatorのREADMEにある手順には書かれていないのですが、GKEの場合、このステップが必要のようです。
ISSUE #36
https://github.com/nats-io/nats-operator/issues/36
$ kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
clusterrolebinding "cluster-admin-binding" created
Operatorをデプロイします。OperatorはKubernetes上のPodとして動作します。
このマニフェストの場合、nats-io
というNamespaceにデプロイされます。
$ kubectl apply -f https://raw.githubusercontent.com/nats-io/nats-operator/master/example/deployment-rbac.yaml
namespace "nats-io" created
serviceaccount "nats-operator" created
deployment "nats-operator" created
clusterrolebinding "nats-io:nats-operator-binding" created
clusterrole "nats-io:nats-operator" created
NATSクラスタを表すカスタムリソースとそのコントローラであるOperatorがデプロイされました。
$ kubectl -n nats-io get crd
NAME AGE
natsclusters.nats.io 10s
$ kubectl -n nats-io get pod
NAME READY STATUS RESTARTS AGE
nats-operator-8df7578c4-5cb2t 1/1 Running 0 5s
3ノードからなるNATSクラスタを作成します。
NatsCluster
というカスタムリソースでNATSクラスタを宣言的に作成、構成、管理できます。便利!
$ echo '
apiVersion: "nats.io/v1alpha2"
kind: "NatsCluster"
metadata:
name: "example-nats-cluster"
spec:
size: 3
version: "1.1.0"
' | kubectl -n nats-io apply -f -
natscluster "example-nats-cluster" created
NATSクラスタが作成されたことを確認します。
$ kubectl -n nats-io get natsclusters
NAME AGE
example-nats-cluster 10s
$ kubectl -n nats-io get pod
NAME READY STATUS RESTARTS AGE
nats-46m7xr10zr 1/1 Running 0 42s
nats-operator-8df7578c4-5cb2t 1/1 Running 0 2m
nats-tjrt32ggsh 1/1 Running 0 32s
nats-tv9q9x0xrk 1/1 Running 0 22s
NATクラスタのためのServiceを確認します。
NATSクライアントは先にNatsCluster
カスタムリソースで定義したexample-nats-cluster
という名前でNATSクラスタにアクセスできます。
$ kubectl -n nats-io get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-nats-cluster ClusterIP 10.47.246.213 <none> 4222/TCP 1m
example-nats-cluster-mgmt ClusterIP None <none> 6222/TCP,8222/TCP 1m
テスト
NATSサブスクライバのためのコンテナを立ち上げます。
$ kubectl -n nats-io run -i --tty nats-sub --image=golang --restart=Never
If you don't see a command prompt, try pressing enter.
root@nats-sub:/go
テストのために、公式Githubリポジトリにあるサブスクライバのサンプルプログラムを用意します。
root@nats-sub:/go# wget https://raw.githubusercontent.com/nats-io/go-nats/master/examples/nats-sub.go
root@nats-sub:/go# go get "github.com/nats-io/go-nats"
サブスクライバからhoge
サブジェクトにサブスクライブします。
root@nats-sub:/go# go run nats-sub.go -s nats://example-nats-cluster:4222 hoge
Listening on [hoge]
別のコンソールからNATSパブリッシャのためのコンテナを立ち上げます。
$ kubectl -n nats-io run -i --tty nats-pub --image=golang --restart=Never
If you don't see a command prompt, try pressing enter.
root@nats-sub:/go
サブスクライバと同様に、公式Githubリポジトリにあるサンプルのパブリッシャのプログラムを用意します。
root@nats-pub:/go# wget https://raw.githubusercontent.com/nats-io/go-nats/master/examples/nats-pub.go
root@nats-pub:/go# go get "github.com/nats-io/go-nats"
パブリッシャからhoge
サブジェクトにメッセージをパブリッシュします。
root@nats-pub:/go# go run nats-pub.go -s nats://example-nats-cluster:4222 hoge hello
Published [hoge] : 'hello'
サブスクライバでは、以下のようにメッセージを受信できます。
[#1] Received on [hoge]: 'hello'
おしまい
参考
Explore NATS Pub Sub
https://nats.io/documentation/tutorials/nats-pub-sub/