주니어 개발자 1호

[Chapter 4]쿠버네티스 스터디 3주차 - ( 배포 관리 ) 본문

Server 관련

[Chapter 4]쿠버네티스 스터디 3주차 - ( 배포 관리 )

No_1 2022. 7. 16. 14:57

학습 목표

이론숙지

  1. 순차적 업데이트
    1. 순차적 업데이트는 최소한의 오버헤드, 최소한의 성능 영향, 최소한의 다운타임으로 애플리케이션을 배포할 수 있기 때문에 가장 좋은 업데이트 방식입니다.
    2. 배포는 순차적 업데이트 매커니즘을 통하여 이미지를 새 버전으로 업데이트 하도록 지원. 배포가 새 버전으로 업데이트되면 ReplicaSet가 만들어지고 이전 ReplicaSet의 복제본이 감소하면서 새 ReplicaSet의 복제본 수가 천천히 증가합니다.

  1. Canary 배포
    1. 프로덕션 환경에서 일부 사용자를 대상으로 새 배포를 테스트하는 목적으로 사용. 작은 규모의 일부 사용자에게만 변경 사항이 적용 된 app을 제공함으로써 테스트함
    2. 이번 챕터의 실습 사례로는 fronted (Nginx)로 전송되는 모든 요청이 Canary 배포에서 처리될 가능성이 있습니다. 이와 같은 경우에는 사용자를 한 배포 또는 다른 배포에 ‘고정’해야 합니다.
    3. 서비스와 함께 세션 어피니티를 만들면 동일한 사용자에게 항상 동일한 버전을 제공할 수 있습니다. 아래 항목은 서비스는 이전과 동일하지만 새로운 세션 어피니티 필드가 추가 되어서 ClientIP로 설정 됩니다. IP주소가 동일한 모든 클라이언트는 동일한 버전의 hello 애플리케이션으로 요청을 보냅니다.
    '''
    spec:
      sessionAffinity: ClientIP
    '''
    

  1. Blue/Green 배포
    1. 순차적 업데이트에 대해 배포를 완료한 후 부하 분산기( Load Balance )를 수정하여 새 버전을 가리키도록 하는 것이 유리한 경우가 있습니다. 이때 Blue/Green 배포가 도움이 됩니다.
    2. blue 버전에 기존 hello 배포를 사용하여 라우터 역할을 하는 서비스를 통해 배포에 엑세스 하게 됩니다.
    3. green 버전이 가동 및 실행되면 서비스를 업데이트 하여 이 버전을 사용하도록 전환하게 됩니다.
    4. 단점: 애플리케이션을 호스팅 하려면 클러스터에 최소 2배의 리소스가 필요합니다.
    5.  

 

실습

  • kubectl 도구 사용 연습
  • 배포 yaml 파일 만들기
  • 배포 시작, 업데이트 및 확장
  • 배포 및 배포 스타일 업데이트 연습

용어 정리

이기종 배포에서는 특정한 기술적, 운영상 요구를 충족하기 위해 2개 이상의 상이한 인프라 환경 또는 리전을 연결합니다. 이기종 배포는 배포 특성에 따라 ‘하이브리드’,’다중 클라우드’또는’공용/사설’이라고 부릅니다.

 

단일 환경 또는 리전에 환정된 배포에서는 다양한 비지니스 및 기술적 난점이 발생할 수 있습니다.

 

세션 어피니티 -  

특정 클라이언트( 사용자 ) 를  ROUTER 를 통해 연결된 기준으로 계속 보내기 위함

 

 

이해에 도움되는 두분의 설명 너무 감사합니다.

대니엘님의 설명

 

강대명님의 설명

Other

기술적 ISSUE List

  • 여유 리소스 부족 - 단일 환경, 특히 온프로레미스 환경에서는 프로덕션 요구를 충족시킬 수 있는 컴퓨팅, 네트워킹, 저장적 리소스가 모자랄 수 있습니다.
  • 제한적 지리적 범위- 단일 환경에서의 배포를 위해서는 지리적으로 서로 멀리 떨어진 사용자들이 하나의 배포에 엑세스를 해야합니다. 이러한 사용자의 트래픽은 특정 위치까지전 서계를 돌아서 이동합니다.
  • 제한된 가용성 - 웹 규모의 트래픽 패턴에서는 애플리키에션의 내결함성 및 탄력성이 상당히 요구됩니다.
  • 공급업체 고착화 - 공급업체 수준의 플랫폼 및 인프라 추성화로 인해 애플리케이션 이식이 어려울 수 있습니다.
  • 유연하지 않은 리소스 - 특정 컴퓨팅, 저장소 또는 네트워킹 오퍼링 집합으로 리소스가 제한될 수 있습니다.

코드

1️⃣ 초기 설정 ( 영역설정, 코드 복사, 클러스터 생성 )

# 영역 설정
gcloud config set compute/zone us-central1-a

# 샘플 코드 복사 이후 경로 진입
gsutil -m cp -r gs://spls/gsp053/orchestrate-with-kubernetes .
cd orchestrate-with-kubernetes/kubernetes

# cluster 생성 ( 5개 생성 )
gcloud container clusters create bootcamp --num-nodes 5 --scopes "<https://www.googleapis.com/auth/projecthosting,storage-rw>"

2️⃣ 배포 객체에 관해 알아보기

# 배포 객체 알아보기 
kubectl explain deployment

# --recursive 를 사용하면 모든 필드를 확인 가능
kubectl explain deployment --recursive

# 특정 메타데이터 확인
kubectl explain deployment.metadata.name

3️⃣ 배포 만들기

목적: auth, hello, frontend 배포 , 서비스 생성

# auta.yaml 파일 이미지 변경
# 2.0.0 -> 1.0.0

vi deployments/auth.yaml

# i를 통해 입력 모드 전환
i

# 컨테이너 부분의 image 변경 
...
containers:
- name: auth
  image: kelseyhightower/auth:1.0.0
...

# 저장하고 종료
:wq

# 확인
cat deployments/auth.yaml

# 출력 확인
apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth
spec:
  replicas: 1
  selector:
    matchLabels:
      app: auth
  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
...

# 배포 객체 생성 
kubectl create -f deployments/auth.yaml

# 배포 객체 확인
kubectl get deployments

# Relicasets 확인
kubectl get replicasets

# 포드 확인
kubectl get pods

# 인증 관련 서비스 생성 
kubectl create -f services/auth.yaml

# hello 객체 또한 배포, 서비스 생성
kubectl create -f deployments/hello.yaml
kubectl create -f services/hello.yaml

# frontend 객체 또한 배포, 서비스 생성 
kubectl create secret generic tls-certs --from-file tls/
kubectl create configmap nginx-frontend-conf --from-file=nginx/frontend.conf
kubectl create -f deployments/frontend.yaml
kubectl create -f services/frontend.yaml

# extenral ip 확인
kubectl get services frontend

# 접속 
curl -ks https://<EXTERNAL-IP>

# ip로 확인하지 않고 서비스로 처리 하는 방법
curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`

4️⃣ 배포 확정

# replicas 필드 확인
kubectl explain deployment.spec.replicas

# replicas scale 확장
kubectl scale deployment hello --replicas=5

# 새 POD가 모두 시작되는데에는 1~2분 정도 걸릴 수 있습니다.

# 포드 개수 확인
kubectl get pods | grep hello- | wc -l

# replicas 축소 5->3
kubectl scale deployment hello --replicas=3

# 포드 개수 확인
kubectl get pods | grep hello- | wc -l

5️⃣ 순차적 업데이트

# -------------- 
# ---순차 업뎃--- 
# -------------- 

# 배포 업데이트를 하려면 
kubectl edit deployment hello

# 배포의 컨테이너 섹션에 있는 image를 변경
# 1.0.0 -> 2.0.0
# 저장 후 종료 
...
containers:
  image: kelseyhightower/hello:2.0.0
...

# 편집기에서 저장하면, 업데이트 된 배포가 클러스터에 
# 저장이 되고 쿠버네티스에서 순차적 업데이트 실행
kubectl get replicaset

# 출시 기록에 새로운 항목이 표시 됨
kubectl rollout history deployment/hello

# -------------- 
# ---업뎃 중지--- 
# -------------- 

# 실행 중인 출시에 문제가 발생하면, 업데이트를 중지 합니다.

# 중지
kubectl rollout pause deployment/hello

# 현재 출시 상태
kubectl rollout status deployment/hello

# 포드에서 직접 확인
kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\\t"}{"\\t"}{.spec.containers[0].image}{"\\n"}{end}'

# -------------- 
# ---업뎃 재개--- 
# -------------- 

# resume 명령어를 사용하여 출시를 재개
kubectl rollout resume deployment/hello

# 출시가 완료되면 status 명령어를 실행할 때 다음이 표시
kubectl rollout status deployment/hello

# 출력 
deployment "hello" successfully rolled out

# -------------- 
# ---업뎃 롤백--- 
# -------------- 

# 롤백 ( 이전 버전으로 돌아감 ) 
kubectl rollout undo deployment/hello

# 기록 확인
kubectl rollout history deployment/hello

# 포드들의 버전 확인
kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\\t"}{"\\t"}{.spec.containers[0].image}{"\\n"}{end}'

6️⃣ Canary 배포

# 새 버전의 Canary 배포 생성
cat deployments/hello-canary.yaml

# 출력
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      labels:
        app: hello
        track: canary
        # 2.0.0 버전을 사용하여 서비스 선택기의 버전과 일치시킵니다
        version: 2.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

# Canary 배포 생성
# track canary가 구분자일 것으로 추측
kubectl create -f deployments/hello-canary.yaml

# hello 랑 hello-canary 두 가지 배포버전이 생김
kubectl get deployments

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

7️⃣ Blue/Green 배포

# 기존의 hello 서비스 사용
# app: hello, version: 1.0.0 으로 선택기를 업데이트
# 선택기는 blue를 배포를 선택하지만, 다른 버전을 사용할 것 이기에 
# green 배포는 선택하지 않습니다

# 서비스 업데이트
kubectl apply -f services/hello-blue.yaml

# blue green 배포를 사용하여 업데이트 하기

# green 배포를 만들기
# 
'''
metadata:
  name: hello-green
spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
'''
# 배포 객체 생성
kubectl create -f deployments/hello-green.yaml

# green 배포가 있고, 제대로 시작된 경우 현재 1.0.0 버전이 아직
# 사용되는지 확인
curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

# 서비스가 새로운 버전을 가르키도록 업데이트 ( apply )
kubectl apply -f services/hello-green.yaml

# 서비스가 업데이트 되면 green 배포가 즉시 사용됩니다.
# 해당 명령어를 통해 사용되고 있는지 확인할 수 있습니다.
curl -ks <https://`kubectl> get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version

# -------------- 
# ---업뎃 롤백--- 
# -------------- 

# 롤백 green -> blue로 변경
kubectl apply -f services/hello-blue.yaml

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

 

참고 사항

[ 세션어피니티 ] https://cloud.google.com/run/docs/configuring/session-affinity?hl=ko