쿠버네티스 블루/그린, 카나리 배포

이준석·2023년 2월 13일
0

쿠버네티스에서 블루/그린, 카나리 배포를 하는 방법은 아래와 같다.

블루/그린 배포


1. 먼저 블루, 그린 두 버전의 디플로이먼트를 만들어준다.

nginx 1.14.2 버전의 블루

apiVersion: apps/v1
kind: Deployment
metadata:
  name: version-blue
  labels:
    app: version
    color: blue
spec:
  replicas: 1
  selector:
    matchLabels:
      app: version
      color: blue
  template:
    metadata:
      labels:
        app: version
        color: blue
    spec:
      containers:
      - name: version
        image: nginx:1.14.2
        ports:
        - containerPort: 8080

nginx 1.16.1 버전의 그린

apiVersion: apps/v1
kind: Deployment
metadata:
  name: version-green
  labels:
    app: version
    color: green
spec:
  replicas: 1
  selector:
    matchLabels:
      app: version
      color: green
  template:
    metadata:
      labels:
        app: version
        color: green
    spec:
      containers:
      - name: version
        image: nginx:1.16.1
        ports:
        - containerPort: 8080

2. 명령어를 통해 디플로이먼트를 배포한다.

kubectl apply -f version-bule.yaml
kubectl apply -f version-green.yaml

3. 서비스 파일에서 selector를 통해 블루 버전을 먼저 선택하여 실행해준다.

apiVersion: v1
kind: Service
metadata:
  name: version
  labels:
    app: version
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: version
    color: blue
kubectl apply -f version-service.yaml

서비스의 설명을 보면 아래와 같다.

kubectl describe svc version
Name:              version
Namespace:         default
Labels:            app=version
Annotations:       <none>
Selector:          app=version,color=blue
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.99.207.157
IPs:               10.99.207.157
Port:              <unset>  80/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.0.22:8080
Session Affinity:  None
Events:            <none>

4. 서비스 패치를 통해 그린 버전으로 배포되도록 변경한다.

kubectl patch service version -p '{"spec":{"selector":{"color":"green"}}}'

패치 후, 다시 서비스 정보를 보면 아래와 같이 그린 버전으로 변경된 것을 알 수 있다.

kubectl describe svc version
Name:              version
Namespace:         default
Labels:            app=version
Annotations:       <none>
Selector:          app=version,color=green
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.99.207.157
IPs:               10.99.207.157
Port:              <unset>  80/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.0.23:8080
Session Affinity:  None
Events:            <none>



카나리 배포


1. 먼저 stable 버전과 카나리 버전의 디플로이먼트를 만들어준다.

레플리카 수가 4개인 stable 버전

apiVersion: apps/v1
kind: Deployment
metadata:
  name: application-deployment
  labels:
    app: application
    version: stable
spec:
  replicas: 4
  selector:
    matchLabels:
      app: application
      version: stable
  template:
    metadata:
      labels:
        app: application
        version: stable
    spec:
      containers:
      - name: application
        image: nginx:1.14.2
        ports:
        - containerPort: 8080

레플리카 수가 1개인 카나리 버전

apiVersion: apps/v1
kind: Deployment
metadata:
  name: application-deployment-canary
  labels:
    app: application
    version: canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: application
      version: canary
  template:
    metadata:
      labels:
        app: application
        version: canary
    spec:
      containers:
      - name: application
        image: nginx:1.16.1
        ports:
        - containerPort: 8080

2. 명령어를 통해 디플로이먼트를 배포한다.

kubectl apply -f canary-stable.yaml
kubectl apply -f canary-canary.yaml

3. 서비스 파일을 만들어준다.

apiVersion: v1
kind: Service
metadata:
  labels:
    app: application
  name: app-service
  namespace: default
spec:
  ports:
  - nodePort: 30880
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: application
  type: NodePort

디플로이먼트를 만들 때, label을 이용해서 두 버전 모두 app: application이지만 version: stable, vesion: canary의 차이를 뒀다.
서비스에서 app: application으로 하여 두 버전 모두 실행되게 하고, 레플리카 수가 4개, 1개로 다르니 비율별로 실행되게 했다.

서비스 정보를 보면 아래와 같이 4개의 stable 버전과 1개의 canary 버전의 endpoint가 적혀있는 것을 볼 수 있다.

Name:                     app-service
Namespace:                default
Labels:                   app=application
Annotations:              <none>
Selector:                 app=application
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.111.214.240
IPs:                      10.111.214.240
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  30880/TCP
Endpoints:                10.244.0.24:8080,10.244.0.25:8080,10.244.0.26:8080 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

0개의 댓글