isucon12 予選に出場し敗退しました

2022/7/23 (土) に開催された ISUCON12 の予選に参加し、最終スコア 9042 (3回の再現スコア計測で85%以下のスコアしかでなかったため失格) で予選敗退しました。

結果は予選敗退となりましたが、学ぶことの多い 1 日となったためブログとして書き残そうと思います。

問題概要

今回のお題は ISUPORTS というマルチテナント SaaS でした。 問題の技術的な概要は後日公式から講評ブログとして出ると思うので、ここには当日競技開始時に流れた動画のリンクを貼っておきます。

www.youtube.com

やったこと

10:00-10:30

今後の開発をスムーズに行うためのセットアップや、nginx, mysql に対する設定等をしました。

アプリケーションのデプロイには自作ツールの isucontinuous を利用しました。このツールを一言で説明すると、Git リポジトリソースコードをいい感じに複数台に展開するためのデプロイツールです。

上記作業は自分ひとりで済む作業だったので、チームメンバーの他二人はこの間にマニュアルを読んだりアプリケーションの振る舞いを理解する時間としました。

10:30-11:30

今回アプリケーションは Docker Compose で動作しておりマシン上に Go のランタイムはインストールされていませんでした。そのため Go のランタイムのインストールや systemd のユニットファイルの作成などを行いました。 また、alp のパス集約など解析のためのツールの調整も 11 時までに行うことが出来ました。

その後、MySQL のスロークエリログを pt-query-digest を通して見て明らかに重いクエリに対してインデックスを張るなどして、この時点でのスコアは5000点弱でした。

11:30 以降

今回の問題は DB が MySQL と SQLite3 とで複数存在する構成でした。 チームメンバーと話し合い、以下の点より「まずは MySQL にすべて寄せるべき」という方針をとりました。

  • 負荷の高いエンドポイントの実装が MySQL 側の DB で 1 クエリ打ったあとに SQLite3 側の DB で N 回クエリを叩くような N+1 だった
  • アプリケーションの負荷が大きかったため、このまま SQLite を残したままだと負荷がアプリケーションに寄ってスケールしないと判断した

メンバーのうち一人がその移行作業を担当し、それ以外のメンバー (自分を含む) は MySQL に移行した後に詰まるであろうポイントに目星をつけそこのチューニングを行いました。

しかしながらこの移行作業に想定以上に時間がかかり、移行作業をしていないメンバーも直近のボトルネックを無視した改善がなかなかベンチを通せず、かなりの時間を溶かしてしまいました。

17:00-18:00

17時頃になりメンバーが sqlite3 から MySQL への移行を完了してくれました。 しかし、ベンチマーカーの initialize リクエストで初期化すべき初期データが大きすぎて (特に player_score) 30秒だと微妙に間に合わない問題があり、17 時時点では事前に手動で initialize 処理を実行した後にベンチを実行することでスコアを確認していました。

17 時以降、「N+1 回クエリを発行している箇所を JOIN に修正」、「ユーザーのオンメモリ管理」、 「initialize を通す作業」をそれぞれ分担して行いましたが、git の merge で conflict が多発し時間も無かったため、この時間でやった改善のうち master に入った改善は結局追加でインデックスを張ることくらいでした。

結局 initialize が 30 秒以内に終わらない問題が解決できなかったため、最後の 10 分で 無理やり initialize リクエストを 30 秒以内で返すようなコード を書いて通したベンチが最終スコアとなりました。

振り返り

個人的に今回の一番の敗因はコミュニケーションミスだと思っています。

例えば 11:30 以降の戦略に関して、以下のような反省点があります。

  • MySQL への移行作業が後続のすべての作業の前提となっていたため、少しでも早く解決するために複数人で作業すべきだった
  • 想定よりも移行に時間がかかりそうなことが分かった時点で、他のメンバーは MySQL への移行が失敗したとしても点数を伸ばすためのフォールバックプランを検討すべきだった

当日上記のことが出来なかったのは、MySQL への移行作業を特に時間を切らず一人に任せきりにしてしまったことが大きな理由だと思っています。

また他にも 17 時以降の initialize が通らない問題に関して、他のメンバーは以下の解決先を思いついていたのですが、競技時間内のコミュニケーション不足が原因で作業者 (自分) はこれらを把握できていませんでした。

  • 案1. /var/lib/mysql 以下のファイルコピーを取って、initialize 時にディレクトリごとコピーする
  • 案2. player_score テーブルのレコードは WHERE で絞り込んだ後にrow_numが一番大きいものしか利用しないので、予め初期データから使われないデータを削除する

結局 17 時以外にインデックスを張る以外の改善が出来ていないため、今振り返ると 17 時時点で一度メンバー全員で足並みを揃えて残り 1 時間でやるべきことを落ち着いて話し合ってから作業に着手すべきであったと思っています。

最後に

このような素晴らしい問題を提供してくださった ISUCON12 運営の皆様方、ありがとうございました!

当日やったことを書き起こしてみると、単に歯が立たなかったというよりは「こうすればよかった」という反省の多い回となってしまったことがわかりとても悔しいです。 来年こそは悔いの残らない戦いをしたい!!

Open Policy Agent Deep Dive

KubeCon + CloudNativeCon Europe 2020 2日目 のセッションである Open Policy Agent Deep Dive についてです。

Open Policy Agent (OPA) について以下のような内容でした。

  • 前半: 基本的な機能の説明から実際にどのようにポリシー制御を行っているか
  • 後半: OPA とその周辺ツールの新機能/将来的に入る機能の紹介

OPA Overview / API Authorization Deep Dive

セッション前半は OPA の基本的な説明と、ユースケースの一つとして Service Mesh の入り口で OPA によるポリシー制御を行う例の説明でした。

当項目については特に目新しいことはなかったため省略します。

New and Feture Feature

セッション後半は OPA の新しい機能についてでした。

Web Assembly Update

  • Rego を以下のコマンドで WASM にコンパイルすることが出来るようになったそうです。
opa build policy.rego -e example/allow -t wasm

Benchmaking Tool

  • ポリシーの評価にかかった時間を測るベンチマークツールが以下のコマンドで実行できるようになったそうです。
# benchmark a single query
opa bench --data rbac.rego 'data.rbac.allow'

# benchmark unit tests
opa test -v --bench ./rbac.rego ./rbac_test.rego
  • 出力は以下 (スライドより)

f:id:skitazawa1121:20200821000009p:plain

Decision log mutation

  • ポリシーの値を既存の構造化されたログファイルから参照することが可能になったそうです。
    • 例えば、ポリシーにはかけないセンシティブなデータのバリデーションに有用

Additional features

他にも以下の機能追加/改善があったそうです。

  • Partial Evaluation enhancements
    • (聞き取れなかったです:bow:)
  • Enhanced subcommand: opa build
    • ビルド時に最適化オプションを渡せるようになったり、WASMコンパイル出来るようになったり
  • New Parser for Rego
    • 実行時間が 1/100
  • Optimization for Group-by idioms
    • O(n2) → O(n) な文法で書けるようになった

Upcoming features

  • Digital signatures for bundle downloads
    • OPA で Bundle の署名と検証を行う
  • Always-on Tracing for Explanations
    • Debbug で利用可能な trace を常時有効化
  • IntelliJ plugin for OPA
  • MongoDB integration
    • MongoDB の query をポリシー制御

Gatekeeper Update

  • New Features
    • Metrics (violations, parformance)
    • Semantic logging に対応
    • CNCF Security review に通った
    • スタンドアロンな audit controller
    • ライブラリに Pod Security Policies *1 が追加された
    • ValidatingWebhook が HA 対応した
    • Constraint, ConstraintTemplate のフォーマットが stable に
    • Namespace 単位で Constraint の除外設定
  • Pre-built policies
    • 自前で Rego でポリシーを書かなくても、元からいろんなポリシーが提供されるように

Welcome Conftest as a new OPA project!

現在以下が Conftest に対応

  • Inputs (ポリシー制御対象)
  • Outputs (Conftest の出力)
  • Integrations (CI ツールで Conftest の利用をサポート)
    • Circle CI
    • Tekton
    • GitHub Actions

感想

今回の発表を聞いて、利用者が OPA に求めるものが安定性も勿論そうですが 速度を求めているようだったので、それほど広く普及しているのかなと個人的に感じました。

自分は業務にて、過去に Kubernetes マニフェストの適用時のバリデーションをどのように行うか検討し、そのときに OPA Gatekeeper が挙がりました。Rego の読み書きが慣れないことや当時の Gatekeeper が一部不安定だったことから、結果としてAdmission Webhook を用いた自前バリデーション API サーバの実装を行いました。 ただ、自前 API サーバのポリシー管理に辛さを感じたら *2 負債化する前に Gatekeeper に移行できるよう、引き続き追っていこうと思います。

それと、自分は今まで OPA を「おーぴーえー」と言っていましたが、正式な呼び方は「おーぱ」だと初めて知りました *3

*1:https://kubernetes.io/docs/concepts/policy/pod-security-policy/

*2:conftest を使いたいのでそのうちすぐ移行したくなるかも・・

*3:https://www.openpolicyagent.org/docs/latest/ より OPA, pronounced “oh-pa

Hubble - eBPF Based Observability for Kubernetes

KubeCon + CloudNativeCon Europe 2020 2日目 のセッションである Hubble - eBPF Based Observability for Kubernetes についてです。

eBPF を用いた CNI である Cilium と、Cilium からメトリクスを得ることでより低いレイヤでの Observability を実現する Hubble についてのセッションです。

What is eBPF

  • eBPF: Linux kernel の機能の一つで、small program を secureefficient に in-kernel へ動的アタッチ
    • アプリケーションを変更せずに可視性がある
    • オーバヘッドが小さい
    • 広くサポートされている (Hubble は Linux 4.9+ をサポート)

How Hubble uses eBPF

f:id:skitazawa1121:20200820021857p:plain

  • Cilium Agent 内に居る Hubble が eBPF Datapath の event を取得

    • Hubble UI でブラウザから閲覧
      • Service Dependency Maps
      • Flow Display and Filtering
      • Network Policy Viewer
    • Hubble CLIコマンドラインから閲覧
      • Detailed Flow Visibility
      • Extensive Filtering
      • JSON output
    • Prometheus/Grafana から閲覧
      • Hubble が Open Metrics format の metrics を吐く
  • 現状の Hubble はどうやら Cilium が前提らしい

    • 以下は発表中の Q&A

Q.How tied to Cilium is Hubble? Is it possible to create additional agent types that export events from different source types than eBPF/Cilium?

A.Currently, Hubble only receives events form Cilium, but this is not a fundamental architectural limitation. The Hubble observer could be extended to also receive data from other sources as well.

Hubble API

  • デフォルトで 4k events / node
  • フィルタでマッチング処理できる
  • Hubble Relay による Cluster-wide な構成を取れる
    • Hubble - Hubble Relay 間は gRPC
  • CLI, UI がここを叩く

f:id:skitazawa1121:20200820021913p:plain

Flow Visibility

以下の情報が取れるそうです

f:id:skitazawa1121:20200820021950p:plain

L7 Visibility

  • Cilium 経由で envoy (L7 Proxy) で Proxy する

f:id:skitazawa1121:20200820021940p:plain

Hubble Metrics

  • Open Metrics format
  • HTTP, DNS, TCP, ICMP 等の Flow Events のメトリクスを吐く
  • Grafana で可視化出来るよ

デモ

Hubble UI / CLI のデモと Grafana でメトリクスを可視化するデモでした。

  • Hubble UI の画面 (発表中のスクショなので画像が荒いです)

f:id:skitazawa1121:20200820022508p:plain

  • Cilium の CiliumClusterwideNetworkPolicy Custom Resource で特定の通信を禁止し curl コマンドが失敗することを確認した後に、実際にどのようなパケットがドロップされたかを CLI と UI でそれぞれ確認 (発表中のスクショなので ry

f:id:skitazawa1121:20200820023351p:plain

f:id:skitazawa1121:20200820023415p:plain

感想

CNI より L3, L4 レベルまで制御出来るのは、 L7 で頑張る Service Mesh と比較して利点になるのかなと感じました。また、Service Mesh を実現するソフトウェアである Istio と連携も可能だそうです。 *1

一方で、トラブルシューティングの用途で eBPF を利用 *2 する利点は理解できますが、それを定常的に取りたいかと言われるとどうなんだろうという疑問が自分の中にあるので、引き続き Cilium 及び Hubble の情報を集めてきちんと pros/cons の整理を付けようと思います。

eBPF and Kubernetes: Little Helper Minions for Scaling Microservices

KubeCon + CloudNativeCon Europe 2020 2日目 のセッションである eBPF and Kubernetes: Little Helper Minions for Scaling Microservices についてです。

以下のような内容でした。

  • eBPF についての初学者向けな説明
  • eBPF の歴史
  • eBPF の Kubernetes CNI 実装である Cilium について

※ 時系列を雑に日本語で起こしましたが知らないことばかりで都度調べながらの作業でした。 結局ほとんどスライドのままな気がしますが、それでも他の記事以上に誤りが多い気がするので間違っている箇所があったら優しく指摘してください・・笑

Challenges from OS kernel side

前半は eBPF を Linux に入れるまでの話?正直良くわからなかった・・

eBPF for networking in a nutshell

eBPF を一言でいうと: カーネル上でプログラムを安全に動作させる仕組み

  • userspace で動作する agent が eBPF 用のコードを生成する
  • userspace の LLVM がそれをオブジェクトファイルにコンパイル
  • bpf syscall より kernelspace 内の BPF verifier , JIT compiler を経て native code になる
  • native code は kernelspace 内の任意の箇所 (例えば, NICTCP/IP Protocol Stack) で動作する
  • agent は kernelspace の BPF maps を経由して native code とやり取りできる

f:id:skitazawa1121:20200820011956p:plain

eBPF のいいところ

  • cannot crash the kernel
  • as fast as kernel module
  • stable API guarantees

Packet flow for kube-proxy

従来の kube-proxy においてパケットがどのように Pod や外部に出ていくのかについて、kernel 処理レベルで説明されていました。

f:id:skitazawa1121:20200820012259p:plain

これが eBPF の実装である CNI の Cilium を利用することで以下のようになりオーバヘッドが減るそうです。

  • Service から自ホスト上の Pod へ転送

f:id:skitazawa1121:20200820012339p:plain

  • Service から別ホスト上の Pod へ転送

f:id:skitazawa1121:20200820012353p:plain

eBPF の歴史

セッション後半は eBPF がどのような歴史をたどってきたか、今後どうなっていくかについての話でした

2013年

  • old "SDN" landscape: Open vSwitch , traffic control (初耳でした) , netfilter (iptables, ipvs, nftables)
  • BPF は tcpdump や seccomp 等、datapath と別の領域で使われていた
  • old "SDN" と eBPF の違いを、SDN を"program" the datapath , eBPF を create the datapath instead と表現されていました。
  • Initial big patch bomb to propose 'extended BPF'
    • inspired by BPF な nftables が出てきたが、この時点ではまだ Linux kernel に merge されなかった

2014年

  • 最初の eBPF パッチがmergeされた

2015年

  • eBPF moved into two directions in parallel: networking & tracing

    • tracing: eBPF backend が LLVM にマージされ、eBPF を kprobes に接続する機能が出た
    • networking: tc が eBPF で完全にプログラム可能になった
  • bcc project の Initial announcement

2016年

  • eXpress DataPath (XDP) の登場
    • nfp : cls_bpf と XDP hook により eBPF で処理をする最初の driver
  • Cilium project first announced
    • メインターゲットを Docker として以下を目指した
      • label-based policy, NAT64, tunnel mesh container connectivity 全てが eBPF を経由する
      • datapath 全体と転送ロジックを eBPF で行う (Docker や ovs の bridge device を必要としない)

2016, 2017年

  • Netflix で eBPF のトレーシングツールを 「Linux BPF superpowers」 と紹介した
  • Facebook で XDP + eBPF な L4 LB である Katran *1 が出た
  • Cloudflace でXDP + BPF で DDos ミティゲーションを実現した

2017, 2018年

  • Linux Kernel における BPF が成熟してきた
  • We apply patches to bpf & bpf-next kernel trees on git.kernel.org
  • Separate bpf kernel mailing list bpf@vger.kernel.org (archive at: lore.kernel.org/bpf/)
  • Our pull requests go to Linus Torvalds via David S. Miller (networking maintainer)
  • kTLS & eBPF : kernel space で TLS 処理を行う

  • bpftool & libbpf : アプリケーションの user space API (syscall + glibc のサブルーチン) のトレーシングツール

2018年

  • Cilium 1.0: K8s CNI integration
  • BTF (BPF Type Format) の策定
  • Linux Plumbers という BPF のカンファレンス
  • AF_XDP*2 が kernel に merge された
    • // AF_PACKET の SOCK_RAW より高速に raw packet を userspace に送るやつという理解
  • bpfilter: iptables ルールを翻訳し、 BPF を利用して XDP や Hardware offload で動作

2018, 2019年

  • DTrace 2.0 として bpftrace が announced
  • BPF本 *3 が出た
  • Cilium 1.6: iptables ベースの kube-proxy を置き換えた
  • BPF の live-patching 対応

f:id:skitazawa1121:20200820012406p:plain

(かわいい)

2019, 2020 年

  • Google が BPF な LSM (Linux Security Module) を社内利用
  • BPF verifier が Spectre の危険性のあるものを検証するようになった
  • SR-IOV 経由で XDP を利用する Cloud Provider
    • AWS: ena driver
    • Azure hv_netvsc driver
  • Cilium 1.8 : XDP ベースのロードバランシングと NetworkPolicy

Bringing eBPF revolution to K8s

kube-proxy を eBPF (Cilium) に置き換えるとどうなるかについての説明でした。

f:id:skitazawa1121:20200820012425p:plain

  • Socket *4 と XDP/tc の二箇所で Cilium の BPF 実装が動作する
    • Socket
      • East-West Traffic をハンドル
      • packet の生成前に BPF が syscall を hook するので、packet-level の NAT が必要ない
      • Node を中継しない (kube-proxy は必要だった)
      • NodePort service はローカルアドレスに公開、 host の 127.0.0.1/::1 で公開 *5
      • 他のアプリケーションによる Service Port の再利用をブロックする
    • XDP / tc
      • North-South Traffic をハンドル
      • DNAT と DSR/SNAT *6
      • XDP がより low-overhead で良い

f:id:skitazawa1121:20200820012433p:plain

感想

自分がまさに eBPF 初学者だったため、非常にためになるセッションでした。 特にセッション後半の eBPF の歴史については、成り立ちや派生ツールを知ることができ良かったです。

*1:https://github.com/facebookincubator/katran

*2:https://www.kernel.org/doc/html/latest/networking/af_xdp.html

*3:http://www.brendangregg.com/bpf-performance-tools-book.html

*4:多分 Pod 内の Socket を指している

*5:疑問点: CVE-2020-8558 が通ってしまうのでは?

*6:なんで DSR が出てきたか分からない・・

Improving the Performance of Your Kubernetes Cluster

KubeCon + CloudNativeCon Europe 2020 1日目 のセッションである Improving the Performance of Your Kubernetes Cluster についてです。

Step 1: Calculating overhead

  • シングルプロセスのオーバヘッドを計算する: https://github.com/priyawadhwa/track-cpu

    • duration と interval を指定すると、その間の監視対象プロセスの平均/最大 cpu 使用率を出してくれる
    • 発表された方の自作ぽい
  • プロセス全体のオーバヘッドを計算する: https://github.com/tstromberg/cstat

    • iostat より 100 倍正確らしい (README より)

それぞれの動作環境で CPU 使用率はそれぞれ以下の結果となった。

  • VM only: 0-4 %
  • VM + Kubeadm: 10-15 %
  • Minikube: 20-40 %

どのように Kubernetes Cluster のパフォーマンスを向上させるか、Minikube を例に以降の発表が続く。

Learning to use performance tools

こんなツールを使うといいよってやつ

The USE Method

USE: Utilization, Saturation and Errors

それぞれ確認した項目、コマンド、結論について述べられている。

Component Command Conclusion
CPU (system wide) mpstat -P ALL 1 CPU の %sys は通常通りで、1コアに負荷が集中してるわけでもない
CPU (minikube process) pidstat 1 -C qemu -h minikube プロセスのオーバヘッドは平均 22% で、内 14.5 % は VM 内からくるもの
Memory capacity free -m 通常
Storage Device I/O (Utilization) iostat -xz 1 通常
Storage Device I/O (Utilization, per process) sudo iotop --only 一度に minikube のもつ複数プロセスがディスク書き込みをしていることが分かった

eBPF in Minikube

  • BCC tools *1 を推奨していた
    • Huge collection of tracing tools in Python
    • These tools profile and trace the Linux kernel
    • Instructions for running bcc tools in minikube can be found at

biosnoop (Block Device I/O をトレースしてPID ごとの latency を取得) を実行してみると、殆ど etcd

f:id:skitazawa1121:20200819115354p:plain

Flame graph

ホストで Flame graph を取ると、CPU_n/KVM というのが見える

f:id:skitazawa1121:20200819115407p:plain

CPU_0/KVM の内訳をみると、ほとんど ioctl syscall が占めている

f:id:skitazawa1121:20200819115417p:plain

Is there a way to tune how often etcd writes to disk?

とりあえずやってみたチューニング (not significant と言われている)

  • etcd のディスク書き込みの頻度を減らしたい!
  • とりあえず etcd の --snapshot-count オプションをチューニングしてみる
  • --snapshot-count=3000 にしたところ 2% しか向上しなかった

ここまでのまとめ

  1. オーバヘッドの調査をした
    • USE の解析より、 etcd が disk 書き込みをめっちゃやってるように見えた
    • Flame Graph より、ioctl 呼び出しが原因っぽい
  2. チューニング: etcd の snapshot count の数を減らした
  3. パフォーマンス向上は見られなかった

What are these spikes?

以下の図より、 CPU 使用率は断続的にスパイクがあるように見える

f:id:skitazawa1121:20200819115431p:plain

pidstat より kubectl apply -f /etc/kubernetes/addons の実行が頻繁に CPU を使ってるように見えた

f:id:skitazawa1121:20200819115447p:plain

What is the addon manager?

  • kube-addon-manager *2 により5秒ごとに kubectl apply が実行されている!

  • ポーリング間隔を延ばしてみてオーバヘッドが改善するか試した -> 改善した!

  • ポーリング間隔とユーザエクスペリエンスはトレードオフだけど、今回は完全にポーリングをやめてみた
  • 32% 削減! *3

kube-apiserver overhead

次にオーバヘッドがありそうな、 kube-apiserver の改善

pprof

kube-apiserver に対して Golang のプロファイリングツールである pprof を利用してみた

  • top で CPU 使用率を見ると syscall.Syscall が flat%: 10.76%, sum%: 50.00% だった

    • flat: 1 call 当たりにかかる時間
    • flat%: 該当 flat の全体に対する割合
    • sum%: 累計flat%
  • flame graph より以下が分かった

    • filters.ServeHTTP が 16%
    • transport.Reader が 12%

Leader election requests from scheduler & controller manager

kube-apiserver を -v=10 で起動してみたら、 Leader election が目立った *4

f:id:skitazawa1121:20200819115556p:plain

  • minikube はシングルノードなので leader election を切ってしまおう!
    • kube-scheduler , kube-controller-manager それぞれのオプションに --leader-elect=false を指定
  • 18% の削減!
    • ついでに codedns の replica 数も1にしたとしれっと書かれている

etcd overhead

etcd でも同じように pprof で見てみた

  • top で CPU 使用率を見ると syscall.Syscall が flat%: 40.00%, sum%: 40.00% だった
  • web でビジュアライズすると、 http.writeFrameAsync というメソッドが 40ms の始まりっぽいのが分かった

Searching through etcd code

  • etcd のソースコード内で Golanghttp ライブラリを使ってる箇所を調べた -> httpproxy パッケージを使っている箇所を発見!
  • refreshInterval がデフォルト30秒で設定されていて、--proxy-refresh-interval オプションで設定できることが分かった
    • --proxy-refresh-interval を 70000 (70秒) に設定 -> 4%削減!

Does changing the refresh interval make user experience worse?

  • --proxy-refresh-interval の値は、endpoint *5 の更新間隔
    • ソースコード *6 より、endpoint が存在しない場合は1秒おきに、存在する場合は --proxy-refresh-interval に設定した秒数おきに更新をかける

まとめ

  • 不必要なものを取り除いた
    • Addon manager
    • Coredns pod
    • Leader election
  • オーバヘッドとユーザエクスペリエンスのトレードオフは考慮しましょう
  • コラボレーションはめっちゃ重要
    • 分からないときには Slack で質問

f:id:skitazawa1121:20200819115613p:plain

感想

ツールを使って計測することで minikube のどこが重いかを調査する内容で、とてもおもしろかったです。 自分は ISUCON をやることがあるのですが、その中でよく使うツールがこの発表でも出てきたので 「おおー ISUCON だ」となりましたw

*1:https://github.com/iovisor/bcc

*2:https://qiita.com/inajob/items/300805e895eec6535dd2 (分かりやすかったので引用させていただきました)

*3:CPU使用率を32%減らした ではなく、最初の状態を100とした場合に32%性能が向上したってことぽい (多分)

*4:これを見て自分はそう思える自信がない・・・

*5:etcd のendpoint のこと?

*6:https://github.com/etcd-io/etcd/blob/cfdc296a3c4f21c7bba244f17b4c2d7f68595ece/proxy/httpproxy/director.go#L52-L68 (聴講後現在の master HEAD)

Startup Containers in Lightning Speed with Lazy Image Distribution

KubeCon + CloudNativeCon Europe 2020 1日目 のセッションである Startup Containers in Lightning Speed with Lazy Image Distribution についてです。

KubeFest Tokyo 2020 の LT でも同様のお話をされていたので、そちらの動画のリンクも合わせて張っておきます。

要するに

OCI Image の lazy pull を実現して、 pull にかかる時間を改善した。

Problems on the OCI/Docker Specs

  • 従来の Docker 利用時の課題の一つ: イメージの pull が遅い
    • コンテナ起動時間の76%はpullに費やされるが、データは6.4%しか読まれないそう *1

Lazypull with containerd Stargz Snopshotter

OCI イメージのアーカイブ形式に tarball の代わりに stargz を利用し、containerd に Stargz Snapshotter をプラグインとして追加することで lazy pull を実現

  • lazy pull
    • pull 時には起動に必要な最小限のみフェッチ
    • 見せかけの rootfs を FUSE で提供
    • ファイルアクセスが有った際にオンデマンドで都度フェッチ

これにより、 python3.7 の docker pull の時間が: 約32秒 -> 約7秒

Stargz

  • tarball は "non-seekable"
    • 全体を読まないと中身のファイルを取得できない
  • Stargz : per-file で取得可能な tarball コンパチなアーカイブ形式

eStargz

  • Stargz の課題: オンデマンド fetch はネットワーク起因のオーバヘッドが無視できない
  • eStargz : 優先されるファイルをプリフェッチすることで上記の課題点を解決

ベンチマーク

スライドにあるので省略しますが、どれも Stargz , eStargz は従来と比べて pull にかかる時間が短くなっています。 また、 glassfish イメージの例では (オンデマンドにフェッチしてくるファイルが多いため?) Stargz でもそれなりに時間がかかってしまっていますが、 eStargz によるプリフェッチでより時間が短くなっています。

感想

言われてみれば docker pull に結構時間を食われるので、lazy pull 機能はすごく魅力的に感じました。 一方でセッション中に質問にも挙がっていましたが、lazy pull 方式をとってしまうと Registry が予期せず落ちてしまっていた場合に lazy pull も失敗してしまうと思うので、その辺りをどううまくやるのか気になりました。

Flux Deep Dive: A GitOps Approach to Progressive Delivery

KubeCon + CloudNativeCon Europe 2020 1日目 のセッションである Flux Deep Dive: A GitOps Approach to Progressive Delivery についてです。

GitOps を実現する CD ツールの一つである Flux について、Experimental な内容の話でした。

Flux は、2019年に話題になった Argo Flux (Flux の GitOps に関するコアな部分に https://github.com/argoproj/gitops-engine を利用したもの) を諦めて、今後 v2 として GitOps Toolkit となるようです。*1

GitOps Toolkit のドキュメントは以下です。発表の内容もほとんどこのドキュメントからでした。

Flux v1 と v2 の違い

GitOps Toolkit

  • GitOps Toolkit は以下のコンポーネントからなる

    • Source Controller
    • Kustomize Controller
    • Helm Controller
    • Notification Controller
    • (検討中らしい) image-update-controller
    • (検討中らしい) fleet-controller
  • これらのコンポーネントtk という CLI ツールから操作可能

Source Controller

以下のカスタムリソースを提供する。

  • GitRepository Resource
  • HelmRepository Resource
  • HelmChart Resource

これらのアーティファクトを以降の Kustomize Controller や Helm Controller が参照する。

f:id:skitazawa1121:20200818233531p:plain

Kustomize Controller

以下のカスタムリソースを提供する。

  • Kustomization
    • Source Controller の扱う GitRepository Resource を参照して以下を実施
      • kustomize build よりマニフェストを生成
      • yaml のバリデーションチェック
      • Kubernetes に apply
      • apply したものの Health Check
      • Notification Controller 経由で様々な外部サービスへ通知

f:id:skitazawa1121:20200818233455p:plain

Helm Controller

以下のカスタムリソースを提供する。

  • HelmRelease
    • HelmRepository , HelmChart Resource を参照して以下を実施

f:id:skitazawa1121:20200818233448p:plain

Notification Controller

以下のカスタムリソースを提供する

  • Receiver
    • GitHub, Harbor 等からイベントを受け取り、それをもとに上記 Controller (Source, Kustomize, Helm) のイベントを発火する
  • Provider , Alert
    • 上記 Controller からイベントを受け取り、それをもとに外部サービスへ通知する

f:id:skitazawa1121:20200818233552p:plain

Flagger

Flux v2 でも Flagger を使って以下の delivery strategies を取れるそうです。

  • Canary Release (progressive traffic shifting)
  • A/B Testing (HTTP headers and cookies traffic routing)
  • Blue/Green (traffic mirroring, traffic switch)

感想

個人的に Argo CD と Flux の統合により最強 GitOps 用 CD ツールが決定しないかなと軽く期待していたため、Flux が GitOps Engine を使わない選択をしたことは正直残念です。 これからも Flux v2 の動向もそうですし、残された GitOps Engine の動向も探っていこうと思います。