Pipeline

Blue - Green 배포 실습 해보기

황동리 2024. 12. 20. 14:49
반응형

이번에 해볼 것은 Blue - Green 배포를 직접 해보겠습니다.

 

사전 준비 사항

  • Github Action 사용법
  • k8s 클러스터 환경
  • Helm 설치

 


목표

Nginx 이미지를 사용해서 Blue - Green 배포 동작 방식을 확인 해보도록 하겠습니다.

 

이제 실습을 해보도록 하겠습니다.

1. ArgoCD, ArgoCD-rollout 설치

Helm 차트를 통해 설치를 진행 해보도록 하겠습니다.

helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 7.7.10
helm install argo-rollout argo/argo-rollouts

2. Nginx 이미지 커스텀

제가 원하는 index 내용을 보여주기 위해 Nginx 이미지를 커스텀 해줍니다.

index.html 작성

처음 배포 했을 때는 index 페이지에 Blue 라는 문구가 나오도록 작성해줍니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Blue</title>
</head>
<body>
    <h1>Blue</h1>
</body>
</html>

Dockerfile 작성

-----
# 기본 이미지를 nginx:latest 로 사용
FROM nginx:latest

# 현재 디렉터리에 있는 index.html 파일을 컨테이너 내 /usr/share/nginx/index.html 위치에 복사
COPY index.html /usr/share/nginx/html/index.html

# 80 포트를 사용하겠다는 선언
EXPOSE 80

# nginx 서비스를 forground에서 실행
CMD ["nginx", "-g", "daemon off;"]

 

Github 레포지터리에 dockerfile 라는 이름의 디렉터리를 생성해줍니다.

 

그리고 해당 디렉터리에 Dockerfile, index.html 파일을 넣고 Push 해줍니다.

3. rollout.yaml 작성

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-bluegreen
spec:
  replicas: 2 # 생성할 파드의 복제본 수를 2개로 설정
  revisionHistoryLimit: 2 
  selector:
    matchLabels:
      app: rollout-bluegreen
  template:
    metadata:
      labels:
        app: rollout-bluegreen
    spec:
      containers:
      - name: rollouts-demo
        image: rnjstngks/blue-green:20
        imagePullPolicy: Always
        ports:
        - containerPort: 80
  strategy:	# 중요
    blueGreen:  
      activeService: rollout-bluegreen-active 
      previewService: rollout-bluegreen-preview 
      autoPromotionEnabled: false

---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-active
spec:
  type: LoadBalancer
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-preview
spec:
  type: LoadBalancer
  selector:
    app: rollout-bluegreen
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

작성된 YAML 파일은 Argo Rollout을 사용하여 Blue-Green 배포 전략을 설정하는

 

kubernetes 리소스 입니다.

 

여기서 Blue-Green 배포 전략의 핵심 역할

 

activeService와 previewService 입니다.
  • activeService: 운영 환경에서 사용되는 서비스
  • previewService: 운영 환경에 영향을 주지 않고 새로 배포된 애플리케이션 버전을 사용 하는 서비스 입니다.
  • autoPromotionEnabled: false: 수동으로 Blue -> Green 배포 진행
  • autoPromotionEnabled: True: 자동으로 Blue -> Green 배포 진행

4. ArgoCD를 통해 Application 배포

앞서 설치 해두었던 ArgoCD 웹 대시보드에 접속 합니다.

 

접속 후, Settings -> Repositories 에 Github 레포지터리를 등록시켜줍니다.

 

그리고 Applications -> New App 클릭 후,

 

앞서 등록해준 Github Repository를 Source로 선택하여 Application 생성을 해줍니다.

 

Application이 정상적으로 등록이 되면, Github 레포지터리에 있는 rollout.yaml

 

파일을 기준으로 자동으로 배포를 진행시켜줍니다.

 

정상적으로 배포가 되면 아래 이미지 처럼 나옵니다.

 

실제 k8s 클러스터에서도 배포된 결과를 확인해보도록 하겠습니다.

 

EXTERNAL-IP 로 접속해서 웹 페이지를 확인 해보면 아래와 같습니다.

 

Active-Service Preview-Service

 

이제 index 페이지의 내용을 Green으로 변경한 이미지를 배포 해보록 하겠습니다.

5. Github Action YAML 파일 작성 및 실행

저는 Workflow를 제 노트북 환경에서 돌리기 위해

 

실행 환경 변경을 위한 설정을 추가해주었습니다.

 

2024.12.19 - [Pipeline] - Github Action 원하는 환경에서 Workflow 작업 해보기

 

Github Action 원하는 환경에서 Workflow 작업 해보기

이번에 해볼 것은 원하는 환경에서 Workflow 를 실행 해보도록 하겠습니다. ex) 노트북, 가상 머신 등Self-hosted runner 설정 1. Github 레포지터리 접속 2. Settings -> Actions -> Runners -> New-self-hosted runner 3.

ksh-cloud.tistory.com

 

name: blue-green deployment

on:
  push:
    branches:
      - main
    paths:
      - "blue-green-deployment/dockerfile/*"
jobs:
  Blue-Green_Deploy:
    runs-on: self-hosted 

    steps:
        # 코드 체크아웃
      - name: Check out Code
        uses: actions/checkout@v3

        # 이미지 빌드
      - name: Docker Build
        working-directory: /mnt/c/Users/Snetsystems/Documents/GitHub/DevOps-RoadMap/blue-green-deployment/dockerfile
        run: docker build -t rnjstngks/blue-green:${{ github.run_number }} .

        # 코드 체크아웃
      - name: Check out Code
        uses: actions/checkout@v3

        # DockerHub 로그인
      - name: Docker Hub login
        uses: docker/login-action@v2
        with:
            username: ${{ secrets.DOCKER_USERNAME }} # Docker Hub 사용자명
            password: ${{ secrets.DOCKER_PASSWORD }} # Docker Hub 비밀번호

        # 이미지 Push
      - name: Docker Push
        run: docker push rnjstngks/blue-green:${{ github.run_number }}

      - name: Change Image Tag
        working-directory: /mnt/c/Users/Snetsystems/Documents/GitHub/DevOps-RoadMap/blue-green-deployment
        run: |
          sed -i 's|image: rnjstngks/blue-green:.*|image: rnjstngks/blue-green:${{ github.run_number }}|g' rollout.yaml

      - name: Try pushing
        working-directory: /mnt/c/Users/Snetsystems/Documents/GitHub/DevOps-RoadMap/blue-green-deployment
        run: |
          git config --global user.name "rnjstngks"
          git config --global user.email "rnjstngks267@naver.com"
          git add rollout.yaml
          git commit -m "Update Image tag"
          git push origin main

 

대략 적인 흐름을 알아보자면,

  1. index.html 파일의 내용을 Green 으로 변경하여 이미지 빌드
  2. Docker hub에 로그인 후 이미지 Push
  3. 작성해둔 rollout.yaml 파일의 내용에서 이미지의 태그만 변경
  4. 변경된 rollout.yaml 파일 다시 Github 레포지터리에 Push

위와 같습니다.

6. 결과 확인

앞서 ArgoCD로 배포된 결과는 아래와 같았습니다.

Active-Service Preview-Service

 

그리고 index.html 파일의 내용을 아래의 내용으로 변경하고 다시 이미지 빌드를 진행하여 배포된 결과는

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Green</title>
</head>
<body>
    <h1>Green</h1>
</body>
</html>

 

아래와 같습니다.

 

Active-Service Preview-Service

 

앞서 rollout.yaml 파일을 작성할 때, autoPromotionEnabled: false 해당 옵션을


false로 해두어서 자동으로 변경된 이미지로 Active-Service로 승격이 되지 않았습니다.

 

이제 수동으로 승격을 시켜보도록 하겠습니다.

 

ArgoCD 대시보드에서 rollout 리소스를 선택하고 Promote-Full을 클릭해줍니다.

 

 

 

그리고 다시 결과를 확인해보도록 하겠습니다.

Active-Service Preview-Service

 

그러면 Active-Service에 접속해보면 변경된 이미지로 배포가 되어있는 것을 확인 할 수 있습니다.


 

이상입니다.

 

반응형