全 Cloud Resource を PostgreSQL に ! CloudQuery を試してみる。
こんにちは k-jun です。今回はパブリッククラウドに存在するリソースを全てレコード化して SQL で検索できるようにする CloudQuery を試してみます。
https://github.com/cloudquery/cloudquery
README.md を見た感じは、PostgreSQL を用意してコマンドを実行するだけみたいですね。ユースケースは正直全く思いついていませんが、列挙できるのは意外と便利かもしれません。
Setup
$ brew install cloudquery/tap/cloudquery $ cloudquery init aws
生成された設定ファイルを見てみると、PostgreSQL の接続情報が書かれています。ということで、これと同じ接続情報で PostgreSQL を起動していきます。
$ cat config.hcl ... connection { dsn = "host=localhost user=postgres password=pass database=postgres port=5432 sslmode=disable" } ...
$ docker run -p 5432:5432 -e POSTGRES_PASSWORD=pass -d postgres
Run
満を持して fetch を実行してみるも失敗している様子。
$ cloudquery fetch Provider fetch complete. Provider aws fetch summary: ✓ Total Resources fetched: 5 ⚠️ Warnings: 0 ❌ Errors: 203
調べるとファイルオープンの上限に引っかかっていたようなので調査して解消。
https://discussions.apple.com/thread/251000125
$ cloudquery fetch ... Provider aws fetch summary: ✓ Total Resources fetched: 2 ⚠️ Warnings: 0 ❌ Errors: 0
良さそう。PostgreSQL の中身を見てみる。
EC2 だけでもこれだけテーブルが作成されている...! すごい...! MySQL も対応していたら、業務導入をよりかんたんに検討できるかもしれないのになぁ...。
postgres=# SELECT * FROM aws_ec2_instances; -[ RECORD 1 ]--------------------------------------+------------------------------------------------------- cq_id | 964684cc-xxxx-xxxx-xxxx-250dac7de772 meta | {"last_updated": "2021-11-27T05:31:30Z"} account_id | 9367844xxxxx region | ap-northeast-1 id | i-0f7141eff3f2xxxxx ami_launch_index | 0 architecture | x86_64 capacity_reservation_id | cap_reservation_preference | open cap_reservation_target_capacity_reservation_id | cap_reservation_target_capacity_reservation_rg_arn | client_token | cpu_options_core_count | 1 cpu_options_threads_per_core | 1 ebs_optimized | f ena_support | t enclave_options_enabled | f hibernation_options_configured | f hypervisor | xen iam_instance_profile_arn | iam_instance_profile_id | image_id | ami-02d36247c5bc58c23 instance_lifecycle | instance_type | t2.micro kernel_id | key_name | k-jun ...
レコードの中身を見てみたけれども、本当に全列挙という感じで情報が全部入っている。これはなかなかすごいぞ...! Cloud Config なんて使用しなくてもいい感じにリソースの監視ができるかもしれない。良さげ。
ということで今回はこのへんで。
GraphQL + NewSQL!? FaunaDB を試してみる。
こんにちは k-jun です。今回は Spanner の論文から派生した NewSQL の一種 FaunaDB を試してみたいと思います。
どうやら、DB 自体は OSS ではないようですね。DB という主要コンポーネントを特定のベンダーに頼る点は結構マイナスですがやっていきます。 せっかく Spanner から派生しているのになんだかもったいないですね。
Setup
サインアップ後のダッシュボードはこんな感じ。データベースを作っていきます。
サンプルのデータを突っ込んだ状態でデータベースを作成しました。中身がダッシュボードからでも確認できるようで、Json らしきものが確認できます。 インデックスの仕組みもあるようで、他の DB 同様に肝となる箇所です。
ドキュメントを参照する限りではインデックスは作り放題みたいに書いてありますが、本当かしら。
you can have hundreds of indexes without affecting overall performance.
FQL と呼ばれる軽いデータ整形関数を DB にて記述できるようです。MySQL での Function なんかに相当するものでしょうか。かゆいところに手が届くといいですね。
Run
ではでは、実際に Query を発行して取得結果を見ていきます。
この Paginate 関数はやばいですね。ページネーションはアンチパターンがあったりといろいろとめんどくさいですし。これ、MySQL にも欲しいなー。
これも表現のレベルが高度。Paginate の 結果を key としてその詳細情報を取ってきて関数に渡しているようですね。かなり面白いです。
GraphQL の Interface 経由でアクセスできることも見ていきます。リンクはこれ。
データベースを作成。
スキーマを GraphQL 形式で記述していきます。
$ cat ~/Desktop/schema.gql type Todo { title: String! completed: Boolean } type Query { allTodos: [Todo!] todosByCompletedFlag(completed: Boolean!): [Todo!] }
作成したスキーマを食わせたところ、見知った画面が開きましたね。
mutation で document も生成できていそうです。
使い勝手は完全に GraphQL ですね。チュートリアルを実行した限りでは、NewSQL の何たるかが全く伝わってこなかったので少し調べてみます。
https://docs.fauna.com/fauna/current/comparisons/compare-faunadb-vs-dynamodb
DynamoDB との比較記事があったのでざっと読みましたが、以下以外に特徴はなさそうだと感じました。
- GraphQL の Interface をサポートしている
- Index へのデータタイプが制限されず柔軟
- ACID トランザクションをサポート
比べるべきは Spanner などであって、DynamoDB ではないはずですね。ここらへん のスター数も微妙ですし、OSS でないことも相まってそこまで活発的ではないのかもしれません。 TiDB や、CockroachDB の利点の一つにベンダーロックインされる Aurora, Spanner と違って、OSS ってのがあるのでやっぱり重要ですよね...。スケールするのかどうかも微妙。
それでは今回はこの辺で。
実行は Terminal で結果は Web から!benchmark ツール plow で遊んでみる。
こんにちは k-jun です。今回は星の数ほどあるベンチマークツールの一つ plow を試してみます。
https://github.com/six-ddc/plow
特徴として結果がブラウザで閲覧できるというのをあげており、その点はたしかに便利そうです。
Setup
$ brew install plow
Run
ヘルプはこんな感じ。
$ plow --help usage: plow [<flags>] <url> A high-performance HTTP benchmarking tool with real-time web UI and terminal displaying Examples: plow http://127.0.0.1:8080/ -c 20 -n 100000 plow https://httpbin.org/post -c 20 -d 5m --body @file.json -T 'application/json' -m POST Flags: --help Show context-sensitive help. -c, --concurrency=1 Number of connections to run concurrently -n, --requests=-1 Number of requests to run -d, --duration=DURATION Duration of test, examples: -d 10s -d 3m -i, --interval=200ms Print snapshot result every interval, use 0 to print once at the end --seconds Use seconds as time unit to print --body=BODY HTTP request body, if start the body with @, the rest should be a filename to read --stream Specify whether to stream file specified by '--body @file' using chunked encoding or to read into memory -m, --method="GET" HTTP method -H, --header=K:V ... Custom HTTP headers --host=HOST Host header -T, --content=CONTENT Content-Type header --cert=CERT Path to the client's TLS Certificate --key=KEY Path to the client's TLS Certificate Private Key -k, --insecure Controls whether a client verifies the server's certificate chain and host name --listen=":18888" Listen addr to serve Web UI --timeout=DURATION Timeout for each http request --dial-timeout=DURATION Timeout for dial addr --req-timeout=DURATION Timeout for full request writing --resp-timeout=DURATION Timeout for full response reading --socks5=ip:port Socks5 proxy --auto-open-browser Specify whether auto open browser to show Web charts --version Show application version. Flags default values also read from env PLOW_SOME_FLAG, such as PLOW_TIMEOUT=5s equals to --timeout=5s Args: <url> request url
今回は、actix-web にご協力を頂きます。localhost:8088 で起動して、いざ尋常に勝負。
$ plow http://localhost:8088/ Benchmarking http://localhost:8088/ using 1 connection(s). @ Real-time charts is listening on http://[::]:18888 Summary: Elapsed 45.4s Count 317111 2xx 317111 RPS 6984.779 Reads 0.859MB/s Writes 0.386MB/s Statistics Min Mean StdDev Max Latency 117µs 141µs 32µs 6.059ms RPS 6430.9 6981.28 192.46 7248.04 Latency Percentile: P50 P75 P90 P95 P99 P99.9 P99.99 130µs 145µs 164µs 187µs 249µs 530µs 774µs Latency Histogram: 139µs 307060 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 182µs 8300 ■ 253µs 1317 376µs 294 556µs 102 694µs 28 1.104ms 4 1.416ms 6
なんかいい感じ。並列度を変更して実験してみる。
$ plow http://localhost:8088/ -c 100 Benchmarking http://localhost:8088/ using 100 connection(s). @ Real-time charts is listening on http://[::]:18888 Summary: Elapsed 16.2s Count 709390 2xx 709390 RPS 43788.941 Reads 5.387MB/s Writes 2.422MB/s Statistics Min Mean StdDev Max Latency 260µs 2.281ms 1.972ms 57.008ms RPS 38219.68 43751.67 4139.92 51467.19 Latency Percentile: P50 P75 P90 P95 P99 P99.9 P99.99 1.601ms 2.358ms 3.859ms 5.497ms 10.98ms 20.886ms 33.886ms Latency Histogram: 2.181ms 692236 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 5.123ms 14863 ■ 12.634ms 2101 23.926ms 109 31.328ms 51 39.959ms 7 48.915ms 2 54.739ms 21
他のツールと比較してもヌルヌル動くバーがあるので使用していて楽しいですね。そして、並列度 100 で 40k RPS を達成する actix-web のヤバさよ...。 ではでは、ブラウザに表示してみます。
$ plow http://localhost:8088/ -c 100 --listen :18888
良い感じにグラフ表示ができました。やはりグラフ化は良いですね。情報量が一気に増えます。40k RPS が達成されていたのは最初の方だけで時間とともに低下。 30k 程度で落ち着きました。
ベンチマークツールは wrk がお気に入りだったのですが、この plow も良さそうです。グラフを簡単に作成できるところは 単純で純粋な強みですね。 wrk も比較で試してみました。wrk のほうがやっぱり性能は良さそうですが、情報量の少なさにびっくりですね。時系列のグラフデータがいかに偉大化が分かります。
$ wrk -d 60 -t 6 -c 100 http://127.0.0.1:8088 Running 1m test @ http://127.0.0.1:8088 6 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 2.44ms 2.18ms 61.88ms 91.17% Req/Sec 7.48k 1.37k 11.15k 69.83% 2678038 requests in 1.00m, 329.46MB read Requests/sec: 44631.71 Transfer/sec: 5.49MB
グラフ化が正義なので、plow のほうが良さそうに思えてきました。急所だけ wrk を使うようにしようと思います。それでは今回はこのへんで。
Kubernetes のサービスメッシュツール Istio を試してみる。
こんにちは k-jun です。今回は Kubernetes 環境などで名前解決、サービスメッシュに使用される istio を試してみます。
https://github.com/istio/istio
最近良く名前を聞くなぁぐらいでやってみることにしましたが、結構難しそうですね。README.md を参照すると、Istio は以下の2つで構成されているようです。
- Envoy - Sidecar proxies per microservice to handle ingress/egress traffic between services in the cluster and from a service to external services.
こちらはサービスメッシュを担当する Proxy の Envoy さんですね。サイドカーとしてくっついてくれるようです。
- Istiod - The Istio control plane. It provides service discovery, configuration and certificate management
Istio のコントロールプレーンであり、サービスディスカバリを担当します。
Setup
ドキュメントを参照すると、良さげなチュートリアルを見つけたのでこちらを参考に試してみることにします。
https://istio.io/latest/docs/setup/getting-started/
$ curl -L https://istio.io/downloadIstio | sh - $ cd istio-1.11.4 $ export PATH=$PWD/bin:$PATH $ istioctl install --set profile=demo -y ✔ Istio core installed ✔ Istiod installed ✔ Ingress gateways installed ✔ Egress gateways installed ✔ Installation complete Thank you for installing Istio 1.11. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/kWULBRjUv7hHci7T6
kubectl コマンド経由で namespace を追加し、デプロイまで行ってしまいます。
$ kubectl label namespace default istio-injection=enabled namespace/default labeled $ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
諸々見てみますが、良さそうです。
$ kubectl get pods NAME READY STATUS RESTARTS AGE details-v1-79f774bdb9-8jkwg 2/2 Running 0 20m productpage-v1-6b746f74dc-j8bp4 2/2 Running 0 20m ratings-v1-b6994bb9-kjnk2 2/2 Running 0 20m reviews-v1-545db77b95-lms4f 2/2 Running 0 20m reviews-v2-7bf8c9648f-642rr 2/2 Running 0 20m reviews-v3-84779c7bbc-24p5k 2/2 Running 0 20m $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.24.7.179 <none> 9080/TCP 20m kubernetes ClusterIP 10.24.0.1 <none> 443/TCP 28m productpage ClusterIP 10.24.12.121 <none> 9080/TCP 20m ratings ClusterIP 10.24.10.233 <none> 9080/TCP 20m reviews ClusterIP 10.24.12.68 <none> 9080/TCP 20m $ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>" <title>Simple Bookstore App</title>
ここからが istio の出番です。現在外部公開されていないサービスを外部に公開していきます。このためにサービスメッシュの入り口を Istio Ingress Gateway を用いて公開していきます。
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml gateway.networking.istio.io/bookinfo-gateway created virtualservice.networking.istio.io/bookinfo created $ kubectl get svc istio-ingressgateway -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.24.1.213 34.121.233.158 15021:30454/TCP,80:32232/TCP,443:30434/TCP,31400:32235/TCP,15443:31426/TCP 39m
サービスにアクセスするために External IP を利用して環境変数を設定していきます。
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}') $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}' $ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT $ echo "$GATEWAY_URL" 34.121.233.158:80
大丈夫そうですね。ではいよいよダッシュボードをデプロイしてサービスメッシュ経由で接続してみます。
$ kubectl apply -f samples/addons $ kubectl rollout status deployment/kiali -n istio-system $ istioctl dashboard kiali
良い感じにダッシュボードが見れました。チュートリアルに従っただけですので、正直何もわかっていませんが Istio で何ができそうかということだけでもわかって面白かったです。 それでは今回はこのへんで。
Rust でフロントエンド開発!? Yew を試してみた。
こんにちは k-jun です。今回は、Rust 製のフロントエンドフレームワーク Yew を試してみます。
https://github.com/yewstack/yew
WebAssembly によるモダンな開発体験が魅力のようです。色々なところで Rust の名前を聞くことが増えてきました。 Javascript のように、果ては サーバーからモバイルまでどこでも Rust が使えるかもしれませんね。
Setup
サンプルコード を発見したので、ひとまずコレを動かしてみます。
$ git clone https://github.com/yewstack/yew-wasm-pack-minimal $ cd yew-wasm-pack-minimal $ cargo install wasm-pack $ wasm-pack build --target web ... [INFO]: 📦 Your wasm pkg is ready to publish at /Users/k-jun/source-code/yew-wasm-pack-minimal/pkg.
何やらファイルが、./pkg 以下に吐かれました。tree でディレクトリ構造を見てみると、wasm と js が生成されているようですね。
$ tree ./pkg ./pkg ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── package.json ├── yew_wasm_pack_minimal.d.ts ├── yew_wasm_pack_minimal.js ├── yew_wasm_pack_minimal_bg.wasm └── yew_wasm_pack_minimal_bg.wasm.d.ts
では、次に rollup コマンドでバンドルしていきます。rollup が入っていなかったので、ついでにインストールしました。
$ npm install -g rollup $ rollup ./main.js --format iife --file ./pkg/bundle.js ./main.js → ./pkg/bundle.js... created ./pkg/bundle.js in 79ms
python で適当なファイルサーバーを立ち上げて中身を見てみます。
ただの hello world じゃん。本当に動いているのだろうか... と思いましたが、以下のファイルをもとに Rendering がなされているようです。
https://github.com/yewstack/yew-wasm-pack-minimal/blob/master/src/app.rs
ということで、あとはこのファイルの編集方法さえわかればなんとかなりそうです。
https://yew.rs/ja/getting-started/build-a-sample-app
さっきより少しだけ複雑な記述内容を見つけたので、これで試してみます。
カウンターが爆誕しました...! 思ったよりフロントエンドっぽくて開発できそうでした。React というよりは、Unity に近い...? ということで、結構面白かったです。それでは今回はこのへんで。
Container 専用のデプロイツール Waypoint を試してみる。
こんにちは k-jun です。今回は、HashiCorp が開発している デプロイツール Waypoint を試してみようと思います。
https://github.com/hashicorp/waypoint
AWS、GCP、Azure、Kubernetes 果ては Nomad までの Deploy を管理できるツールのようですが、果たして。
Setup
こちら を参考にインストールしていきます。
$ brew tap hashicorp/tap
$ brew install hashicorp/tap/waypoint
$ which waypoint
/usr/local/bin/waypoint
Run
こちら を参考に、まずは簡単なものから試してみます。
$ waypoint install -platform=docker -accept-tos
お試しで使えるアプリケーションがあるようなので、コチラを clone します。
$ git clone https://github.com/hashicorp/waypoint-examples.git
$ cd waypoint-examples/docker/nodejs
では、waypoint コマンド経由で起動してみます。
$ waypoint init $ waypoint up » Building example-nodejs... Creating new buildpack-based image using builder: heroku/buildpacks:20 Creating new buildpack-based image using builder: heroku/buildpacks:20 ✓ Creating pack client ✓ Building image │ [exporter] Adding layer 'process-types' │ [exporter] Adding label 'io.buildpacks.lifecycle.metadata' │ [exporter] Adding label 'io.buildpacks.build.metadata' │ [exporter] Adding label 'io.buildpacks.project.metadata' │ [exporter] Setting default process type 'web' │ [exporter] Saving example-nodejs... │ [exporter] *** Images (22264e01b316): │ [exporter] example-nodejs │ [exporter] Adding cache layer 'heroku/nodejs-engine:nodejs' │ [exporter] Adding cache layer 'heroku/nodejs-engine:toolbox' ✓ Injecting entrypoint binary to image Generated new Docker image: example-nodejs:latest » Deploying example-nodejs... ✓ Setting up network... ✓ Starting container ✓ App deployed as container: example-nodejs-01FKKF3P7J70A8PKMWFYQE50W6 ✓ Docker image "example-nodejs:latest" up to date! ✓ Finished building report for Docker platform ✓ Finished building report for Docker network resource ✓ Finished building report for Docker container resource ✓ All 2 resources are reporting READY » Releasing example-nodejs... No release phase specified, skipping... The deploy was successful! A Waypoint deployment URL is shown below. This can be used internally to check your deployment and is not meant for external traffic. You can manage this hostname using "waypoint hostname." URL: https://promptly-divine-peacock.waypoint.run Deployment URL: https://promptly-divine-peacock--v1.waypoint.run[f:id:K-jun1221:20211104025742p:plain]
docker ps で確認すると container が確認できるので、 ローカルで起動していることは間違いなさそうです。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0e7944d22fe6 example-nodejs:latest "/waypoint-entrypoin…" 2 minutes ago Up 2 minutes 0.0.0.0:55000->3000/tcp example-nodejs-01FKKF3P7J70A8PKMWFYQE50W6 845eebe4dc0c hashicorp/waypoint:latest "/usr/bin/waypoint r…" 8 minutes ago Up 8 minutes waypoint-runner 816957fab970 hashicorp/waypoint:latest "/usr/bin/waypoint s…" 8 minutes ago Up 8 minutes 0.0.0.0:9701-9702->9701-9702/tcp waypoint-server
では、destroy でもとに戻して他の機能も試してみます。
$ waypoint destroy -auto-approve
ここ を参照すると、Deploy 先の選択肢としては Lambda, ECS, Cloud Run が今の所あるようですね。 Kubernetes や Nomad もできるようですが、ここらへんは群雄割拠ですので今回は Cloud Run に Deploy してみようと思います。
ということで、ここ に従っていく。
$ git clone https://github.com/hashicorp/waypoint-examples.git
$ cd waypoint-examples/gcp/google-cloud-run/nodejs
デプロイする GCP の プロジェクトID を設定する。gcloud も必要になるようなので、存在しない場合は適宜インストールと設定を。 今回自分も諸々の設定が足りていなかったので以下のようにコマンドを実行。
$ sed -i -e 's/<my-project-id>/<YOUR_GCP_ID>/g' waypoint.hcl $ gcloud services enable containerregistry.googleapis.com $ gcloud auth configure-docker
$ waypoint init $ waypoint up ... » Releasing example-nodejs... The deploy was successful! A Waypoint deployment URL is shown below. This can be used internally to check your deployment and is not meant for external traffic. You can manage this hostname using "waypoint hostname." Release URL: https://example-nodejs-6nrl32uqta-ue.a.run.app
良い感じにデプロイが完了したようです。コンソールから確認した限りでも大丈夫そうです。設定ファイルの中身を見ても簡単そうですし、イメージの Build と Push も自動でやってくれて便利そうです。 Waypoint 結構便利ですね。それでは今回はこのへんで。
Rust 製の JS 管理ツール VOLTA を使ってみた。
こんにちは k-jun です。今回は、JavaScript 製の cli なんかの管理ツール VOLTA を使ってみます。
https://github.com/volta-cli/volta
npm、yarn あたりがよく言われているのは install が遅いという点ですね...。これが Rust 製にしたことでもしかしたら解決するかも...? 一縷の望みをかけて使ってみます。
Setup
以下手順に従ってインストールして行きます。
https://docs.volta.sh/guide/getting-started
$ curl https://get.volta.sh | bash $ which volta /Users/k-jun/.volta/bin/volta
Run
それでは使ってみましょう。ディレクトリを検知して自動で参照する package の version を変えてくれるらしいのでやってみます。 例えば、
$ pwd /tmp/a $ volta install node@16.13.0 $ node -v v16.12.0
と
$ pwd /tmp/b $ volta install node@16.12.0 $ node -v v16.12.0
え、だめじゃん。どうやら、volta pin なるものを打たないと行けないらしい。コレによって、package.json に以下の値が挿入され version の固定ができるみたい。
{ ... "volta": { "node": "16.12.0" } }
うーん。package.json の engine で良くないか。正直いらん。他 サブコマンドもざっと漁ってもめぼしいものは無し。
$ volta --help ... SUBCOMMANDS: fetch Fetches a tool to the local machine install Installs a tool in your toolchain uninstall Uninstalls a tool from your toolchain pin Pins your project's runtime or package manager list Displays the current toolchain completions Generates Volta completions which Locates the actual binary that will be called by Volta setup Enables Volta for the current user / shell run Run a command with custom Node, npm, and/or Yarn versions help Prints this message or the help of the given subcommand(s)
ということで、自分は使う意味を見いだせませんでした。有効な使用方法を知っている人は教えて下さい... ( )。 それでは今回はこのへんで。