$30 off During Our Annual Pro Sale. View Details »

K8sとTraefikでつくるマイクロフロントエンド

Kim, Hirokuni
September 08, 2020

 K8sとTraefikでつくるマイクロフロントエンド

CloudNative Days Tokyo 2020 #CNDT2020_A

Kim, Hirokuni

September 08, 2020
Tweet

More Decks by Kim, Hirokuni

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. 9
    解決したい問題

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  15. 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
    マイクロサービスのアイデアをフロントエンドに応用する

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


    新UIのリプレイスが進まない

    View Slide

  25. 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...

    View Slide

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

    View Slide

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

    View Slide

  28. 28
    Traefikとは?

    View Slide

  29. 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/

    View Slide

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

    View Slide

  31. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  35. 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

    View Slide

  36. 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
    追加してデプロイ

    View Slide

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

    View Slide

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

    View Slide

  39. 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

    View Slide

  40. 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
    期待通りにリダイレクトされる?

    View Slide

  41. 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のテスト環境が必要となる

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. 45
    Traefikのおかげで…

    View Slide

  46. 46
    Traefikのおかげで…
    2 × ⚙

    View Slide

  47. 47
    Traefikのおかげで…
    3 × ⚙

    View Slide

  48. 48
    Traefikのおかげで…
    4 × ⚙

    View Slide

  49. 49
    Traefikのおかげで…
    5 × ⚙

    View Slide

  50. 50
    Traefikのおかげで…
    6 × ⚙

    View Slide

  51. 51
    Traefikのおかげで…
    7 × ⚙

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  61. 61
    DRY問題

    View Slide

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

    View Slide

  63. 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に書かないといけない

    View Slide

  64. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  75. 75
    まとめ

    View Slide

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

    View Slide

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

    View Slide