K8sを意識せずにアプリをデプロイできるKubeVelaにシュっと入門
GitHubのトレンドを眺めていたところ、KubeVelaというOSSが目に止まりました。
KubeVelaとは
一言で言えば、開発者が楽にK8sにアプリをデプロイするためのツールセットです。
通常、開発者がK8sにアプリをデプロイする際はPod、Service、Ingress、Resource Request、CRD etc...の概念を理解する必要があり、これらを全て理解することは決して楽ではありません。
KubeVelaはこの労力を最小限にするアプローチの1つとして提供されており、開発者はAppfileという設定ファイルのみを管理するだけで良くなるため、複雑なK8sの設定をあまり意識せずにデプロイすることが可能になります。
今回は、このKubeVelaをローカルのK8sクラスター上に展開しながら、動作を確認していきます。
検証環境
- Mac OS Catalina
- Docker: 19.03.13
- kubectl: v1.19.4
- Kind: 0.9.0
- Vela: v0.1.2
説明しないこと
- 以下のインストール手順
- Docker
- kind
- kubectl
もし新規でkind、kubectlのインストールを行う場合は、公式の手順通り入れても全く問題ありませんが、以下のasdf-vmというCLI用のバージョン管理マネージャーを利用するのも個人的にオススメです[1]。
KubeVelaのインストール
- kindでクラスター構築
$ cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
# 起動確認
$ kubectl get no
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready master 2m49s v1.19.1
- Nginx Ingressのインストール
ルーティングの設定を行うために必要です。
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
- Vela CLIのインストール
公式のReleaseページからバイナリをダウンロードし、PATHが通っているところに配置します。
$ tar zxvf ~/Downloads/vela-v0.1.2-darwin-amd64.tar.gz
$ sudo mv darwin-amd64/vela /usr/local/bin/vela
$ sudo chmod +x /usr/local/bin/vela
- Velaの動作確認
Macの新しいバージョンだと、Apple Developer Keyで署名されていないバイナリの実行がブロックされるため、システム環境設定 -> セキュリティとプライバシー -> 一般 -> ダウンロードしたアプリケーションの実行許可から許可をします。
$ vela version
Version: refs/tags/v0.1.2
GitRevision: git-816b7d2
GolangVersion: go1.14.12
- Velaの初期化
このタイミングでVela用のNamespaceが作成され、専用のHelm Chartがインストールされます。
$ vela install
...
- Finished successfully.
- Velaコンポーネントの諸々の確認
Velaは内部的に複数のOSS・Operatorを利用しており、vela install
のタイミングでDeployツールのFlagger、イベント駆動でPodのオートスケールを実現するKEDA、Prometheusがインストールされていることが分かります。
# Chart
$ helm list -n vela-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
flagger vela-system 1 2020-11-23 07:03:14.4367091 +0000 UTC deployed flagger-1.1.0 1.1.0
kubevela vela-system 1 2020-11-23 16:02:25.955088 +0900 JST deployed vela-core-0.1.0 0.1.0
$ helm list --all-namespaces
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
flagger vela-system 1 2020-11-23 07:03:14.4367091 +0000 UTC deployed flagger-1.1.0 1.1.0
keda keda 1 2020-11-23 07:03:20.8723254 +0000 UTC deployed keda-2.0.0-rc3 2.0.0-rc2
kube-prometheus-stack monitoring 1 2020-11-23 07:03:35.7623397 +0000 UTC deployed kube-prometheus-stack-9.4.4 0.38.1
kubevela vela-system 1 2020-11-23 16:02:25.955088 +0900 JST deployed vela-core-0.1.0 0.1.0
KubeVelaでサンプルアプリを動かす
- 公式のサンプルアプリをクローン
$ git clone https://github.com/oam-dev/kubevela.git
$ cd kubevela/docs/examples/testapp
- vela.yamlを確認する
見ての通り、docker-compose.yamlライクな設定ファイルとなっています。
こちらは偶然ではなく、公式にもdocker-composeを意識したつくりとしていることが示唆されています。
name: testapp
services:
express-server:
# this image will be used in both build and deploy steps
image: oamdev/testapp:v1
build:
# Here more runtime specific build templates will be supported, like NodeJS, Go, Python, Ruby.
docker:
file: Dockerfile
context: .
# Uncomment the following to push to local kind cluster
# push:
# local: kind
# type: webservice (default) | worker | task
cmd: ["node", "server.js"]
port: 8080
# scaler:
# replicas: 1
# route:
# domain: example.com
# rules:
# - path: /testapp
# rewriteTarget: /
# metrics:
# format: "prometheus"
# port: 8080
# path: "/metrics"
# scheme: "http"
# enabled: true
# autoscale:
# min: 1
# max: 4
# cron:
# startAt: "14:00"
# duration: "2h"
# days: "Monday, Thursday"
# replicas: 2
# timezone: "America/Los_Angeles"
# pi:
# image: perl
# cmd: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
- vela.yamlの編集
公式ページでは、image: oamdev/testapp:v1
の部分を自分のレジストリアカウントに変更した後、そのままvela up
というdocker-compose up
ライクなコマンドを用いてデプロイする手順が記載されています。
ただその場合はリモートレジストリの用意が必須となってしまうため、ローカルの閉じた環境で検証できるように
ローカルプッシュオプションを有効化します。
具体的には、vela.yaml
の以下の部分をコメントインします。
build:
# Uncomment the following to push to local kind cluster
- # push:
- # local: kind
+ push:
+ local: kind
- サンプルアプリのデプロイ
$ vela up
Parsing vela.yaml ...
Loading templates ...
~~~
Applying deploy configs ...
Checking if app has been deployed...
App has not been deployed, creating a new deployment...
✅ App has been deployed 🚀🚀🚀
Port forward: vela port-forward testapp
SSH: vela exec testapp
Logging: vela logs testapp
App status: vela status testapp
Service status: vela status testapp --svc express-server
- サンプルアプリの動作確認
アプリへのポートフォワード、コマンド実行、ログ確認など
必要なものは一通り揃っています。
# ポートフォワード
# kubectl port-forwardと違い、そのままブラウザでページが開かれる点が異なる
$ vela port-forward testapp
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Forward successfully! Opening browser ...
Handling connection for 8080
Handling connection for 8080
# コンテナ内でのコマンド実行
$ vela exec testapp -it -- sh
/app # ls
Dockerfile node_modules package-lock.json package.json server.js vela.yaml
# ログ確認。表示のされ方はsternと似ている
$ vela logs testapp
+ express-server-666bd6b4dc-wzsnl › express-server
express-server-666bd6b4dc-wzsnl express-server 2020-11-23T07:37:10.689096100Z Running on http://0.0.0.0:8080
# ステータス確認
$ vela status testapp express-server
About:
Name: testapp
Namespace: default
Created at: 2020-11-23 16:37:09.443828 +0900 JST
Updated at: 2020-11-23 16:37:09.44383 +0900 JST
Services:
- Name: express-server
Type: webservice
HEALTHY Ready: 1/1
Traits:
Last Deployment:
Created at: 2020-11-23 16:37:09 +0900 JST
Updated at: 2020-11-23T16:37:09+09:00
vela port-forward
するとブラウザが開くので、
そこでHello Worldが表示されれば正常に動作しています。
KubeVelaでルーティングの設定
ここまででサンプルアプリの動作確認はできたので、ルーティングの設定を試していきます。
- vela.yamlの編集
- # route:
- # domain: example.com
- # rules:
- # - path: /testapp
- # rewriteTarget: /
+ route:
+ domain: example.com
+ rules:
+ - path: /testapp
+ rewriteTarget: /
- vela up
$ vela up
- ステータス確認
再度vela status
を叩くと、通常のコンテナの起動状態の他に、追加したルーティングの状態も確認可能です。
$ vela status testapp
About:
Name: testapp
Namespace: default
Created at: 2020-11-23 18:20:39.551359 +0900 JST
Updated at: 2020-11-23 18:20:39.551359 +0900 JST
Services:
- Name: express-server
Type: webservice
HEALTHY Ready: 1/1
Traits:
- ✅ route: Visiting URL: http://example.com IP: localhost
Last Deployment:
Created at: 2020-11-23 16:37:09 +0900 JST
Updated at: 2020-11-23T18:20:39+09:00
- 設定確認
Hostヘッダーを付与しつつ確認を行うと、次のように正常に振り分けられていることが確認できます。
$ curl -H "Host:example.com" http://localhost/testapp
Hello World
# 対応するIngress、Serviceも作成されている
$ kubectl get ing,svc -l app.oam.dev/component=express-server
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.extensions/express-server-trait-64845c5b65-0 <none> example.com localhost 80 5m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/express-server-trait-64845c5b65 ClusterIP 10.96.149.63 <none> 8080/TCP 5m44s
KubeVelaでオートスケールの設定
先述の通り、KEDAが入っている環境のため、Podのオートスケールを行うこともできます。
条件としては、タイミング(e.g. 火曜日の22時から1時間)か、
負荷(e.g. コンテナのCPU使用率が10%増える)のいずれかに対応してスケールさせることが可能です。
今回は、決まったタイミングでオートスケールさせるCronタイプのスケーリングを試していきます。
- vela.yamlの編集
例によってvela.yamlを編集します。
見ての通りですが、Podのレプリカ数の最小値と最大値に加えて
オートスケールする条件(月曜21:12から1分間だけレプリカを2個にスケール)を加えています。
- # autoscale:
- # min: 1
- # max: 4
- # cron:
- # startAt: "14:00"
- # duration: "2h"
- # days: "Monday, Thursday"
- # replicas: 2
- # timezone: "America/Los_Angeles"
+ autoscale:
+ min: 1
+ max: 5
+ cron:
+ startAt: "21:12"
+ duration: "1m"
+ days: "Monday"
+ replicas: 2
+ timezone: "Asia/Tokyo"
- vela up
$ vela up
- 動作確認
# 元々のPod数
$ vela status testapp
~~~
- Name: express-server
Type: webservice
HEALTHY Ready: 1/1
Traits:
- ✅ autoscale: type: cron replicas(min/max/current): 1/5/1
# 時間になるとオートスケール
$ vela status testapp
~~~
- Name: express-server
Type: webservice
HEALTHY Ready: 2/2
Traits:
- ✅ autoscale: type: cron replicas(min/max/current): 1/5/2
# durationを過ぎると元のPod数に戻る
$ vela status testapp
~~~
- Name: express-server
Type: webservice
HEALTHY Ready: 1/1
Traits:
- ✅ autoscale: type: cron replicas(min/max/current): 1/5/1
待っていると、無事オートスケールされました。
少し気になった点として、スケールアウトは時間通りに実行されたものの
スケールインされるまでは5分弱ラグがありました(理由はKEDAの仕様と絡んでいるかもしれないので、調査中です)。
所感
とにかくdocker-composeの使用感を維持したままK8sにアプリをデプロイしたい人にとっては、ちょうどいいツールという肌感でした。
アプリのビルドからリリースまで一貫して面倒を見るという意味では、先日Hashicorpから発表されたWaypointに少し似ていますが、次のような点に違いがあります。
項目 | KubeVela | Waypoint |
---|---|---|
ビルドランタイム | Docker | Buildpacks |
対応プラットフォーム | K8sのみ | K8s以外も対応 |
対応言語 | 制限なし | Buildpacksの対応に依存 |
設定フォーマット | Yaml | HCL |
Waypointは幅広いプラットフォームに対応していますが、KubeVelaはK8s上の利用に特化している分、K8sの関連OSSと連携して痒い所に手が届くような印象でした。
また一方で、動かす上で躓く点は少なかったですが、複数のOperatorが自動セットアップされる関係でリソースをそこそこ食うので、個人開発用のような小さめのクラスターだと少し重く感じるかもしれません。
現在KubeVelaはアルファリリースですが、使用感や設定自体は非常にシンプルで良かったので、今後の動向をチェックしていきたいと思います。
-
対応しているCLIツールのバージョン切り替えが簡単に行えます。 ↩︎
Discussion