概要
kubelsss は k8s 上でサーバレスアーキテクチャを実現できるツールです
今回は minikube を使って kubeless に入門してみました
環境
- macOS 10.14.2
- minikube v0.28.2
- kubeless 1.0.1
minikube 起動
minikube の環境は構築済みを想定しています
minikube に関してはこちらの記事を参照してください
minikube start
うまく起動しない場合は一旦キャッシュを削除してイメージの再取得から行ってください
rm -rf ~/.minikube
kubeless インストール
今回は homebrew を使ってインストールしました
公式だと Github から zip をダウンロードしてそこに含まれるバイナリを PATH に通す手順になっています
その手順でも全然 OK です
brew install kubeless
リソースファイルの取得
YAML ファイルなどが含まれている zip ファイルをダウンロードしておきます
ちなみにこの中に kubeless のバイナリファイルも含まれています
wget https://github.com/kubeless/kubeless/archive/v1.0.1.zip
unzip v1.0.1.zip
namespace 作成
kubectl create ns kubeless
kubectl get ns
NAME STATUS AGE
default Active 1h
kube-public Active 1h
kube-system Active 1h
kubeless Active 6s
kubeless 環境のデプロイ
k8s 上に kubelss を実行するために必要なコンテナをデプロイしていきます
kubectl create -f https://github.com/kubeless/kubeless/releases/download/v1.0.1/kubeless-v1.0.1.yaml
configmap/kubeless-config created
deployment.apps/kubeless-controller-manager created
serviceaccount/controller-acct created
clusterrole.rbac.authorization.k8s.io/kubeless-controller-deployer created
clusterrolebinding.rbac.authorization.k8s.io/kubeless-controller-deployer created
customresourcedefinition.apiextensions.k8s.io/functions.kubeless.io created
customresourcedefinition.apiextensions.k8s.io/httptriggers.kubeless.io created
customresourcedefinition.apiextensions.k8s.io/cronjobtriggers.kubeless.io created
いろいろなコンポーネントが作成されています
デプロイされたら pods を確認してみます
kubectl get all --namespace kubeless
NAME READY STATUS RESTARTS AGE
pod/kubeless-controller-manager-568b578f78-vkgd5 3/3 Running 0 4m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/kubeless-controller-manager 1 1 1 1 4m
NAME DESIRED CURRENT READY AGE
replicaset.apps/kubeless-controller-manager-568b578f78 1 1 1 4m
deployment, replicaSet, pod がデプロイされています
またそれ以外では configmap もデプロイされています
kubectl get configmap --namespace kubeless
NAME DATA AGE
kubeless-config 10 8m
dashboard で確認しても良いと思います
関数を作成、デプロイ
とりあえずサンプルにある通り素直に python でやってみたいと思います
- vim city-bikes.py
import urllib2
import json
def find(event, context):
term = event["data"]["term"]
url = "https://feeds.capitalbikeshare.com/stations/stations.json"
response = urllib2.urlopen(url)
stations = json.loads(response.read())
hits = []
for station in stations["stationBeanList"]:
if station["stAddress1"].find(term) > -1:
hits.append(station)
return json.dumps(hits)
サンプルをそのまま使っています
一部修正しています (引数を event と context の 2 つに修正しています)
JSON を取得してそれを出力しています
この関数を kubeless deploy
コマンドでデプロイします
kubeless function deploy bikesearch --runtime python2.7 --handler city-bikes.find --from-file city-bikes.py
INFO[0000] Deploying function...
INFO[0000] Function bikesearch submitted for deployment
INFO[0000] Check the deployment status executing 'kubeless function ls bikesearch'
--runtime
は python2.7
を使います
--handler
は実行する関数のメソッドを指定します
今回は city-bikes.py
の find というメソッドを登録しています
function ls
サブコマンドで確認できます
kubeless function ls
NAME NAMESPACE HANDLER RUNTIME DEPENDENCIES STATUS
bikesearch default city-bikes.find python2.7 1/1 READY
pods としても動作しているのが確認できます
namespace は default でデプロイされるようです
kubectl get pods
NAME READY STATUS RESTARTS AGE
bikesearch-fcb99cd8-5mvdl 1/1 Running 0 3m
http trigger を作成
関数を http 経由で実行してみましょう
minikube の場合 ingress アドオンを有効にする必要があります
minikube addons enable ingress
少し時間がかかるので待ちましょう
kubectl get pod -n kube-system -l app=nginx-ingress-controller
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5984b97644-4v86w 1/1 Running 0 1m
Running になれば OK です
ではトリガー「http」を作成します
kubeless trigger http create bikesearch-trigger --function-name bikesearch
INFO[0000] HTTP trigger bikesearch-trigger created in namespace default successfully!
function 同様に ls コマンドがあるのでこれで確認しましょう
kubeless trigger http ls
NAME NAMESPACE FUNCTION NAME
bikesearch-trigger default bikesearch
関数実行
では関数を実行してみます
ingress が新たに作成されているので確認してみます
kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
bikesearch-trigger bikesearch.192.168.99.100.nip.io 10.0.2.15 80 1m
このエンドポイントに対して curl でコールしてみます
curl --data '{"term":"Eastern"}' -H "Host: bikesearch.192.168.99.100.nip.io" -H "Content-Type:application/json" 192.168.99.100
minikube の ingress 場合 VirtualHost で振り分けを行っているため Host の指定を忘れないようにしましょう
これで JSON の結果が返ってくれば OK です
ちなみに関数の挙動を確認するのにはログを見るのが良いと思います
kubeless function logs -f bikesearch
Ruby でもやってみる
kubeless は runtime に Ruby (ruby2.3, ruby2.4, ruby2.5) もサポートしています
今度は Ruby の関数を試してみたいと思います
- touch handler.rb
- vim handler.rb
require 'json'
def handle(event, context)
{body: event[:data]["body"]}.to_json
end
関数をデプロイして
kubeless function deploy rfunc --runtime ruby2.5 --handler handler.handle --from-file handler.rb
http トリガーを関数に紐づけして
kubeless trigger http create rfunc-trigger --function-name rfunc
コールします
curl -v --data "hoge" -H "Host: rfunc.192.168.99.100.nip.io" -H "Content-Type:application/json" 192.168.99.100
{"body":"hoge"}
こんな感じです
関数のレスポンスが JSON でない場合はエラーになりました
Rubygems を使っている場合
例えば以下のような場合は
- vim Gemfile
gem "slack-ruby-client"
- vim handler.rb
require 'json'
require 'slack-ruby-client'
def handle(event, context)
{body: 'ok'}.to_json
end
デプロイ時に --dependencies
を付与することで対応できます
kubeless function deploy rfunc --runtime ruby2.5 --handler handler.handle --from-file handler.rb --dependencies Gemfile
内部的には bundle install が走っているので pod の起動には少し時間がかかります
あとは同じです
kubeless trigger http create rfunc-trigger --function-name rfunc
curl -v -H "Host: rfunc.192.168.99.100.nip.io" 192.168.99.100
Tips
関数削除
kubeless function delete bikesearch
最後に
minikube で kubeless に入門してみました
関数は AWS lambda と同様に書けます (おそらく使い回すこともできると思います)
仕組み的にも lambda に近いので lambda に慣れている人は導入障壁は低いと思います
k8s の仕組みを知らなくても何とかなりそうですが kubectl を使ったオペレーションも若干発生するので覚えておいて損はないと思います
runtime は今回 python2.7 と ruby2.5 を使いましたが他にも JVM や Golang も使えます
また今回は公式のチュートリアルを元に進めましたがかなり情報が古いのでそのままだと動きません
Github にあるドキュメントがかなり充実しているのでそちらを見ながら進めると良いと思います
0 件のコメント:
コメントを投稿