Slide 1

Slide 1 text

Masaya Aoyama 3-shake Kubernetesクラスタ内のリソースに 柔軟なフィルタリングをかける方法 3-shake SRE Tech Talk #4 LT amsy810 @amsy810

Slide 2

Slide 2 text

- Co-chair ⻘⼭真也 + CREATIONLINE - 技術アドバイザ + SAKURA Internet Research Center – 客員研究員 + 3-shake 技術顧問 + PLAID - Organizer - KaaS Product Owner - Publications Twitter: @amsy810

Slide 3

Slide 3 text

kubectl get pods --filter Service ʹඥ෇͍͍ͯͳ͍Pod

Slide 4

Slide 4 text

kubectl get ServiceMonitors --filter Serviceʹඥ෇͍͍ͯͳ͍ServiceMonitor

Slide 5

Slide 5 text

Ͳ͏΍ͬͯ΍Γ·͔͢ʁ

Slide 6

Slide 6 text

• ServiceMonitor は Prometheus Operator で実装されている API • 指定された条件の Service (Endpoint)に対して Scrape を⾏う ServiceMonitor と Service リソース Kind: ServiceMonitor spec: endpoints: - path: /metrics port: service namespaceSelector: matchNames: - default selector: matchLabels: app: my-app Kind: Service metadata: namespace: default labels: app: my-app spec: {} Service Endpoint 10.0.0.1 Endpoint 10.0.0.2 app: my-app app: my-app app: my-app Scrape

Slide 7

Slide 7 text

• ラベルの整理を⾏ったところ ServiceMonitor にマッチしない状態に • Argo CD が app.kubernetes.io/instance ラベルを付与する兼ね合いで Git リポジトリ上では判別できないケースもあり ServiceMonitor と Service リソース Kind: ServiceMonitor spec: endpoints: - path: /metrics port: service namespaceSelector: matchNames: - default selector: matchLabels: app: my-app Kind: Service metadata: namespace: default labels: app: dummy spec: {} Service Endpoint 10.0.0.1 Endpoint 10.0.0.2 app: dummy app: dummy app: dummy Scrape

Slide 8

Slide 8 text

無意味な ServiceMonitor の⼀覧を表⽰したい = ServiceMonitor で指定されている Service が存在するか否か • e.g. Deployment に PDB / HPA / etc が存在しているか • e.g. 使われていない ConfigMap / ServiceAccount / etc が存在するか 実現したいこと Service Endpoint 10.0.0.1 Endpoint 10.0.0.2 app: dummy app: dummy app: dummy Scrape

Slide 9

Slide 9 text

• kubectl get servicemonitors -o jsonpath=ʻ.items[?(@...)]ʼ • 複数のリソースにまたがる条件⼀致は指定できない • jq や go-template でも同様 • 軽量なプログラムを Go などで実装する • client-goで実装し、ポリシーロジックを実装するのは少々⼿間がかかる • Gatekeeper で ServiceMonitor / Service の 作成/更新時 にチェックを⾏う • audit 機能があるものの新たな要件発⽣時には対応しづらい 考えられる⽅法

Slide 10

Slide 10 text

ղܾࡦͷ࣮૷ํ๏ࣗମ͸Α͋͘Δ࿩Ͱ͢

Slide 11

Slide 11 text

• kubectl get した結果を元に Conftest を実⾏する Conftest を⽤いて柔軟なフィルターを実装する deny[msg] { sm = input.items[_] sm.kind == "ServiceMonitor" not has_valid_svc(sm, input.items) msg = sprintf("ServiceMonitor=%s", [sm.metadata.name]) } $ kubectl get service,servicemonitor –A –o yaml apiVersion: v1 items: - kind: Service metadata: {name: svc-1} - kind: Service metadata: {name: svc-2} - kind: ServiceMonitor metadata: {name: sm-1} ... • 取得した複数の Object は items[] 配列に格納 • YAML ストリームではなく単⼀のドキュメントと して返されるため、”conftest test” 実⾏時の --combine オプションは不要

Slide 12

Slide 12 text

kubectl get と conftest test --combine を両⽴する • kubectl get で取得した list を元にテストする場合 deny[msg] { sm = input[_] sm.kind == "ServiceMonitor" not has_valid_svc(sm, input) msg = sprintf("ServiceMonitor=%s", [sm.metadata.name]) } deny[msg] { sm = input.items[_] sm.kind == "ServiceMonitor" not has_valid_svc(sm, input.items) msg = sprintf("ServiceMonitor=%s", [sm.metadata.name]) } • conftest test --combine でマニフェストを元にテストする場合(CI での利⽤を想定) 後々 CI にも Conftest を組み込んで再利⽤できる形で関数を実装する 特定のリソース or リソースの配列に対する関数を意識して実装する

Slide 13

Slide 13 text

あとは Rego でポリシーを実装するだけ • ServiceMonitor の Selector に⼀致する Service の存在確認(実際には Namespace を考慮すること) # ServiceMonitor にマッチする Service が1つ以上存在することの確認 has_valid_svc(sm, items){ svc = items[i] svc.kind == "Service" match_svc(sm, svc) } # 「1つのServiceMonitorのSelector」と「1つのServiceのラベル」がマッチするか否かの確認 match_svc(sm, svc) { s := {sprintf("%s=%s", [i, sm.spec.selector.matchLabels[i]]) | sm.spec.selector.matchLabels[i]} l := {sprintf("%s=%s", [i, svc.metadata.labels[i]]) | svc.metadata.labels[i]} sub := s - l count(sub) = 0 } ポリシーは下記の通り数⾏で表現可能

Slide 14

Slide 14 text

まとめ クラスタから取得した情報をもとに、柔軟にフィルタリングを掛ける場合にも Conftest は有⽤ • yq などでの表現⼒ < Rego の表現⼒ • 複数のリソースにまたがるポリシー 実装したフィルタリングポリシーは、場合によっては CI に組み込むことも有⽤ • ServiceMonitor に適切な Service が存在するか(不適切な Selector の防⽌) Kind: ServiceMonitor spec: endpoints: - path: /metrics port: service selector: matchLabels: app: my-app Kind: Service metadata: namespace: default labels: app: dummy spec: {} ?

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Thank you for your attention Twitter: @amsy810