wasmシリーズ第二弾です
前回の続き
今回はwasccのほうのruntimeを使う
wasiとwasccの違いはこちらに
krustlet/providers.md at master · deislabs/krustlet · GitHub
今回は、Rustとwasccで素数の判定&計算するAPIサーバーを書いて、k8sのkrustlet (wascc)のノードで動かすのを試した
結構大変でした
ソースコードはここ
Prime APIの実装
Rustで書いた
httpリクエストを受ける
/is_prime?<number>
/prime_less_than?<number>
の2種類のエンドポイントを用意する
クエリ文字列に指定した数が素数かどうか判別するものと、指定した数より小さい素数を返すものの2種類
krustlet-example/lib.rs at master · hayashikun/krustlet-example · GitHub
素数の判定はエラトステネスの篩でやった
targetはwasm32-unknown-unknown
に設定する
krustlet-example/config at master · hayashikun/krustlet-example · GitHub
ただし、テストはtargetがwasmだと動かないので、別途指定する macなので、こんな感じ
$ cargo test --package prime-api --lib tests --target x86_64-apple-darwin
ビルドするとprime_api.wasm
ができる
$ cargo build --release $ ls target/wasm32-unknown-unknown/release/ build/ deps/ examples/ incremental/ prime_api.d prime_api.wasm
Container Registryにimageをpush
wasmをk8sからpullして動かすたためには、.wasm
に署名して、コンテナイメージに変換し、AzureかGCPかどこかのRegistryにそのイメージをpushする必要がある
demoではjustfileに書いてやってるけど、今回はぽちぽちコマンドを打ってやっていく
署名はwascap
とnkeys
を使う
GitHub - wasmCloud/nkeys: Rust implementation of the NATS nkeys library
$ cargo install wascap --features "cli" $ cargo install nkeys --features "cli"
$ mkdir .key $ nk gen account > .key/account.txt && awk '/Seed/{ print $2 }' .key/account.txt > .key/account.nk $ nk gen module > .key/module.txt && awk '/Seed/{ print $2 }' .key/module.txt > .key/module.nk $ wascap sign target/wasm32-unknown-unknown/release/prime_api.wasm target/wasm32-unknown-unknown/release/prime_api_signed.wasm -i .key/account.nk -u .key/module.nk -s -f -l -n prime_api
署名したら、OCIへの変換とregistryへのpushはwasm-to-oci
がやってくれる
wasm-to-oci
のインストールはreleaseからダウンロードしてPATHの通ったところに置くだけ
今回はGCPのContainer Registryを使った
ずっとAWSのECRを使っていたが、どうもAWSはこのタイプのイメージはpushできないぽい?
AWSばっかりでGCPを使ったことが全然無かったので、google-clould-sdkの導入などからやった
wasm-to-oci
でpushするためには、スタンドアロン認証情報ヘルパーを設定する必要がある
Authentication methods | Container Registry documentation
設定できたらpushする
$ wasm-to-oci push target/wasm32-unknown-unknown/release/prime_api_signed.wasm asia.gcr.io/<project_id>/krustlet-example/prime-api:v1 INFO[0012] Pushed: asia.gcr.io/<project_id>/krustlet-example/prime-api:v1 INFO[0012] Size: 1739890 INFO[0012] Digest: sha256:076ca5272e98b95bb7d97027ae04f5ee84815aaa1cf4b7063fe716030ac19c31
hostはasia.gcr.io
にした
<project_id>
はProject IDを入れる
k8sで動かしてみる
$ kubectl apply -f prime-api-pod.yaml $ kubectl get pods NAME READY STATUS RESTARTS AGE prime-api 0/1 Running 0 4s
8080で受けられるようにしているのでlocalhostにリクエストを投げれば
$ curl "localhost:8080/is_prime?2021" {"is_prime":false} $ curl "localhost:8080/is_prime?2017" {"is_prime":true} $ curl "localhost:8080/prime_less_than?100" {"prime":[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]}
とJSONが返ってくる
わーい
イメージはpublicですがめちゃめちゃpullしたりしないでくださいね><
imagePullSecretsでprivateをpullするのはまだ無理ぽい?
最初はimageをprivateにしていたので、pullするためにsecretを作成してやってみた
まずjsonキーを作って
Authentication methods | Container Registry documentation
$ kubectl create secret docker-registry gcr-reg \ --docker-server=asia.gcr.io \ --docker-username=_json_key \ --docker-email=<email> \ --docker-password=$(cat path/to/key.json)
gcr-reg
という名前でsecretを追加
<email>
にはService accountのemail
spec
に以下を追加
imagePullSecrets: - name: gcr-reg
としてapplyしてみたけど、なんかうまくいかない
error decoding response body: missing field `detail` at line 1 column 159 Caused by: missing field `detail` at line 1 column 159
みたいなエラーが出る
もうちょっと後で調べる