minikube + helmでローカル環境を構築する
plasmaの動作確認のためにローカル環境を構築する機会がありminikube + helmで構築してみようと始めたのがエントリのモチベーション。
plasmaはServer Push型のミドルウェアでFRESH!で使われている。ポーリング撲滅を掲げgRPC/SSEを用いて省コネクションでイベントのSubscribeを実現している。
plasmaの動作確認にはplasma
と redis
のミドルウェアとイベントをSubscribeするアプリケーションが必要(kotlin + SpringBootで書いた)。これらをコンテナ化してローカル環境で確認していきたい。
これまでのローカルのコンテナ実行環境は docker-compose
でやっていたけど、Kubernetesの初学も兼ねてminikubeでやってみる。helmを使いコンテナ全体をパッケージングしていく。
minikubeでkubernetes環境を起動する
$ minikube start $ eval $(minikube docker-env)
必要なDockerイメージをビルドまたはプルした状態がこちら。
$ docker images | grep -v "gcr.io" REPOSITORY TAG IMAGE ID CREATED SIZE soushin/plasmacli latest 49ca95df3dad 2 days ago 942MB redis latest 861cc310cd91 4 days ago 107MB openfresh/plasma latest 7ff567596426 6 weeks ago 16.6MB java openjdk-8 d23bdf5b1b1b 12 months ago 643MB
※ gcr.io/*
のイメージはリストから排除しています
helmを使いコンテナ全体をパッケージングをする
$ helm create plasmacli $ tree ./plasmacli ./plasmacli ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── ingress.yaml │ └── service.yaml └── values.yaml
helm create {packageName}
で雛形を生成する。
このエントリで修正したyamlは values.yaml
とtemplates/deployment.yaml
の2つ。
templates/deployment.yaml
にコンテナとコンテナ内の環境変数、Internal/Externalのポートを定義する。値は values.yaml
から参照する。
templates/deployment.yamlとvalues.yaml
# `plasmacli`コンテナ定義を抜粋 containers: - name: plasmacli image: "{{ .Values.plasmaCli.image.repository }}:{{ .Values.plasmaCli.image.tag }}" imagePullPolicy: {{ .Values.plasmaCli.image.pullPolicy }} ports: - name: plasmacli containerPort: {{ .Values.service.internalPort }} env: - name: PLASMA_CLI_PORT value: {{ .Values.service.internalPort | quote }} - name: PLASMA_HOST value: {{ .Values.plasmaCli.env.plasmaHost | quote }} - name: PLASMA_PORT value: {{ .Values.plasmaCli.env.plasmaPort | quote }}
# 関連する値を `values.yaml`から抜粋 plasmaCli: image: repository: soushin/plasmacli tag: latest pullPolicy: IfNotPresent env: plasmaHost: localhost plasmaPort: 50051 service: type: NodePort port: 80 internalPort: 8080
パッケージングしたchartをインストールする
$ helm package plasmacli $ helm install --name plasmacli local/plasmacli NAME: plasmacli LAST DEPLOYED: Sat Jan 27 11:30:23 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE plasmacli NodePort 10.98.66.149 <none> 80:31118/TCP 0s ==> v1beta2/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE plasmacli 1 0 0 0 0s
podを確認してみると無事起動している。
$ kubectl get pods -n default NAME READY STATUS RESTARTS AGE plasmacli-957c79484-d4dkh 3/3 Running 0 2d
クラスタの外からアクセスする
クラスタの外からのアクセスにはserviceをNodePort化したのでポート番号が払い出されている。
アクセスURLは次のように確認できる。
$ minikube service plasmacli --url http://192.168.64.12:31118
このURLのバックエンドにはイベントをSubscribeするアプリケーションが設定されているので次のように /health_check
が叩けるようになっている。
$ curl http://192.168.64.12:31118/health_check true
plasmaの動作確認をしてみよう
イベントをSubscribeするアプリケーションではイベント名:my-event
をSubscribeするようにしている。
redisからchannelへPublishする。
PUBLISH plasma '{"meta": { "type": "my-event"}, "data": "HELLO"}' PUBLISH plasma '{"meta": { "type": "my-event"}, "data": "My Plasma"}'
イベントをSubscribeするアプリケーションのログの最後にPayloadデータ(HELLO
, My Plasma
の文字列)が出力できた。
$ kubectl logs -f plasmacli-957c79484-d4dkh -c plasmacli . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.0.M7) [INFO ][2018-01-27 11:30:26.380] Starting Application.Companion on plasmacli-957c79484-d4dkh with PID 5 (/usr/local/plasma-cli/lib/plasma-cli.jar started by root in /) [INFO ][2018-01-27 11:30:26.420] No active profile set, falling back to default profiles: default [INFO ][2018-01-27 11:30:26.582] Refreshing org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@445b84c0: startup date [Sat Jan 27 11:30:26 GMT+09:00 2018]; root of context hierarchy [INFO ][2018-01-27 11:30:29.531] Mapped (Accept: [application/json] && /health_check) => { (GET && /) -> org.springframework.web.reactive.function.server.RouterFunctionDsl$GET$1@709ba3fb } [INFO ][2018-01-27 11:30:29.564] Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.reactive.resource.ResourceWebHandler] [INFO ][2018-01-27 11:30:29.565] Mapped URL path [/**] onto handler of type [class org.springframework.web.reactive.resource.ResourceWebHandler] [INFO ][2018-01-27 11:30:29.661] Looking for @ControllerAdvice: org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@445b84c0: startup date [Sat Jan 27 11:30:26 GMT+09:00 2018]; root of context hierarchy [INFO ][2018-01-27 11:30:31.598] Registering beans for JMX exposure on startup [INFO ][2018-01-27 11:30:31.745] Started HttpServer on /0.0.0.0:8080 [INFO ][2018-01-27 11:30:31.761] Netty started on port(s): 8080 [INFO ][2018-01-27 11:30:31.773] Started Application.Companion in 6.292 seconds (JVM running for 7.875) [INFO ][2018-01-27 11:46:06.378] stream observe: onNext={"HELLO"} [INFO ][2018-01-27 11:48:48.386] stream observe: onNext={"My Plasma"}
コードはgithubにあります
コードはgithubに置いてますので合わせて参照ください。
まとめ
- 簡易的なplasmaの動作確認環境が構築できた。
- これからは公開するアプリケーションのコンテナパッケージはhelmで公開していこうとモチベーションがあがった。
- kubectlの各種コマンドはDockerコマンドライクなところが多く、ここらへんはとても飲み込みやすい。
- 今回は初学ということで用語の解説などを飛ばしまったので触っていきながら用語の理解を深めていく必要を感じた。
- helmのvaluesで定義した値とdeployment.yamlで参照する値のKeyのマッピングにミスが多かったのでIDEのhelmライブラリがあると便利そう。
- Serviceの
ClusterIP
やPod間のアクセスなど気になるところが数多あるので引き続きアウトプットしていく。