基本的な思想として、SREs は必要悪で、全員で Site Reliability Enginering ができるのが理想だと思っている。もちろん SREs の仕事は Platform 開発や OnCall(うちは OnCall Rotation を持っていないが)、Architect, Performance のような Production に関わることを含むので、すぐにはゼロにはできないが、SRE の思想や、やってる内容は少しずつ Product Team に委譲し、Product Team が Market に対して爆速で仮説検証をできるように(しかも信頼性も Keep しながら!Reliability is a feature である)していきたいと思っている。
そういった話をもとに、いままさに導入して試行錯誤の最中である SLI/SLO の導入説明や、robbie が提案する Mission Control Program - Google が提唱した、Developer が短期的に SRE Team に移動して知見を得て元の Team に戻っていく Program - の提案や実現性のヒアリングを行なった。また、 @suzuki-shunsuke が爆速で進めてきた Terrraform を state 分割して各チームにオーナーシップを持たせる話も説明した。
これらの説明を建設的に、前向きに彼らは受け取ってくれた。僕が1番驚いたのは Indonesia Team の Product Management だ。Product Manager の rofiqi が本当にしっかりしていて、Indonesia Branch の Product / Area ごとに、さらに細分化された Team ごとに 達成度合いを OKR を運用しており、その説明もとてもわかりやすかった。
SLI/SLO の導入の部分で、OKR にどう Align していけば良いか?という質問が行われたので、追加のセッションで Indonesia Team の OKR System をそもそもどのように運用しているのかを説明してもらったあと、基本的な SLI/SLO の話や原則、ポイントを簡単に説明したのち、最終的には「君らにまかせる」という回答をした。
彼らが OKR として採用している Key Result は Product Team であれば獲得した Paid User 数だったり、学習時間だったりするし、Enginering Team であれば 開発速度や、バグの数などがあった。Product によってはそこで SLI として採用している Availability(uptime) があったりした。
目指す姿としては全 Product Team の全員が Site Reliability Enginering をできる、あるいは Team 内に mini-SRE がいてそれを Lead してくれるような形だが、少なくとも半年以上は先の話であり、現状は remote で Tokyo の SRE-global と各地の Developer で協力してやっていく必要がある。
今後は(現在議論中に事情により)仕事で日本と Global の Devs が関わる機会は徐々に減ってくる。しかし技術的な Knowledge Share が重要なことは変わりがない(むしろ相対的に重要度は増す)以前やっていた Technical な Study Session をもう一度復活させるもありかもなぁ、みたいな話をした。でもそれを僕が Lead するにはあと少し勇気が足りない。機運待ち。
あとはこの旅で robbie が彼にしか出せない Value を出しまくってるわけで、自分はどうしていくかなぁと彼と最終日バーで飲みながら考えたりもした。もちろん今の SRE Team は全得意領域をそれぞれ持っていてそれぞれ Value を出している。「で、お前はどうなん?Value 出してるん?」ってもう1人の僕に聞かれている。
role 的な点で他のメンバーと比べて unique なのは global 担当でありながら日本人であるということで、その両者のシナジーを作るだとか、うまいこと応用を聞かせるとか、輸入したり輸出したりできるようにするとか、そういうところなのかなぁ、とぼんやり思ったりするところで終わっている。いや、Technical に突き抜けいよと言われる気もするが、いい意味でも悪い意味でも技術(の内容)にこだわりがないので半ば諦めている。Production Reliability に関する Culture Making の部分はこれからも引き続きやっていく。
さて、まだ Control Plane を持っていないのだが、現状 Kubernetes 上で Service Discovery は誰が担っているかというと、k8s service になる。
k8s service が 実際に転送先の pod の IP の list を持っていて、pod 生き死にすると、新しい endpoint を service が知るので、envoy cluster 側は 転送したい cluster IP だけ知っていればよく、かつそれは kube-dns で引ける。
そう考えるとこのパターンだと service discovery という感じではなく、load balancing は service が行うことになるので、envoy としては cluster が単一の宛先を覚えてるだけですね。
istio が入るとこのへんどう変わってくるんだろうか。なんか envoy だけまずは知ろうとしてるけど早くも control plane の話出てきたし順番間違ったかな。まぁこのまま進むけど。
root@d21849f0ad80:/# envoy -h
USAGE:
envoy [--disable-extensions <string>] [--use-fake-symbol-table <bool>]
[--cpuset-threads] [--enable-mutex-tracing]
[--disable-hot-restart] [--max-obj-name-len <uint64_t>]
[--max-stats <uint64_t>] [--mode <string>]
[--parent-shutdown-time-s <uint32_t>] [--drain-time-s <uint32_t>]
[--file-flush-interval-msec <uint32_t>] [--service-zone <string>]
[--service-node <string>] [--service-cluster <string>]
[--hot-restart-version] [--restart-epoch <uint32_t>] [--log-path
<string>] [--log-format-escaped] [--log-format <string>]
[--component-log-level <string>] [-l <string>]
[--local-address-ip-version <string>] [--admin-address-path
<string>] [--reject-unknown-dynamic-fields]
[--allow-unknown-static-fields] [--allow-unknown-fields]
[--config-yaml <string>] [-c <string>] [--concurrency <uint32_t>]
[--base-id <uint32_t>] [--] [--version] [-h]
Where:
--disable-extensions <string>
Comma-separated list of extensions to disable
--use-fake-symbol-table <bool>
Use fake symbol table implementation
--cpuset-threads
Get the default # of worker threads from cpuset size
--enable-mutex-tracing
Enable mutex contention tracing functionality
--disable-hot-restart
Disable hot restart functionality
--max-obj-name-len <uint64_t>
Deprecated and unused; please do not specify.
--max-stats <uint64_t>
Deprecated and unused; please do not specify.
--mode <string>
One of 'serve' (default; validate configs and then serve traffic
normally) or 'validate' (validate configs and exit).
--parent-shutdown-time-s <uint32_t>
Hot restart parent shutdown time in seconds
--drain-time-s <uint32_t>
Hot restart and LDS removal drain time in seconds
--file-flush-interval-msec <uint32_t>
Interval for log flushing in msec
--service-zone <string>
Zone name
--service-node <string>
Node name
--service-cluster <string>
Cluster name
--hot-restart-version
hot restart compatibility version
--restart-epoch <uint32_t>
hot restart epoch #
--log-path <string>
Path to logfile
--log-format-escaped
Escape c-style escape sequences in the application logs
--log-format <string>
Log message format in spdlog syntax (see
https://github.com/gabime/spdlog/wiki/3.-Custom-formatting)
Default is "[%Y-%m-%d %T.%e][%t][%l][%n] %v"
--component-log-level <string>
Comma separated list of component log levels. For example
upstream:debug,config:trace
-l <string>, --log-level <string>
Log levels:
[trace][debug][info][warning][error][critical][off]
Default is [info]
--local-address-ip-version <string>
The local IP address version (v4 or v6).
--admin-address-path <string>
Admin address path
--reject-unknown-dynamic-fields
reject unknown fields in dynamic configuration
--allow-unknown-static-fields
allow unknown fields in static configuration
--allow-unknown-fields
allow unknown fields in static configuration (DEPRECATED)
--config-yaml <string>
Inline YAML configuration, merges with the contents of --config-path
-c <string>, --config-path <string>
Path to configuration file
--concurrency <uint32_t>
# of worker threads to run
--base-id <uint32_t>
base ID so that multiple envoys can run on the same host if needed
--, --ignore_rest
Ignores the rest of the labeled arguments following this flag.
--version
Displays version information and exits.
-h, --help
Displays usage information and exits.
envoy