You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
3회차에 되돌리기를 해보셨습니다. 그때 화면에 노란 경고가 같이 떴고, 배포 기록을 보는 명령도 쳐 보셨습니다.
kubectl rollout undo deploy/frontend
kubectl rollout history deploy/frontend
이 두 명령을 제대로 쓰려면 알아야 할 것이 있어서 정리합니다.
기록은 남지만 번호가 뭘 가리키는지는 안 나옵니다
kubectl rollout history deploy/frontend
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
번호는 있는데 CHANGE-CAUSE가 전부 비어 있습니다. 이러면 2번이 무엇이었는지 알 수가 없습니다.
빈칸인 이유는 이렇습니다. 쿠버네티스 문서의 서술입니다.
CHANGE-CAUSE is copied from the Deployment annotation kubernetes.io/change-cause to its revisions upon creation.
(CHANGE-CAUSE는 Deployment의 kubernetes.io/change-cause 어노테이션에서 복사됩니다.)
즉 그 어노테이션을 붙이지 않으면 채워지지 않습니다. 자동으로 채워 주지 않습니다.
예전에는 명령 끝에 --record를 붙이면 자동으로 채워졌습니다. 지금은 쓰지 않습니다.
In older versions of Kubernetes, you could use the --record flag with kubectl commands to automatically populate the CHANGE-CAUSE field. This flag is deprecated and will be removed in a future release.
(예전 버전에서는 --record 플래그로 CHANGE-CAUSE를 자동으로 채울 수 있었습니다. 이 플래그는 더 이상 사용을 권고하지 않는 상태이며 앞으로 제거될 예정입니다.)
이 상태가 꽤 오래됐습니다. --record에 폐기 표시가 붙은 것은 2021년 6월이고 쿠버네티스 1.22에 들어갔습니다. 그런데 5년이 지난 지금도 제거되지 않았고, 자동으로 채워 주는 대체 수단도 나오지 않았습니다. 명령은 남아 있지만 쓰면 경고가 뜨고, 그렇다고 대신 쓸 것도 없는 상태입니다.
그래서 지금 할 수 있는 것은 직접 남기는 방법뿐입니다.
그러면 번호를 어떻게 고르나
두 가지 방법이 있습니다.
방법 1. 그 번호의 내용을 열어 봅니다
지금 바로 쓸 수 있는 방법입니다.
kubectl rollout history deploy/frontend --revision=2
그 리비전의 Pod 템플릿이 나옵니다. 이미지 태그가 보이니 어느 시점인지 알 수 있습니다.
번호를 하나씩 열어 보면서 돌아갈 곳을 정하시면 됩니다. 리비전이 몇 개 안 될 때는 이 방법이 제일 빠릅니다.
방법 2. 앞으로 기록을 남깁니다
바꿀 때마다 이유를 적어 두는 방법입니다.
kubectl set image deploy/frontend frontend=ghcr.io/sysnet4admin/ssf15-frontend:v2
kubectl annotate deploy/frontend kubernetes.io/change-cause="v2로 변경"
그러면 다음부터 목록이 이렇게 나옵니다.
REVISION CHANGE-CAUSE
1 <none>
2 v2로 변경
yaml 파일에 어노테이션을 직접 적어 두어도 됩니다. 문서가 말하는 방법은 세 가지입니다. 명령으로 붙이기, 매니페스트에 직접 쓰기, 자동으로 붙여 주는 도구 쓰기입니다.
번호는 언제 생기나
아무 때나 생기는 것이 아닙니다.
A Deployment's revision is created when a Deployment's rollout is triggered. This means that the new revision is created if and only if the Deployment's Pod template (.spec.template) is changed ... Other updates, such as scaling the Deployment, do not create a Deployment revision.
(Deployment의 리비전은 롤아웃이 일어날 때 만들어집니다. 곧 Pod 템플릿이 바뀔 때만 새 리비전이 생깁니다. 개수를 조정하는 것 같은 다른 변경은 리비전을 만들지 않습니다.)
3회차에 하신 것을 이 기준으로 보면 이렇습니다.
한 일
리비전이 생기나
kubectl apply -f k8s/로 처음 만들었을 때
생깁니다 (1번)
kubectl scale --replicas=3
생기지 않습니다. 개수는 Pod 템플릿이 아닙니다
kubectl set image로 v2로 바꿨을 때
생깁니다 (2번)
kubectl rollout undo로 되돌렸을 때
생깁니다 (3번)
여기서 하나가 따라옵니다. 되돌리기는 Pod 템플릿만 되돌립니다. 개수는 리비전에 들어 있지 않으니 rollout undo를 해도 replicas는 그대로 3입니다. 3회차에서 마지막에 kubectl scale --replicas=1을 따로 친 이유가 이것입니다.
되돌리면 번호가 다시 붙습니다
이것도 알아 두시면 헷갈리지 않습니다. 특정 번호로 돌아가면 그 내용에 새 번호가 붙습니다. 옛 번호는 목록에서 사라집니다.
2번으로 돌아갔는데 목록에서 2번이 없어지고 대신 4번이 생깁니다. 내용은 2번이었던 것입니다. 문서의 예시에서도 리비전 2로 롤백한 뒤 Deployment의 어노테이션이 deployment.kubernetes.io/revision=4가 됩니다.
그래서 번호를 외워 두는 것은 소용이 없습니다. 돌아갈 때마다 목록을 다시 보셔야 합니다.
그리고 경고가 뜹니다
3회차에 rollout undo를 치면 이런 경고가 함께 나왔습니다.
Warning: resource deployments/frontend was previously managed with 'kubectl apply'.
Rolling back will not update the kubectl.kubernetes.io/last-applied-configuration annotation,
which may cause unexpected behavior on future 'kubectl apply' operations.
Consider using 'kubectl apply' with your previous configuration file instead.
풀어 쓰면 이렇습니다. 이 Deployment는 예전에 kubectl apply로 관리하던 것인데, 되돌리기는 last-applied-configuration 어노테이션을 고치지 않으니 앞으로 apply를 할 때 예상과 다르게 동작할 수 있고, 차라리 이전 설정 파일로 apply 하는 편이 낫다는 안내입니다.
apply가 붙이는 그 어노테이션
kubectl apply를 하면 적용한 내용 전체를 JSON으로 만들어 오브젝트에 붙여 둡니다.
kubectl get deploy frontend -o yaml
맨 위 annotations 아래에 kubectl.kubernetes.io/last-applied-configuration이 있고, 그 값이 한 줄로 화면을 가득 채웁니다. apply를 하고 나면 yaml이 길어지는 이유가 이것입니다. kubectl create로 만들면 붙지 않습니다.
왜 붙여 두느냐면, apply가 세 가지를 비교해서 병합하기 때문입니다.
flowchart LR
F["내 yaml 파일<br/>지금 적용하려는 것"] --> M["apply가 병합"]
L["last-applied 어노테이션<br/>지난번에 적용한 것"] --> M
C["클러스터의 실제 값<br/>지금 들어 있는 것"] --> M
M --> R["최종 결과"]
class L key
classDef key fill:#854d0e,stroke:#fbbf24,color:#ffffff
Loading
지난번에 적용한 내용을 알아야 이번에 무엇이 빠졌는지 판단할 수 있습니다. 그래서 어노테이션에 적어 둡니다.
그런데 undo는 그 어노테이션을 안 건드립니다
rollout undo가 하는 일은 옛 ReplicaSet의 Pod 템플릿을 Deployment에 복사하는 것까지입니다. 어노테이션은 그대로 둡니다.
그러면 이런 상태가 됩니다.
값
클러스터의 실제 이미지
v1 (되돌렸으니까)
last-applied 어노테이션에 적힌 이미지
v1 (마지막 apply 때 내용)
내 yaml 파일
v1
이 경우는 문제가 없습니다. 하지만 중간에 파일을 고쳤거나, 여러 항목을 지웠다 넣었다 한 뒤에 되돌리면 세 값이 어긋납니다. 그 상태에서 apply를 하면 병합 결과가 예상과 달라집니다. 되돌린 것이 다시 앞으로 감기거나, 지웠어야 할 항목이 남습니다.
경고는 그 가능성을 알려 주는 것입니다. 지금 무언가 잘못됐다는 뜻이 아닙니다.
이 경고도 오래 걸려서 붙었습니다
이 문제를 처음 제기한 이슈는 2020년 9월에 열렸습니다. 댓글이 43개 달린 끝에 2026년 3월에 닫혔고, 실제로 경고 문구가 kubectl에 들어간 것은 2026년 2월입니다. 제기부터 반영까지 5년 5개월 걸렸습니다.
그리고 같은 계열의 이슈 하나는 2022년 10월에 열려 지금도 열려 있습니다. rollout undo가 last-applied-configuration을 함께 고쳐야 한다는 이야기는 아직 결론이 안 났습니다.
3회차에 되돌리기를 해보셨습니다. 그때 화면에 노란 경고가 같이 떴고, 배포 기록을 보는 명령도 쳐 보셨습니다.
kubectl rollout undo deploy/frontend kubectl rollout history deploy/frontend이 두 명령을 제대로 쓰려면 알아야 할 것이 있어서 정리합니다.
기록은 남지만 번호가 뭘 가리키는지는 안 나옵니다
kubectl rollout history deploy/frontend번호는 있는데
CHANGE-CAUSE가 전부 비어 있습니다. 이러면 2번이 무엇이었는지 알 수가 없습니다.빈칸인 이유는 이렇습니다. 쿠버네티스 문서의 서술입니다.
즉 그 어노테이션을 붙이지 않으면 채워지지 않습니다. 자동으로 채워 주지 않습니다.
예전에는 명령 끝에
--record를 붙이면 자동으로 채워졌습니다. 지금은 쓰지 않습니다.이 상태가 꽤 오래됐습니다.
--record에 폐기 표시가 붙은 것은 2021년 6월이고 쿠버네티스 1.22에 들어갔습니다. 그런데 5년이 지난 지금도 제거되지 않았고, 자동으로 채워 주는 대체 수단도 나오지 않았습니다. 명령은 남아 있지만 쓰면 경고가 뜨고, 그렇다고 대신 쓸 것도 없는 상태입니다.그래서 지금 할 수 있는 것은 직접 남기는 방법뿐입니다.
그러면 번호를 어떻게 고르나
두 가지 방법이 있습니다.
방법 1. 그 번호의 내용을 열어 봅니다
지금 바로 쓸 수 있는 방법입니다.
kubectl rollout history deploy/frontend --revision=2그 리비전의 Pod 템플릿이 나옵니다. 이미지 태그가 보이니 어느 시점인지 알 수 있습니다.
번호를 하나씩 열어 보면서 돌아갈 곳을 정하시면 됩니다. 리비전이 몇 개 안 될 때는 이 방법이 제일 빠릅니다.
방법 2. 앞으로 기록을 남깁니다
바꿀 때마다 이유를 적어 두는 방법입니다.
그러면 다음부터 목록이 이렇게 나옵니다.
yaml 파일에 어노테이션을 직접 적어 두어도 됩니다. 문서가 말하는 방법은 세 가지입니다. 명령으로 붙이기, 매니페스트에 직접 쓰기, 자동으로 붙여 주는 도구 쓰기입니다.
번호는 언제 생기나
아무 때나 생기는 것이 아닙니다.
3회차에 하신 것을 이 기준으로 보면 이렇습니다.
kubectl apply -f k8s/로 처음 만들었을 때kubectl scale --replicas=3kubectl set image로 v2로 바꿨을 때kubectl rollout undo로 되돌렸을 때여기서 하나가 따라옵니다. 되돌리기는 Pod 템플릿만 되돌립니다. 개수는 리비전에 들어 있지 않으니
rollout undo를 해도replicas는 그대로 3입니다. 3회차에서 마지막에kubectl scale --replicas=1을 따로 친 이유가 이것입니다.되돌리면 번호가 다시 붙습니다
이것도 알아 두시면 헷갈리지 않습니다. 특정 번호로 돌아가면 그 내용에 새 번호가 붙습니다. 옛 번호는 목록에서 사라집니다.
2번으로 돌아갔는데 목록에서 2번이 없어지고 대신 4번이 생깁니다. 내용은 2번이었던 것입니다. 문서의 예시에서도 리비전 2로 롤백한 뒤 Deployment의 어노테이션이
deployment.kubernetes.io/revision=4가 됩니다.그래서 번호를 외워 두는 것은 소용이 없습니다. 돌아갈 때마다 목록을 다시 보셔야 합니다.
그리고 경고가 뜹니다
3회차에
rollout undo를 치면 이런 경고가 함께 나왔습니다.풀어 쓰면 이렇습니다. 이 Deployment는 예전에
kubectl apply로 관리하던 것인데, 되돌리기는last-applied-configuration어노테이션을 고치지 않으니 앞으로apply를 할 때 예상과 다르게 동작할 수 있고, 차라리 이전 설정 파일로apply하는 편이 낫다는 안내입니다.apply가 붙이는 그 어노테이션
kubectl apply를 하면 적용한 내용 전체를 JSON으로 만들어 오브젝트에 붙여 둡니다.맨 위
annotations아래에kubectl.kubernetes.io/last-applied-configuration이 있고, 그 값이 한 줄로 화면을 가득 채웁니다. apply를 하고 나면 yaml이 길어지는 이유가 이것입니다.kubectl create로 만들면 붙지 않습니다.왜 붙여 두느냐면,
apply가 세 가지를 비교해서 병합하기 때문입니다.지난번에 적용한 내용을 알아야 이번에 무엇이 빠졌는지 판단할 수 있습니다. 그래서 어노테이션에 적어 둡니다.
그런데 undo는 그 어노테이션을 안 건드립니다
rollout undo가 하는 일은 옛 ReplicaSet의 Pod 템플릿을 Deployment에 복사하는 것까지입니다. 어노테이션은 그대로 둡니다.그러면 이런 상태가 됩니다.
이 경우는 문제가 없습니다. 하지만 중간에 파일을 고쳤거나, 여러 항목을 지웠다 넣었다 한 뒤에 되돌리면 세 값이 어긋납니다. 그 상태에서
apply를 하면 병합 결과가 예상과 달라집니다. 되돌린 것이 다시 앞으로 감기거나, 지웠어야 할 항목이 남습니다.경고는 그 가능성을 알려 주는 것입니다. 지금 무언가 잘못됐다는 뜻이 아닙니다.
이 경고도 오래 걸려서 붙었습니다
이 문제를 처음 제기한 이슈는 2020년 9월에 열렸습니다. 댓글이 43개 달린 끝에 2026년 3월에 닫혔고, 실제로 경고 문구가 kubectl에 들어간 것은 2026년 2월입니다. 제기부터 반영까지 5년 5개월 걸렸습니다.
그리고 같은 계열의 이슈 하나는 2022년 10월에 열려 지금도 열려 있습니다.
rollout undo가last-applied-configuration을 함께 고쳐야 한다는 이야기는 아직 결론이 안 났습니다.알아 두시면 좋은 점이 하나 있습니다. 널리 쓰이는 도구에도 이렇게 오래 남아 있는 문제가 있습니다. 화면에 뜨는 경고를 무시하지 않고 한 번 찾아보는 습관이 그래서 필요합니다. 이 경고도 5년을 기다려서 생긴 것입니다.
실습에서는 넘어가셔도 됩니다
3회차 실습은
apply로 만들고set image로 바꾸고undo로 되돌린 단순한 흐름이라 어긋날 것이 없습니다. 뒤 회차의apply도 정상으로 동작합니다.정리
kubectl rollout history deploy/frontendkubectl rollout history deploy/frontend --revision=2kubectl rollout undo deploy/frontendkubectl rollout undo deploy/frontend --to-revision=2kubectl annotate deploy/frontend kubernetes.io/change-cause="이유"그리고 기억하실 것 세 가지입니다.
CHANGE-CAUSE는 직접 남기지 않으면 비어 있습니다그래서 실무에서는
경고의 마지막 문장이 권고입니다. 이전 설정 파일로
apply하라는 것입니다.7회차에 할 GitOps가 그 방향을 끝까지 밀어붙인 것입니다. 되돌릴 때
rollout undo를 치지 않고 Git에서 이전 커밋으로 되돌린 뒤 그것을 클러스터에 반영합니다. 그러면 파일과 클러스터가 항상 같은 것을 가리킵니다. 이 이야기는 #23에 적어 두었습니다.왜 되돌리기가 가능한 구조인지는 #22에 있습니다.
참고: 어노테이션이 무엇인가
위에서 어노테이션(annotation)이 여러 번 나왔습니다. 수업에서 잠깐 말씀드렸는데 여기에 정리해 둡니다. 본론을 읽는 데 꼭 필요하지는 않습니다.
어노테이션은 오브젝트에 붙여 두는 메모입니다. 키와 값 한 쌍입니다.
비슷한 것으로 레이블(label)이 있습니다. 이미 쓰고 계십니다.
k8s/frontend-deployment.yaml의app: frontend가 레이블입니다. 둘의 차이는 용도입니다.app: frontendkubernetes.io/change-cause: v2로 변경selector, ReplicaSet의matchLabels쿠버네티스 문서의 서술입니다.
k8s/frontend-service.yaml의selector가app: frontend로 Pod를 찾아내는 것이 레이블의 일입니다. 찾는 데 쓰이니 짧고 형식이 정해져 있습니다.어노테이션은 찾는 데 쓸 수 없습니다. 대신 무엇이든 담을 수 있습니다.
kubectl apply가 설정 전체를 JSON으로 통째로 넣어 둘 수 있는 것도 그래서입니다.누가 붙이나
사람만 붙이는 것이 아닙니다. 쿠버네티스와 도구가 스스로 붙이는 것이 더 많습니다.
kubectl.kubernetes.io/last-applied-configurationkubectl applydeployment.kubernetes.io/revisionkubernetes.io/change-cause이름 앞의
kubectl.kubernetes.io/나deployment.kubernetes.io/는 누가 쓰는 값인지 나타내는 접두사입니다. 그래서 이름만 봐도 어디서 붙인 것인지 짐작할 수 있습니다.보는 방법
맨 위
Annotations:줄에 나옵니다. 값만 보려면 이렇게 합니다.kubectl get deploy frontend -o jsonpath='{.metadata.annotations}'직접 붙이고 지워 보실 수도 있습니다.
마지막 줄처럼 키 뒤에 빼기 기호를 붙이면 지워집니다.
출처: Deployment 문서의 롤백 절
이 글은 참고용입니다. 읽지 않아도 수업 진행에는 지장이 없습니다.