Slide 1

Slide 1 text

©2021 Wantedly, Inc. Kubernetes ͔ΒֶΜͩ 
 Go ͷઃܭ࿦ (P$POGFSFODF4QSJOH 0OMJOF "QS 5BLBNJDIJ0NPSJ!POTE@

Slide 2

Slide 2 text

©2021 Wantedly, Inc. Takamichi Omori @onsd_ DX Squad Intern, Wantedly, Inc. Love Kubernetes, Go, etc *BN 2 https://www.wantedly.com/id/onsd_

Slide 3

Slide 3 text

©2021 Wantedly, Inc. /42 8BOUFEMZͱ(P ຊ൪ͷ͸(P ύϑΥʔϚϯε͕༏ઌ͞ΕΔͱ͜Ζ ௨஌؅ཧͳͲͷج൫ Kubernetes ؔ࿈ CLIπʔϧ 3

Slide 4

Slide 4 text

©2021 Wantedly, Inc. /42 %94RVBEͱ͸ʁ %FWFMPQFSF9QFSJFODF4RVBE https://event.cloudnativedays.jp/cndo2021/talks/281 ٕज़ج൫νʔϜͱ঺հ͞ΕΔ͜ͱ΋ଟ͍Ͱ͢ ະདྷͷ։ൃମݧΛͭ͘Δ ։ൃऀͷੜ࢈ੑΛ޲্ͤ͞ΔͨΊʹ͸ԿͰ΋΍͍ͬͯ͘νʔϜ ৽͍͠ Microservice ͷ։ൃମݧ ෳࡶͳMicroservice Ͱ΋։ൃ͕؆୯ʹߦ͑ΔΑ͏ͳ࢓૊Έ࡞Γ ৽͍͠։ൃମݧ ʹ͍ͭͯৄ͘͠͸ 4

Slide 5

Slide 5 text

©2021 Wantedly, Inc. /42 ࠓ೔࿩͢͜ͱ ,VCFSOFUFT͔ΒֶΜͩ(Pͷઃܭ࿦ 5 ࣮ྫɿCustom Controller ͷ࣮૷͔ΒֶΜͩઃܭ࿦ • Package Λ෼͚ͯॲཧΛΘ͔Γ΍͘͢͢Δํ๏ • εφοϓγϣοτςετʹ͍ͭͯ

Slide 6

Slide 6 text

©2021 Wantedly, Inc. $VTUPN$POUSPMMFSͱ͸ Photo by NeONBRAND on Unsplash 6

Slide 7

Slide 7 text

©2021 Wantedly, Inc. /42 $VTUPN$POUSPMMFSͱ͸ ,VCFSOFUFTΛ֦ு͢Δ࢓૊ΈͷҰͭ https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ 7 Kubernetes ʹ͸ Deployment, Service ͷΑ͏ʹͨ͘͞ΜͷϦιʔε͕ଘࡏ͢Δ Custom Controller ͸ɺಠࣗʹઃܭͨ͠ϦιʔεΛίϯτϩʔϧ͢ΔͨΊͷΞϓϦέʔγϣϯ

Slide 8

Slide 8 text

©2021 Wantedly, Inc. ୊ࡐͱ͢Δ Custom Controller ͷಛ௃ Photo by Nikolai Chernichenko on Unsplash 8

Slide 9

Slide 9 text

©2021 Wantedly, Inc. /42 ୊ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ௃ πϦʔߏ଄ʹͳ͍ͬͯΔ 9 ਌͔Βෳ਺ͷϦιʔε͕Ͱ͖Δ

Slide 10

Slide 10 text

©2021 Wantedly, Inc. /42 ୊ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ௃ ਌ϦιʔεҎ֎͔ΒӨڹΛड͚ΔϦιʔε͕͋Δ ผϦιʔε͕มߋ͞Εͨͱ͖ʹࢠϦιʔεΛมߋ͢Δ controller Λผʹ࡞Δඞཁ͕͋Δ 10

Slide 11

Slide 11 text

©2021 Wantedly, Inc. ෳࡶͳ controller ͸ ϨΠϠʔΛ෼͚Α͏ Photo by Hasan Almasi on Unsplash 11

Slide 12

Slide 12 text

©2021 Wantedly, Inc. /42 3FDPODJMF 3FDPODJMF ͋ΔϦιʔεͷঢ়ଶ͔ΒΫϥελͷঢ়ଶΛߋ৽͢Δॲཧ 
 Kubebuilder Λ࢖͍ͬͯΔ৔߹ɺ 
 ඞཁͳϦιʔεΛ࡞੒͢ΔॲཧΛReconcile ʹॻ͘ 12

Slide 13

Slide 13 text

©2021 Wantedly, Inc. /42 ૉ௚ʹॻ͍͍ͯͬͨ৔߹ 3FDPODJMFʹ͢΂ͯΛॻ͘ੈք 1. ཧ૝తͳϦιʔεͷঢ়ଶΛܭࢉ 2. ࠩ෼͕͋Δ৔߹͸ߋ৽ 3. ඞཁ͕ͳ͘ͳͬͨϦιʔε͕͋Δ৔߹͸ফ͢ 
 ࠓճͷྫͩͱɺෳ਺ͷϦιʔεΛ࡞੒ɾߋ৽ɾ࡟আ 
 ͢Δඞཁ͕͋ͬͨ 13

Slide 14

Slide 14 text

©2021 Wantedly, Inc. /42 ୊ࡐͱ͢Δ$VTUPN$POUSPMMFSͷಛ௃ ਌ϦιʔεҎ֎͔ΒӨڹΛड͚ΔϦιʔε͕͋Δ ผϦιʔε͕มߋ͞Εͨͱ͖ʹࢠϦιʔεΛมߋ͢Δ controller Λผʹ࡞Δඞཁ͕͋Δ 14

Slide 15

Slide 15 text

©2021 Wantedly, Inc. /42 ෳ਺ͷDPOUSPMMFSΛؚΉ৔߹ͷ໰୊఺ 3FDPODJMFʹ͢΂ͯΛॻ͘ ෳ਺ͷController ͔Β 
 ߋ৽͞ΕΔϦιʔε͕͋Δ 
 Reconciler ʹ௚઀ॲཧΛॻ͘ͱɺ 
 ಉ͡ॲཧ͕ෳ਺ͷՕॴͰॏෳͯ͠͠·͏ 15

Slide 16

Slide 16 text

©2021 Wantedly, Inc. /42 6QEBUFSͷಋೖ 6QEBUFS ಛఆͷϦιʔεΛ࡞੒ɾߋ৽ɾ࡟আ͢ΔྲྀΕΛ·ͱΊͯ 
 Updaterͱ࣮ͯ͠૷͢Δ Controller ʹ௚઀ॻ͍ͨ৔߹ͱൺ΂ͯɺॲཧͷڞ௨Խ ͕ਤΕΔ 16

Slide 17

Slide 17 text

©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 }

Slide 18

Slide 18 text

©2021 Wantedly, Inc. /42 6QEBUFS͕શͯͷॲཧΛߦ͏ͱ͖ͷ໰୊఺ ͢΂ͯͷ৚݅Λ໢ཏ͢Δͷ͕େม ӈͷྫͩͱɺ࡟আ͢Δॲཧ·ͰUpdaterͰ΍͍ͬͯΔɻ - ࡟আ͢Δ৚݅ - ԿΛͲ͜·Ͱফ͍͍ͯ͠ͷ͔ ͳͲ͕Θ͔ΓͮΒ͘ͳΓɺ࣮૷͕େมʹͳΔɻ 18

Slide 19

Slide 19 text

©2021 Wantedly, Inc. /42 3FGSFTIFSͷಋೖ 3FGSFTIFS ཧ૝తͳϦιʔεͷঢ়ଶ͕౉͞ΕΔͱɺΫϥελ্ͷ 
 Ϧιʔε͕ཧ૝తͳঢ়ଶʹͳΔΑ͏ʹ 
 ௥Ճɾߋ৽ɾ࡟আΛߦ͏ϢʔςΟϦςΟϥΠϒϥϦ 19

Slide 20

Slide 20 text

©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 }

Slide 21

Slide 21 text

©2021 Wantedly, Inc. /42 3FGSFTIFS͕͋ΔͱԿ͕خ͍͠ͷ͔ ໰୊ͷ؆ུԽ ཧ૝ঢ়ଶΛड͚औΓɺෆཁͳϦιʔε͸࡟আ͢Δ RefresherΛಋೖ͢Δ͜ͱͰ 
 UpdaterΛ࣮૷͢Δࡍʹඞཁͳͷ͸ɺཧ૝తͳ ϦιʔεͷϦετΛ࡞Δॲཧ͚ͩʹͳͬͨ 21 ॲཧͷڞ௨Խ Ϧιʔεʹ਌ࢠؔ܎͕͋Δ৔߹ɺRefresherΛ 
 ࢖͏͜ͱͰॲཧͷڞ௨Խ͕Ͱ͖Δ

Slide 22

Slide 22 text

©2021 Wantedly, Inc. /42 3FGSFTIFS͕ݱঢ়Λཧ૝ʹ͚ۙͮΔํ๏ ࡟আ͢ΔϦιʔεͷಛఆ Refresher ͸ɺ਌Ϧιʔεͱཧ૝తͳࢠϦιʔεͷ 
 ϦετΛड͚औΔ ਌Ϧιʔε͔Β͢Ͱʹଘࡏ͢ΔࢠϦιʔεΛಛఆ͠ɺ 
 ड͚औͬͨϦιʔεͱൺֱ͢Δ͜ͱͰ࡟আ͢Δ΂͖ 
 ϦιʔεΛಛఆͰ͖Δ ਌ࢠؔ܎ͷ੍໿ ͋ΔϦιʔε͸ඞͣ਌ϦιʔεΛ࣋ͭͱ͍͏੍໿ 22

Slide 23

Slide 23 text

©2021 Wantedly, Inc. /42 ,VCFSOFUFT্Ͱ਌ࢠؔ܎Λࣔ͢ํ๏ 0XOFS3FGFSFODF 23 Ϧιʔεʹ͍ͭͯɺͦͷΦʔφʔϦιʔεΛࣔ͢ϑΟʔϧυ OwnerReference ͷϝϦοτ Owner ͕ফ͑ͨͱ͖ʹGC ͕ࢠϦιʔεΛফͯ͘͠ΕΔ πϦʔߏ଄Λ࣋ͭϦιʔεΛ؅ཧ͢Δͱ͖͚͓ͭͯ͘ͱศར

Slide 24

Slide 24 text

©2021 Wantedly, Inc. /42 #VJMEFSͷಋೖ #VJMEFS • ͋ΔϦιʔεʹ͍ͭͯɺཧ૝తͳঢ়ଶΛܭࢉ͢Δ • ܭࢉͨ݁͠ՌΛRefresherʹΘͨ͢ 24

Slide 25

Slide 25 text

©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 ) }

Slide 26

Slide 26 text

©2021 Wantedly, Inc. /42 ϨΠϠʔ෼͚ͷ·ͱΊ Updater Builder Refresher ͋ΔϦιʔεʹ͍ͭͯͷॲཧΛ·ͱΊΔ ͋ΔϦιʔεʹ͍ͭͯɺཧ૝తͳঢ়ଶΛͭ͘Δ Builder͕౉͢Ϧετʹଇͬͯ ཧ૝తͳঢ়ଶΛ࣮ݱ͢ΔϥΠϒϥϦ 26

Slide 27

Slide 27 text

©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 }

Slide 28

Slide 28 text

©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 }

Slide 29

Slide 29 text

©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

Slide 30

Slide 30 text

©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 ϦιʔεͷϦετΛड͚औΓ 
 Ϋϥελͷঢ়ଶΛ߹ΘͤΔ

Slide 31

Slide 31 text

©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 ϦιʔεͷϦετΛड͚औΓ 
 Ϋϥελͷঢ়ଶΛ߹ΘͤΔ

Slide 32

Slide 32 text

©2021 Wantedly, Inc. ಈ࡞֬ೝͱςετͷॻ͖ํ 32

Slide 33

Slide 33 text

©2021 Wantedly, Inc. /42 ςετͷ໨త ςετͰ͔֬Ί͍ͨ͜ͱ͸ʁ ద੾ͳKubernetesͷObject͕࡞੒͞ΕΔ͔Ͳ͏͔ • Builder • ͋ΔϦιʔε͕ଘࡏ͍ͯ͠Δͱ͖ʹɺద੾ͳϦιʔε͕࡞੒͞ΕΔ͔͔֬Ί͍ͨ • Refresher • ͋ΔϦιʔε͕ଘࡏ͍ͯ͠Δͱ͖ʹɺड͚औͬͨϦιʔεͰΫϥελͷঢ়ଶΛมߋ͍ͨ͠ • มߋ͞ΕͨΫϥελͷঢ়ଶ͕ཧ૝తͰ͋Δ͔͔֬Ί͍ͨ 33

Slide 34

Slide 34 text

©2021 Wantedly, Inc. /42 4OBQTIPUςετ $VQBMPZΛ࢖ͬͨTOBQTIPUςετ • Kubernetes ͷ Object List ͷ snapshot ΛࡱΓɺ yaml ͱͯ͠อଘ͢Δ • Yaml ͷࠩ෼͸ github ্Ͱ΋มߋ͕Θ͔Γ΍͍͢ͷͰɺReview΋͠΍͍͢ Controller ʹมߋΛՃ͑Δͱ͖ 1. ݱঢ়ͷڍಈΛอଘ͢Δ 2. มߋΛՃ͑ɺεφοϓγϣοτΛߋ৽͢Δ • ૝ఆ͍ͯ͠ΔڍಈΛ͍ͯ͠Δ͔Ͳ͏͔Λ͔֬ΊΔ https://github.com/bradleyjkemp/cupaloy 34

Slide 35

Slide 35 text

©2021 Wantedly, Inc. /42 4OBQTIPUςετ $VQBMPZΛ࢖ͬͨTOBQTIPUςετ • Kubernetes ͷ Object List ͷ snapshot ΛࡱΓɺ yaml ͱͯ͠อଘ͢Δ • Yaml ͷࠩ෼͸ github ্Ͱ΋มߋ͕Θ͔Γ΍͍͢ͷͰɺReview΋͠΍͍͢ Controller ʹมߋΛՃ͑Δͱ͖ 1. ςετ͕ͳ͚Ε͹௥Ճ • ݱঢ়ͷڍಈΛอଘ͓ͯ͘͠ 2. มߋΛՃ͑ɺςετ͢Δ • ૝ఆ͍ͯ͠ΔڍಈΛ͍ͯ͠Δ͔Ͳ͏͔Λ͔֬ΊΔ https://github.com/bradleyjkemp/cupaloy 35

Slide 36

Slide 36 text

©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 ) })

Slide 37

Slide 37 text

©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 ) } ) ςετͷͨΊͷઃఆ

Slide 38

Slide 38 text

©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 ) } ) ςετͷͨΊͷઃఆ ؔ਺Λ࣮ߦ

Slide 39

Slide 39 text

©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 ) } ) ςετͷͨΊͷઃఆ ؔ਺Λ࣮ߦ ݁ՌΛऔಘ

Slide 40

Slide 40 text

©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 } ) ςετͷͨΊͷઃఆ ؔ਺Λ࣮ߦ ݁ՌΛऔಘ औಘͨ݁͠ՌΛอଘ

Slide 41

Slide 41 text

©2021 Wantedly, Inc. /42 4OBQTIPUςετͷϝϦοτɾσϝϦοτ ˓ؾܰʹςετ͕Ͱ͖Δ มߋ͢ΔՕॴͷϦετΛऔಘͯ͠อଘ͢Δ͚ͩ 
 ·ͨɺऔಘͷॲཧ΋͕͔͔࣌ؒΒͳ͍ͷͰಋೖ͸͠΍͍͢ ✕4OBQTIPU͕େྔʹอଘ͞ΕΔ ໢ཏతʹ͢Δͱsnapshot ͕େྔʹͳͬͯ PR ͕ٯʹݟͮΒ͘ͳΔ 
 ૝ఆ֎ͷͱ͜Ζʹ diff ͕ग़Δͱ൑ఆ͕೉͘͠ͳΔ ˓ͲΜͲΜ࣮૷͍͚ͯ͠Δ ؾܰʹςετ͕Ͱ͖ΔͷͰͲΜͲΜ࣮૷͍ͯ͘͠ϑΣʔζʹ޲͍͍ͯΔ ࢓༷͕มΘͬͨͱ͖ʹ snapshot ʹࠩ෼͕ͰΔͷͰΘ͔Γ΍͍͢ 41

Slide 42

Slide 42 text

©2021 Wantedly, Inc. /42 42 Kubernetes ͔ΒֶΜͩ Go ͷઃܭ࿦ ෳࡶͳ໰୊͸؆୯ͳ໰୊ʹ੾Γग़ͦ͏ Custom Controller Λ࡞Δ্Ͱ௚໘͕ͪ͠ͳ໰୊ͱͦͷղܾ ΄͍͠Ϧιʔεͷ࡞੒ͱΫϥελͷঢ়ଶͷߋ৽ΛΘ͚Δͱ͏·͍͘͘ ద੾ͳ package ෼͚͸΍͸Γେࣄ Wantedly Ͱ͸ Go ΋࢖ΘΕ͍ͯ·͢ ϓϩμΫγϣϯͷΞϓϦέʔγϣϯ͔Βɺࣾ಺πʔϧ·Ͱ ·ͱΊ ॲཧΛ࠶ར༻Ͱ͖Δ͘͠ΈΛͭ͘Ζ͏