Kubernetes

10 Kubernetes Basics - Performing a Rolling Update

zerobig-k8s 2018. 8. 23. 21:20

<출처> 

https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/





Objectives


  • kubectl 을 이용해 롤링 업데이트를 수행한다.



Updating an application


사용자들은 애플리케이션이 항상 가용한 상태일 것이라 여기고 개발자들은 하루에 여러번씩 새로운 버전을 배포하도록 요구 받고있다. 쿠버네티스에서는 이것을 롤링 업데이트를 통해 이루고 있다. 롤링 업데이트는 파드 인스턴스를 점진적으로 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어질 수 있도록 해준다. 새로운 파드는 가용한 자원을 보유한 노드로 스케줄될 것이다.


이전 모듈에서 여러 개의 인스턴스를 동작시키도록 애플리케이션을 스케일했다. 이것은 애플리케이션의 가용성에 영향을 미치지 않으면서 업데이트를 수행하는 것에 대한 요구이다. 기본적으로, 업데이트가 이루어지는 동안 이용 불가한 파드의 최대 개수와 생성 가능한 새로운 파드의 최대 개수는 하나다. 두 옵션은 (파드에 대한) 개수 또는 백분율로 구성될 수 있다. 쿠버네티스에서, 업데이트는 버전으로 관리되고 어떠한 디플로이먼트 업데이트라도 이전의 (안정적인) 버전으로 원복이 가능하다.



롤링 업데이트는 파드 인스턴스를 점진적으로 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어질 수 있도록 해준다.




Rolling updates overview










애플리케이션 스케일링과 유사하게, 디플로이먼트가 외부로 노출되면, 서비스는 업데이트가 이루어지는 동안 오직 가용한 파드에게만 트래픽을 로드밸런스 할 것이다. 가용한 파드란 애플리케이션의 사용자들에게 가용한 상태의 인스턴스를 말한다.

롤링 업데이트는 다음 동작들을 허용해준다.




  • 하나의 환경에서 또 다른 환경으로의 애플리케이션 프로모션 (컨테이너 이미지 업데이트를 통해)
  • 이전 버전으로의 롤백
  • 서비스 중단 없는 애플리케이션의 지속적인 통합과 지속적인 전달


디플로이먼트가 외부로 노출되면, 서비스는 업데이트가 이루어지는 동안 오직 가용한 파드에게만 트래픽을 로드밸런스 할 것이다.


다음 대화형 강좌에서, 새로운 버전의 애플리케이션을 업데이트 하고 나서, 롤백을 수행하도록 해보자.



Interactive Tutorial - Updating Your App


이번 시나리오의 목표는 kubectl set image 로 배포된 어플리케이션을 업데이트 하고 rollout undo 명령을 통해 롤백을 해보는 것이다.


Step 1: Update the version of the app


"get deployments" 명령을 이용하여 디플로이먼트를 확인한다.


1
2
3
root@zerobig-vm:~# kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   2         2         2            2           21h
cs


"get pods" 명령을 이용하여 동작중인 파드를 확인한다.



1
2
3
4
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS    RESTARTS   AGE
kubernetes-bootcamp-5c69669756-d4kgp   1/1       Running   2          21h
kubernetes-bootcamp-5c69669756-jlqrw   1/1       Running   0          35m
cs



현재 앱에 대한 애플리케이션의 이미지 버전을 보려면, 파드에 대해 "describe" 명령을 수행한다(이미지 필드를 살편본다).



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
root@zerobig-vm:~# kubectl describe pods
Name:           kubernetes-bootcamp-5c69669756-d4kgp
Namespace:      default
Node:           minikube/10.0.2.15
Start Time:     Thu, 09 Aug 2018 00:31:44 +0900
Labels:         app=v1
                pod-template-hash=1725225312
                run=kubernetes-bootcamp
Annotations:    <none>
Status:         Running
IP:             172.17.0.5
Controlled By:  ReplicaSet/kubernetes-bootcamp-5c69669756
Containers:
  kubernetes-bootcamp:
    Container ID:   docker://19a99d11a3053c3e42be636c3fc877a800ce054fc35f081f052f34cd98569843
    Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
    Image ID:       docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 09 Aug 2018 20:50:28 +0900
    Last State:     Terminated
      Reason:       Error
      Exit Code:    255
      Started:      Thu, 09 Aug 2018 09:25:51 +0900
      Finished:     Thu, 09 Aug 2018 20:49:43 +0900
    Ready:          True
    Restart Count:  2
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7d4h2 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-7d4h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7d4h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
 
 
Name:           kubernetes-bootcamp-5c69669756-jlqrw
Namespace:      default
Node:           minikube/10.0.2.15
Start Time:     Thu, 09 Aug 2018 21:27:14 +0900
Labels:         pod-template-hash=1725225312
                run=kubernetes-bootcamp
Annotations:    <none>
Status:         Running
IP:             172.17.0.8
Controlled By:  ReplicaSet/kubernetes-bootcamp-5c69669756
Containers:
  kubernetes-bootcamp:
    Container ID:   docker://4fe92425350cfbb3a694630760066690534ca459394a25e67dc57bc6dac3ca70
    Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
    Image ID:       docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 09 Aug 2018 21:27:16 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7d4h2 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-7d4h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7d4h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              36m   default-scheduler  Successfully assigned kubernetes-bootcamp-5c69669756-jlqrw to minikube
  Normal  SuccessfulMountVolume  36m   kubelet, minikube  MountVolume.SetUp succeeded for volume "default-token-7d4h2"
  Normal  Pulled                 36m   kubelet, minikube  Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already present on machine
  Normal  Created                36m   kubelet, minikube  Created container
  Normal  Started                36m   kubelet, minikube  Started container
cs



(참고로 이미지 버전만을 확인하기 위해서라면 아래 명령이 보다 적합할 듯 하다.)



1
2
3
4
5
root@zerobig-vm:~# kubectl describe pods | grep Image
    Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
    Image ID:       docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
    Image:          gcr.io/google-samples/kubernetes-bootcamp:v1
    Image ID:       docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
cs



애플리케이션의 버전을 2로 업데이트하기 위해 "set image" 명령을 사용하자. 배포 이름과 새로운 이미지 버전 뒤에 버전 정보가 따른다.


1
2
root@zerobig-vm:~# kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
deployment.apps "kubernetes-bootcamp" image updated
cs



이 명령은 디플로이먼트에게 애플리케이션에 다른 이미지를 사용하도록 통보해주고 롤링 업데이트가 개시되도록 해준다.  "get pods" 명령으로 새로운 파드의 상태와 이전 파드가 소멸되는지 확인해보자.


1
2
3
4
5
6
7
8
9
10
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS        RESTARTS   AGE
kubernetes-bootcamp-5c69669756-d4kgp   1/1       Terminating   2          21h
kubernetes-bootcamp-5c69669756-jlqrw   1/1       Terminating   0          48m
kubernetes-bootcamp-7799cbcb86-6hfvm   1/1       Running       0          16s
kubernetes-bootcamp-7799cbcb86-lxht5   1/1       Running       0          23s
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS    RESTARTS   AGE
kubernetes-bootcamp-7799cbcb86-6hfvm   1/1       Running   0          1m
kubernetes-bootcamp-7799cbcb86-lxht5   1/1       Running   0          1m
cs




Step 2: Verify an update


먼저 애플리케이션이 동작하는지 확인해 본다. 노출되어진 IP 와 Port 정보를 알아내기 위해 "describe service" 를 이용할 수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@zerobig-vm:~# kubectl describe services/kubernetes-bootcamp
Name:                     kubernetes-bootcamp
Namespace:                default
Labels:                   run=kubernetes-bootcamp
Annotations:              <none>
Selector:                 run=kubernetes-bootcamp
Type:                     NodePort
IP:                       10.102.90.35
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  31988/TCP
Endpoints:                172.17.0.7:8080,172.17.0.9:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
cs



지정된 노드 포트의 값을 갖는 NODE_PORT 라는 환경 변수를 생성한다.



1
2
3
root@zerobig-vm:~# export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
root@zerobig-vm:~# echo NODE_PORT=$NODE_PORT
NODE_PORT=31988
cs


다음, 노출된 IP와 Port 로 curl 을 수행할 것이다.



1
2
3
4
5
6
7
8
9
10
root@zerobig-vm:~# curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7799cbcb86-lxht5 | v=2
root@zerobig-vm:~# curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7799cbcb86-lxht5 | v=2
root@zerobig-vm:~# curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7799cbcb86-6hfvm | v=2
root@zerobig-vm:~# curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7799cbcb86-lxht5 | v=2
root@zerobig-vm:~# curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7799cbcb86-6hfvm | v=2
cs



매번 호출 할때 마다 다른 Pod 에게 요청이 전달되어 처리되고 모든 파드가 최신 버전(v2) 로 동작됨을 볼 수 있다. 

업데이트 또한 rollout status 명령을 수행함으로서 확인 가능하다. 



1
2
root@zerobig-vm:~# kubectl rollout status deployments/kubernetes-bootcamp
deployment "kubernetes-bootcamp" successfully rolled out
cs



앱에 대한 현재의 이미지 버전을 보려면, 파드에 대한 describe 명령으로 확인 가능 하다. 



1
2
3
4
5
root@zerobig-vm:~# kubectl describe pods | grep Image
    Image:          jocatalin/kubernetes-bootcamp:v2
    Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
    Image:          jocatalin/kubernetes-bootcamp:v2
    Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
cs


앱이 버전 2로 동작하고 있다.(이미지 필드를 확인한다.)


Step 3: Rollback an update


다른 업데이트를 수행하고 v10으로 이미지 태킹하여 배포를 한다.



1
2
root@zerobig-vm:~# kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10
deployment.extensions/kubernetes-bootcamp image updated
cs


디플로이먼트 상태를 보기 위해 "get  deployments" 를 이용한다.



1
2
3
4
5
6
7
8
9
root@zerobig-vm:~# kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   2         3         1            2           21h
root@zerobig-vm:~#
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS             RESTARTS   AGE
kubernetes-bootcamp-5f76cd7b94-9t56c   0/1       ImagePullBackOff   0          29s
kubernetes-bootcamp-7799cbcb86-6hfvm   1/1       Running            0          11m
kubernetes-bootcamp-7799cbcb86-lxht5   1/1       Running            0          11m
cs



그런데 무언가 잘못 되었다. 우리가 원했던 수의 파드가 가용하지 않은 것이다. 다시 파드를 리스트 해보자.


1
2
3
4
5
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS             RESTARTS   AGE
kubernetes-bootcamp-5f76cd7b94-9t56c   0/1       ImagePullBackOff   0          29s
kubernetes-bootcamp-7799cbcb86-6hfvm   1/1       Running            0          11m
kubernetes-bootcamp-7799cbcb86-lxht5   1/1       Running            0          11m
cs



파드에 대한 "describe" 명령은 더 자세한 정보를 제공해 준다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
root@zerobig-vm:~# kubectl describe pods
Name:           kubernetes-bootcamp-5f76cd7b94-9t56c
Namespace:      default
Node:           minikube/10.0.2.15
Start Time:     Thu, 09 Aug 2018 22:26:42 +0900
Labels:         pod-template-hash=1932783650
                run=kubernetes-bootcamp
Annotations:    <none>
Status:         Pending
IP:             172.17.0.5
Controlled By:  ReplicaSet/kubernetes-bootcamp-5f76cd7b94
Containers:
  kubernetes-bootcamp:
    Container ID:  
    Image:          gcr.io/google-samples/kubernetes-bootcamp:v10
    Image ID:      
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7d4h2 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          False
  PodScheduled   True
Volumes:
  default-token-7d4h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7d4h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason                 Age                From               Message
  ----     ------                 ----               ----               -------
  Normal   Scheduled              1m                 default-scheduler  Successfully assigned kubernetes-bootcamp-5f76cd7b94-9t56c to minikube
  Normal   SuccessfulMountVolume  1m                 kubelet, minikube  MountVolume.SetUp succeeded for volume "default-token-7d4h2"
  Normal   BackOff                25s (x2 over 58s)  kubelet, minikube  Back-off pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
  Warning  Failed                 25s (x2 over 58s)  kubelet, minikube  Error: ImagePullBackOff
  Normal   Pulling                14s (x3 over 1m)   kubelet, minikube  pulling image "gcr.io/google-samples/kubernetes-bootcamp:v10"
  Warning  Failed                 12s (x3 over 59s)  kubelet, minikube  Failed to pull image "gcr.io/google-samples/kubernetes-bootcamp:v10": rpc error: code = Unknown desc = Error response from daemon: manifest for gcr.io/google-samples/kubernetes-bootcamp:v10 not found
  Warning  Failed                 12s (x3 over 59s)  kubelet, minikube  Error: ErrImagePull
...
 
cs

<이하 생략>


레파지토리에 v10이란 이미지가 없다. 바로 이전 정상동작 버전으로 롤백을 시행하자. "rollout undo"  명령을 이용할 것이다.



1
2
root@zerobig-vm:~# kubectl rollout undo deployments/kubernetes-bootcamp
deployment.extensions/kubernetes-bootcamp
cs



rollout 명령은 이전에 알고 있던(known) state (v2의 이미지) 로 디플로이먼트를 되돌렸다. 업데이트들은 버전으로 관리되어지고, 여러분은 디플로이먼트에 대해 이전의 알고 있던 어떠한 상태로도 되돌릴 수 있다. 다시 파드를 리스트 해본다. 


1
2
3
4
root@zerobig-vm:~# kubectl get pods
NAME                                   READY     STATUS    RESTARTS   AGE
kubernetes-bootcamp-7799cbcb86-6hfvm   1/1       Running   0          13m
kubernetes-bootcamp-7799cbcb86-lxht5   1/1       Running   0          13m
cs


4개의 파드가 동작 중이다.(참고로 이전 모듈에서 스케일 다운 하여 2개로 줄여 둔 상태이므로 파드는 2개가 맞다.) 다시 파드에 배포된 이미지를 확인해 본다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
root@zerobig-vm:~# kubectl describe pods
Name:           kubernetes-bootcamp-7799cbcb86-6hfvm
Namespace:      default
Node:           minikube/10.0.2.15
Start Time:     Thu, 09 Aug 2018 22:15:31 +0900
Labels:         pod-template-hash=3355767642
                run=kubernetes-bootcamp
Annotations:    <none>
Status:         Running
IP:             172.17.0.9
Controlled By:  ReplicaSet/kubernetes-bootcamp-7799cbcb86
Containers:
  kubernetes-bootcamp:
    Container ID:   docker://436e6598baf5ad41c4f71940692a847361d0ea90ee340bb0a39ef88727a298a1
    Image:          jocatalin/kubernetes-bootcamp:v2
    Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 09 Aug 2018 22:15:33 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7d4h2 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-7d4h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7d4h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              13m   default-scheduler  Successfully assigned kubernetes-bootcamp-7799cbcb86-6hfvm to minikube
  Normal  SuccessfulMountVolume  13m   kubelet, minikube  MountVolume.SetUp succeeded for volume "default-token-7d4h2"
  Normal  Pulled                 13m   kubelet, minikube  Container image "jocatalin/kubernetes-bootcamp:v2" already present on machine
  Normal  Created                13m   kubelet, minikube  Created container
  Normal  Started                13m   kubelet, minikube  Started container
 
 
Name:           kubernetes-bootcamp-7799cbcb86-lxht5
Namespace:      default
Node:           minikube/10.0.2.15
Start Time:     Thu, 09 Aug 2018 22:15:24 +0900
Labels:         pod-template-hash=3355767642
                run=kubernetes-bootcamp
Annotations:    <none>
Status:         Running
IP:             172.17.0.7
Controlled By:  ReplicaSet/kubernetes-bootcamp-7799cbcb86
Containers:
  kubernetes-bootcamp:
    Container ID:   docker://f592eb99ffcd20a0209df40847469c883eb79c2e13d0c772191922e81ec6c520
    Image:          jocatalin/kubernetes-bootcamp:v2
    Image ID:       docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 09 Aug 2018 22:15:30 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7d4h2 (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-7d4h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7d4h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              13m   default-scheduler  Successfully assigned kubernetes-bootcamp-7799cbcb86-lxht5 to minikube
  Normal  SuccessfulMountVolume  13m   kubelet, minikube  MountVolume.SetUp succeeded for volume "default-token-7d4h2"
  Normal  Pulling                13m   kubelet, minikube  pulling image "jocatalin/kubernetes-bootcamp:v2"
  Normal  Pulled                 13m   kubelet, minikube  Successfully pulled image "jocatalin/kubernetes-bootcamp:v2"
  Normal  Created                13m   kubelet, minikube  Created container
  Normal  Started                13m   kubelet, minikube  Started container
cs



디플로이먼트는 안정적인 앱 버전(v2) 을 이용하고 있다. 롤백이 성공적으로 이루어 진 것이다.