삽질의 현장/- Docker&Kubernetes

[GCP Study Jam] Kubernetes Engine으로 배포 관리

shovelman 2019. 1. 20. 01:26

GCP를 활용한 Kubernetes 학습을 진행하며 정리하는 글입니다 (Google Cloud Study Jam 참여 중).


Introduction to deployment

배포가 단일 환경 또는 지역으로 제한될 경우 다음과 같은 이슈가 발생 할 수 있습니다.

  1. Resource limits reached
    • 단일 환경, 특히 내부 환경에서는 Resource가 Production 요구사항을 충족하지 못할 수 있습니다.
  2. Limited geographical scope
    • 단일 환경에서 배포하면 지리적으로 멀리 떨어진 사용자들이 모두 하나의 배포에 접근해야 합니다.
  3. Limited availability
  4. Provider-Dependent
    • 제공업체 수준의 플랫폼 및 인프라 추상화가 애플리케이션 포팅에 방해가 될 수 있습니다.
  5. Rigid resources
    • 리소스가 특정한 컴퓨팅, 저장소 또는 네트워킹 제공 서비스로 제한될 수 있습니다.

이기종 배포(Heterogeneous Deployment)에서는 일반적으로 서로 다른 2개 이상의 인프라 환경 또는 지역을 연결해 기술 또는 운영 상의 특정한 요구를 해결할 수 있습니다.

이기종 배포는 배포 세부사항에 따라 아래의 명칭으로 부릅니다.

  • 공개 멀티 클라우드 환경 (multi-cloud)
  • 내부 및 공개 클라우드 환경 (hybrid, public-private)

효과적인 배포 프로세스는 반복 가능해야하며, 관리, 프로비저닝, 구성, 유지보수에 있어 검증된 방식을 사용해야 합니다.

이기종 배포에 대한 일반적인 3가지 시나리오가 있습니다.

  • 멀티 클라우드 배포
  • Front-End 내부 데이터
  • CI / CD 프로세스

Deployment Object

explain 명령을 사용하면 Deployment Object에 대한 정보를 알 수 있습니다.

kubectl explain deployment
kubectl explain deployment --recursive // 모든 필드 확인
kubectl explain deployment.CATEGORY.NAME // 배포 객체 내 개별 필드 확인

Deployment 만들기

Deployment 구성 파일 내 image 필드의 버전을 변경합니다.

## DEPLOYMENT_NAME.yaml 파일구성
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: auth
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: auth
        track: stable
    spec:
      containers:
        - name: auth
          image: "kelseyhightower/auth:1.0.0"
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

Deployment 에서 복제본이 하나 생성되며 컨테이너 버전 1.0.0을 사용 중임을 알 수 있습니다.

Deployment를 생성하면 Deployment 매니페스트의 데이터를 따르는 Pod가 하나 생성됩니다.

kubectl create -f DEPLOYMENT_NAME.yaml
kubectl get deployments // 생성 확인
kubectl get replicasets // Deployment의 복제본 세트 생성
kubectl get pods // Deployment 생성 과정에서 만든 Pod 생성 확인

Deployment 확장하기

구성 파일 내 'spec.replicas' 필드 값을 조정하면 Deployment의 확장/축소가 가능합니다.

kubectl scale deployment DEPLOYMENT_NAME --replicas=COUNT

지속적 업데이트

Deployment에서는 지속적 업데이트 메터니즘을 통해 이미지가 새 버전으로 업데이트 되도록 지원합니다. 지속적 업데이트는 최소한의 오버헤드, 성능 영향, 다운 타임으로 천천히 애플리케이션을 배포할 수 있다는 점에서 이상적입니다. Deployment가 새 버전으로 업데이트 되면

  1. 새로운 복제본 세트가 생성되고 기존 복제본 세트의 복제본이 줄어듭니다.
  2. 새 복제본의 세트의 복제본 수가 서서히 늘어납니다.

Deployment를 업데이트 합니다.

kubectl edit deployment DEPLOYMENT_NAME

## DEPLOYMENT_NAME.yaml 구성파일 내 이미지 버전 변경
...
containers:
- name: hello
  image: kelseyhightower/hello:2.0.0 ## update!
...

업데이트가 완료되면 Deployment가 클러스터에 저장되고 Kubernetes에서 지속적 업데이트를 시작합니다.

Kubernetes에서 만든 새 복제본 세트가 조회 가능합니다.

kubectl get replicaset

'rollout history'에서 확인이 가능합니다.

kubectl rollout history DEPLOYMENT_NAME

업데이트를 중지할 수 있습니다.

kubectl rollout pause DEPLOYMENT_NAME
kubectl rollout status DEPLOYMENT_NAME // rollout의 현재 상태 체크

업데이트를 재개할 수 있습니다.

kubectl rollout resume DEPLOYMENT_NAME
kubectl rollout status DEPLOYMENT_NAME // rollout의 현재 상태 체크

이전 버전으로 롤백할 수 있습니다.

kubectl rollout undo DEPLOYMENT_NAME
kubectl rollout history DEPLOYMENT_NAME // history에서 롤백 내역 확인

Canary Deployment

Canary Deployment를 사용하면 소수의 사용자 집합에 변경 사항을 릴리즈해 새릴리즈와 관련된 위험을 완하시킬 수 있습니다.

Canary Deployment는 새 버전의 별도 Deployment와 안정적인 일반 Deployment 및 Canary Deployment를 타켓팅하는 서비스로 이루어집니다.


먼저 새 버전에 해당하는 새로운 Canary Deployment를 만듭니다.

kubectl create -f CANARY_DEPLOYMENT.yaml

## CANARY_DEPLOYMENT.yaml 파일구성
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-canary
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
        track: canary
        # Use ver 1.0.0 so it matches version on service selector
        version: 1.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

Canary Deployment가 생성된 것을 확인할 수 있습니다. (생성된 Deployment 수에 따라 사용되는 버전이 다른 것을 볼 수 있습니다.)

curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

사용자에게 여러 Deployment 중 하나만 사용하게 조치할 수 있습니다.

기존 yaml 형식의 구성 파일에서 'sessionAffinity' 필드를 추가하고 IP를 명시해주면 됩니다.

kind: Service
apiVersion: v1
metadata:
  name: "hello"
spec:
  sessionAffinity: ClientIP
  selector:
    app: "hello"
  ports:
    - protocol: "TCP"
      port: 80
      targetPort: 80

Deployment 삭제도 가능합니다.

kubectl delete deployment DEPLOYMENT_NAME

Blue-Green 배포

완전히 배포된 후에 새 버전을 가리키도록 Load Balancer를 수정하는 편이 유용할 때가 있습니다.


Kubernetes에서는 기존 'Blue' 버전과 새로운 'Green' 버전의 배포를 각각 하나씩 생성하고 기존 Blue 버전을 사용하다가 새로운 Green 버전이 실행되면 Service를 업데이트하여 새로운 버전을 사용하도록 전환할 수 있습니다.

기존 버전의 Service를 업데이트 합니다.

kubectl apply -f BLUE_SERVICE_NAME.yaml

Blue-Green 배포 스타일을 위해 새 버전에 해당하는 새로운 Deployment를 생성합니다. 버전 라벨 및 이미지 경로는 이전 버전과 달라야 합니다.

kubectl create -f GREEN_DEPLOYMENT_NAME.yaml

## GREEN_DEPLOYMENT_NAME.yaml 파일구성
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-green
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
        track: stable
        version: 2.0.0 ## CHANGE
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0 ## CHANGE
...

현재 버전을 확인 하고 새 버전을 가리키도록 Service를 업데이트 합니다. Service가 업데이트되는 즉시 'Green' Deployment가 사용됩니다.

curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version // 버전확인
kubectl apply -f services/hello-green.yaml
curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version // 버전확인

필요한 경우 기존 버전으로 롤백이 가능합니다.

kubectl apply -f BLUE_SERVICE_NAME.yaml


학습 내용 출처 : https://run.qwiklabs.com/focuses/639?parent=catalog