2019年1月31日木曜日

kubeless 超入門

概要

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' 

--runtimepython2.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 件のコメント:

コメントを投稿