Process ExporterとTreemap for Grafanaでプロセスごとのメモリ使用量をざっくり可視化する
タイトルまま。 いい加減Grafana力を高めようと最近Grafonnetに入門し、Process Exporterをソースとした有益なダッシュボードを作りたいなーとあれこれ試していた過程でTreemapプラグインを発見し、Datadogで以前みかけたメモリマップみたいなビュー作ったら良さそうだなーということで作ってみた。
環境
Process Exporterは2環境で動かしていてOSはそれぞれUbuntu xenial、bionic
- Grafana 7.2.0
- Treemap plugin 0.5.0
- process-exporter 0.7.5
Process Exporterの設定
Process Exporterの設定はちょっと癖のある感じだが、どの単位でグルーピングしたいか?を定義して上から順に試行してマッチしたところにまとめられる、みたいな動作だと思っている。
のでこれはまとめたいみたいなものを上の方に条件として書いていき、最後にどこにもマッチしなかったら実行ユーザー単位でまとめるみたいな設定を書いている。
process_names: - comm: - php-fpm7.2 - mysqld - memcached - apache2 - name: "exporters" cmdline: - '/usr/local/bin/.+[_-]exporter' - name: "{{.Username}} processes" cmdline: - '.+'
exporter系はまとめたいなーとかそういう扱いをしているが、とりあえず実行ユーザー単位でまとめておけばカーディナリティも爆発せず割と推測できるレベルにまとまるのであまりがんばらなくてもいいんじゃないかと思う(ubuntuのデフォ環境だったらwww-dataだったらapacheの子プロセスだよねーとか)。
process exporterでまとまった結果はプロセス数もメトリクスとして持っているので、たとえば「長期的にapacheの1プロセスあたりが使うメモリが増えてきている」みたいな傾向をみたりするのにも使えるのでうまく使えばベンリなんでないかと。
グラフの定義
ダッシュボードが二個混在していて分かりづらいですがこんな感じで。 Treemapはtextとnumericの値をもったtable的な構造を期待しているので、Rangeとしての結果ではなくInstantオプションを指定して最新の値のみを使うように。
↑はgrezzlyでapplyすることを前提にしているのでいちおう出力結果のjsonはこんな感じ。
2021/2/14 追記
ある程度汎用的に定義しなおしてgrafana.comの方にあげてみました
2020
特に技術的な話でもないやつ、あまりに書く意味あるのみたいなことを書くのもどうかという気持ちになるくらいおっさんになったものの、まあなんかたまにはええやろというのと、そもそもかつてインターネッツはそういうところだったよね、という気分になったのでやる気があるうちに書いておくメモ。
SRE NEXT
人生初登壇、というわけではないのだけど「初proposal出して通ってお話したやつ」ということで結構個人的に頑張ったなあというやつ。
イベント自体も非常によかったしこれ本当に翌月以降の状況をみるにできていてよかったですねーーと思わざるを得ない。
懇親会も含め非常に体験がよかったので、次回というものがあるのか、どういう形になるのか、というか運営の皆様マジお疲れ様ですと思いつつ機会があるのならばぜひ参加したいイベント。
ちょうど人はなぜ登壇するのかみたいな話があがっていたりいなかったりするようですが、これに関しては結構思うところがあり「SREは盛り上がってるしSRE本で紹介されているプラクティスは素晴らしいが他方これは基本的にGoogleの話であり、規模もサービスの性質も異なる我々は実際どのようにこのプラクティスを自組織に適用していったり、あるいはしなかったりしているのかがみんな知りたいんじゃないの?というか自分はめっちゃ知りたいんだが・・」ということでGoogleが提示する理想と現実の我々、みたいなところをお話し、自分としては各組織感の差分を知っていきたいみたいなモチベーションで内容を考えてproposalを出すに至ったというところでした(ので内容もなるべくこういうプラクティスではあるけどうちはこうやったよみたいなところを意識してスライドを作った、つもり)。
個人的に反省点はめっちゃあり、人はおっさんになってもこんなに緊張するんかというくらい緊張したし、当初時間の少ない枠を選択し、時間に対しこれくらいの内容を提示できれば良いという方向で考えていたもののいざスライドを作っていくと連鎖的に説明が必要になる内容が増え、結果的にだいぶ駆け足になってしまい聞き苦しかったのではないかーーすいませんというところが非常にはい。
次登壇の機会があればこのあたりもっとペース配分考えてうまく作っていきたい。
英語
2018年のre:invent、2019年のSREcon19 Americasと続けて海外カンファレンスに参戦する機会があり、どちらもそれなりに良い体験であったもの、セッションをもうちょい自然に聞き取れるようになりたいなーということで人生において割と最高潮に高まっていたところ、リモートワーク環境も整ったというのもあり5月からレアジョブでオンライン英会話を開始した。 一回あたりのレッスン費用を考えると大変お安いのだが生来の貧乏性と半ば意地もありオフィシャルな休校日を除き開始から毎日継続している。基本カレンダー抑えて、超絶難しい教材を選択しない限りは会話、たのしい、くらいなのでそんなに頑張っているという感じではないがとはいえ予定があったりお酒飲みたかったりしたりする日もあるので調整しつつ継続している感じで。 出社がなくなり単に家族以外と話をする機会をもつ、という意味においてもまあ良いんじゃないかと思っている、微妙な英語力でもアニメの話したり、興味のある話をするのはまあまあたのしい。
9月頃TOEICのオンライン公開模試があって試しに家でやってみたところ800前後のまあまあよさげなスコアが取れたので、これはまあ少なくとも下がることはないだろうということで、会場の抽選にもあたったので実に16年ぶりくらいにTOEICを受けスコアを更新した。680->800ちょいくらい。
海外カンファレンスがオンライン開催になって参加しやすくのでeBPF Summit 2020、SREcon20 Americasはリアタイ参戦してみたが、レベル的には幾分ましにはなったもののやはりスピードがはやく抽象的な話に寄ってるものは厳しく、結局語彙の不足と英語発音が単純に聞き分けできてないってことで聞き分けとスピードの方は発音がーという一周まわってまあ地道にやるしかないですよねえ、ということで。
レッスンでも語彙が増えないわけではないのだけど、まあ会話だけしてても急に伸びたりはしないよねーという当たり前の話なので覚悟を決めて発音の訓練をやらんとなあ・・という結論になって終わった2020、でした、ね。ということで引き続き地味にやっていき。
技術方面
eBPF関連がたのしくBPF Performance Toolsを会社のみなさまの力を借りつつ読みすすめたりしつつ、特に現在語られる文脈とはやや違うものの、Brendan Gregg氏のいうプロダクション向けの継続的なSuperpowerなObservabilityツールとして有益な意思決定につなげる運用に持ち込みたいなーと目論んでいきたいとい2021ということで、周辺技術とか低レイヤーな方面を引き続きもうちょいなんとかしていきたいところ。
eBPF+USDTでphpをトレースしてみる、php-fpmとmod-phpでもやる
前回から気づけばだいぶ経過してましたが
実際phpスクリプトが動いてる環境はmod-phpであったりphp-fpmであったりするので、そのあたりは結局動かせておらず
このあたりも試してみたのでいちおう記録として。 個人的な環境のアレによりphp-fpmの方はubuntu bionic、mod-phpの方はfocalで動かしたがまあ特にやることは変わらないはず。
結局動かすためにはプロセスに対しUSE_ZEND_DTRACE=1環境変数をセットすることが必要で、「どこから仕込むことができるか?」ということだけですね、ということで基本はsystemdの設定を上書きする方法でトレースは実行できました。
環境は上述の通りubuntu前提ですがsystemdレイヤーでやっているので、他の環境でも同様にできはするかなと(ubuntu以外で--enable-dtraceされてるバイナリが提供されてるのかどうかは定かではないですが・・
php-fpm
systemdの設定を上書きするunitファイルを仕込んでみます。
sudo cp /lib/systemd/system/php7.2-fpm.service /etc/systemd/system/php7.2-fpm.service
して /etc/systemd/system/php7.2-fpm.service
に Environment="USE_ZEND_DTRACE=1"
を追加して設定反映、再起動すればOK
$ cat /etc/systemd/system/php7.2-fpm.service [Unit] Description=The PHP 7.2 FastCGI Process Manager customized Documentation=man:php-fpm7.2(8) After=network.target [Service] Type=notify PIDFile=/run/php/php7.2-fpm.pid ExecStart=/usr/sbin/php-fpm7.2 --nodaemonize --fpm-config /etc/php/7.2/fpm/php-fpm.conf ExecReload=/bin/kill -USR2 $MAINPID Environment="USE_ZEND_DTRACE=1" [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl restart php7.2-fpm.service
おもむろにbpftraceでトレースすると対象プロセスでUSDTがトレースできることができる。
$ sudo BPFTRACE_STRLEN=200 bpftrace -e 'usdt:/usr/sbin/php-fpm7.2:execute__entry { printf("%s, %d\n", str(arg0), arg1); }' -p `pgrep -u www-data php-fpm|head -n1` Attaching 2 probes... /var/www/html/info.php, 2 , 0 /var/www/html/info.php, 2 , 0 ...
probeが二個あることになってるのはなんでやろ・・。とりあえず動きはしたのでヨシ。
mod-php
php-fpmと同様にsystemdの設定に書くか、apacheのenvvarsで設定する、どちらでもとりあえず動かせはする。
$ cat /etc/systemd/system/apache2.service [Unit] Description=The Apache HTTP Server Customized After=network.target remote-fs.target nss-lookup.target Documentation=https://httpd.apache.org/docs/2.4/ [Service] Type=forking Environment="APACHE_STARTED_BY_SYSTEMD=true" "USE_ZEND_DTRACE=1" ExecStart=/usr/sbin/apachectl start ExecStop=/usr/sbin/apachectl stop ExecReload=/usr/sbin/apachectl graceful PrivateTmp=true Restart=on-abort [Install] WantedBy=multi-user.target
or
/etc/apache2/envvars
に export USE_ZEND_DTRACE=1
を追記しておく。
おもむろに子プロセスにアタッチしてみれば動く、こちらの環境はlibphp7.4が使われてるのでこんなかんじで。
$ sudo BPFTRACE_STRLEN=200 bpftrace -e 'usdt:/usr/lib/apache2/modules/libphp7.4.so:execute__entry { printf("%s, %d\n", str(arg0), arg1); }' -p `pgrep -u www-data apache2|head -n1` Attaching 1 probe... /var/www/html/test.php, 2 /var/www/html/test.php, 2 /var/www/html/test.php, 2 ...
その他
bpftraceで --usdt-file-activation
使えるとプロセス特定してアタッチみたいなところが幾分楽できそうな気がする。
--usdt-file-activationは/proc/[0-9]*/maps覗いてアタッチすべきプロセスを見つけたらアタッチするという流れっぽくてpid指定しないで動くのは楽ちんだけど当たり前ながらpid変わったら追っかけられないのでちょっと楽くらいの位置づけかなあ https://t.co/PNV9lIWDsF
— EG (@EGMC) 2020年12月26日
まとめ
ということで若干あやしいところもありつつトレース自体は動かせた。
いずれにせよ USE_ZEND_DTRACE=1
したプロセスしかトレースはできないし、php-fpmにせよmod-phpにせよ子プロセスは入れ替わっていくので、アドホックなトレーシングはともかく「追っかけ続ける」仕組みをつくるのはしんどそうだなーとか、例えばexecute__entryを逐一標準出力に出していくみたいなのはもちろんプロダクションでおもむろにやるにはオーバーヘッドが許容できないであろうということは容易に想像でき、じゃあBPF_MAPを使うのか、どの粒度で情報を保持するのか、そもそもそここまでしてUSDT使うのか、みたいなところでやはりなかなか使い所はむずかしいなーという印象です。動かせるのは楽しいんですけどね。
全体に雰囲気で動かしているのでもっとうまくやる方法があればすごく知りたいところ・・。
参考
ubuntuのsystemd設定上書きについてはこちらの記事を参照させていただきました
第598回 systemdユニットの設定を変える:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
eBPF+USDTでphpをトレースしてみる、bpftaceとRbBCCでやる
最近プロダクション環境での諸々の調査に使いたいというモチベーションで BPF Performance Tools (Book) 読み進めつつ、提供されているbcc-toolsを試したりbpftraceでlibほげほげの関数パラメータを抜いたりしていた、のだがUSDTを使用したトレースはうまく動かせず悶々としていた。
正直USDTはパッケージ入れておけばいきなりproductionでさくっと使える、という感じでもなく当初の目的からはやや外れているのだが、機構があるのに動かせないというのはなんとももどかしいので、諸々試行錯誤してとりあえず動いた、というころまでの記録を残しておく。対象はphpで。
なぜphpなのかというと、プライベート的にもお仕事的にも馴染みがありワンチャン使える可能性もあるのでは・・という期待と、ツールを試す過程で標準パッケージのphpで
$ tplist-bpfcc -l /usr/bin/php b'/usr/bin/php' b'php':b'request__startup' b'/usr/bin/php' b'php':b'request__shutdown' b'/usr/bin/php' b'php':b'compile__file__entry' b'/usr/bin/php' b'php':b'compile__file__return' b'/usr/bin/php' b'php':b'function__return' b'/usr/bin/php' b'php':b'function__entry' b'/usr/bin/php' b'php':b'execute__entry' b'/usr/bin/php' b'php':b'execute__return' b'/usr/bin/php' b'php':b'error' b'/usr/bin/php' b'php':b'exception__thrown' b'/usr/bin/php' b'php':b'exception__caught'
を観測したためこれはもしや--enable-dtraceされてるのでは・・となり、試してみたくなったため。
結果的にUbuntuなら先日リリースされた20.04 LTSのイメージで特に独自ビルドなどは頑張らなくてもいくつかのパッケージインストールのみで(一応)動かすこと自体はできることがわかった。
環境
AWS上でUbuntu 20.04 LTS (Focal Fossa) のインスタンスを立てて動かした。
ami
$ echo `curl -s http://instance-data/latest/meta-data/ami-id` ami-0c1ac8728ef7f87a4 # ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20200423
ii php7.4-cli 7.4.3-4ubuntu1 amd64 command-line interpreter for the PHP scripting language
ii ruby2.7 2.7.0-5ubuntu1 amd64 Interpreter of object-oriented scripting language Ruby
bpf関連
ii bpfcc-tools 0.12.0-2 all tools for BPF Compiler Collection (BCC) ii bpftrace 0.9.4-1 amd64 high-level tracing language for Linux eBPF ii libbpfcc 0.12.0-2 amd64 shared library for BPF Compiler Collection (BCC) ii python3-bpfcc 0.12.0-2 all Python 3 wrappers for BPF Compiler Collection (BCC)
サンプルスクリプト
手頃なものがなかったのではるか昔書いた雑スクリプトの先頭に(pidをアタッチする時間を稼ぐために)sleepを追加して試した、今みるとコード的にもなかなかあれだが、まあサイズ的にもコンパクトでいいかな、ということで・・。
https://github.com/egmc/dscheck
実行条件
phpの場合、--enable-dtraceでビルドしただけでは不十分で USE_ZEND_DTRACE=1
で実行しないとDTrace Supportが有効にならない模様。
. Disabled PHP call tracing by default (it makes significant overhead). This may be enabled again using envirionment variable USE_ZEND_DTRACE=1.
上述の通りfocalの標準パッケージは--enable-dtrace自体はされてるようなのでこれでいける
$ /usr/bin/php -i |grep -i dtrace DTrace Support => available, disabled $ USE_ZEND_DTRACE=1 /usr/bin/php -i |grep -i dtrace DTrace Support => enabled
試しに --enable-dtrace
なしでビルドしたphpは以下のようになっていた
$ /usr/local/php7.4-no-trace/bin/php -i |grep -i dtrace DTrace Support => disabled
bpftaceでトレースする
上述のphpスクリプト($ USE_ZEND_DTRACE=1 php dscheck.php
)を実行させつつ、別窓でトレースを実行してテスト
probeのパラメータはここで何が取れるのか確認
autoload処理、関数呼び出しが観測できる、arg1はlineno
# BPFTRACE_STRLEN=200 bpftrace -p `pgrep php` -e 'usdt:/usr/bin/php:execute__entry { printf("%s, %d\n", str(arg0), arg1); }'|head -n10 Attaching 1 probe... /home/ubuntu/dscheck/vendor/autoload.php, 5 /home/ubuntu/dscheck/vendor/composer/autoload_real.php, 74 /home/ubuntu/dscheck/vendor/composer/autoload_real.php, 21 /home/ubuntu/dscheck/vendor/composer/autoload_real.php, 11 /home/ubuntu/dscheck/vendor/composer/ClassLoader.php, 446 /home/ubuntu/dscheck/vendor/composer/autoload_static.php, 38 /home/ubuntu/dscheck/vendor/composer/autoload_static.php, 30 /home/ubuntu/dscheck/vendor/composer/autoload_static.php, 32 /home/ubuntu/dscheck/vendor/composer/ClassLoader.php, 302
compile__file__entry
でスクリプトのコンパイルを覗いてみる(arg0が char *compile_file
のはずだがこちらは空になっている・・
# BPFTRACE_STRLEN=200 bpftrace -p `pgrep php` -e 'usdt:/usr/bin/php:compile__file__entry { printf("%s\n", str(arg1)); }' Attaching 1 probe... /home/ubuntu/dscheck/vendor/autoload.php /home/ubuntu/dscheck/vendor/composer/autoload_real.php /home/ubuntu/dscheck/vendor/composer/ClassLoader.php /home/ubuntu/dscheck/vendor/composer/autoload_static.php /home/ubuntu/dscheck/vendor/composer/../swiftmailer/swiftmailer/lib/swift_required.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php /home/ubuntu/dscheck/vendor/composer/../symfony/yaml/Symfony/Component/Yaml/Parser.php /home/ubuntu/dscheck/vendor/composer/../../src/DsCheck/DsCheck.php /home/ubuntu/dscheck/vendor/composer/../symfony/yaml/Symfony/Component/Yaml/Inline.php /home/ubuntu/dscheck/vendor/composer/../symfony/yaml/Symfony/Component/Yaml/Unescaper.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/swift_init.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/dependency_maps/../mime_types.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/preferences.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Preferences.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MailTransport.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailTransport.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SimpleMailInvoker.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/MailInvoker.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php /home/ubuntu/dscheck/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php
なおpidを指定せずにトレースしようとすると以下のように怒られる
# BPFTRACE_STRLEN=200 bpftrace -e 'usdt:/usr/bin/php:compile__file__entry { printf("%s\n", str(arg1)); }' Attaching 1 probe... Error finding or enabling probe: usdt:/usr/bin/php:php:compile__file__entry
RbBCCでトレースする
udzuraさんのこちらのエントリでrubyでbccできるぞ、というのを試してみたく
こちらのサンプルを写経させて頂き、probe対象を変更してfunction名を取得するだけのサンプルを試してみた。 (というか実際のところはところこちらを先に動かして、あれ、とれるやんけ・・となりbpftrace側でも同様にトレースできることを確認出来たという流れ)
require 'rbbcc' include RbBCC pid = ARGV[0]&.to_i || raise("Usage: #{$0} PID") bpf_text = <<BPF #include <uapi/linux/ptrace.h> struct data_t { u64 ts; char function[128]; }; BPF_PERF_OUTPUT(events); int do_trace_function_entry(struct pt_regs *ctx) { struct data_t data = {}; data.ts = bpf_ktime_get_ns(); bpf_usdt_readarg_p(1, ctx, &data.function, sizeof(data.function)); events.perf_submit(ctx, &data, sizeof(data)); return 0; }; BPF u = USDT.new(pid: pid.to_i) u.enable_probe(probe: "function__entry", fn_name: "do_trace_function_entry") b = BCC.new(text: bpf_text, usdt_contexts: [u]) puts("%-18s %s" % ["TIME(s)", "function"]) start = nil b["events"].open_perf_buffer do |cpu, data, size| event = b["events"].event(data) start ||= event.ts time_s = ((event.ts - start).to_f) / 1_000_000_000 puts("%-18.9f %s" % [time_s, event.function]) end Signal.trap(:INT) { puts "\nDone."; exit } loop { b.perf_buffer_poll }
こんな感じでトレースできる
# ruby phpusdt.rb `pgrep php` | head -n20 TIME(s) function 0.000000000 main 0.000193415 main 0.000223335 getLoader 0.000248361 loadClassLoader 0.000652416 main 0.000740099 main 0.000760310 getInitializer 0.000781820 Composer\Autoload\{closure} 0.000799492 register 0.000818768 composerRequirea069f98d7345659050bcc164f0155069 0.000888641 main 0.000979718 main 0.000999792 registerAutoload 0.001022639 loadClass 0.001038429 findFile 0.001054807 findFileWithExtension 0.001089370 Composer\Autoload\includeFile 0.002951398 main 0.002981065 __construct Possibly lost 227 samples
pythonバインディングもそれほどコード書くわけではないのだけど、gemでさくっと自前のbccツールを、みたいなのが出来るのはいいかもしれない・・。
ということで
なんとかphpでUSDTを使用したbcc/bpftraceでのトレースを実行することができた。
少なくともfocalではphpの再ビルドせずに使うことはできるものの、依然条件は厳しく、PHPであればnewrelic等のAPM使うなど、そこまでこれでなにかを観測したいという強いモチベーションもなく、どうかなーというところですが。
(compile__file__xxx
でopcodeのキャッシュ状況みるとかワンチャンどうかなーと思いつつ、実際phpスクリプトが動いてる環境はmod-phpであったりphp-fpmであったりするので、そのあたりは結局動かせておらず
ついでにメモ
bccのレポジトリにも各言語のトレースサンプルが存在している、がこちらは
bpf_probe_read_user missing (added in Linux 5.5).
ということでカーネル5.4.0なfocalでは動作しなかった。
ホームページのメンテナンスをして大体15年目になった話
ウェブサイトというかホームページという方がしっくり来るよねというタイトルで。 技術的なものはなし。
高校からの友人でジャズギタリストである佐津間純のサイトを2005年に作成し、引っ越し、リニューアルなどを経て大体15年目になった。 現状は言ってしまえばまあただのwordpressサイトで、何がしかのサービスの面倒みてました!みたいな話ではないのだけど、一般的なサイトであっても長くメンテしていればそれなりに出来事もあるということで。
レンサバでシージーアイなところからスタートし、2020に至ってついにhttp2を喋るようになり、自分がメンテしてたどのサイト、個人サービスより長くなったのでまあまあ感慨深いなーということで、インターネッツなアーカイブを発掘しながら半分記録的な感じでだらだらと書く。
サーバ遍歴としては
さくらのレンサバ->ロリポ->さくらのVPS(CentOS)->Amazon Lightsail(Ubuntu Bionic)
で計3回引っ越しをしている。
その間に自分は
HTML/CSSがちょい書けるだけの専門学生 -> SIer -> web系のサーバサイドエンジニア ->フロント以外全部みるやつ -> インフラエンジニア
という徐々に低レイヤー技術に近寄っていっており、なんとなくそのときどきのトレンドであったり、思考であったりが反映された感じになってる。
以下記録兼思い出的なもの
作成時点で自分はいちおう音楽系の専門学生でウェッブデザイン的なものをぼんやりと考えており、コードは全然書けない状態。
2005年当時のドメインは http://junsatsuma.sakura.ne.jp/ でさくらのレンサバを使ってる。このアドレス今でもアクセスするとリダイレクトしてくれるんだけど管理はどうなっているんだっけな・・。
$ curl -I http://junsatsuma.sakura.ne.jp/ HTTP/1.1 301 Moved Permanently Server: nginx Date: Sun, 01 Mar 2020 13:06:32 GMT Content-Type: text/html; charset=iso-8859-1 Connection: keep-alive Location: http://junsatsuma.com/
アイコンとかは専門の同級生にお願いして作ってもらったやつ。 シージーアイは魔法の世界なので適当に755とか設定してjcode.plをアレしてFFFTPでテキストモードで転送して、とかやると動くと思っているのでそういうのが動いてる。 マウスオーバーするとアイコンが動いたりする。なんかそういう時代だったやつ。
独自ドメインは2008年に取得している。 自分の状態としては就職してSIerになっており主にJavaなどを書きはじめているもののまだウェッブの世界とは言えない時期。
Domain Name: JUNSATSUMA.COM Registry Domain ID: 1529192299_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.enom.com Registrar URL: http://www.enom.com Updated Date: 2019-11-20T00:29:13Z Creation Date: 2008-11-19T01:22:28Z
アクセスカウンターがついてるのも時代を感じる。 まださくらのレンサバを引き続き使っている。
2013年にさくらからロリポップに引っ越しをしている。 リニューアルということでwordpressで作り直していて、テンプレは大変時代を感じるbootstrapベースのものをカスタマイズして使っている。 ロゴは例によって友人に頼んで作成してもらった。
bootstrapベースのジャズミュージシャンのサイトというのは割とレアなんでないかと思う。
デザイン面ではこの時点から変更していないのだけど2020年でもそれなりに動いていて長持ちする記述は悪くないなーと思える。 ロリポを採用してるのはなんでだろう。
この時点の自分のスキルとしてはサーバサイドのphpコードはそれなりに書けてインフラもいちおう構築はできる、みたいな状態なのだけど、レンサバのほうが管理が任せられていいだろう的なところでこうしていたのかもしれない。
その後2014年頃にwordpressで踏みがちな外部からサイトを一部改ざんされる事件があり、対応自体はできたものの緊急退避的に個人サービスを動かしていたさくらVPSサーバに引っ越しをして、結局そのまま使い続けることになった。
なお改ざん事件の対応自体はロリポのサポートも親切かつ技術面でもきちんと見てくれおり、割と安プランなのにありがたいなーと思ったものです。
2019年春にフルhttps対応を行って(よくあるあれとしてfacebookのいいねがリセットされたりしつつ)そのタイミングでhttp2を喋るようにするつもりだったのだけど、さすがに環境が古くてビルドもまわりも色々とめんどくさく、かつ同居してるサービスの更新もしんどかったので引越し先をAWSのLightsailにすることにして、結局先日ようやく引っ越しが完了した。
とりあえず現行のサーバはubuntu bionicでprefork mpmでmod_phpなapacheからevent-mpmでphp-fpmを使うapacheとなり、無駄にサーバ監視も充実し、ミドルウェアバージョンアップはあるもののwordpressはきっと、10年後もメンテされてるでしょうということでゆるゆるとメンテし続けていけるのではないかと思っている。 ただいかんせん興味のレイヤーが下がってきてしまったので今からフロントをリニューアル、みたいなことをやろうとするとちょっとしんどい気がする。
個人サービスとかアプリとかちょろちょろメンテしてたけど、ただのウェブサイトでも一つ長期間メンテしているものがある、というのはそれはそれで自身の振り返りもなってよいものですね。
おまけ
ジャズミュージシャンのサイトを方面する層はそもそも年齢層も高く、はてぶユーザーなんて全然いないはずなのになぜか1ブクマ&コメントもついててなんかアイコンに見覚えが。
色々ありますね。
インスタンス内からAmazon Lightsailの裏側を想像してみる(小ネタ)
タイトルどおり特にこれといって役に立つお話ではないのですがなんとなく気になって色々見てみた小ネタ。
きっかけは、Lightsailで起動したubuntuインスタンス内でsnapで入ってるssm-agentが動いており、なんとなく見始めたところから。
TL;DR
- Lightsailの実態は単にAWS管理下のアカウント内にあるEC2インスタンスっぽい
- 起動しているインスタンスも例えばUbuntu 18.04のamiならpublicイメージを元に起動してるだけでamiとして特に差分があるわけではない
- AWSが自社の提供するサービスを組み合わせていい感じにパッケージして定型化したものを別サービスっぽく仕立てて安く提供しているものだと思えばよさそう
- 単に既存のサービスを組み合わせてターゲットを変えたユーザー層に安価に提供するという戦略なのだろうけどAWS的にも省エネでうまいことできている気がする(使う側からすればまあやすいし)
そういえば
環境
- LightsailのOS OnlyでUbuntu 18.04
- ap-northeast-1a
- メモリ1GB、1 vCPU の5$プラン
見てみたとこ
起動してるssm-agentののログ
AccessDeniedException: User: arn:aws:sts::596322350845:assumed-role/AmazonLightsailInstanceRole/i-095f243859d90fbfd is not authorized to perform: ssm:UpdateInstanceInformation on resource: arn:aws:ec2:ap-northeast-1:596322350845:instance/i-095f243859d90fbfd
おもむろにget-caller-identityしてみる
$ aws sts get-caller-identity { "Arn": "arn:aws:sts::596322350845:assumed-role/AmazonLightsailInstanceRole/i-095f243859d90fbfd", "Account": "596322350845", "UserId": "AROAYVV4U6367357MRC4Q:i-095f243859d90fbfd" }
596322350845
はLightsailを使用してる自アカウントではない。
i-095f243859d90fbfd
は起動しているインスタンスIDだが 596322350845
アカウント内にあるのでまあ当然自アカウント上では見えない
AmazonLightsailInstanceRole
というロールがアタッチされてるが特に権限はついてなさそう。
メタデータから普通にクレデンシャルを取ることができるが特に何ができるというわけでもない。
インスタンスタイプ
$ curl http://169.254.169.254/latest/meta-data/instance-type t2.micro
ami-id
$ curl http://169.254.169.254/latest/meta-data/ami-id ami-07ad4b1c3af1ea214
インスタンスは東京リージョンの通常のubuntuイメージ ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180912
で起動してることがわかる(のでデフォルトでssm-agentも入ってくる)
セキュリティグループ
Your Parkside Resources Ingress from Your Parkside LoadBalancers ps-adhoc-10022_22_443_80_9100_9104_9117_9253
が付与されている、インスタンス起動時にこのへんは裏側で動的に作成されるのでしょう、たぶん。
userdata
Lightsail用にCA公開鍵を生成してTrustedUserCAKeysに追加するスクリプトが動いている LightsailのコンソールからターミナルにログインするとAWSのIPからCA認証でログインしたと思われるログが出力されるのでおそらくそれ用のものと思われる
snapshotをとってexportしてみる
Lightsailでsnapshotを取得し、EC2にexportした際に生成されたsnapshotをみると以下のようなdescriptionになっている
Copied for DestinationAmi ami-0d4e5e150b0e9fe87 from SourceAmi ami-06751be45589128e9 for SourceSnapshot snap-0f5472d00cc91a548. Task created on 1,582,454,630,187.
おそらくAWS管理下のアカウントで普通にamiが取得されて管理されていて、Lightsail上で起動する場合は単にそれが使用され、exportするとamiが自アカウントにコピーされてきてSourceAmiのIDはその名残的なところなのかなーと。
ということで
まあ色々眺めて多分Lightsailはこんなかんじなんだろーなーという想像ネタでした。 AWSのサービスは既存の基盤の組み合わせで出来てるものが多くあり、個人的には「別サービスのリソースを実質管理下に置くが手で変更できてしまう」系のサービスがあまり好きではなく、その点Lightsailは(想像ですがおそらく)アカウントごと別ということで必要な機能だけがラッピングされて提供しており割と扱いやすくなっている気がします。
QNAP NAS上でnode_exporterをデーモン化しつつ自動起動
前回prometheus+grafanaを導入してNASのモニタリングも開始してみた、の続きで
雑に起動していたQNAP NAS上のnode_exporterをNAS再起動時に自動起動するようにする小ネタ。
やること
これだけでOK。
環境はQNAP TS-220(QTS 4.3.3.0299)
以下順に
雑いinitスクリプト書く
/etc/init.d
以下のスクリプトを眺めつつ、こちら
QNAP TS-469Lをmackerelを使ってモニタリングする | misty-magic.h
でmackerel-agentをQNAP上で起動されてる事例を参考に、というか割と流用させて頂きつつとりあえずstop、startだけ出来るスクリプトを用意。
他のスクリプトでも使われている/sbin/daemon_mgr
でpid管理などをよしなにやってくれる模様。ちょっと楽。
/etc/config/qpkg.conf
に設定を追加して自動起動する
作成した起動スクリプトに実行権限をつけ、起動、停止確認ができたらqpkg.confに設定を追記する。 こんな感じで
[node_exporter] Name = node_exporter Version = 0.16.0 Author = prometheus Date = 2018-05-15 Shell = /usr/local/node_exporter/etc/init.d/node_exporter.sh Install_Path = /usr/local/node_exporter QPKG_File = /usr/local/node_exporter/DUMMY Enable = TRUE
QPKG_FileはダミーでOK。
Authorとかいろいろ適当だが、meもなにか違うしまあオレオレということで・・。
なお、パス配置は起動スクリプトを素直に/etc/init.d/node_exporter.sh
に置くとNASの再起動で消えて悲しいことになるので、ひとまず/usr/local/node_exporter以下に諸々配置する構成にしている。
qpkg.confに書いた時点でAppCenter上で見えるようになり、サービスの起動、停止が出来るようになる。
この状態でNASを再起動すると、アプリケーション起動処理の中でnode_exporterも自動で起動されるようになる。
ブラウザで9100を確認、ちゃんと起動している。
これで停電があっていつのまにか再起動してたわー的なことがあっても勝手に起動してくれるはず。
2018-08-19追記
再起動では消えないもののQTSのアップデートで/usr/local以下に配置したnode_exporter一式は消えてしまったので、普通にマウントしたディスク領域の共有フォルダ以下に置いた方がよさそう。
/share/MD0_DATA/
以下に置いてひとまず様子見。