Kubernetes/쿠버네티스 모범 사례 스터디

버전, 릴리스, 롤아웃

막이86 2023. 11. 14. 15:20
728x90

쿠버네티스 모범 사례을 요약한 내용입니다.

6.1 버전

  • 대부분의 소프트웨어 회사와 개발자는 시멘틱 버전의 유용함에 동의 함
  • 시멘틱 버전은 마이크로서비스와의 API 호환성에 의존하는 경우 더욱 유용
  • 시멘틱 버전은 기본적으로 세 개의 버전 숫자로 이루어짐
    • 메이저 버전, 마이너 버전, 패치 버전
    • 1(메이저).2(마이너).3(패치) 와 같이 점 표기로 표현
  • 패치 버전은 버그 수정이나 API변경 없는 사소한 수정마다 증가
  • 마이너 버전은 API 변경이 있더라도 이전 버전과 하위 호환이 가능
    • 마이크로서비스에서는 협업하는 개발자에게 매우 중요
  • 메이저 버전은 대규모 코드 변경을 의미
    • API는 호환되지 않음
  • 4가지 버전을 사용할 수도 있음
    • ex) 1.4.7.0은 알파 코드, 1.4.7.3은 릴리즈 등

6.2 릴리즈

  • 쿠버네티스에는 릴리즈 컨트롤러가 없음
    • 릴리즈와 관련된 기본 개념이 없음
  • 보통 디플로이먼트 metadata.labels 명세나 pod.spec.template.metadata.label 명세에 릴리즈 정보를 넣음
  • CD를 사용해 변경사항을 디플로이먼트에 업데이트하는 방법에 따라 다양한 영향을 미칠수 있음</aside>
  • <aside> ❓ 다양한 영향...?
  • 쿠버네티스의 레이블은 API 문법 규칙에 맞는 키/값 쌍으로 자유롭게 표현할 수 있음
  • 각 컨트롤러가 레이블을 다루고, 변경하고, 셀렉터가 매치하는 방법
  • 레이블 셀렉털르 생성한 후에는 변경할 수 없음
  • 새로운 셀렉터를 추가하고 파드의 레이블을 매치했을 떄 기존 레플리카셋이 업그레이드 되는 것이 아닌 새로운 레플리카 셋이 만들어짐

6.3 롤아웃

  • 디플로이먼트 컨트롤러가 등장하기 전에 쿠버네티스 컨트롤러 프로세스가 애플리케이션을 롤아웃 하는 유일한 방법은 커멘트라인 인터페이스(CLI)로 명령을 내리는 것이었음
  • 매니페스트의 상태가 아니기 떄문에 선언전 CD 모델에서 처리하기 어려움
    • 시스템이 우연히 롤백되지 않도록 매니페스트가 적절하게 업데이트 되었는지 등을 신중히 확인 해야함
  • 디플로이먼트 컨트롤러에는 특정 전략을 이용하여 업데이트를 자동화하는 기능이 있음
  • 시스템은 디플로이먼트의 spec.template의 변경사항을 기반으로 새로운 선언적 상태를 읽을수 있음
    • 초기에는 디플로이먼트 메타데이터 필드 안에 레이블을 견경하고, 매니페스트를 다시 적용했을때 업데이트가 일어나지 않으면 당황하고는 했음
  • 배포에는 rollingUpdate와 recreate 두가지가 있으며 rollingUpdate가 기본값
  • 디플로이먼트 컨트롤러가 업데이트 이력을 보관하고 있으며 CLI를 이용해 이전버전으로 롤백할 수 있음
  • recreate 전략은 서비스 성능의 저하 없이 레플리카셋의 모든 파드를 중단할 수 있는 특정 워크로드에 적합

6.4 버저느 릴리즈, 롤아웃 통합 예제

  • 디플로이먼트 예제에서 모범 사례를 살펴보기
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gb-web-deploy
  labels:
   app: guest-book
   appver: 1.6.9
   environment: production
   release: guest-book-stable
   release number: 34e57f01
spec:
  strategy:
   type: rollingUpdate
   rollingUpdate:
    maxUnavailbale: 3
    maxSurge: 2
  selector:
   matchLabels:
    app: gb-web
    ver: 1.5.8
  matchExpressions:
   - {key: environment, operator: In, values: [production]}
  template:
    metadata:
      labels:
        app: gb-web
        ver: 1.5.8
        environment: production
    spec:
      containers:
      - name: gb-web-cont
        image: evillgenius/gb-web:v1.5.5
        env:
        - name: GB_DB_HOST
          values: gb-mysql
        - name: GB_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
          ports:
          - containerPort: 80
---
# DB 디플로이먼트
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gb-mysql
  labels:
    app: guest-book
    appver: 1.6.9
    environment: production
    release: guest-book-stable
    release number: 34e57f01
spec:
  selector:
    matchLabels:
      app: gb-db
      tier: backend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: gb-db
        tier: backend
        ver: 1.5.9
        environment: production
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
---
# DB 백업 잡
apiVersion: batch/v1
kind: Job
metadata:
  name: db-backup
  labels:
    app: guest-book
    appver: 1.6.9
    environment: production
    release: guest-book-stable
    release number: 34e57f01
  annotations:
    "helm.sh/hook": pre-upgrade
    "helm.sh/hook": pre-delete
    "helm.sh/hook": pre-rollback
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    metadata:
      labels:
        app: gb-db-backup
        tier: backend
        ver: 1.6.1
        environment: production
    spec:
      containers:
      - name: mysqldump
        image: evillgenius/mysqldump:v1
        env:
        - name: DB_NAME
          value: gbdb1
        - name: GB_DB_HOST
          value: gb-mysql
        - name: GB_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        volumMounts:
        - mountPath: /mysqldum
          name: mysqldump
      volumes:
      - name: mysqldump
        hostPath:
          path: /home/bck/mysqldump
      restartPolicy: Never
    backoffLimit: 3

6.5 버전, 릴리즈, 롤아웃, 모범 사례

효과적인 CI/CD와 무중단 배포를 위해서는 버전과 릴리즈 관리를 위한 일관성 있는 모범 사례를 알아야 합니다. 데브옵스 팀이 소프트웨어를 매끄럽게 배포하기 위해서는 일관된 매개변수를 정의 해야 합니다.

  • 애플리케이션 전체에 시멘티 버전을 적용
    • 컨테이너의 버전과 파드 배포 버전은 다름
    • 컨테이너와 애플리케이션 자체도 독립적인 라이프사이클을 가짐
  • 무언가가 변경되었을 때 원칙적 계층 방식을 이용해 쉽게 추적할 수 있음
  • 디플로이먼트 메타데이터 내의 릴리즈와 릴리즈 버전/숫자 레이블을 사용해 CI/CD파이프 라인 릴리즈를 추적하세요
    • 릴리즈 이름과 숫자는 CI/CD 도구 레코드의 실제 릴리즈와 연계되어야 합니다.
    • 클러스터에서 CI/CD 과정을 추적할 수 있으며 롤백을 쉽게 식별할 수 있음
    • 릴리즈 숫자는 매니패스트를 생성한 CD파이프라인의 릴리즈 아이디에서 가져온 것임
  • 디플로이먼트 패키지 서비스로 헬름을 사용하고 있다면 헬름 차트와 함께 롤백이 되거나 업그레이드될 서비스를 함께 묶을 수 있도록 각별히 주의하세요
    • 모든 컴포넌트를 쉽게 롤백하여 업그레이드 이전으로 되돌릴 수 있음
  • 헬름은 YAML 설정을 전달하기 전에 템플릿과 모든 헬름 지시자를 처리하기 때문에 라이프사이클 훅을 적절하게 사용하여 업그레이드와 롤백이 올바르게 실행되도록 보장할 수 있음
  • 조직의 운영 흐름에 맞는 릴리즈 명명법을 합의 하세요
    • stable, canary, alpha 만으로 대부분 충분함

6.6 마치며

  • 크고 작은 회사에서 쿠버네티스를 이용해 복잡한 애자일 개발 프로세스를 수행할 수 있음
  • 복잡한 프로세스를 자동화하려면 많은 인력과 기술 자원이 필요하지만 이제는 스타트업에서도 편리하게 클라우드 패턴을 사용할 수 있음
  • 레이블과 네이티브 쿠버네티스 컨트롤러를 적절히 사용할 때 비로소 쿠버네티스의 선언적 트성이 빛을 발함
  • 도구화와 자동화를 통해 복잡한 업그레이드, 롤아웃, 롤백을 쉽게 관리할 수 있음
728x90