task, drill, coredns を試してみた。

task

make コマンドの代替を目指している task というコマンドが存在するようなので試してみる。

https://github.com/go-task/task

軽く見た感じ、make で辛い変数化周りをきちんと整理していたり、include できるようにしてあって連携が考えられていたりと便利そう。 本当に make じゃなくてこれが普及してほしい。make は変数の受け渡しがめんどくさすぎる..。

version: '3'

tasks:
  status:
    cmds:
      - aws ec2 describe-instance-status | jq -r ".InstanceStatuses[] | select(.InstanceState.Name == \"running\") | .InstanceId" | xargs aws ec2 describe-instances --instance-id | jq -r ".Reservations[].Instances[] | [.InstanceId,.Tags[].Value,.PublicIpAddress,.PrivateIpAddress] | @csv" 
  status-onlyips:
    cmds:
      - aws ec2 describe-instance-status | jq -r ".InstanceStatuses[] | select(.InstanceState.Name == \"running\") | .InstanceId" | xargs aws ec2 describe-instances --instance-id | jq -r ".Reservations[].Instances[] | .PublicIpAddress"
  watch-status:
    cmds:
      - watch task status

includes:
  sub: ./TaskfileSub.yml

tasks 以下に上記のようにコマンドを列挙できる。便利なのは includes で include した Taskfile の task も呼び出せること。 記述していないが、include した際のタスクを実行するディレクトリも指定できるのでらくらく。

# TaskfileSub.yml
version: '3'

tasks:
  echo-os:
    deps: [echo-env]
    cmds:
      - echo {{OS}}
  echo-env:
    vars:
      VAR: abc!
      VAR2:
        sh: uuidgen
    cmds:
      - echo "environment variables"
      - echo {{.VAR}}
      - echo {{.VAR2}}
  echo-args:
    cmds:
      - echo {{.CLI_ARGS}}
$ task sub:echo-os
task: [sub:echo-env] echo "environment variables"
environment variables
task: [sub:echo-env] echo abc!
abc!
task: [sub:echo-env] echo 8BDD785D-97F1-4D84-B404-D45B054F0DED
8BDD785D-97F1-4D84-B404-D45B054F0DED
task: [sub:echo-os] echo darwin
darwin

$ task sub:echo-args -- this is passed from args
task: [sub:echo-args] echo this is passed from args
this is passed from args

かなり便利。自前で使っている Makefile 全部これで書き直します...。

drill

JMeter の置き換えを目指す rust 製の負荷計測ツール。軽く README を見たところでは、簡単な yaml を記述するだけで柔軟なシナリオを記述可能で非常に良さそう。

https://github.com/fcsonline/drill

https://httpbin.org/ を対象にやってみる。

concurrency: 3
base: 'https://httpbin.org/'
iterations: 3
rampup: 3

plan:
  - name: basic auth
    request:
      url: /basic-auth/k-jun/password
      headers:
        Authorization: 'Basic ay1qdW46cGFzc3dvcmQ='
      assign: basicauth
  - name: post todo
    request:
      url: /post
      method: POST
      headers:
        Content-Type: 'application/json'
      body: '{"id": "2aa068b7-890d-341c-970f-e75ed5e152d1", "title": "facilis", "body": "Reprehenderit tenetur qui sunt. Consequatur possimus soluta nihil est velit hic maiores. Placeat at voluptatem deserunt laudantium maxime rerum illo."}'
    assign: createdTodo
  - name: get todo
    request:
      url: /get?id={{ createdTodo.body.json.id }}
  - name: put todo
    request:
      url: /put
      method: PUT
      headers:
        Content-Type: 'application/json'
      body: '{"id": "{{ createdTodo.body.json.id  }}", "title": "iusto"}'
    assign: updatedTodo
  - name: delete todo
    request:
      url: /delete?id={{ updatedTodo.body.json.id }}
      method: DELETE
$ drill --benchmark benchmark.yml --stats
Concurrency 3
Iterations 3
Rampup 3
Base URL https://httpbin.org/

basic auth                https://httpbin.org//basic-auth/k-jun/password 200 OK 1026ms
basic auth                https://httpbin.org//basic-auth/k-jun/password 200 OK 214ms
post todo                 https://httpbin.org//post 200 OK 377ms
post todo                 https://httpbin.org//post 200 OK 375ms
get todo                  https://httpbin.org//get?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 377ms
get todo                  https://httpbin.org//get?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 346ms
put todo                  https://httpbin.org//put 200 OK 192ms
put todo                  https://httpbin.org//put 200 OK 179ms
delete todo               https://httpbin.org//delete?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 189ms
basic auth                https://httpbin.org//basic-auth/k-jun/password 200 OK 182ms
delete todo               https://httpbin.org//delete?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 177ms
post todo                 https://httpbin.org//post 200 OK 183ms
get todo                  https://httpbin.org//get?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 183ms
put todo                  https://httpbin.org//put 200 OK 183ms
delete todo               https://httpbin.org//delete?id=2aa068b7-890d-341c-970f-e75ed5e152d1 200 OK 182ms

basic auth                Total requests            3
basic auth                Successful requests       3
basic auth                Failed requests           0
basic auth                Median time per request   649ms
basic auth                Average time per request  492ms
basic auth                Sample standard deviation 402ms

post todo                 Total requests            3
post todo                 Successful requests       3
post todo                 Failed requests           0
post todo                 Median time per request   368ms
post todo                 Average time per request  304ms
post todo                 Sample standard deviation 89ms

get todo                  Total requests            3
get todo                  Successful requests       3
get todo                  Failed requests           0
get todo                  Median time per request   365ms
get todo                  Average time per request  303ms
get todo                  Sample standard deviation 88ms

put todo                  Total requests            3
put todo                  Successful requests       3
put todo                  Failed requests           0
put todo                  Median time per request   312ms
put todo                  Average time per request  268ms
put todo                  Sample standard deviation 122ms

delete todo               Total requests            3
delete todo               Successful requests       3
delete todo               Failed requests           0
delete todo               Median time per request   185ms
delete todo               Average time per request  182ms
delete todo               Sample standard deviation 4ms

Time taken for tests      2.9 seconds
Total requests            15
Successful requests       15
Failed requests           0
Requests per second       5.18 [#/sec]
Median time per request   213ms
Average time per request  310ms
Sample standard deviation 221ms

認証情報も受け渡せるし良い感じ。繰り返して実行する際に、変数展開みたいにある程度値のばらつきをもたせる仕組みは考えないと行けない気がするがそれでもかなり柔軟。 DELETE は body がつけられないなぁ.. と思っていたらどうもつけられないのが正しいらしい...。

しかし便利だ。頑張って Vegeta とか使っていたのがアホらしい。

coredns

CoreDNS is a Cloud Native Computing Foundation graduated project.

とのことなのでかなり期待できる dns

https://github.com/coredns/coredns

UDP/TCP/https2/gRPC と一通り対応していそう。バックエンドには etcd が使用されているらしい。

brew install coredns

以下のように設定してあげると、静的な host 名の解決ができることを確認。

$ cat Corefile
k-jun.com {
    cache
    errors
    log
    reload

    hosts {
        10.0.0.1 k-jun.com
        fallthrough
    }

    forward . 8.8.8.8:53
}

. {
    cache
    forward . 8.8.8.8:53
}

~/source-code master* ⇣
$ coredns -dns.port=1053 --conf ./Corefile
.:1053
k-jun.com.:1053
[INFO] plugin/reload: Running configuration MD5 = 8dd98d1755651542d41665b2292a4365
CoreDNS-1.8.4
darwin/amd64, go1.16.4,
[INFO] [::1]:59783 - 42716 "A IN k-jun.com. udp 38 false 4096" NOERROR qr,aa,rd 52 0.000108431s
$ dig @localhost k-jun.com -p 1053 +short
10.0.0.1

どうやら etcd という KVS と連携すると動的な 名前解決ができるようになるようなのでこれも試してみる。 まずは etcd を用意。

$ etcd
{"level":"info","ts":"2021-08-09T17:03:04.210+0900","caller":"etcdmain/etcd.go:72","msg":"Running: ","args":["etcd"]}
{"level":"info","ts":"2021-08-09T17:03:04.210+0900","caller":"etcdmain/etcd.go:99","msg":"failed to detect default host","error":"default host not supported on darwin_amd64"}
{"level":"warn","ts":"2021-08-09T17:03:04.210+0900","caller":"etcdmain/etcd.go:104","msg":"'data-dir' was empty; using default","data-dir":"default.etcd"}
...

$ etcdctl put /com/k-jun/1 '{"host": "10.0.0.1", "ttl": 60}'
OK
$ etcdctl put /com/k-jun/2 '{"host": "10.0.0.2", "ttl": 60}'
OK
$ etcdctl put /com/k-jun/3 '{"host": "10.0.0.3", "ttl": 60}'
OK

設定を入れて、名前解決してみると。

k-jun.com {
    cache 60
    errors
    log
    reload

    etcd {
        path /
        endpoint http://127.0.0.1:2379
        fallthrough
    }

    forward . 8.8.8.8:53
}

. {
    cache
    forward . 8.8.8.8:53
}

いい感じにできる。

$ dig @localhost k-jun.com -p 1053 +short
10.0.0.1
10.0.0.2
10.0.0.3

A レコードだけでなく SRV レコードもいけるらしいのでやってみる。

$ etcdctl put /com/k-jun/srv/1 '{"host": "one.k-jun", "ttl": 60, "priority": 10, "port": 8080}'
OK
$ etcdctl put /com/k-jun/srv/2 '{"host": "two.k-jun", "ttl": 60, "priority": 20, "port": 8080}'
OK
$ etcdctl put /com/k-jun/srv/3 '{"host": "three.k-jun", "ttl": 60, "priority": 30, "port": 8080}'
OK

$ dig @localhost srv.k-jun.com SRV -p 1053 +short
10 100 8080 one.k-jun.
20 100 8080 two.k-jun.
30 100 8080 three.k-jun.

おおお!! これは面白い! 内部的な DNS サーバーを構築する必要があるときにめちゃくちゃ便利そう。