問題
リモート端末がある場合、ダイナミックDNSやらVPNやら色々設定した挙げ句、リモートとローカルのIPセグメントが同じだと(例: 192.168.0.xxx)IPがぶつかって通信できないとか、色々面倒。
プログラム的にファイルを共有するにもscp
だとなんだし、手っ取り早くdropboxでやり取りしていた。ヘッドレスなlinux側なのでotherguy/dropbox
を使ってみたが、意外とCPUを常時食う。
リモート端末への接続解決
VPNだと色々な呪縛から逃れられないので、tailscaleに変える。
リモート側はRPiだったので、直接ダウンロードに書いてあるようにそのまま入れた。
ローカル側はdocker上に構成しているので、network_mode: host
でも良いが、mosquittoをローカルでも使ってるし、mqttポートをデフォルトのままで使いたかったのでdocker上にtailscaleを置いて、そこにつなぐmosquittoブローカーを置いて、リモートからのデータを受けるようにしてみた。
richnorth/tailscaleをまんまコピー。
tailscale:
image: richnorth/tailscale:v0.99.1
volumes:
- "./tailscale/tailscale_var_lib:/var/lib" # State data will be stored in this directory
- "/dev/net/tun:/dev/net/tun" # Required for tailscale to work
cap_add: # Required for tailscale to work
- net_admin
- sys_module
command: tailscaled
$ docker-compose up -d
$ docker-compose exec tailscale tailscale up
とするとリンクが表示されるので、ログインしてこのコンテナがtailscaleのプライベートネットワークに入るようにする。volumeで/var/lib
へマウントしてるので永続化出来る。
dropboxからmqttへ
RPi側ではDropbox-Uploaderを使ってプログラム的にdropboxへファイルを送っていたが、これを止めてmqttでデータを送るようにした。
- 画像データはbase64に一回変えて文字として
- それ以外はJSONにして
本来はローカルにmqttブローカーを建てずにshiftr.ioを使って視覚化をしたかったが、publish出来るデータサイズが64KBに制限されているので諦めた(画像が300KBぐらいある)。
Enforced Limits
The client identifier length is limited to 64 characters.
The topic length is limited to 128 characters.
The topic format is limited to letters, numbers and the following special characters: .,:;-_$/+#.
The payload size of publish messages is limited to 64 KB.
The active subscriptions per connection are limited to 100.
The minimum keep alive interval is 1 second while the maximum is 5 minutes.
mosquitto:
image: eclipse-mosquitto
restart: always
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
user: "1000:1000"
network_mode: service:tailscale
network_mode: service:tailscale
としてやることでtailscaleネットワーク上で動作することになり、リモートからtailscale内のプライベートIPで1883ポートにデータが流せる。
解決したこと
- OpenVPNを除去
- ダイナミックDNSを除去
- dropboxを除去
-
otherguy/dropbox
を除去することによりCPU使用率低下(15%程度削減) - listen gem除去
以前まではdropboxでファイルがsyncした際にlistenで反応させていたが、mqttでメッセージを受け取ることをイベントと出来るので、全体がよりシンプルになった。(以前だと何にしてもファイルに落とし込んで、dropboxで同期させる必要があった)