본문 바로가기

Container/Kubernetes

[k8s]쿠버네티스 개념

쿠버네티스(Kubernetes, k8s)란

  • 오픈소스로 만들어진 컨테이너 오케스트레이션 도구
  • 컨테이너화된 애플리케이션을 자동으로 배포, 스케일링하는 등의 관리 기능을 제공
    • 각기 다른 환경(온프레미스 서버, VM, 클라우드)에 대응 가능

무엇을 오케스트레이션 하나?

orchestrate의 사전적 의미는 다음과 같다.

to plan and organize
something carefully and sometimes secretly in order to achieve a desired result

아키텍처가 모놀리식에서 마이크로 서비스화되어 필요한 컨테이너가 증가하고, 확장성을 높이기 위해 스케일링을 할 경우 더욱 많은 컨테이너가 필요하다. 이 때 쿠버네티스는 수 많은 컨테이너를 더 잘 관리할 수 있는  도구이다.

언제 사용하지 말아야 하는가?

  • 여러 Tier(단계)로 나뉘어지지 않은 모놀리식 아키텍처에서는 적합하지 않다.
    • 모놀리식 아키텍처는 먼저 마이크로서비스 분해 전략을 세우는 것이 우선이다.
  • 고작 서너 개에 불과한 컨테이너만을 다루려면 적합하지 않다.
    • 서너 개의 불과한 컨테이너는 docker-compose로도 충분하다.
  • 비교적 단순한 아키텍처에, 스케일링이 필요하지 않은 경우에는 적합하지 않다.
    • 이후 트래픽이 증가하거나, 스케일링이 필요한 경우, 서버리스 서비스를 사용하면 다소 저렴한 가격에 관리형 서비스를 이용할 수 있으며, AWS 내에서도 오토 스케일링과 같은 관리형 서비스가 배포 환경에서 제공된다.

기능과 언제 사용해야 하는가?

  • 마이크로서비스를 컨테이너 방식으로 운영하는 조직이 확장성을 고려해야 할 때
  • 무중단 서비스, 즉 고가용성을 제공해야 할 때
  • 그 밖에 다양한 기능들: 자가 치유,배치 실행, 구성 관리, 로드 밸런싱...

 

  • 쿠버네티스를 이용해 온프레미스 상에서 (사설) 클라우드 인프라를 구성하고,
  • 저렴한 클라우드 서비스의 일부분을 도입하여 하이브리드 형태로 구성하기도 하며,
  • 필요에 따라 쿠버네티스로 구성한 인프라를 통째로 AWS 등에 마이그레이션 합니다. (이식성)
    • 주요 퍼블릭 클라우드 공급자들은 관리형 쿠버네티스를 지원합니다. 예) AWS EKS

 


Q. 디플로이먼트가 지원하는 배포 전략에서 블루/그린이나 카나리는 찾아볼 수 없습니다. 어떻게 블루/그린이나 카나리 배포를 할 수 있을까?

Deployment?

  • 파드의 교체/배치(placement)와 관련된 선언적 명세이다.
  • 파드를 원하는 개수만큼 실행시킬 수 있다.
  • 파드를 업데이트할 수 있다.
  • 파드를 롤백할 수 있다.

쿠버네티스는 컨테이너를 오케스트레이션하는 것으로, 주요 목적은 파드에 장애가 발생했을시 자동 복구하거나, 많은 트래픽이 몰렸을 시 파드를 자동으로 확장해주는 것에 있다. 그렇기에 파드는 일시적이고, 언제나 삭제될 수 있다. 그렇기에 파드를 직접관리하기 보다는 Deployment, 스테이풀셋, 데몬셋을 이용해 관리하는 것이 바람직하다.

 

앞서 여러 복제본으로 구성된 애플리케이션을 새 버전으로 업데이트하는 방법으로 재생성, 블루/그린 배포, 롤링 배포, 카나리 배포를 배웠다. 그런데 쿠버네티스는 재생성과 롤링 배포만 배포 전략으로 선택할 수 있다. 여기서 주제와 같은 의문이 생긴다.

 

블루 그린 배포

블루 그린 배포를 잠깐 살펴보면, 기존 버전인 블루 배포에 사용자의 트래픽을 라우팅하고, 새로운 버전인 그린 배포를 준비한다. 이때 프로덕션 환경에서 충분히 테스트를 진행한 후, 사용자의 트래픽을 그린 배포로 옮기면 블루 그린 배포는 끝난다. 동일한 배포 환경을 두개 다뤄야하고 라우팅을 옮기는 네트워크관련 과정도 포함되어 있어서 까다롭다. 쿠버네티스를 활용하여 어떻게 할 수 있을까?

 

Deployment는 RollingUpdate와 Recreate만 배포전략으로 지원한다 .yaml파일을 보면 다음과 같다.

spec:
 strategy:
    type: RollingUpdate or Recreate

RollingUpdate는 한정된 리소스 자원을 이용하여 하나하나씩 파드들을 업데이트하고, 하나하나씩 기존의 파드들을 지우는 과정으로 진행된다. 즉 다운타임이 없는 무중단 배포이다. 반면, Recreate는 모든 기존의 파드들을 지우고, 새로운 파드들을 업데이트한 후 배포한다. 즉, 다운타임이 발생하게 된다. 블루 그린 배포는 사용자의 트래픽을 라우팅해야하기에 Deployment만으로 배포하기 힘들다. Service라는 클러스터 내 리소스를 사용자에게 노출시키는 것을 이용한다. 간단하게 로드밸런서 Service를 이용한다.

 

예시로 블루 버전의 Service, Deployment가 있다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cozserver-blue
  labels:
    app: cozserver
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cozserver
      color: blue
  template:
    metadata:
      labels:
        app: cozserver
        color: blue
    spec:
      containers:
      - name: cozserver
        image: sebcontents/cozserver:1.0
        ports:
        - containerPort: 8080
apiVersion: v1
kind: Service
metadata:
  name: cozserver-service
  namespace: default
spec:
  selector:
    color: blue # 구버전을 바라본다.
  type: LoadBalancer
  ports:
  - name: cozserver
    protocol: TCP
    port: 8080
    targetPort: 8080

새로운 버전, 그린이 적용된 Deployment를 하나 더 생성한다. 다음과 같다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cozserver-green
  labels:
    app: cozserver
spec:
  replicas: 3
  selector:
    matchLabels:
      app: cozserver
      color: green
  template:
    metadata:
      labels:
        app: cozserver
        color: green
    spec:
      containers:
      - name: cozserver
        image: sebcontents/cozserver:2.0 #신버전
        ports:
        - containerPort: 8080

그린 버전의 Deployment가 준비되었고, 프로덕션환경에서 충분히 테스트가 되었다고 판단한다. 그리고 pact-service.yaml 파일을 작성하므로써 서비스를 수정한다. blue가 아닌 신버전 green을 바라본다.

spec:
  selector:
    color: green

test-service를 업데이트하는 쿠버네티스 명령어를 입력한다.

$ kubectl patch service cozstory-service -p "$(cat patch-service.yaml)"

패치가 성공적으로 잘 되었고 트래픽이 그린을 바라본다면, 블루 그린 배포는 성공이다. 그 이후 블루 버전의 프로덕션환경이 필요없다면 삭제해주면된다.

$ kubectl delete deployment.apps/cozserver-blue

 

이외에도 CI/CD툴을 이용한 무중단 배포방식이 존재한다. 다음의 글을 참고하면 된다.

https://semaphoreci.com/blog/continuous-blue-green-deployments-with-kubernetes

 

Continuous Blue-Green Deployments With Kubernetes - Semaphore

Learn how to create a CI/CD pipeline that deploys an application in Kubernetes using the blue-green methodology.

semaphoreci.com

 

카나리 배포

카나리 배포는 일부 사용자를 새버전의 애플리케이션으로 리다이렉션하여 본격적인 배포 전 일부 사용자들에게 테스트할 수 있는 배포방법이다. 따라서 새 릴리스가 완전히 롤아웃되기 전에 실제 운영 트래픽을 수신할 수 있도록 프로덕션환경에 신버전(카나리)과 구버전을 나란히 배포하는 것이 일반적이다.

Deployment의 track 레이블을 사용하여 다른 릴리스와 구별할 수 있다.

구버전의 track은 stable로, 신버전의 track은 canary로 다음과 같이 Deployment를 구성한다.

 name: frontend
 replicas: 3
 ...
 labels:
    app: guestbook
    tier: frontend
    track: stable
 ...
 image: gb-frontend:v3
 name: frontend-canary
 replicas: 1
 ...
 labels:
    app: guestbook
    tier: frontend
    track: canary
 ...
 image: gb-frontend:v4

이때 Service를 두버전이 걸쳐있는 공통 서브넷을 선택한다. 그 방법은 다음과 같이 track레이블을 생략하면 된다.

selector:
 app: guestbook
 tier: frontend

현재 두 버전의 레플리카 비율은 3:1이다. 이 비율을 조정하므로써 카나리 버전에 들어가는 트래픽 양을 조절할 수 있고, 충분한 테스트가 진행되었다고 판단하면, 새로운 안전 릴리스의 track을 추가하여 카나리를 제거할 수 있다.


 

Q. 서비스의 타입은 ClusterIP, NodePort, LoadBalancer, ExternalName 네 가지가 있다. 이들은 어떻게 다른가?

  • ClusterIP: 서비스를 클러스터-내부 IP에 노출시킨다. 이 값을 선택하면 클러스터 내에서만 서비스에 도달할 수 있다. 이것은 ServiceTypes의 기본 값이다. 
  • NodePort: 고정 포트로 각 노드의 IP에 서비스를 노출시킨다. NodePort 서비스가 라우팅되는 ClusterIP 서비스가 자동으로 생성된다. NodeIP: NodePort를 요청하여, 클러스터 외부에서 NodePort 서비스에 접속할 수 있다.
  • LoadBalancer: 클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출시킨다. 외부 로드밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
  • ExternalName: 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠(ex. foo.bar.example.com)에 매핑한다. 어떤 종류의 프록시도 설정되어 있지 않다.

'Container > Kubernetes' 카테고리의 다른 글

[k8s]readiness probe로 파드 health check 하기!  (0) 2022.04.26
[k8s]스테이트풀 셋  (0) 2022.04.26
[k8s]서비스 디스커버리  (0) 2022.04.25