Slide 1

Slide 1 text

1 K8sとTraefikでつくる マイクロフロントエンド Marek Nowak Engineering Manager 金 洋国 Staff Site Reliability Engineer

Slide 2

Slide 2 text

2 CircleCIについて ✓ 世界最大規模のクラウド CI/CD サービス ✓ より良いコードをより速く、簡単にリリースすることを可能に ✓ 2011年設立、サンフランシスコ本社 ✓ 300人+の社員(米国、東京、英国にオフィス) ✓ 2020年4月 1億ドルのシリーズEを実施 Representative Customers

Slide 3

Slide 3 text

3 宣伝: CircleCIの本が発売されます 発売日: 9月 出版社: 技術評論社 WEB+DB PRESS シリーズ 著者: 浦井誠人、大竹智也、金洋国

Slide 4

Slide 4 text

4 コミュニティーもやっています CircleCI・connpassで検索!

Slide 5

Slide 5 text

5 UIのリプレイスについて 旧 UI 新 UI

Slide 6

Slide 6 text

6 Marek Nowak (ノバック マレック) Engineering Manager 新UI 開発チームのマネージャー Wall Street Journalに載ってた 絵文字エキスパート。 Kim, Hirokuni (金 洋国) Staff Site Reliability Engineer SREチーム CircleCIで5年ほど働いています。サポート、開発、 日本支社立ち上げ、色々やってきました 自己紹介

Slide 7

Slide 7 text

7 このプレゼンテーションについて ✓ モノリスの旧UIをマイクロフロントエンドの新UIに置き換えた時の話 ✓ バックエンド (キム) とフロントエンド (マレック) の両側面からお話します ✓ 時間の関係で内容は広く・浅くなりますがご容赦を

Slide 8

Slide 8 text

8 Agenda 解決したい問題 Traefikとは? MFを導入して学んだこと DRY問題 まとめ 1 2 3 4 5

Slide 9

Slide 9 text

9 解決したい問題

Slide 10

Slide 10 text

10 解決したい問題 (フロントエンド編) ✗ 旧UIのフロントエンドはレガシーコード

Slide 11

Slide 11 text

11 解決したい問題 (フロントエンド編) ✗ 旧UIのフロントエンドはレガシーコード ○ 三つのフレームワークが混ざってて 複雑 ■ ClojureScript/Om ■ ClojureScript/Om Next ■ JavaScript + Flow

Slide 12

Slide 12 text

12 解決したい問題 (フロントエンド編) ✗ 旧UIのフロントエンドはレガシーコード ○ 三つのフレームワークが混ざってて 複雑 ■ ClojureScript/Om ■ ClojureScript/Om Next ■ JavaScript + Flow ○ 変更するのは難しい ○ 新機能の開発はもうムリ

Slide 13

Slide 13 text

13 解決したい問題 (フロントエンド編) ✗ 旧UIのフロントエンドはレガシーコード ○ 三つのフレームワークが混ざってて 複雑 ■ ClojureScript/Om ■ ClojureScript/Om Next ■ JavaScript + Flow ○ 変更するのは難しい ○ 新機能の開発はもうムリ ✗ フロントエンド開発したいチームは 複数

Slide 14

Slide 14 text

14 解決したい問題 (フロントエンド編) ✗ 旧UIのフロントエンドはレガシーコード ○ 三つのフレームワークが混ざってて 複雑 ■ ClojureScript/Om ■ ClojureScript/Om Next ■ JavaScript + Flow ○ 変更するのは難しい ○ 新機能の開発はもうムリ ✗ フロントエンド開発したいチームは 複数 ○ レガシーコードー直しても また複雑になるリスク

Slide 15

Slide 15 text

15 マイクロフロントエンド(MF)とは? Good frontend development is hard. <省略> We'll describe a recent trend of breaking up frontend monoliths into many smaller, more manageable pieces, and how this architecture can increase the effectiveness and efficiency of teams working on frontend code. https://martinfowler.com/articles/micro-frontends.html#Benefits マイクロサービスのアイデアをフロントエンドに応用する

Slide 16

Slide 16 text

16 マイクロフロントエンド(MF)とは? チーム1 チーム2 チーム3

Slide 17

Slide 17 text

17 マイクロフロントエンド(MF)とは? チーム1 チーム2 チーム3

Slide 18

Slide 18 text

18 projects MF pipeline MF org MF plans MF users MF 複数のフロントエンドで作られている

Slide 19

Slide 19 text

19 新コードベース ローカル開発環境の セットアップも、 新機能の開発も スピードアップのために。 マイクロサービスは 当たり前 CircleCIではすでにマイクロサー ビスは当たり前になった。 同じアイデアをフロントエンドにも 適用しましょう! 複数のチームでも 楽々 他のチームを 邪魔せずに 自由に開発できるように。 MFを導入の目的は…

Slide 20

Slide 20 text

20 解決したい問題 (バックエンド編) ✗ 一つMFを作るために、、、 ○ DNS設定 ○ ELB設定 ○ Nginx設定 ○ CDN設定

Slide 21

Slide 21 text

21 解決したい問題 (バックエンド編) ✗ 気軽に変更できない ○ すでに circleci.com のホスティングに使われている ○ MFを追加する度にリスク ○ フロントエンド開発者はNginx触りたくない ○ 毎回SREがやらないといけない

Slide 22

Slide 22 text

22 その結果、、、 SREがボトルネックに

Slide 23

Slide 23 text

23 その結果、、、 マイクロフロントエンドの開発スピードダウン SREがボトルネックに ⬇

Slide 24

Slide 24 text

24 その結果、、、 マイクロフロントエンドの開発スピードダウン SREがボトルネックに ⬇ ⬇ 新UIのリプレイスが進まない

Slide 25

Slide 25 text

25 それでどうなった? ELB1 ELB2 ELB3 ELB4 mf-onboarding mf-pipeline mf-user-settings mf-project-settings Node Port:30001 Node Port:30002 Node Port:30003 Node Port:30004 DNSとELBをそれぞれのMFごとに作ってNginxを回避 onboarding.circleci.com ui.circleci.com accounts.circleci.com projects.circleci.com circleci.com 新UI 旧UI some pods...

Slide 26

Slide 26 text

26 その結果 「Add Projects」を押すと https://projects.circleci.com へ 「Organization Settings」を押すと https://accounts.circleci.com へ メインの画面は https://ui.circleci.com

Slide 27

Slide 27 text

27 なんとかせんといかん! ✓ MFごとにDNSとELBを作ってはいけない ✓ app.circleci.com でMFをまとめよう ✓ 開発チームがSREに依存しなくていいようにNginxを置き換えよう

Slide 28

Slide 28 text

28 Traefikとは?

Slide 29

Slide 29 text

29 Træfɪk Traefik is a leading modern reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically. https://containo.us/traefik/

Slide 30

Slide 30 text

30 Traefikの特徴 ✓ NginxみたいなReverse Proxy ✓ HAProxyみたいなLoad Balancer ✓ Container Native (次のスライドで解説) ✓ 動的な設定のリロード ○ MFの変更ごとに再起動しなくてもいい ○ Nginxだと設定変更の度に再起動が必要

Slide 31

Slide 31 text

31 Traefik V1 ● V1のリリースは 2016年 ● No TCPサポート ● 主にHTTPのReverse Proxyとして設計 ● V1の最後のバージョンは 1.7.18 ● CircleCIでは1.7.18を使用 ● MFを構築する機能は十分! Traefik V2 ● 2019年9月にV2リリース ● ブログ: https://containo.us/blog/traefik-2-0-6531ec5196c2/ ● TCPサポート ● Middlewareサポート ● その他色々 Traefik: V1 vs V2

Slide 32

Slide 32 text

32 Container Native ✓ Telemetryの標準サポート ○ Metrics ○ Tracing ✓ マルチプラットフォーム ○ Docker ○ Mesos ○ Kubernetes

Slide 33

Slide 33 text

33 K8s上ではIngress Controllerとして動作

Slide 34

Slide 34 text

34 IngressとIngress Controllerについて Ingress Controller -> リクエストを実際にハンドリング ✓ Traefik ✓ Nginx ✓ AWS ALB Ingress -> K8s オブジェクト ✓ Internet -> K8s -> Service のルーティング ✓ Ingressだけでは意味がない

Slide 35

Slide 35 text

35 Traefik良かったこと: Self-Serving Deployの推進 kind: Ingress metadata: spec: rules: - host: app.circleci.com http: paths: - path: /path-foo backend: serviceName: foo-service /path-foo -> foo-service

Slide 36

Slide 36 text

36 Traefik良かったこと: Self-Serving Deployの推進 kind: Ingress metadata: spec: rules: - host: app.circleci.com http: paths: - path: /path-foo backend: serviceName: foo-service kind: Ingress metadata: spec: rules: - host: app.circleci.com http: paths: - path: /path-foo backend: serviceName: foo-service - path: /path-bar backend: serviceName: bar-service /path-foo -> foo-service /path-foo -> foo-service /path-bar -> bar-service 追加してデプロイ

Slide 37

Slide 37 text

37 Traefik良かったこと: Self-Serving Deployの推進 ✓ 各フロントエンドのK8sマニフェストでIngress設定を管理 ✓ 各チームが自由にDeployできる

Slide 38

Slide 38 text

38 Traefik良かったこと: Self-Serving Deployの推進 ✓ 各フロントエンドのK8sマニフェストでIngress設定を管理 ✓ 各チームが自由にDeployできる SREがボトルネックにならない

Slide 39

Slide 39 text

39 Traefik困ったこと: Annotationのテストの難しさ 例えば、https://foo.circleci.com -> https://bar.circleci.com にリダイレクトしたい kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/redirect-permanent: "true" traefik.ingress.kubernetes.io/redirect-regex: ^https://foo.circleci.com traefik.ingress.kubernetes.io/redirect-replacement: https://bar.circleci.com

Slide 40

Slide 40 text

40 Traefik困ったこと: Annotationのテストの難しさ 例えば、https://foo.circleci.com -> https://bar.circleci.com にリダイレクトしたい kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/redirect-permanent: "true" traefik.ingress.kubernetes.io/redirect-regex: ^https://foo.circleci.com traefik.ingress.kubernetes.io/redirect-replacement: https://bar.circleci.com 期待通りにリダイレクトされる?

Slide 41

Slide 41 text

41 Traefik困ったこと: Annotationのテストの難しさ 例えば、https://foo.circleci.com -> https://bar.circleci.com にリダイレクトしたい kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/redirect-permanent: "true" traefik.ingress.kubernetes.io/redirect-regex: ^https://foo.circleci.com traefik.ingress.kubernetes.io/redirect-replacement: https://bar.circleci.com K8sのテスト環境が必要となる

Slide 42

Slide 42 text

42 Traefik困ったこと: SREボトルネック再び ✓ Traefik導入後すぐにMFの数が増えた (現在15個くらい) ✓ 各チームでやりたいことが徐々に複雑に、、、 ○ 共通のエラーページを使いたい ○ カスタムヘッダーってどう設定するんだっけ? ✓ K8s/Traefikのテスト環境を用意しないといけない

Slide 43

Slide 43 text

43 Traefik困ったこと: SREボトルネック再び ✓ Traefik導入後すぐにMFの数が増えた (現在15個くらい) ✓ 各チームでやりたいことが徐々に複雑に、、、 ○ 共通のエラーページを使いたい ○ カスタムヘッダーってどう設定するんだっけ? ✓ K8s/Traefikのテスト環境を用意しないといけない SREでやり方を調査する待たせてしまう

Slide 44

Slide 44 text

44 MFを導入して学んだこと

Slide 45

Slide 45 text

45 Traefikのおかげで… ⚙

Slide 46

Slide 46 text

46 Traefikのおかげで… 2 × ⚙

Slide 47

Slide 47 text

47 Traefikのおかげで… 3 × ⚙

Slide 48

Slide 48 text

48 Traefikのおかげで… 4 × ⚙

Slide 49

Slide 49 text

49 Traefikのおかげで… 5 × ⚙

Slide 50

Slide 50 text

50 Traefikのおかげで… 6 × ⚙

Slide 51

Slide 51 text

51 Traefikのおかげで… 7 × ⚙

Slide 52

Slide 52 text

52 MFを導入して学んだこと 使っているツール ✓ TypeScript ✓ React ✓ Apollo GraphQL ✓ Next.js 7 × ⚙

Slide 53

Slide 53 text

53 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も

Slide 54

Slide 54 text

54 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も ! モノリスでも、MFでも コミュニケーションは難しい

Slide 55

Slide 55 text

55 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も ! モノリスでも、MFでも コミュニケーションは難しい ○ 「Frontend Roundtable」

Slide 56

Slide 56 text

56 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も ! モノリスでも、MFでも コミュニケーションは難しい ○ 「Frontend Roundtable」 ○ クロスチームコラボレーション

Slide 57

Slide 57 text

57 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も ! モノリスでも、MFでも コミュニケーションは難しい ○ 「Frontend Roundtable」 ○ クロスチームコラボレーション ○ 「Frontend Platform Team」

Slide 58

Slide 58 text

58 MFを導入して学んだこと ✓ MFの段階的なロールアウトは便利 ○ 一つずつのMFを導入できる ○ Feature Flagを使用して MF以内の新機能も ! モノリスでも、MFでも コミュニケーションは難しい ○ 「Frontend Roundtable」 ○ クロスチームコラボレーション ○ 「Frontend Platform Team」 ✓ 複雑なレガシーコードーになるリスクは 小さくなった

Slide 59

Slide 59 text

59 MFを導入して学んだこと ✓ ローカル開発環境のセットアップはとても簡単になりました ○ 前のモノリスの〜8時間から… ○ …10分に!

Slide 60

Slide 60 text

60 MFを導入して学んだこと ✓ ローカル開発環境のセットアップはとても簡単になりました ○ 前のモノリスの〜8時間から… ○ …10分に! ✓ デザイナー達までも直接開発できるようになった!

Slide 61

Slide 61 text

61 DRY問題

Slide 62

Slide 62 text

62 DRY問題 (バックエンド) ✓ グローバルな設定の扱い辛さ ○ 各IngressのAnnotationに同じことを書かないといけない

Slide 63

Slide 63 text

63 DRY問題 (バックエンド) ✓ グローバルな設定の扱い辛さ ○ 各IngressのAnnotationに同じことを書かないといけない kind: Ingress metadata: annotations: ingress.kubernetes.io/custom-response-headers: Strict-Transport-Security:max-age=N; includeSubDomains 例: Hypertext Strict Transport Security(HSTS)の設定 これを各Ingressに書かないといけない

Slide 64

Slide 64 text

64 DRY問題 (バックエンド) K8sマニフェストのラッパーを導入 # ラッパー kind: Ingress metadata: annotations: commonSecureHeaders: enable # 実際にレンダリングされる Ingress kind: Ingress metadata: annotations: ingress.kubernetes.io/browser-xss-filter: "true" ingress.kubernetes.io/content-type-nosniff: "true" ingress.kubernetes.io/custom-frame-options-value: SAMEORIGIN ingress.kubernetes.io/custom-response-headers: Strict-Transport-Security:max-age=N; includeSubDomains

Slide 65

Slide 65 text

65 DRY問題 (フロントエンド ) ! ブートストラップ     ✨

Slide 66

Slide 66 text

66 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡ 

Slide 67

Slide 67 text

67 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡ 

Slide 68

Slide 68 text

68 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー       ! デザイン ○ Component System  ! モニタリング ○ エラー       

Slide 69

Slide 69 text

69 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡ 

Slide 70

Slide 70 text

70 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡  ○ アップタイム    

Slide 71

Slide 71 text

71 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡  ○ アップタイム     ➡ 

Slide 72

Slide 72 text

72 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡  ○ アップタイム     ➡ 

Slide 73

Slide 73 text

73 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡  ○ アップタイム     ➡  ! デプロイ        

Slide 74

Slide 74 text

74 DRY問題 (フロントエンド ) ! ブートストラップ     ✨ ➡  ! APIのラッパー        ➡  ! デザイン ○ Component System   ➡  ! モニタリング ○ エラー        ➡  ○ アップタイム     ➡  ! デプロイ          ➡  +

Slide 75

Slide 75 text

75 まとめ

Slide 76

Slide 76 text

76 MF 続ける? やめる? SREとしては、 ✓ フロントエンドチームの開発速度をあげることができたので続けたい ✓ Traefikの細かい問題はあったけど、多くは v2で改善されている フロントエンド開発チームとしては、 ✓ 自由な開発やロールアウトは最高 ✓ クロスチームコミュニケーションはどうしても大事だから頑張らなくちゃ

Slide 77

Slide 77 text

77 ありがとうございました