본문 바로가기

Cloud

[Cloud] k8s(Kubernetes)의 대표적인 기능

k8s(kubernetes)

 

쿠버네티스에는 어떠한 기능들이 있을까요?
대표적인 기능으로는 다음의 네 가지가 있습니다.

  1. Load Balancing
  2. Self-Healing
  3. Auto Scailing
  4. Rolling Update

하나하나씩 예시와 함께 차근차근 살펴보도록 하겠습니다.

사용 툴

  • Grafana : 대시보드를 통해 직관적으로 확인하기 위해 사용
  • Kubernetes Dashboard : 그라파나와 마찬가지로 대시보드를 통해 파드들의 상태를 확인하기 위해 사용
  • Loki : 로깅을 확인하기 위해 사용

실습 코드

코드를 살펴보기 전에, 쿠버네티스의 선언적 관리 환경을 사용하는데 이에 대해 간단히 언급하고 넘어가겠습니다.

Object들의 배포를 코드로 관리함으로써 자동화된 오브젝트 관리를 이룰 수 있습니다.

 

즉, 해당 파일을 참조하며 구성 파일의 상태와 현재 파드들의 상태가 일치하는 가를 체크하며 Self healing, Auto scailing 등의 기능을 수행하는 것입니다.

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1-2-2-1
spec:
  selector:
    matchLabels:
      app: '1.2.2.1'
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: '1.2.2.1'
    spec:
      containers:
        - name: app-1-2-2-1
          image: 1pro/app
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
          startupProbe:
            httpGet:
              path: "/ready"
              port: http
            failureThreshold: 10
          livenessProbe:
            httpGet:
              path: "/ready"
              port: http
          readinessProbe:
            httpGet:
              path: "/ready"
              port: http
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "200Mi"
              cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: app-1-2-2-1
spec:
  selector:
    app: '1.2.2.1'
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 31221
  type: NodePort
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-1-2-2-1
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app-1-2-2-1
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 40

 

각각의 Object들을 선언적으로 구성하였고, 해당 파일을 통해 쿠버네티스가 파드들을 관리하게 됩니다.
각 Object들을 간단히 정리해보겠습니다.

  • Deployment : Pod를 생성하고 업데이트하는 방법을 제공합니다.
  • Service : Pod에게 트래픽을 연결해주는 역할을 수행합니다.
  • HorizentalPodAutoscailer(HPA) : 부하에 따라 pod를 늘려주고 줄여주는 Autoscaler의 역할을 수행합니다.

1. Load Balancing

첫 번째 기능인 Load Balancing 기능입니다.


하나의 파드에 대해 모든 트래픽이 몰리게 되면, 파드에서 사용되는 컴퓨팅 자원의 한계에 다다를 수 있습니다.

그 결과로는 파드가 제 기능을 수행하지 못하는 상황에 이르게 되고, 시스템의 중지를 초래할 수 있는 위험한 상황이 발생할 수 있습니다.

 

한 파드에 부하가 집중될 때 다른 파드에 트래픽을 분산시켜 위와 같은 상황이 발생하지 않도록 하는 것이 Ingress 컨트롤러의 로드 밸런싱 기능입니다.
해당 기능을 수행하기 위해 여러 개의 파드가 있어야 하는데, 이는 HPA의 Auto-Scailing 기능과 관련이 있습니다.

 

Traffic Routing

 

이와 같이 여러 개의 파드가 있을 때 트래픽이 분산되어 이동하는 것을 알 수 있습니다.

그렇다면, 어떻게 분산이 되는지 조금 더 자세히 알아보겠습니다.

 

Ingress

 

Ingress는 클러스터 외부에서 클러스터 내부의 서비스로 HTTP와 HTTPS 경로를 노출해주는 API 객체입니다.

 

사용자가 Ingress를 통해 관리하려는 서비스의 라우팅 규칙을 정의하고, 해당 규칙에 따라 Ingress 리소스를 생성하게 됩니다.

구성된 리소스를 기반으로 Ingress Controller가 해당 규칙을 해석해 라우팅을 진행하게 된다고 생각하면 됩니다.

 

다음 소스를 한 번 보겠습니다.

 

AWS의 로드밸런서를 활용하는 ingress 리소스 설정 파일입니다.

apiVersion: networking.k8s.io/v1 # Ingress의 리소스 버전 정의
kind: Ingress # k8s의 리소스 유형을 나타냄, 클러스터의 서비스에 대한 외부 액세스를 관리하는 API 객체로, 일반적으론 HTTP 이용
metadata: # Ingress 리소스의 메타 데이터
  name: <ingress-name> # Ingress 리소스의 이름 지정
  namespace: dev
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/load-balancer-name: <load-balancer-name>
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/subnets: <my-subnet-list>
spec: # Ingress 리소스의 원하는 상태 지정
  ingressClassName: alb
  rules: # 들어오는 요청에 대한 라우팅 규칙 정의
  - host: <my-load-balancer-dns-name> # 해당 라우팅 규칙이 적용되는 호스트 이름 지정
    http: # http에 특화된 라우팅 규칙 지정
      paths: # 경로 기반의 라우팅 규칙을 정의
      - path: / # path "/"가 프런트엔드 서비스로 라우팅되어야 함을 지정
        pathType: Prefix # 경로의 일치 유형을 지정, 프리픽스 매칭으로 "/"로 시작하는 모든 경로가 일치
        backend: # 이 경로와 일치하는 요청이 전달될 백엔드 서비스를 지정
          service: # 백엔드 서비스 이름 지정
            name: <my-fe-service>
            port: # 백엔드 서비스의 포트를 지정
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: <my-be-service>
            port:
              number: 80

 

해당 소스에서는 서비스에 따라서 라우팅 규칙을 정의하고 있습니다.

  • '/' 경로로 들어오는 트래픽의 경우 Frontend 서비스
  • '/api' 경로로 들어오는 트래픽의 경우 Backend 서비스

해당 Ingress 리소스는 L7(HTTP/HTTPS) 계층에서 동작하며 HTTP 요청의 헤더, URL, 호스트 네임 등의 내용을 기반으로 로드밸런싱을 수행합니다.

2. Self-Healing

두 번째 기능인 셀프 힐링 기능입니다.
파드들이 잘 실행되다가 하나의 파드가 어떠한 문제로 작동 중지되었다고 해보겠습니다.

 

하나를 삭제하게 되면 선언적 구성에서 맞춰야 했던 파드 수를 유지하기 위해 하나의 파드가 다시 running 상태에 돌입하게 됩니다.

 

Self-healing

 

해당 기능을 통해 파드에 문제가 생겨도 k8s에서 이상적인 상태의 파드 수를 맞추기 위해 노력한다는 것을 알 수 있습니다.

 

3. Auto Scailing

 

세 번째 기능인 Auto-Scailing 기능입니다.

앞서 언급했던 실습 코드 상의 HPA Object 부분을 따로 보며 확인해 보겠습니다.

 

spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app-1-2-2-1
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 40

 

minReplicas에서 최소 파드 수를 정의하고, maxReplicas에서 최대 파드 수를 정의합니다.

그리고 metrics에서 파드의 수를 조절할 설정을 정의하는데요. 위의 실습 코드에선 CPU의 사용량이 평균 40%가 될 수 있도록 파드의 수를 조절합니다.

 

예를 들어, 파드의 cpu 사용량이 40%를 넘어가게 되면 파드의 수를 증가(Auto Scailing)시켜 해당 metrics 기준을 충족할 수 있도록 하는 것입니다.

 

Auto-scailing

 

Self-healing 부분에서 파드의 수가 4개였는데 위 사진에선 2개입니다. 이와 같이 metrics에서 지정한 기준에 따라 파드의 수를 자동으로 증감시키는 것이 Auto-scailing 기능입니다.

 

4. 무중단 배포

 

네 번째 기능인 무중단 배포 기능입니다.

k8s에선 지원하는 대표적인 방법으로는 다음과 같이 세 가지의 방법이 있습니다.

 

  • 블루 / 그린 배포
  • 롤링 업데이트
  • 카나리아 배포

Deployment Object의 strategy 부분에서 업데이트 방식을 지정하게 됩니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1-2-2-1
spec:
  selector:
    matchLabels:
      app: '1.2.2.1'
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: '1.2.2.1'

 

이 부분에선 Rolling update가 어떻게 수행되는지 사진과 함께 살펴보겠습니다.

 

 

app의 업데이트 버전인 app-update 버전으로 업그레이드했다고 예를 들어보겠습니다.

 

새롭게 파드를 생성해서 k8s에서 검증이 진행되게 됩니다.

검증이 완료되면, 다음과 같이 한 개의 파드씩 app-update로 변경되게 됩니다.

 

마지막에는 app 버전이 남아있지 않고, 모두 app-update 버전으로 변경되어 존재하는 것을 알 수 있습니다.

 

그렇다면, 업데이트된 버전에서 설정 등으로 인해 오류를 초래하게 되면 어떻게 될까요?

 

에러가 발생하는 버전으로 업데이트를 시켜보겠습니다.

 

 

Rolling update의 첫 번째 사진에서 봤듯이, k8s에서 파드를 생성하게 됩니다.

 

 

 

에러가 발생한 경우 상태가 Error로 변경되어 업데이트가 진행되지 않고 파드가 재시작되게 됩니다. 해당 상태는 CrashLoopBackOff로서, 애플리케이션에 문제가 발생되어 재시작하는 상태를 말합니다.

 

해당 경우를 살펴보며 k8s는 새 이미지가 잘 기동이 되는지 확인한 후에 기존 이미지를 바꾸기 때문에 작업자의 실수가 있어도 보완을 해준다는 사실을 알 수 있습니다.

 

이와 같이 쿠버네티스의 대표적인 네 가지 기능들을 정리해보았습니다, 잘못된 점이 있다면 지적해주시면 감사드리겠습니다.

 

 

 

인프런 - 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2의 일프로 님의 강의를 듣고 정리한 글입니다.

 

 

https://kubernetes.io/docs/concepts/services-networking/ingress/

https://www.brainz.co.kr/tech-story/view/id/245#u

https://ooeunz.tistory.com/124

'Cloud' 카테고리의 다른 글

[Cloud] 컨테이너란 무엇일까?  (4) 2024.04.20