hnwの日記

GAE/SE PHP 7.2環境は実用性が高そうだという話

筆者の周囲だけかもしれませんが、さいきんGoogle App Engine Standard Environment(以下GAE/SE)が再注目されつつあるように思います。今回筆者もgVisorベースのGAE/SE PHP 7.2環境に触ってみたので、その内容を紹介します。

GAE/SEとは

GAE/SEは元祖PaaSとも言えるような、Googleが提供するフルマネージド環境です。以前からJavaPython、Go、PHPの4言語の環境が提供されていましたが、Go以外の言語のバージョンアップは長いこと提供されておらず、Googleの本気度に疑問を持っていた人も多かったように思います(私もその一人でした)。

ところが最近になってNode.js 8、Java 8、Python 3.7、PHP 7.2と立て続けに新バージョンを提供してきており、Googleが水面下でGAE/SEに開発リソースを投入していたことが明らかになってきました。

この急ピッチの言語提供に一役買っているのが新サンドボックス実装であるgVisorです。私のざっくりの理解ではLinuxシステムコール類をユーザーランドで提供するようなもので、既に多くのOSSが修正なしで動くような対応状況になっているようです。このgVIsorはGoでフルスクラッチ実装されており、ソースコードも公開されています。

サンドボックスのGAE/SE PHP 5.5環境とPHP 7.2環境の違い

以前のGAE/SE PHP 5.5環境を使ったことがある人は、GAEは制約が強い環境だという印象を持っているかもしれません。実際、旧サンドボックス上で動作しているPHP 5.5環境には次のような制約がありました。

  • PHP本体にかなり大きなパッチが当たっている
    • SAPI名からして「Google AppEngine PHP Runtime SAPI」と普通ではない雰囲気
  • PHPから読めるディレクトリが非常に少ない
    • 自分のデプロイしたファイルくらいしか見えない
  • PHPから書き込めるディレクトリはおそらく無い
    • ファイルを作りたい場合GCSに書く必要がある
  • コマンド実行が許可されていない
    • そもそもプロセスの概念が存在する環境なのか疑問

特にファイル操作とコマンド実行の制約が大きく、既存のPHPアプリケーションがそのまま動くとは言いがたい状況でした。

一方、PHP 7.2環境は次のような状況です。

  • 普通のPHPが動いている
    • SAPIはphp-fpm
  • PHPから全ファイルが見える
  • /tmpがtmpfsになっており、PHPから書き込める
  • コマンド実行ができる
    • /usr/bin などに置いてあるバイナリが実行可能
    • Ubuntux86_64バイナリをデプロイすると実行可能
  • わりと普通のLinux環境っぽい
    • /proc/devがある(まだ少し足りていない雰囲気)

サンドボックス環境に比べれば圧倒的に普通の環境と言えそうです。PHP 5.5時代にGAEは厳しいなーと思った人がいたとしても、今回は当時とは全然違う印象になるのではないでしょうか。

PHP 7.2環境の各種コマンドの実行結果

いくつかのコマンドを試した中から面白かったものを紹介します。

ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.3  0.2  13488  5620 ?        Ssl  17:11   0:00 serve index.php
root        14  1.0  4.2 265716 88352 ?        Ss   17:11   0:00 php-fpm: master process (/tmp/serve-361831195/php-fpm.conf)
root        15  0.8  3.0 266060 63724 ?        S    17:11   0:00 php-fpm: pool app
root        16  2.4  1.1  30132 23492 ?        Sl   17:11   0:00 caddy -quiet -conf /tmp/serve-361831195/Caddyfile
root        38  0.4  0.1  12680  3240 ?        S    17:11   0:00 sh -c ps aux 2>&1
root        39  0.4  0.2  42440  5928 ?        R    17:11   0:00 ps aux

サンドボックス環境を知っていると「psコマンドがマトモに動く!」という当たり前のことに感動してしまいますね。

PID 16番のCaddyはGo言語で書かれたWebサーバ実装で、php-fpmの前段で動いているようです。

lsof -p 16

lsofコマンドでCaddyがオープンしているファイルを確認してみました。

COMMAND PID USER   FD      TYPE DEVICE     SIZE NODE NAME
caddy    16 root  cwd   unknown                      /proc/16/cwd (readlink: No such file or directory)
caddy    16 root  rtd   unknown                      /proc/16/root (readlink: No such file or directory)
caddy    16 root  txt       REG   0,14 20099720  200 /usr/local/sbin/caddy
caddy    16 root    0u      CHR    0,0             5 /dev/null
caddy    16 root    1u     FIFO   0,12             2 host
caddy    16 root    2u     FIFO   0,12             3 host
caddy    16 root    3u     sock    0,5             5 can't identify protocol
caddy    16 root    4u     0000    0,2        0   14 anon_inode
caddy    16 root    5u     sock    0,5            24 can't identify protocol
caddy    16 root    6u     sock    0,6            23 can't identify protocol

ファイルディスクリプタ3番5番6番TCPだと思うんですが、「can't identify protocol」となっています。/proc以下の未実装部分の影響でしょう。

ちなみにlsofコマンドは標準イメージ内に無かったのでUbuntu環境から持ってきたバイナリファイルをデプロイしましたが、普通に動きました。

ifconfig

eth0      Link encap:AMPR NET/ROM  HWaddr
          inet addr:192.168.1.1  Mask:255.255.255.255
          UP RUNNING  MTU:0  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth2      Link encap:AMPR NET/ROM  HWaddr
          inet addr:169.254.8.1  Mask:255.255.255.255
          inet6 addr: fe80::c001/128 Scope:Global
          UP RUNNING  MTU:0  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:AMPR NET/ROM  HWaddr
          inet addr:127.0.0.1  Mask:255.255.255.255
          inet6 addr: ::1/128 Scope:Global
          UP RUNNING  MTU:0  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ifconfigコマンドもUbuntuから持ってきたものです。送受信パケット数がゼロなのは、現時点では未実装ということだと思います。

一部コマンドは動かない

体感値としては9割以上のコマンドがそれっぽい結果を返してくれるのですが、コマンドによっては異常終了するものもあります。

たとえばdfコマンドは未実装システムコールを呼んでいるのか「Function not implemented」というエラーが出て終了してしまいます。また、netstatを試すとサービス全体が刺さってしまい、インスタンスを再起動する羽目になりました。gVisor自体がまだ不安定なのかもしれません。

まとめ

そんなわけでGAE/SE PHP 7.2環境で色々試してみて、PHP 5.5環境よりは断然制約が少ない環境のように感じました。

これだけ普通のLinuxっぽければ言語本体の移植が早いのも不思議は無いしアプリケーションの動作もほぼ問題なしだよね、という気持ちになります*1。逆に、以前のサンドボックスがマゾすぎたとも言えそうですね…。

gVisorの開発は続いていくはずですので、その意味でも今後ますます期待できる環境だと言えそうです。

*1:たとえば既にWordPressは動いているようです