๋กœ์ผ“๐Ÿพ
article thumbnail

 

ํ•ด๋‹น ๊ธ€์€ ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์Œ๊ป ์ง€์ ํ•ด์ฃผ์„ธ์š”!

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์œ„์— ์žˆ๋Š” ๋ชจ๋“  ํŒŒ๋“œ์™€ ๋…ธ๋“œ๋Š” ephermeral ํ•˜๊ฒŒ ๋””์ž์ธ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ์— ๋”ฐ๋ผ ํŒŒ๋“œ์™€ ๋…ธ๋“œ๋Š” ์–ธ์ œ ๊ฐ‘์ž๊ธฐ ๊ธ‰์‚ฌ? ํ• ์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ธ‰์‚ฌ ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์„œ๋น„์Šค์— ์˜ํ–ฅ์ด ๊ฐ€์„  ์•ˆ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๊ณ ๊ฐ€์šฉ์„ฑ(HA) ์€ ๋ฐ˜๋“œ์‹œ ๋™๋ฐ˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ ์ง€ํ•˜์ง€ ์œ„ํ•ด์„œ๋Š” ์—ฌ๋Ÿฌ ์ ˆ์ฐจ๊ฐ€ ๋™๋ฐ˜๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๊ทธ ์ค‘ Stateful ํ•œ ์„œ๋น„์Šค์˜ ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ธ '๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜(Leader Election Mechanism)' ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ ์ „์— Stateless ํ•œ ์„œ๋น„์Šค์˜ ๊ณ ๊ฐ€์šฉ์„ฑ๋ถ€ํ„ฐ ์•Œ์•„๋ด…์‹œ๋‹ค.

 

Stateless ํ•œ ํŒŒ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๊ณ , Service ๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์ด ๋ผ์šฐํŒ… ๋ฉ๋‹ˆ๋‹ค.

Stateless

 

Stateless ํŠน์„ฑ์ƒ ์•„๋ฌด ํŒŒ๋“œ๋‚˜ ํŠธ๋ž˜ํ”ฝ์„ ๋ฐ›์•„๋„ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‹ค ํ˜น์‹œ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ถ€์กฑํ•ด์ง€๋”๋ผ๋„ HPA ๋ฅผ ํ†ตํ•ด์„œ ์Šค์ผ€์ผ ์•„์›ƒ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Stateless + HPA

 

์ด๋ ‡๊ฒŒํ•ด์ฃผ์–ด๋„ ๊ฝค๋‚˜ ๊ดœ์ฐฎ์€ ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Stateless ์€ ํฌ๊ฒŒ ์‹ ๊ฒฝ์“ธ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์„œ๋น„์Šค๊ฐ€ Stateful ํ•˜๊ฒŒ ๋˜๋ฉด ์–˜๊ธฐ๊ฐ€ ์‚ด์ง ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ํŠธ๋ž˜ํ”ฝ์„ ๋ฐ›๋Š” ์„œ๋น„์Šค๊ฐ€ ์•„๋‹Œ, Karpenter ์™€ ๊ฐ™์ด Control Loop ์„ ์ง„ํ–‰ํ•˜๋Š” Stateful ์„œ๋น„์Šค๋กœ ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Stateful

 

Karpenter ๊ฐ™์€ ๊ฒฝ์šฐ Ec2NodeClass ์™€ ๊ฐ™์€ CRD ๋ฅผ Control Loop ์„ ํ†ตํ•ด ์ง€์ผœ๋ณด๋‹ค๊ฐ€ ํŠน์ด ์‚ฌํ•ญ์ด ์ƒ๊ธฐ๋ฉด AWS EC2 ๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, Karpenter ํŒŒ๋“œ๊ฐ€ 3๊ฐœ๋ผ๊ณ  ํ•˜๋ฉด ๋˜‘๊ฐ™์€ AWS EC2 ๊ฐ€ 3๊ฐœ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. 3๊ฐœ์˜ ํŒŒ๋“œ ๋ชจ๋‘ ๊ฐ์ž์˜ ์ผ์„ ํ• ํ…Œ๋‹ˆ๊นŒ์š”.

Karpenter ์ฝ”๋“œ๋Š” ๊นŒ๋ณด์ง€ ์•Š์•˜์ง€๋งŒ, ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ ์ž ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ์™ธํ•œ)
๋‹จ์ˆœํžˆ ์˜ˆ์ œ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด๋•Œ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๋ฆฌ๋” ํŒŒ๋“œ๋งŒ ์ž‘์—…์„ ํ•˜๊ฒŒ ๋˜์–ด AWS EC2 ๊ฐ€ ๋™์‹œ์— 3๊ฐœ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ค‘๋ณต์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋” ๋†’์€ ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ„ํ•ด์„œ๋ผ๋ฉด VPA ์™€ ๊ฐ™์€ ์Šค์ผ€์ผ ์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)

Stateful

 

์ถ”๊ฐ€์ ์œผ๋กœ Karpenter ๋ฅผ Deployment ๊ฐ€ ์•„๋‹Œ StatefulSet ๋กœ ์ƒ์„ฑํ•ด๋„ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค.

StatefulSet ๋Š” ๋„คํŠธ์›Œํฌ, ์Šคํ† ๋ฆฌ์ง€ ๊ฐ™์€ ์‹๋ณ„์ž๋ฅผ ๋‘์–ด, ํŠธ๋ž˜ํ”ฝ์— ๋Œ€ํ•œ Stateful ์€ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ๊ฒฐ๊ตญ StatefulSet ์˜ ํŒŒ๋“œ๊ฐ€ 3๊ฐœ๋ผ๋ฉด Deployment ์ฒ˜๋Ÿผ ์ค‘๋ณต๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค ์ž์ฒด๋ฅผ ์ œ์–ดํ•  ์ˆœ ์—†์œผ๋‹ˆ๊น์š”.

 

 

๊ทธ๋Ÿผ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋ญ๊ณ , ์™œ ํ•„์š”ํ•œ์ง€ ๊ฐ„๋žตํ•˜๊ฒŒ ์•Œ์•„๋ดค์œผ๋‹ˆ, ์ฝ”๋“œ๋กœ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ง€ ๋ฐ”๋กœ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ฃ !

 

๋ ›์ธ ๋‘๋”์ฝ”๋“œ~

 

 

Code - Go Client


์‘๋‹ต๊ฐ’์œผ๋กœ ํ˜„์žฌ์˜ ํŒŒ๋“œ ์ด๋ฆ„๊ณผ IP ๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” gin ๊ธฐ๋ฐ˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์—ˆ๊ณ , ์—ฌ๊ธฐ์— ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‘๋‹ต ์˜ˆ์‹œ

 

๊ทธ๋ฆฌ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฏธ๋‹ˆ PC ๋กœ ์šด์˜ํ•˜๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

๋ฏธ๋‹ˆ PC ๋กœ ์šด์˜ํ•˜๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์—ฌ๊ธฐ ํด๋ฆญ!

 

๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์•Œ์•„๋ณด๋ฉด์„œ ๊ฐ€์žฅ ๊ถ๊ธˆํ–ˆ๋˜ ๊ฒƒ์ด, "๋ˆ„๊ฐ€ ๋ฆฌ๋”์ธ์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์–ด๋–ป๊ฒŒ ์•Œ์ง€?" ์˜€์Šต๋‹ˆ๋‹ค.

์™œ๋ƒ ๋งŒ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ™์€ ์Šคํ† ๋ฆฌ์ง€๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด์˜€์Šต๋‹ˆ๋‹ค.

 

์ตœ์†Œํ•œ ๋ˆ„๊ฐ€ ๋ฆฌ๋”์ธ์ง€๋Š” ์•Œ์•„์•ผ ๋ฆฌ๋”๋ฅผ ๋ฝ‘์„ ํ…Œ๋‹ˆ ๋ง์ด์ฃ .

 

๋‹คํ–‰ํžˆ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ์ด๋ฅผ Lease ๋ผ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Lease ๋Š” ETCD ๋กœ ๊ด€๋ฆฌ๋˜๊ฒ ์ฃ .

apiVersion: coordination.k8s.io/v1

 

์ด ๋ง์€ ์ฆ‰ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

config, err := buildConfig(kubeconfig)
if err != nil {
    klog.Fatal(err)
}
client := clientset.NewForConfigOrDie(config)

 

buildConfig ํ•จ์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜๋ฉด ์ปค๋งจ๋“œ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๊ณ , ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ƒ์—์„œ ์‹คํ–‰๋œ๋‹ค๋ฉด rest.InClusterConfig() ๋ฅผ ํ†ตํ•ด Service Account Token ์„ ์ฐพ์•„์ค๋‹ˆ๋‹ค.

func buildConfig(kubeconfig string) (*rest.Config, error) {
    if kubeconfig != "" {
        cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
        if err != nil {
            return nil, err
        }
        return cfg, nil
    }

    cfg, err := rest.InClusterConfig()
    if err != nil {
        return nil, err
    }
    return cfg, nil
}

 

๋‹ค์Œ์€ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ์‹คํ–‰ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

์—”๋“œํฌ์ธํŠธ "/" ๋ฅผ ํ†ตํ•ด ํŒŒ๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š” ์‘๋‹ต๊ฐ’์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

run := func(ctx context.Context) {
    // complete your controller loop here
    klog.Info("Controller loop...")

    engine := gin.New()
    engine.Use(
        CorsHandler(),
    )

    engine.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "pod_namespace": os.Getenv("POD_NAMESPACE"),
            "pod_name":      os.Getenv("POD_NAME"),
            "pod_id":        os.Getenv("POD_IP"),
            "id":            id,
        })
    })
    engine.Run(fmt.Sprintf("%s:%d", "0.0.0.0", 8080))
}
๋‹น์—ฐํ•˜๊ฒŒ๋„ engine.Run ๊ณผ ๊ฐ™์ด foreground ๋กœ ์ง€์†์ ์œผ๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰์‹œ์ผœ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ์œ„์—์„œ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ Lease ๋ผ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ํ†ตํ•ด ์ง„ํ–‰๋œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์ด ์—ญ์‹œ Lease ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

var leaseLockName = os.Getenv("LEASE_LOCK_NAME")
var leaseLockNamespace = os.Getenv("LEASE_LOCK_NAMESPACE")
var id = uuid.New().String()

lock := &resourcelock.LeaseLock{
    LeaseMeta: metav1.ObjectMeta{
        Name:      leaseLockName,
        Namespace: leaseLockNamespace,
    },
    Client: client.CoordinationV1(),
    LockConfig: resourcelock.ResourceLockConfig{
        Identity: id,
    },
}

 

leaseLockName ๊ณผ leaseLockNamespace ๋Š” Configmap ์„ ์ด์šฉํ•ด์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ๋„˜๊ฒจ์ค„ ๊ฒƒ์ด๊ณ , Identity ๋Š” uuid ๋ฅผ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

 

์ด์ œ๋ถ€ํ„ฐ๊ฐ€ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ํ•ต์‹ฌ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
    Lock: lock,
    ReleaseOnCancel: true,             // true๋กœ ์„ค์ •ํ•˜๋ฉด, ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ทจ์†Œ๋  ๋•Œ ๋ฆฌ์Šค๋ฅผ ์ฆ‰์‹œ ํ•ด์ œ
    LeaseDuration:   60 * time.Second, // RenewDeadline ๋™์•ˆ ๊ฐฑ์‹ ์— ์‹คํŒจํ–ˆ์„ ๋•Œ, ๋ฆฌ๋”์‹ญ์ด ์œ ์ง€๋  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„
    RenewDeadline:   15 * time.Second, // ๋ฆฌ๋”๋Š” ์ด ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฆฌ๋”์‹ญ์„ ๊ฐฑ์‹ ํ•ด์•ผํ•จ
    RetryPeriod:     5 * time.Second,  // ๋ฆฌ๋” ํš๋“ ์‹œ๋„ ๊ฐ„์˜ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์„ค์ •
    Callbacks: leaderelection.LeaderCallbacks{
        OnStartedLeading: func(ctx context.Context) {
            run(ctx)
        },
        OnStoppedLeading: func() {
            klog.Infof("leader lost: %s", id)
            os.Exit(0)
        },
        OnNewLeader: func(identity string) {
            if identity == id {
                return
            }
            klog.Infof("new leader elected: %s", identity)
        },
    },
})

 

์œ„์—์„œ ์ƒ์„ฑํ–ˆ๋˜ run ํ•จ์ˆ˜๋„ leaderelection.RunOrDie ์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๋กœ ์‹คํ–‰๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

OnStartedLeading ํ•จ์ˆ˜๋Š” ๋ฆฌ๋”๊ฐ€ ๋˜์—ˆ์„ ๋•Œ ํ•œ๋ฒˆ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๊ณ , OnStoppedLeading ์€ ๋ฆฌ๋”๋ฅผ ์ƒ์‹คํ–ˆ์„ ๋•Œ ํ•œ๋ฒˆ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜๊ณ , OnNewLeader ๋Š” ์ƒˆ๋กœ์šด ๋ฆฌ๋”๊ฐ€ ์„ ์ถœ๋˜์—ˆ์„ ๋•Œ ๋ฆฌ๋”๊ฐ€ ์•„๋‹Œ ์„œ๋น„์Šค์—์„œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

์ƒ๊ฐ๋ณด๋‹ค ์–ด๋ ค์šด ๋ถ€๋ถ„์€ ์—†๋Š”๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ข€ ๋” ๋””ํ…Œ์ผํ•œ ์ดํ•ด๋ฅผ ์œ„ํ•ด Deep Dive ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋™์ž‘ ๋ฐฉ์‹๋งŒ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ Deep Dive ํŒŒํŠธ๋Š” ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค.

 

 

Code - Deep Dive


๋‹ค์Œ์€ kube-controller-manager ์˜ ์ฝ”๋“œ์ธ๋ฐ ๊ด€๋ฆฌํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณด๋ฉด Lease ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, kube-controller-manager ๊ฐ€ Lease ์˜ Yaml ์„ ๋ฐ”๋ผ๋ณด๋ฉด์„œ Reconcile ํ•  ๊ฒƒ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

controllermanager.go

 

์ด ๋ง์€ ๋˜ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ Lease ๋ฆฌ์†Œ์Šค๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

ํ•œํŽธ, ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ leaderelection.RunOrDie ํ•จ์ˆ˜๋ฅผ ์‹œ์ž‘์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

leaderelection.go

 

Run ํ•จ์ˆ˜๋ฅผ ๋ณด๊ฒŒ๋˜๋ฉด ์•„๊นŒ ์ฝœ๋ฐฑ์— ์ž‘์„ฑํ–ˆ๋˜ OnStoppedLeading defer ํ•จ์ˆ˜์™€ OnStartedLeading ๊ณ ๋ฃจํ‹ด์„ ์‹คํ–‰ํ•˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๊ณ , le.renew(ctx) ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

leaderelection.go

 

renew ํ•จ์ˆ˜๋ฅผ ๋ณด๊ฒŒ ๋˜๋ฉด, ์ข€ ๋” ํ•ต์‹ฌ์ ์ธ ์ฝ”๋“œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ ํฌ๊ฒŒ tryAcquireOrRenew ์™€ tryCoordinatedRenew ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ํ•จ์ˆ˜๋“ค์€ ๋ชจ๋‘ wait.Until ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

wait.Until ์€ ์ง€๋‚œ [Kubernetes] Controller ์™€ Operator, ์–ด๋””๊นŒ์ง€ ๊นŒ๋ดค๋‹ˆ? ์—์„œ ๋‹ค๋ฃฌ์ ์ด ์žˆ์ฃ .

 

tryAcquireOrRenew ๋ถ€ํ„ฐ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

leaderelection.go

 

ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฆฌ๋”์ด๊ณ , Lease ๊ฐ€ ์œ ํšจํ•˜๋‹ค๋ฉด, ์ด์ „ Lease ์˜ AcquireTime, LeaderTransitions ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ์ด์ „ Lease ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ RenewTime ๋งŒ ์—…๋ฐ์ดํŠธ ๋˜๊ฒ ์ฃ .

 

๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด true ๋ฅผ ๋ฆฌํ„ดํ•ด์คŒ์œผ๋กœ์จ ๊ฐฑ์‹ ์— ์„ฑ๊ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ฒซ๋ฒˆ์งธ ๋กœ์ง์—์„œ ๋๋‚˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ๋‹ค์Œ ๋‘๋ฒˆ์งธ ๋กœ์ง์œผ๋กœ ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

leaderelection.go

 

btye ๋กœ ๊ตฌ์„ฑ๋œ ์ด์ „ Lease ์— ๋Œ€ํ•œ ์ •๋ณด์™€ ๊ตฌ์กฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ง„ Lease ์ •๋ณด๋ฅผ ๊ฐ–๊ณ  ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฐ”๋กœ ์•„๋ž˜ if ๋ฌธ์„ ํƒ€๊ฒŒ ๋˜๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐฑ์‹ ์— ์‹คํŒจํ•˜๊ณ , ๋ฆฌ๋”๋ฅผ ์žƒ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋‘๋ฒˆ์งธ ๋กœ์ง์—์„œ ๋๋‚˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ๋‹ค์Œ ์„ธ๋ฒˆ์งธ ๋กœ์ง์œผ๋กœ ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

leaderelection.go

 

์ด์ „ Lease ์˜ HolderIdentity ๊ฐ€ ์กด์žฌํ•˜๊ณ , ์œ ํšจํ•˜์ง€๋งŒ ๋ฆฌ๋”๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๊ฐฑ์‹ ์„ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋กœ์ง์ž…๋‹ˆ๋‹ค.

 

์„ธ๋ฒˆ์งธ ๋กœ์ง์—์„œ ๋๋‚˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ๋งˆ์ง€๋ง‰ ๋„ค๋ฒˆ์งธ ๋กœ์ง์œผ๋กœ ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

leaderelection.go

 

ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฆฌ๋”๋ผ๋ฉด ์ฒซ๋ฒˆ์งธ ๋กœ์ง๊ณผ ๋น„์Šทํ•˜๊ฒŒ RenewTime ๋งŒ ์—…๋ฐ์ดํŠธ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋งŒ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ฒซ๋ฒˆ์งธ ๋กœ์ง์€ FastPath ์ด๊ณ , ๋„ค๋ฒˆ์งธ ๋กœ์ง์€ SlowPath ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ธ€์ด ๋„ˆ๋ฌด ๊ธธ์–ด์ ธ์„œ ๊ตณ์ด FastPath ์™€ SlowPath ๋Š” ๋‹ค๋ฃจ์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ชจ๋“  ๋กœ์ง์ด ๋๋‚˜๊ณ ๋„, ๋กœ์ง์ด ๊ณ„์† ๋ˆ๋‹ค๋ฉด ์ตœ์ข…์ ์œผ๋กœ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก true ๋ฅผ ๋ฆฌํ„ดํ•ด์ค๋‹ˆ๋‹ค.

 

๋‹ค์Œ์€ tryCoordinatedRenew ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

tryAcquireOrRenew ์™€ ๋‹ฌ๋ฆฌ ์ƒˆ๋กœ์šด ๋ฆฌ๋”๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ผ๊ธฐ ๋ณด๋‹ค๋Š” ์ด๋ฆ„์—์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋ฆฌ๋” ์กฐ์œจ์„ ์œ„ํ•œ ํ•จ์ˆ˜๋กœ ์ดํ•ดํ•˜๋ฉด ์‰ฝ์Šต๋‹ˆ๋‹ค.

leaderelection.go

 

์ฝ”๋“œ๋„ ์„œ๋กœ ๊ต‰์žฅํžˆ ๋น„์Šทํ•œ๋ฐ ํฐ ์ฐจ์ด๋ผ๊ณ  ํ•˜๋ฉด tryCoordinatedRenew ์€ ์ตœ์ข… true ๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ๊ฑฐ ๋นผ๊ณ , ์ „๋ถ€ false ๋งŒ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ๊ฒƒ์ด์ฃ . ํŠน์ด ์‚ฌํ•ญ์ด ์ƒ๊ธฐ๊ฒŒ ๋˜๋ฉด ๊ฐฑ์‹ ์„ ํ•ด์ฃผ์ง€ ์•Š์•„ ๋ฆฌ๋”๋ฅผ ๋ฐ•ํƒˆ์‹œ์ผœ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

 

๊ฒฐ๊ณผ์ ์œผ๋กœ ํ˜„์žฌ ๋ฆฌ๋”์ธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฃผ์–ด์ง„ ์‹œ๊ฐ„์— ๊ฐฑ์‹ ์„ ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋˜๋ฉด, ๋ฆฌ๋” ์ž๊ฒฉ์„ ์žƒ๊ฒŒ ๋˜๊ณ  ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฆฌ๋”๋ฅผ ์ฐจ์ง€ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ์˜ ๋™์ž‘ ๋ฐฉ์‹


์ง€๊ธˆ๊นŒ์ง€ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ดค์œผ๋‹ˆ, ์ด๋ฒˆ์—” ํ•ด๋‹น ์ฝ”๋“œ๋กœ ์ž‘์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์œ„์—์„  ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yamls

 

๋จผ์ € Lease ๋ฆฌ์†Œ์Šค๋ถ€ํ„ฐ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

Lease

 

ํ˜„์žฌ ๋ฆฌ๋”์˜ id ๋Š” ae4cf8ca-f345-481c-b4dc-67995c009951(uuid ๋กœ ์ƒ์„ฑํ–ˆ๋˜) ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ตœ๋Œ€ 60์ดˆ ๋‚ด๋กœ ๋ฆฌ๋” ํŒŒ๋“œ๋Š” ์ž์‹ ์ด ๋ฆฌ๋”๋กœ์„œ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ๋ช…ํ•˜์ง€ ๋ชปํ•˜๋ฉด ๋‹ค๋ฅธ ํŒŒ๋“œ๊ฐ€ ๋ฆฌ๋”๊ฐ€ ๋˜๊ฒ ์ฃ .

 

๋‹ค์Œ์€ ๋ฐฐํฌ๋œ ํŒŒ๋“œ๋“ค์˜ ๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด 3๊ฐœ์˜ ํŒŒ๋“œ๊ฐ€ ๋ฐฐํฌ๋˜์—ˆ๊ณ , ๊ทธ ์ค‘ ํ•˜๋‚˜๋งŒ ๋ฆฌ๋”๋กœ ์„ ์ถœ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

I'm Leader

 

๊ทธ๋ฆฌ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด, ๋ฆฌ๋” ํŒŒ๋“œ์˜ ์ •๋ณด๋งŒ ์‘๋‹ต ๋ฐ›๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

id ๋˜ํ•œ Lease ๋ฆฌ์†Œ์Šค์˜ holderIdentity ์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

Only Leader

 

์ด๋ฒˆ์—” ํ•œ๋ฒˆ ๋ฆฌ๋” ํŒŒ๋“œ๋ฅผ ์ฃฝ์—ฌ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ์กด์˜ ๋ฆฌ๋” ํŒŒ๋“œ๊ฐ€ ์ฃฝ์—ˆ๋‹ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด ํŒŒ๋“œ๊ฐ€ ๋ฆฌ๋”๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

New Leader

 

Lease ๋ฆฌ์†Œ์Šค๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด holderIdentity ๊ฐ€ ๋ฐ”๋€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , leaseTransitions ๋„ ๋ฆฌ๋”๊ฐ€ ๋ฐ”๋€œ์— ๋”ฐ๋ผ ์นด์šดํŠธ๊ฐ€ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

Lease

 

์ถ”๊ฐ€๋กœ ๋ฆฌ๋”๊ฐ€ ๋œ ํŒŒ๋“œ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ฃฝ์˜€์„ ๋•Œ RetryPeriod(์ด ์˜ต์…˜์€ ์ฝ”๋“œ ๋ ˆ๋ฒจ์— ์žˆ์Œ) ์ดํ›„์— ์ƒˆ๋กœ์šด ํŒŒ๋“œ๊ฐ€ ๋ฆฌ๋”๊ฐ€ ๋˜์„œ ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Leaders

 

๋Œ€ํ‘œ์ ์ธ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค


๊ทธ๋Ÿผ ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ํ”„๋กœ์ ํŠธ๋“ค์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ์š”?

๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค

 

Karpenter, Cert Manager, ArgoCD, AWS LB Controller, Kubernetes Components ๋“ฑ ์—„์ฒญ๋‚˜๊ฒŒ ๋‹ค์–‘ํ•œ ํ”„๋กœ์ ํŠธ๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฆฌ๋” ์„ ์ถœ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฉด ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€!

profile on loading

Loading...