じゃあ、おうちで学べる

思考を呼び覚ます このコードに、君は抗えるか。

sablier でコンテナのScale to zero が実現できるので覗き見だけした。

はじめに

人は強欲なのでコンテナを使っているのに必要な時必要な分だけのリソースを起動させてほしいという願いを常に持っている。Kubernetes の場合はKnativeなどを利用すれば達成できる。が今回はsablierというツールを紹介する。sablierはリバースプロキシを利用してアクセスがない時は自動的にシャットダウンしてアクセスがあれば指定のコンテナを起動することができるツールです。

sablier/hourglass.png at main · acouvreur/sablier · GitHub より

やってみる

公式サイトにはサンプルコードとして Cloud Native なアプリケーションプロキシーTraefikを用いたものが紹介されている。ブログを書いている2022年11月25日の時点でplugins配下にTraefik しかないがnginxも追加しようというIssues が上がっている。

Git Clone

Git Clone をとりあえずしてRepositoryを持ってくる。こういう時にghqでローカルリポジトリを管理するかとても悩むのですが私は検証のみを行いたい時にはghqでは管理しないことが多いです。

git clone https://github.com/acouvreur/sablier
cd sablier

docker compose up

最近、docker-compose がdocker に統合されたのでdocker-compose ではなくdocker compose を利用する。自分自身のこういうスタンス、嫌いではないです。

docker compose up -d
[+] Running 13/13
 ⠿ whoami Pulled                                                                                     6.7s
   ⠿ 29015087d73b Pull complete                                                                      0.9s
   ⠿ 0109a00d13bc Pull complete                                                                      1.2s
   ⠿ dfc0c371343c Pull complete                                                                      3.0s
 ⠿ traefik Pulled                                                                                    7.3s
   ⠿ 47517142f6ba Pull complete                                                                      2.0s
   ⠿ 24e179f025e9 Pull complete                                                                      2.3s
   ⠿ 94b59dd82910 Pull complete                                                                      5.4s
   ⠿ d3d7e56d0086 Pull complete                                                                      5.5s
 ⠿ sablier Pulled                                                                                   10.1s
   ⠿ 9b18e9b68314 Pull complete                                                                      3.0s
   ⠿ f8cfeb0e421f Pull complete                                                                      5.8s
   ⠿ 3e48bafb90b9 Pull complete                                                                      5.8s
[+] Running 3/3
 ⠿ Container sablier-sablier-1  Started                                                              0.7s
 ⠿ Container sablier-whoami-1   Started                                                              0.8s
 ⠿ Container sablier-traefik-1  Started                                                              0.8s

sablier-sablier-1,sablier-traefik-1,sablier-whoami-1 が動作していることが分かる。

docker compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
sablier-sablier-1   "/etc/sablier/sablie…"   sablier             running             10000/tcp
sablier-traefik-1   "/entrypoint.sh --ex…"   traefik             running             0.0.0.0:8080->80/tcp
sablier-whoami-1    "/whoami"                whoami              running             80/tcp

説明しておくとsablier-sablier-1 がシャットダウンさせたりしているアプリです。sablier-traefik-1 がリバースプロキシなのですがPluginの機構としてこちらがあることによってアプリケーションに変更を加えることなく機能の追加を行うことができる。典型的なサイドカーパターンですね。sablier-whoami-1 がアプリケーションの本体です。

sablier/reverse-proxy-integration.png at main · acouvreur/sablier · GitHub より

また、起動したdocker-compose の設定ファイルを読むと分かるが設定ファイルに関してdynamic-config.ymlが設定されておりアプリケーションの本体に対する設定はこちらで行われている。

version: "3.7"

services:
  traefik:
    image: traefik:2.9.1
    command:
      - --experimental.plugins.sablier.moduleName=github.com/acouvreur/sablier
      - --experimental.plugins.sablier.version=v1.1.0
      - --entryPoints.http.address=:80
      - --providers.docker=true
      - --providers.file.filename=/etc/traefik/dynamic-config.yml
    ports:
      - "8080:80"
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
      - './dynamic-config.yml:/etc/traefik/dynamic-config.yml'

  sablier:
    image: acouvreur/sablier:1.1.0
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
    labels:
      - traefik.enable=true
      # Dynamic Middleware
      - traefik.http.middlewares.dynamic.plugin.sablier.names=sablier-whoami-1
      - traefik.http.middlewares.dynamic.plugin.sablier.sablierUrl=http://sablier:10000
      - traefik.http.middlewares.dynamic.plugin.sablier.sessionDuration=1m
      - traefik.http.middlewares.dynamic.plugin.sablier.dynamic.theme=hacker-terminal
      # Blocking Middleware
      - traefik.http.middlewares.blocking.plugin.sablier.names=sablier-whoami-1
      - traefik.http.middlewares.blocking.plugin.sablier.sablierUrl=http://sablier:10000
      - traefik.http.middlewares.blocking.plugin.sablier.sessionDuration=1m
      - traefik.http.middlewares.blocking.plugin.sablier.blocking.timeout=30s

  whoami:
    image: containous/whoami:v1.5.0
    # Cannot use labels because as soon as the container is stopped, the labels are not treated by Traefik
    # The route doesn't exist anymore. Use dynamic-config.yml file instead.
    # labels:
    #  - traefik.enable
    #  - traefik.http.routers.whoami.rule=PathPrefix(`/whoami`)
    #  - traefik.http.routers.whoami.middlewares=dynamic@docker

sablier/docker-compose.yml at main · acouvreur/sablier · GitHub より

一旦、万全な状態でのアクセス確認を行う

curl http://localhost:8080/whoami/blocking
Hostname: 57f6719e2c3b
IP: 127.0.0.1
IP: 172.24.0.2
RemoteAddr: 172.24.0.4:35092
GET /whoami/blocking HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.84.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.24.0.1
X-Forwarded-Host: localhost:8080
X-Forwarded-Port: 8080
X-Forwarded-Proto: http
X-Forwarded-Server: d53703352004
X-Real-Ip: 172.24.0.1

アクセスの確認ができた。

docker compose stop

アプリケーション本体のコンテナを止める。

docker compose stop whoami
[+] Running 1/1
 ⠿ Container sablier-whoami-1  Stopped

アプリケーション本体が止まっていることを確認できました。

docker compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
sablier-sablier-1   "/etc/sablier/sablie…"   sablier             running             10000/tcp
sablier-traefik-1   "/entrypoint.sh --ex…"   traefik             running             0.0.0.0:8080->80/tcp
sablier-whoami-1    "/whoami"                whoami              exited (2)

curl http://localhost:8080/whoami/blocking

先程、と同様にエンドポイントを確認するとアクセスすることが確認できた。秒数としてどれくらい差分があるのか確認したかったが眠い。

curl http://localhost:8080/whoami/blocking
Hostname: 57f6719e2c3b
IP: 127.0.0.1
IP: 172.24.0.2
RemoteAddr: 172.24.0.4:35104
GET /whoami/blocking HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.84.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.24.0.1
X-Forwarded-Host: localhost:8080
X-Forwarded-Port: 8080
X-Forwarded-Proto: http
X-Forwarded-Server: d53703352004
X-Real-Ip: 172.24.0.1

docker compose logs でログを確認するとStarting up on port 80とシャットダウンと起動を何度か繰り返していることが確認できた。また、自主的にstop せずとも落ちていることは確認できた。Linux 側からもプロセスを確認しようと思っていたが深夜なのでもう眠い。

docker compose logs 
sablier-whoami-1   | Starting up on port 80
sablier-whoami-1   | Starting up on port 80

さいごに

あまり使わない機能が多い検証環境や開発環境で利用するにはとても良いサービスだと思った。深夜かつ飲酒によって、本来はKubernetes 環境での動作確認までしたかったのですが眠いので終わりますが一応、公開します。