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環境を起動する
1
2
|
$ minikube start
$ eval $(minikube docker-env)
|
必要なDockerイメージをビルドまたはプルした状態がこちら。
1
2
3
4
5
6
|
$ 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を使いコンテナ全体をパッケージングをする
1
2
3
4
5
6
7
8
9
10
11
12
|
$ 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# `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 }}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 関連する値を `values.yaml`から抜粋
plasmaCli:
image:
repository: soushin/plasmacli
tag: latest
pullPolicy: IfNotPresent
env:
plasmaHost: localhost
plasmaPort: 50051
service:
type: NodePort
port: 80
internalPort: 8080
|
パッケージングしたchartをインストールする
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ 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を確認してみると無事起動している。
1
2
3
|
$ kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
plasmacli-957c79484-d4dkh 3/3 Running 0 2d
|
クラスタの外からアクセスする
クラスタの外からのアクセスにはserviceをNodePort化したのでポート番号が払い出されている。
アクセスURLは次のように確認できる。
1
2
|
$ minikube service plasmacli --url
http://192.168.64.12:31118
|
このURLのバックエンドにはイベントをSubscribeするアプリケーションが設定されているので次のように /health_check
が叩けるようになっている。
1
2
|
$ curl http://192.168.64.12:31118/health_check
true
|
plasmaの動作確認をしてみよう
イベントをSubscribeするアプリケーションではイベント名:my-event
をSubscribeするようにしている。
redisからchannelへPublishする。
1
2
|
PUBLISH plasma '{"meta": { "type": "my-event"}, "data": "HELLO"}'
PUBLISH plasma '{"meta": { "type": "my-event"}, "data": "My Plasma"}' |
イベントをSubscribeするアプリケーションのログの最後にPayloadデータ(HELLO
, My Plasma
の文字列)が出力できた。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
$ 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間のアクセスなど気になるところが数多あるので引き続きアウトプットしていく。