촬리의늘솔길

2023 INFCON 후기(를 빙자한 필기 및 공부) - EKS 비용 절감 관련 세션 편 [k8s] 中 Karpenter 에 대하여 본문

✍️2023/Cloud

2023 INFCON 후기(를 빙자한 필기 및 공부) - EKS 비용 절감 관련 세션 편 [k8s] 中 Karpenter 에 대하여

리촬리 2023. 9. 6. 18:42

세션이 여러개였는데,,

기억에 남는 세션 다시 정리와 추가 공부 할 겸 적어봅니다.

제가 작성한 글은 온전히 저의 생각이 아닌 타 기술블로그와 가끔 저의 두서없는 감탄사가 융합된 짬뽕글로

...

여러 기술블로그를 찾기 귀찮으신 분들께 그저 정리용도로 추천드립니다.


[ EKS 비용 절감 관련 세션 中 Karpenter 에 대하여 ]

세션에서 들은 내용 + 추가적으로 알아본 내용을 적었습니다.

1. 스팟 인스턴스 & 적절한 노드 선택

비용 절감을 위해서는 spot Instance 와 적절한 노드 선택을 권장하셨다.

spot 인스턴스는 On-demand Instance 대비 가격이 매우 저렴하지만, Instance 가 언제든 종료될 수 있다는것이 단점이다.

(이에 대한 내용은 추후에 더 다루는것이 좋을 것 같아 skiiiiip...)

 

어쨌든 ,, 이 세션을 통해 처음 알게 된게

"Karpenter" 라는 것이다.

Karpenter : cluster Autoscaling tool , 노드 수를 자동으로 조절

하는 aws 에서 제공하는 서비스라고 하는데, 한번 제대로 찾아보자.

 

AWS EKS 클러스터를 자동으로 조정하기 위한 프로비저닝 도구로, 많이 알려져있는 쿠버네티스 클러스터 오토 스케일러가 있고(CA) , 카펜터가 있다.

일단 기초부터 천천히 짚고 가보자. 

(굉장히 돌아갈 수 있음)

 

1-1. 파드가 노드에 어떻게 올라갈까?

쿠버네티스에서 파드는 하나의 어플리케이션 단위이다. 가장 기본이 되는 단위이다. 

만약 5개의 어플리케이션을 운영한다면, 보통 5개의 서로 다른 파드를 생성한다.

하나의 파드에는 여러개의 컨테이너가 동작할 수 있지만, 서로 다른 애플리케이션을 같은 파드에서 운영하지는 않는다.

갑자기 드는 의문점, 파드 하나에 컨테이너 하나가 권장사항일까?

단순성, 확장성 및 결함격리의 핵심원칙을 중심으로 하는 여러가지의 이유로 인해 Kubernetes에서 파드당 하나의 컨테이너만 보유하는 것이 좋다고 한다.

이유는 아래와 같다.

 

1. 단일 책임 원칙 : 각 파드에는 관심사를 명확하게 분리할 수 있는 특정 작업 또는 기능이 있어야 한다. (이게 곧 위에서 말한 서로 다른 애플리케이션을 같은 파드에서 운영하지 않는다는 부분인 것 같다.)

 

2. 손쉬운 확장 : 쿠버네티스에서 확장은 일반적으로 pod 수준에서 수행된다. 파드당 하나의 컨테이너가 있으면, 애플리케이션의 개별 구성 요소를 독립적으로 확장하기가 더 쉬워진다. 이는 시스템의 전반적 확장성과 응답성 개선에 도움이 된다. 

 

3. 오류 격리 : pod 당 단일 컨테이너 실행하면, 오류 격리와 계단식 오류를 방지할 수 있다. 다중 컨테이너 pod 에서 컨테이너가 실패하면, 동일한 pod의 다른 컨테이너에 잠재적으로 영향을 미칠 수 있다. 단일 컨테이너 pod를 사용하면 장애가 특정 pod로 제한되므로, 문제 해결 및 복구가 쉬워진다. 

 

4. 리소스 관리 : 쿠버네티스는 cpu, 메모리 및 스토리지 할당을 포함하는 pod 수준에서 리소스 관리를 제공한다. pod당 하나의 컨테이너를 사용하면 최적의 리소스 사용이 보장되고, 동일한 pod내의 컨테이너간 리소스 경합이 방지된다.

 

5. 간소화된 모니터링 및 로깅 : pod 당 단일 컨테이너가 있을 때, 모니터링 및 로깅이 더욱 간단해진다. 이 접근 방식을 사용하면, 로그 및 메트릭을 특정 구성요소와 쉽게 연결하여 문제를 식별하고 성능을 분석하기가 더 쉬워진다.

 

6. 수명 주기 관리 : pod 의 각 컨테이너는 동일한 수명 주기를 공유한다. 단일 pod에 여러 컨테이너가 있는 경우에 개별 컨테이너의 수명 주기를 관리하는데에 문제가 발생할 수 있다. pod당 단일 컨테이너를 실행하면, 각 구성요소의 수명 주기를 개별적으로 관리하기가 쉬워져 필요할 때 원활한 업데이트 및 롤백이 보장된다. 

 

 

파드의 특징

다시 본론으로 돌아와서, 어쨌든 일반적으로 한개의 파드는 한개의 어플리케이션의 단일 인스턴스를 실행한다.

여러 프로세스를 컨테이너 하나로 묶지 않기 때문에, 컨테이너를 함께 묶고 하나의 단위로 관리할 수 있는 또 다른 상위 구조가 필요하다. 이 때문에 파드가 필요한 것이다.

 

1. 기본적으로 하나의 파드에는 하나 이상의 컨테이너가 포함된다. 필요에 따라 하나의 파드에 여러 컨테이너를 포함시킬 수 있다. (이 필요가 무엇인지는 좀이따 다룰것)

2. 파드는 노드 IP 와 별개로 고유 IP를 할당 받으며, 파드 안의 컨테이너들은 그 IP를 공유한다.

3. 파드 자체는 일반적으로 1개의 IP만 가진다. (단, Multus CNI 이용 등 특정 조건에 한해 2개의 IP를 가질 수도 있다.)

4. 파드 안의 컨테이너들은 동일한 볼륨과 연결이 가능하다.(이 부분도 현재 하고있는 플젝에서 중요해서 후에 다룰 예정)

5. 파드는 클러스터에서 배포의 최소단위이고, 특정 네임스페이스 안에서 실행된다.

6. 파드는 기본적으로 반영속적이다(ephemeral) 

--> 동일한 역할을 하는 파드라도 환경에 따라 다른 노드들에 각각 배치될 수 있고, 특정 노드가 죽으면 해당 노드의 파드들이 건강한 상태의 다른 노드로 옮겨지기도 한다.  or 필요에 따라 파드 숫자의 구성도 수시로 달라질 수도 있다.

 

쿠버네티스에서의 파드는 무언가가 구동중인 상태를 유지하기 위해 동원되는 일회성 자원이며, 필요에 따라 언제든 삭제될 수 있는 것임을 유념. 

 

 

그렇다면, 다중 컨테이너 pod에 대한 유효한 사용 사례는 없을까 ?

 

1-2. SideCar 

다중 컨테이너를 실행하는 파드

단일 파드에서 함께 배치 또는 관리되는 여러 컨테이너를 그룹화하는 것은 비교적 고급 Use-Case라고 한다. 

파드끼리 밀접하게 결합되어 있고 리소스를 공유해야 할 때, 여러 개의 컨테이너로 구성된 애플리케이션을 캡슐화할 수 있다. 이와 같이 함께 배치된 컨테이너는 하나의 결합된 서비스 단위를 형성한다. ex) 사이드카 패턴

 

그렇다면 사이드 카란 무엇인지 자세히알아보자.

클라우드 네이티브 애플리케이션 설계와 구현을 위한 쿠버네티스 디자인 패턴 24개중 하나를 나타낸다. 

사이드카 패턴은 보조 컨테이너가 동일한 pod내에서 기본 컨테이너와 함께 실행되는 패턴이다.

 

 

붙이든 떼든 오토바이가 굴러가는것 자체에는 별 영향을 주지 않는 사이드 카

즉, 기본 컨테이너와 독립적으로 동작하는 별도의 컨테이너를 붙이는 패턴이기 때문에 기존 어플리케이션 컨테이너의 핵심기능을 변경이나 수정 없이 독립적으로 추가 기능 또는 지원을 제공 및 동작하는 컨테이너를 붙였다 뗐다 할 수 있다.

 

사이드카 컨테이너의 일반적인 사용 사례는 다음과 같다.

1. 로그 관리 : 로그 집계, 처리 및 중앙 로깅 서비스로의 전달을 담당할 수 있다. 이렇게 하면 기본 컨테이너가 로그관리에 대한 걱정없이 핵심 기능에 집중할 수 있다.

2. 모니터링 : 사이드카 컨테이너는 기본 컨테이너에서 애플리케이션 별 메트릭을 수집하고, 이를 Prometheus와 같은 모니터링 시스템에 노출할 수 있다. 이는 애플리케이션 논리에서 모니터링 작업을 분리하는데에 도움이 된다.

3. 프록시 : 사이드카 컨테이너는 기본 컨테이너에 대한 수신 또는 발신 네트워크 트래픽을 처리하는 프록시 역할을 할 수 있다. 예를들어 사이드 카는 트래픽 라우팅, 부하 분산 및 보안 정책과 같은 서비스 메시 기능을 구현할 수 있다.

4. 보안 : 사이드카 컨테이너를 사용하여 보안 정책을 실행하거나, 비밀 및 자격 증명을 관리하여 중요한 데이터를 기본 컨테이너와 분리할 수 있다.

 

사이드카 패턴은 파드에 둘 이상의 컨테이너를 포함하지만, 사이드카 컨테이너가 기본 컨테이너와 밀접하게 결합되어 해당 기능을 직접 지원하기 때문에 파드당 하나의 컨테이너를 권장하는 사항에 대해 예외이다. 

 

 

1-1. 파드가 노드에 어떻게 올라갈까? 를 이어서 말하자면,,

돌고 돌아 다시 처음으로 왔다.

어쨌든 사용자는 쿠버네티스 API를 통해 파드를 생성할 수 있다. 

쿠버네티스 API서버는 API 요청을 받으면, 해당 정보를 etcd 라는 저장소에 저장한다. 정보를 저장하더라도 바로 파드를 생성하지는 않는다. 실제로 생성을 요청하는 녀석은 쿠버네티스 스케줄러 이다.

 

쿠버네티스 스케줄러는 아직 노드에 스케줄링 되지 않는 파드가 있는지 쿠버네티스 API 서버에 물어본다. 만약 스케줄링이 필요한 파드가 있으면, 요청 스펙을 보고 적합한 노드를 찾는다. 예컨대, CPU 가 4 core 이상 필요하다면, 4 core 이상읭 여유가 있는 노드만 선별하고, 그 중 가장 적합하다고 생각되는 노드를 선정한다. 

선정이 완료되면 선정된 노드에 파드를 생성해 달라고 쿠버네티스 API 서버에 요청한다.

 

각 노드의 Kubelet은 자신의 노드에 할당된 파드가 있는지 지속적으로 확인한다. 만약 노드가 할당된 파드가 있으면 쿠버네티스 API 서버에 파드 정보를 요청해서 스펙을 확인하고, 그에 맞게 파드를 생성한다. 이때 파드 생성에 실패할 수도 있다. 파드를 생성하지 못하더라도 쿠버네티스 스케쥴러는 다시 노드를 선정하지 않는다. 노드를 지정한 후에는 더이상 스케쥴러가 파드 생성에 관여하지 않는다.

 

 

 

1-3. CA의 동작 방식

쿠버네티스에서는 다음과 같은 3가지 Autoscaling 방법이 있다.

* HPA(Horizontal Pod Autoscaler)

* VPA(Vertical Pod Autoscaler)

* CA(Cluster Autoscaler)

 

 

 

 AWS 의 경우는 AutoScaling Group(ASG) 을 통해 CA 기능을 구현하기 때문에 클러스터의 확장 시나리오는 다음과 같아진다.

카카오 스타일 기술블로그

 

  1. Horizontal Pod AutoScaler(HPA) 에 의한 pod의 수평적 확장이 한계에 다다르면, pod는 적절한 Node 를 배정받지 못하고 pending 상태에 빠진다.
  2. 이때 CA 는 Pod 의 상태를 관찰하다가 지속해서 할당에 실패하면 Node Group  ASG Desired Capacity 값을 수정하여 Worker Node 개수를 증가하도록 설정한다.
  3. 이를 인지한 ASG 가 새로운 Node를 추가한다.
  4. 여유 공간이 생기면 kube-scheduler 가 Pod를 새 Node에 할당한다.

 

 기존 hpa와 vpa가 eks에서 내에서 scaling을 진행하는 것과는 달리, worker node를 확보하기 위해 EC2의 Auto Scaling Group (이하 ASG)을 사용하여 의존도가 높으며 k8s와 ec2 별도의 Layer를 관리해야 하는 운영 복잡도가 발생하게 된다.

여기에 만약 Node 에 custom userdata 를 추가해야 한다면 Launch template 을 따로 관리해야하고,

워크로드별 인스턴스 요구사항이 달라 여러 관리형 Node Group 을 도입해야 한다면 여러 벌의 ASG 을 운영해야 하는 등 운영 부담이 늘어난다고 한다. 

gs neotek 기술블로그

 

이에 대한 대안으로 드디어 다루고자 했던,

1-4. Karpenter란?

aws 가 개발한 K8s 의 Worker Node 자동 확장 기능을 수행하는 오픈소스 프로젝트이다.

CA와 비슷한 역할을 수행하지만, AWS 리소스에 의존성이 없어 JIT(Just In-Time) 배포가 가능하다는 점에서 다른 확장 시나리오를 가지고 있다.

 

KarPenter 동작 원리

카카오 스타일 기술블로그

  1. Horizontal Pod AutoScaler(HPA) 에 의한 Pod의 수평적 확장이 한계에 다다르면, Pod 는 적절한 Node 를 배정받지 못하고 pending 상태에 빠집니다.
  2. 이때 Karpenter 는 지속해서 unscheduled Pod 를 관찰하고 있다가, 새로운 Node 추가를 결정하고 직접 배포합니다.
  3. 추가된 Node가 Ready 상태가 되면 Karpenter  kube-scheduler 를 대신하여 pod 의 Node binding 요청도 수행한다.

위와 같이 Karpenter 는 기존 CA 에 비해 훨씬 단순한 구조를 가지고 있으며 클러스터 확장 시 일어나는 많은 부분을 Karpenter 에서 직접 처리해서 빠르게 확장을 처리할 수 있도록 설계되었습니다. 모든 Worker Node 는 Karpenter 에 의해 lifecycle 이 결정된다.

 

카펜터의 구성 요소

 

카펜터는 Provisioner 와 NodeTemplate 을 통해 조건에 알맞은 노드 타입을 빠르게 프로비저닝 해준다.

먼저 Provisioner는 프로비저닝이 될 때 사용할 수 있는

인스턴스 패밀리, 가용영역, 가중치 등으로구성해서 노드가 생성될 때 필요한 프로바이더(providerref)의 역할을 하게 된다.

 

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: on-demand
spec:
  providerRef:
    name: on-demand
  ttlSecondsAfterEmpty: 30
  limits:
    resources:
      cpu: 1k
      memory: 1000Gi
  requirements:
    # Include general purpose instance families
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["on-demand"]
    - key: karpenter.k8s.aws/instance-family
      operator: In
      values: ["t3"]
    - key: karpenter.k8s.aws/instance-size
      operator: NotIn
      values: ["nano", "micro", "small"]
    - key: kubernetes.io/arch
      operator: In
      values: ["amd64"]
    - key: topology.kubernetes.io/zone
      operator: In
      values: ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]

 

다음으로 NodeTemplate는 Provisioner의 spec.providerRef부분에 들어가고, 프로비저닝될 노드가 어떤 AMI로 실행하고, 혹은 어떤 보안 그룹을 사용할 것인지 등 노드에 대한 정의를 하는 템플릿이라고 볼 수 있다.

apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
  name: spot
spec:
  subnetSelector:
    karpenter.sh/discovery: daxdapne2-207b
  securityGroupSelector:
    karpenter.sh/discovery: daxdapne2-207b
  instanceProfile: MyInstanceProfile
  amiFamily: Bottlerocket

(사실 직접 써보지 않아서 이렇게만 보면 확 와닿게 이해되지는 않는듯)

 

 

Karpenter 가 동작하는 시점

그러면 Karpenter 는 정확히 언제 동작해야할까?

바로, 스케쥴러가 적합한 노드를 찾지 못할 때이다. Karpenter 컨트롤러는 준 실시간으로 스케쥴링되지 않는 파드를 찾는다. 한번 쿠버네티스 스케쥴러가 스케쥴링을 시도 했음에도 여전히 Pending 상태라면 Karpenter는 일을 시작한다.

 아래의 동작과정 그림을 보면, CA와는 다르게 ASG와 관계없이 동작하는 것을 확인할 수 있다. 이렇기 때문에 파드를 할당할 수 있는 노드가 부족할 때, JIT(Just-In-Time)으로 노드 프로비저닝이 일어나기 때문에 보다 빠르게 파드를 할당 할 수 있게 된다.

 

 

aws 공식 사이트

 

 

나머지 KarPenter에 관한 동작관련 내용은 타 기술블로그를 참조해주시길 바랍니다.

(왜냐면 제가 실습을 안해봐서 이해가 완벽히 안되기때문에,,,)

 

 

 

 

 

 

[참고]

https://devblog.kakaostyle.com/ko/2022-10-13-1-karpenter-on-eks/

 

EKS클러스터 Karpenter 적용기

안녕하세요! 카카오스타일 SRE팀 네사입니다. 오늘은 카카오스타일 SRE팀에서 올해 EKS 클러스터 이전을 하며 새롭게 도입 했던 AWS Karpenter 에 대해 공유를 해보려 합니다.

devblog.kakaostyle.com

https://brunch.co.kr/@growthminder/87

 

Karpenter 작동 원리

어떻게 Karpenter는 노드를 관리할까? | Karpenter는 노드 생성 및 삭제를 도와주는 오픈소스 도구이다. 클러스터 상에 파드를 올릴 노드가 없으면 Karpenter는 노드를 생성한다. Karpenter는 자신이 생성

brunch.co.kr

https://medium.com/uplusdevu/karpenter%EC%99%80-empty-pod%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%8A%A4%EC%BC%80%EC%9D%BC%EB%A7%81-1-775737f265b3

 

Karpenter와 Empty Pod을 활용한 스케일링(1)

이번 글에서는 AWS의 관리형 서비스인 EKS(Elastic Kubernetes Service)환경에서 노드 프로비저닝(node provisioning)에 사용되는 Cluster Autoscaler(CA)와 카펜터(Karpenter)에 대해…

medium.com

https://easyitwanner.tistory.com/178

 

[Container 이론] 5. 컨테이너 파드(pod)와 사이드카

목차 pod란? 여러 프로세스를 실행하는 하나의 컨테이너 VS 하나의 프로세스를 실하는 다중 컨테이너 하나의 파드 안에 하나의 컨테이너 사용을 권장하는 이유 파드의 특징 사이드카? pod란? Kuberne

easyitwanner.tistory.com

https://akasai.space/kubernetes/about_pod/

 

Pod란? | devlog.akasai

CKA를 준비하며 공부하고 있는 내용을 정리해보려고 합니다. 공부 순서대로 정리를 하고 있어서 다소 부족한 부분도 많을 수 있습니다. 파드(Pod…

akasai.space

https://yoonchang.tistory.com/94#:~:text=%5B%20%EC%82%AC%EC%9D%B4%EB%93%9C%EC%B9%B4%20%ED%8C%A8%ED%84%B4(Sidecar%20pattern),%EB%A5%BC%20%EC%B6%94%EA%B0%80%ED%95%98%EB%8A%94%20%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%8B%A4. 

 

[Kubernetes] 13. 쿠버네티스 사이드카 패턴(Sidecar pattern) 및 실습

[주의] 개인 공부를 위해 쓴 글이기 때문에 주관적인 내용은 물론, 쓰여진 정보가 틀린 것일 수도 있습니다! 피드백 부탁드립니다. (- -)(_ _) 꾸벅 Logging Architecture Application logs can help you understand wha

yoonchang.tistory.com

https://seongjin.me/kubernetes-pods/

 

파드(Pod)의 개념과 생명 주기, 그리고 상태 진단을 위한 프로브(Probe) 활용

쿠버네티스 클러스터에서 이용되는 최소 단위의 객체인 파드(Pod)에 대해 자세히 알아본다. 파드의 개념과 종류, 생명 주기, 그리고 프로브(Probe)를 이용한 상태 진단법을 살펴보기로 하자.

seongjin.me

https://www.wisen.co.kr/pages/blog/blog-detail.html?idx=12079 

 

[Re2021] 새로운 K8s Cluster Autoscaler, Karpenter 소개

GS네오텍의 IT서비스 브랜드 WiseN으로 진정한 프리미엄을 경험하세요

www.wisen.co.kr:443

 

728x90