Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Go design theory learned from Kubernetes
Search
Takamichi Omori
April 24, 2021
Programming
3.7k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Go design theory learned from Kubernetes
Takamichi Omori
April 24, 2021
More Decks by Takamichi Omori
See All by Takamichi Omori
小さい仕事をするLLMと精度検証
onsd
3
3.3k
AI-UXを実現する請求書自動分割の裏側
onsd
0
350
pprof で見つけた OOM の真相 #layerxgo
onsd
0
650
プロダクトライフサイクルに合わせた 「技術選定」の実践
onsd
1
600
kubefork - development experience like owning your own cluster
onsd
1
1.9k
Other Decks in Programming
See All in Programming
mrbgem 三角測量 開発
ogom
0
170
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
9.3k
カツオ、ご期待ください
suneo3476
0
130
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
410
GitHubハンズオン講座 — 実務レベルのチーム開発のフローを身につけよう
junhat6
0
110
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
520
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
230
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.2k
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
380
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.3k
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
140
Agents on Rails - Rails at Scale 2026
irinanazarova
0
310
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
260
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
690
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
750
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Making the Leap to Tech Lead
cromwellryan
135
10k
Automating Front-end Workflow
addyosmani
1369
210k
It's Worth the Effort
3n
188
29k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
Transcript
©2021 Wantedly, Inc. Kubernetes ͔ΒֶΜͩ Go ͷઃܭ (P$POGFSFODF4QSJOH 0OMJOF
"QS 5BLBNJDIJ0NPSJ!POTE@
©2021 Wantedly, Inc. Takamichi Omori @onsd_ DX Squad Intern, Wantedly,
Inc. Love Kubernetes, Go, etc *BN 2 https://www.wantedly.com/id/onsd_
©2021 Wantedly, Inc. /42 8BOUFEMZͱ(P ຊ൪ͷ(P ύϑΥʔϚϯε͕༏ઌ͞ΕΔͱ͜Ζ ௨ཧͳͲͷج൫ Kubernetes ؔ࿈
CLIπʔϧ 3
©2021 Wantedly, Inc. /42 %94RVBEͱʁ %FWFMPQFSF9QFSJFODF4RVBE https://event.cloudnativedays.jp/cndo2021/talks/281 ٕज़ج൫νʔϜͱհ͞ΕΔ͜ͱଟ͍Ͱ͢ ະདྷͷ։ൃମݧΛͭ͘Δ ։ൃऀͷੜ࢈ੑΛ্ͤ͞ΔͨΊʹԿͰ͍ͬͯ͘νʔϜ
৽͍͠ Microservice ͷ։ൃମݧ ෳࡶͳMicroservice Ͱ։ൃ͕؆୯ʹߦ͑ΔΑ͏ͳΈ࡞Γ ৽͍͠։ൃମݧ ʹ͍ͭͯৄ͘͠ 4
©2021 Wantedly, Inc. /42 ࠓ͢͜ͱ ,VCFSOFUFT͔ΒֶΜͩ(Pͷઃܭ 5 ࣮ྫɿCustom Controller ͷ࣮͔ΒֶΜͩઃܭ
• Package Λ͚ͯॲཧΛΘ͔Γ͘͢͢Δํ๏ • εφοϓγϣοτςετʹ͍ͭͯ
©2021 Wantedly, Inc. $VTUPN$POUSPMMFSͱ Photo by NeONBRAND on Unsplash 6
©2021 Wantedly, Inc. /42 $VTUPN$POUSPMMFSͱ ,VCFSOFUFTΛ֦ு͢ΔΈͷҰͭ https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ 7 Kubernetes ʹ
Deployment, Service ͷΑ͏ʹͨ͘͞ΜͷϦιʔε͕ଘࡏ͢Δ Custom Controller ɺಠࣗʹઃܭͨ͠ϦιʔεΛίϯτϩʔϧ͢ΔͨΊͷΞϓϦέʔγϣϯ
©2021 Wantedly, Inc. ࡐͱ͢Δ Custom Controller ͷಛ Photo by Nikolai
Chernichenko on Unsplash 8
©2021 Wantedly, Inc. /42 ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ πϦʔߏʹͳ͍ͬͯΔ 9 ͔ΒෳͷϦιʔε͕Ͱ͖Δ
©2021 Wantedly, Inc. /42 ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ ϦιʔεҎ֎͔ΒӨڹΛड͚ΔϦιʔε͕͋Δ ผϦιʔε͕มߋ͞Εͨͱ͖ʹࢠϦιʔεΛมߋ͢Δ controller Λผʹ࡞Δඞཁ͕͋Δ 10
©2021 Wantedly, Inc. ෳࡶͳ controller ϨΠϠʔΛ͚Α͏ Photo by Hasan
Almasi on Unsplash 11
©2021 Wantedly, Inc. /42 3FDPODJMF 3FDPODJMF ͋ΔϦιʔεͷঢ়ଶ͔ΒΫϥελͷঢ়ଶΛߋ৽͢Δॲཧ Kubebuilder Λ͍ͬͯΔ߹ɺ
ඞཁͳϦιʔεΛ࡞͢ΔॲཧΛReconcile ʹॻ͘ 12
©2021 Wantedly, Inc. /42 ૉʹॻ͍͍ͯͬͨ߹ 3FDPODJMFʹͯ͢Λॻ͘ੈք 1. ཧతͳϦιʔεͷঢ়ଶΛܭࢉ 2. ͕ࠩ͋Δ߹ߋ৽
3. ඞཁ͕ͳ͘ͳͬͨϦιʔε͕͋Δ߹ফ͢ ࠓճͷྫͩͱɺෳͷϦιʔεΛ࡞ɾߋ৽ɾআ ͢Δඞཁ͕͋ͬͨ 13
©2021 Wantedly, Inc. /42 ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ ϦιʔεҎ֎͔ΒӨڹΛड͚ΔϦιʔε͕͋Δ ผϦιʔε͕มߋ͞Εͨͱ͖ʹࢠϦιʔεΛมߋ͢Δ controller Λผʹ࡞Δඞཁ͕͋Δ 14
©2021 Wantedly, Inc. /42 ෳͷDPOUSPMMFSΛؚΉ߹ͷ 3FDPODJMFʹͯ͢Λॻ͘ ෳͷController ͔Β ߋ৽͞ΕΔϦιʔε͕͋Δ
Reconciler ʹॲཧΛॻ͘ͱɺ ಉ͡ॲཧ͕ෳͷՕॴͰॏෳͯ͠͠·͏ 15
©2021 Wantedly, Inc. /42 6QEBUFSͷಋೖ 6QEBUFS ಛఆͷϦιʔεΛ࡞ɾߋ৽ɾআ͢ΔྲྀΕΛ·ͱΊͯ Updaterͱ࣮ͯ͢͠Δ Controller
ʹॻ͍ͨ߹ͱൺͯɺॲཧͷڞ௨Խ ͕ਤΕΔ 16
©2021 Wantedly, Inc. /42 6QEBUFSͷJOUFSGBDF 6QEBUFS 17 // type NamespacedName
struct { / / Namespace strin g / / Name strin g // } type Updater interface { Update(ctx context.Context, slug types.NamespacedName) erro r / / ListOption is used specify namespac e UpdateAll(ctx context.Context, opts ...client.ListOption) erro r }
©2021 Wantedly, Inc. /42 6QEBUFS͕શͯͷॲཧΛߦ͏ͱ͖ͷ ͯ͢ͷ݅Λཏ͢Δͷ͕େม ӈͷྫͩͱɺআ͢Δॲཧ·ͰUpdaterͰ͍ͬͯΔɻ - আ͢Δ݅ -
ԿΛͲ͜·Ͱফ͍͍ͯ͠ͷ͔ ͳͲ͕Θ͔ΓͮΒ͘ͳΓɺ࣮͕େมʹͳΔɻ 18
©2021 Wantedly, Inc. /42 3FGSFTIFSͷಋೖ 3FGSFTIFS ཧతͳϦιʔεͷঢ়ଶ͕͞ΕΔͱɺΫϥελ্ͷ Ϧιʔε͕ཧతͳঢ়ଶʹͳΔΑ͏ʹ
Ճɾߋ৽ɾআΛߦ͏ϢʔςΟϦςΟϥΠϒϥϦ 19
©2021 Wantedly, Inc. /42 3FGSFTIFSͷJOUFSGBDF 3FGSFTIFS 20 ࣮ࡍϨΠϠʔͱ͍͏ΑΓϥΠϒϥϦ // util.Object
represents Kubernetes Resourc e type Refresher interface { Refresh(ctx context.Context , parent util.Object, children []util.Object) erro r }
©2021 Wantedly, Inc. /42 3FGSFTIFS͕͋ΔͱԿ͕خ͍͠ͷ͔ ͷ؆ུԽ ཧঢ়ଶΛड͚औΓɺෆཁͳϦιʔεআ͢Δ RefresherΛಋೖ͢Δ͜ͱͰ UpdaterΛ࣮͢Δࡍʹඞཁͳͷɺཧతͳ
ϦιʔεͷϦετΛ࡞Δॲཧ͚ͩʹͳͬͨ 21 ॲཧͷڞ௨Խ Ϧιʔεʹࢠ͕ؔ͋Δ߹ɺRefresherΛ ͏͜ͱͰॲཧͷڞ௨Խ͕Ͱ͖Δ
©2021 Wantedly, Inc. /42 3FGSFTIFS͕ݱঢ়Λཧʹ͚ۙͮΔํ๏ আ͢ΔϦιʔεͷಛఆ Refresher ɺϦιʔεͱཧతͳࢠϦιʔεͷ ϦετΛड͚औΔ
Ϧιʔε͔Β͢Ͱʹଘࡏ͢ΔࢠϦιʔεΛಛఆ͠ɺ ड͚औͬͨϦιʔεͱൺֱ͢Δ͜ͱͰআ͢Δ͖ ϦιʔεΛಛఆͰ͖Δ ࢠؔͷ੍ ͋ΔϦιʔεඞͣϦιʔεΛ࣋ͭͱ͍͏੍ 22
©2021 Wantedly, Inc. /42 ,VCFSOFUFT্ͰࢠؔΛࣔ͢ํ๏ 0XOFS3FGFSFODF 23 Ϧιʔεʹ͍ͭͯɺͦͷΦʔφʔϦιʔεΛࣔ͢ϑΟʔϧυ OwnerReference ͷϝϦοτ
Owner ͕ফ͑ͨͱ͖ʹGC ͕ࢠϦιʔεΛফͯ͘͠ΕΔ πϦʔߏΛ࣋ͭϦιʔεΛཧ͢Δͱ͖͚͓ͭͯ͘ͱศར
©2021 Wantedly, Inc. /42 #VJMEFSͷಋೖ #VJMEFS • ͋ΔϦιʔεʹ͍ͭͯɺཧతͳঢ়ଶΛܭࢉ͢Δ • ܭࢉͨ݁͠ՌΛRefresherʹΘͨ͢
24
©2021 Wantedly, Inc. /42 #VJMEFSͷJOUFSGBDF #VJMEFS • ͋ΔϦιʔεʹ͍ͭͯɺཧతͳঢ়ଶΛܭࢉ͢Δ • ܭࢉͨ݁͠ՌΛRefresherʹΘͨ͢
25 // util.Object represents Kubernetes Resourc e type Builder interface { Build(ctx context.Context) ([]util.Object, error ) }
©2021 Wantedly, Inc. /42 ϨΠϠʔ͚ͷ·ͱΊ Updater Builder Refresher ͋ΔϦιʔεʹ͍ͭͯͷॲཧΛ·ͱΊΔ ͋ΔϦιʔεʹ͍ͭͯɺཧతͳঢ়ଶΛͭ͘Δ
Builder͕͢Ϧετʹଇͬͯ ཧతͳঢ়ଶΛ࣮ݱ͢ΔϥΠϒϥϦ 26
©2021 Wantedly, Inc. /42 ϨΠϠʔ͚ͷ۩ମྫ 27 // type virtualServiceUpdater struct
{ // client client.Clien t // log logr.Logge r // scheme *runtime.Schem e // } func (r virtualServiceUpdater) Update(ctx context.Context, serviceSlug types.NamespacedName) error { service := &corev1.Service{ } if err := r.client.Get(ctx, serviceSlug, service); err != nil { return errors.WithStack(err ) } objList, err := lister. NewVirtualServiceBuilder(r.client, serviceSlug).Build(ctx ) if err != nil { return errors.WithStack(err ) } ref := refresh.New(r.client, r.scheme ) if err := ref.Refresh(ctx, service, objList); err != nil { return errors.WithStack(err ) } return ni l }
©2021 Wantedly, Inc. /42 VirtualServiceUpdater ͋Δ service ʹඥͮ͘ virtualService
Λ࡞͢Δ Updater ϨΠϠʔ͚ͷ۩ମྫ 28 // type virtualServiceUpdater struct { // client client.Clien t // log logr.Logge r // scheme *runtime.Schem e // } func (r virtualServiceUpdater) Update(ctx context.Context, serviceSlug types.NamespacedName) error { service := &corev1.Service{ } if err := r.client.Get(ctx, serviceSlug, service); err != nil { return errors.WithStack(err ) } objList, err := lister. NewVirtualServiceBuilder(r.client, serviceSlug).Build(ctx ) if err != nil { return errors.WithStack(err ) } ref := refresh.New(r.client, r.scheme ) if err := ref.Refresh(ctx, service, objList); err != nil { return errors.WithStack(err ) } return ni l }
©2021 Wantedly, Inc. /42 VirtualServiceUpdater ͋Δ service ʹඥͮ͘ virtualService
Λ࡞͢Δ Updater ϨΠϠʔ͚ͷ۩ମྫ 29 // type virtualServiceUpdater struct { // client client.Clien t // log logr.Logge r // scheme *runtime.Schem e // } func (r virtualServiceUpdater) Update(ctx context.Context, serviceSlug types.NamespacedName) error { service := &corev1.Service{ } if err := r.client.Get(ctx, serviceSlug, service); err != nil { return errors.WithStack(err ) } objList, err := lister. NewVirtualServiceBuilder(r.client, serviceSlug).Build(ctx ) if err != nil { return errors.WithStack(err ) } ref := refresh.New(r.client, r.scheme ) if err := ref.Refresh(ctx, service, objList); err != nil { return errors.WithStack(err ) } return ni l } VirtualServiceBuilder VirtualServiceʹ͍ͭͯɺ ཧతͳঢ়ଶΛ࡞Δ Builder
©2021 Wantedly, Inc. /42 VirtualServiceUpdater ͋Δ service ʹඥͮ͘ virtualService
Λ࡞͢Δ Updater ϨΠϠʔ͚ͷ۩ମྫ 30 // type virtualServiceUpdater struct { // client client.Clien t // log logr.Logge r // scheme *runtime.Schem e // } func (r virtualServiceUpdater) Update(ctx context.Context, serviceSlug types.NamespacedName) error { service := &corev1.Service{ } if err := r.client.Get(ctx, serviceSlug, service); err != nil { return errors.WithStack(err ) } objList, err := lister. NewVirtualServiceBuilder(r.client, serviceSlug).Build(ctx ) if err != nil { return errors.WithStack(err ) } ref := refresh.New(r.client, r.scheme ) if err := ref.Refresh(ctx, service, objList); err != nil { return errors.WithStack(err ) } return ni l } VirtualServiceBuilder VirtualServiceʹ͍ͭͯɺ ཧతͳঢ়ଶΛ࡞Δ Builder Refresher ϦιʔεͷϦετΛड͚औΓ Ϋϥελͷঢ়ଶΛ߹ΘͤΔ
©2021 Wantedly, Inc. /42 ϨΠϠʔ͚ͷ۩ମྫ 31 // type virtualServiceUpdater struct
{ // client client.Clien t // log logr.Logge r // scheme *runtime.Schem e // } func (r virtualServiceUpdater) Update(ctx context.Context, serviceSlug types.NamespacedName) error { service := &corev1.Service{ } if err := r.client.Get(ctx, serviceSlug, service); err != nil { return errors.WithStack(err ) } objList, err := lister. NewVirtualServiceBuilder(r.client, serviceSlug).Build(ctx ) if err != nil { return errors.WithStack(err ) } ref := refresh.New(r.client, r.scheme ) if err := ref.Refresh(ctx, service, objList); err != nil { return errors.WithStack(err ) } return ni l } VirtualServiceUpdater ͋Δ service ʹඥͮ͘ virtualService Λ࡞͢Δ Updater VirtualServiceBuilder VirtualServiceʹ͍ͭͯɺ ཧతͳঢ়ଶΛ࡞Δ Builder Refresher ϦιʔεͷϦετΛड͚औΓ Ϋϥελͷঢ়ଶΛ߹ΘͤΔ
©2021 Wantedly, Inc. ಈ࡞֬ೝͱςετͷॻ͖ํ 32
©2021 Wantedly, Inc. /42 ςετͷత ςετͰ͔֬Ί͍ͨ͜ͱʁ దͳKubernetesͷObject͕࡞͞ΕΔ͔Ͳ͏͔ • Builder •
͋ΔϦιʔε͕ଘࡏ͍ͯ͠Δͱ͖ʹɺదͳϦιʔε͕࡞͞ΕΔ͔͔֬Ί͍ͨ • Refresher • ͋ΔϦιʔε͕ଘࡏ͍ͯ͠Δͱ͖ʹɺड͚औͬͨϦιʔεͰΫϥελͷঢ়ଶΛมߋ͍ͨ͠ • มߋ͞ΕͨΫϥελͷঢ়ଶ͕ཧతͰ͋Δ͔͔֬Ί͍ͨ 33
©2021 Wantedly, Inc. /42 4OBQTIPUςετ $VQBMPZΛͬͨTOBQTIPUςετ • Kubernetes ͷ Object
List ͷ snapshot ΛࡱΓɺ yaml ͱͯ͠อଘ͢Δ • Yaml ͷࠩ github ্Ͱมߋ͕Θ͔Γ͍͢ͷͰɺReview͍͢͠ Controller ʹมߋΛՃ͑Δͱ͖ 1. ݱঢ়ͷڍಈΛอଘ͢Δ 2. มߋΛՃ͑ɺεφοϓγϣοτΛߋ৽͢Δ • ఆ͍ͯ͠ΔڍಈΛ͍ͯ͠Δ͔Ͳ͏͔Λ͔֬ΊΔ https://github.com/bradleyjkemp/cupaloy 34
©2021 Wantedly, Inc. /42 4OBQTIPUςετ $VQBMPZΛͬͨTOBQTIPUςετ • Kubernetes ͷ Object
List ͷ snapshot ΛࡱΓɺ yaml ͱͯ͠อଘ͢Δ • Yaml ͷࠩ github ্Ͱมߋ͕Θ͔Γ͍͢ͷͰɺReview͍͢͠ Controller ʹมߋΛՃ͑Δͱ͖ 1. ςετ͕ͳ͚ΕՃ • ݱঢ়ͷڍಈΛอଘ͓ͯ͘͠ 2. มߋΛՃ͑ɺςετ͢Δ • ఆ͍ͯ͠ΔڍಈΛ͍ͯ͠Δ͔Ͳ͏͔Λ͔֬ΊΔ https://github.com/bradleyjkemp/cupaloy 35
©2021 Wantedly, Inc. /42 6QEBUFSʹ͓͚Δ4OBQTIPUςετͷྫ 36 t.Run(testcase.name, func(t *testing.T) {
existingResources := testcase.initialStat e clnt := fake.NewFakeClientWithScheme(scheme, existingResources... ) up := updater.NewVirtualServiceUpdater(clnt, ctrl.Log, scheme ) ctx := context.Background( ) err := up.UpdateAll(ctx, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } vsl := &istio.VirtualServiceList{ } err = clnt.List(ctx, vsl, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } ut.SnapshotYaml(t, vsl ) })
©2021 Wantedly, Inc. /42 6QEBUFSʹ͓͚Δ4OBQTIPUςετͷྫ 37 t.Run(tc.name, func(t *testing.T) {
existingResources := tc.initialStat e clnt := fake.NewFakeClientWithScheme(scheme, existingResources... ) up := updater.NewVirtualServiceUpdater(clnt, ctrl.Log, scheme ) ctx := context.Background( ) err := up.UpdateAll(ctx, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } vsl := &istio.VirtualServiceList{ } err = clnt.List(ctx, vsl, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } ut.SnapshotYaml(t, vsl ) } ) ςετͷͨΊͷઃఆ
©2021 Wantedly, Inc. /42 6QEBUFSʹ͓͚Δ4OBQTIPUςετͷྫ 38 t.Run(tc.name, func(t *testing.T) {
existingResources := tc.initialStat e clnt := fake.NewFakeClientWithScheme(scheme, existingResources... ) up := updater.NewVirtualServiceUpdater(clnt, ctrl.Log, scheme ) ctx := context.Background() err := up.UpdateAll(ctx, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } vsl := &istio.VirtualServiceList{ } err = clnt.List(ctx, vsl, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } ut.SnapshotYaml(t, vsl ) } ) ςετͷͨΊͷઃఆ ؔΛ࣮ߦ
©2021 Wantedly, Inc. /42 6QEBUFSʹ͓͚Δ4OBQTIPUςετͷྫ 39 t.Run(tc.name, func(t *testing.T) {
existingResources := tc.initialStat e clnt := fake.NewFakeClientWithScheme(scheme, existingResources... ) up := updater.NewVirtualServiceUpdater(clnt, ctrl.Log, scheme ) ctx := context.Background( ) err := up.UpdateAll(ctx, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } vsl := &istio.VirtualServiceList{ } err = clnt.List(ctx, vsl, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } ut.SnapshotYaml(t, vsl ) } ) ςετͷͨΊͷઃఆ ؔΛ࣮ߦ ݁ՌΛऔಘ
©2021 Wantedly, Inc. /42 6QEBUFSʹ͓͚Δ4OBQTIPUςετͷྫ 40 t.Run(tc.name, func(t *testing.T) {
existingResources := tc.initialStat e clnt := fake.NewFakeClientWithScheme(scheme, existingResources... ) up := updater.NewVirtualServiceUpdater(clnt, ctrl.Log, scheme ) ctx := context.Background( ) err := up.UpdateAll(ctx, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } vsl := &istio.VirtualServiceList{ } err = clnt.List(ctx, vsl, &client.ListOptions{Namespace: "some-namespace"} ) if err != nil { t.Fatal(err ) } ut.SnapshotYaml(t, vsl) // make objectList to string and take snapsho t } ) ςετͷͨΊͷઃఆ ؔΛ࣮ߦ ݁ՌΛऔಘ औಘͨ݁͠ՌΛอଘ
©2021 Wantedly, Inc. /42 4OBQTIPUςετͷϝϦοτɾσϝϦοτ ˓ؾܰʹςετ͕Ͱ͖Δ มߋ͢ΔՕॴͷϦετΛऔಘͯ͠อଘ͢Δ͚ͩ ·ͨɺऔಘͷॲཧ͕͔͔࣌ؒΒͳ͍ͷͰಋೖ͍͢͠ ✕4OBQTIPU͕େྔʹอଘ͞ΕΔ
ཏతʹ͢Δͱsnapshot ͕େྔʹͳͬͯ PR ͕ٯʹݟͮΒ͘ͳΔ ఆ֎ͷͱ͜Ζʹ diff ͕ग़Δͱఆ͕͘͠ͳΔ ˓ͲΜͲΜ࣮͍͚ͯ͠Δ ؾܰʹςετ͕Ͱ͖ΔͷͰͲΜͲΜ࣮͍ͯ͘͠ϑΣʔζʹ͍͍ͯΔ ༷͕มΘͬͨͱ͖ʹ snapshot ʹ͕ࠩͰΔͷͰΘ͔Γ͍͢ 41
©2021 Wantedly, Inc. /42 42 Kubernetes ͔ΒֶΜͩ Go ͷઃܭ ෳࡶͳ؆୯ͳʹΓग़ͦ͏
Custom Controller Λ࡞Δ্Ͱ໘͕ͪ͠ͳͱͦͷղܾ ΄͍͠Ϧιʔεͷ࡞ͱΫϥελͷঢ়ଶͷߋ৽ΛΘ͚Δͱ͏·͍͘͘ దͳ package ͚Γେࣄ Wantedly Ͱ Go ΘΕ͍ͯ·͢ ϓϩμΫγϣϯͷΞϓϦέʔγϣϯ͔Βɺࣾπʔϧ·Ͱ ·ͱΊ ॲཧΛ࠶ར༻Ͱ͖Δ͘͠ΈΛͭ͘Ζ͏