k8s를 공부하다보면 어떤 경우는 kubectl create 로 yaml 파일을 실행하고, 어떤 경우는 kubectl apply로 실행하는 경우가 있다.
예전에는 무슨 차이가 있는지도 몰랐고, 대다수 kubectl create로 리소스를 생성했었는데, 간혹가다 replicas를 변경하거나 어떤 특수한 경우에 대해서는 kubectl create로만 작업을 했었는데 Udemy 강의를 보니 명령형/선언형 접근방법의 차이가 있다고 한다.
명령형 접근방법 vs 선언형 접근방법
선언방법 | 리소스가 없을 경우 | 리소스가 없을 경우 | 비고 |
create | 리소스를 생성한다. | 에러가 발생한다. | 명령형 접근방법 |
apply | 리소스를 생성한다. | 리소스가 업데이트 된다,. | 선언형 접근방법 |
replace | 에러가 발생한다. | 리소스를 삭제(--force)하고, 재생성한다. |
먼저 명령형 접근방법이란?
명령형 접근방법을 사전식으로 풀이해보자면 원하는 상태를 만들기 위한 지시 방법으로 명시되어 있다. 즉, 사용자의 요구사항을 어떻게 만들것인가?에 초점을 두고 있다. 즉, 업데이트보다는 생성에 초점에 맞춰져있다고 보면된다.
리소스 생성에 초점에 맞춰져있기 떄문에 리소스가 없는 상태에서는 리소스가 잘 생성된다. 하지만 동일한 이름의 리소스가 있는 경우에는 실패가 난다. kubectl create, replace가 대표적인 경우이며, 필요한 요소를 빠르고 간결하게 생성할 때는 유용하다.
반면에 선언형 접근방법이란?
이름에서도 알 수 있듯이 원하는 상태를 선언하는 방법이다. 즉, 리소스 존재 유/무를 따지지 않고 원하는 상태로 업데이트 할 수 있는 경우로 보면 이해하기가 쉬우며 요구사항이 무엇인가?에 초점을 둔다.
그렇기 때문에 명령형 접근방법과 다르게 동일한 리소스가 있더라도, 현재 리소스가 있더라도 동일한 UID이면 변경분에 대해서만 업데이트를 한다. 즉, 현재 리소스 존재 유/무와 상관이 없다는 뜻이다.
예시로 살펴보는 접근방법의 차이
위 명령형 접근방법, 선언형 접근방법을 글로만 보면 이해하기가 어렵다. 그렇기에 실습을 통해서 한번 살펴보자.
먼저 nginx 이미지를 가지는 test라는 이름의 pod를 만들어서 이미지를 생성하였다. 그 다음에 이미지 변경이 필요한 상황이 발생하여 현재 정보를 yaml 파일로 받아서 이미지를 redis로 업데이트해보자.
1. 명령형 접근방법으로 업데이트하는 경우(=create)
이미 test라는 pod가 만들어져있기 때문에 명령형 접근방법(=어떻게 pod를 만들것인가)에 대해서는 에러가 발생한다.
2. 선언형 접근방법으로 업데이트하는 경우(=apply)
선언형 접근방법은 리소스의 현재 상태를 정의하는것이기 때문에, 이미지가 redis로 변경되었고 pod가 재생성되지는 않았다.
이것이 kubectl create와 가장 큰 차이점이다. 그렇다면 리소스를 업데이트 하는 경우는 반드시 apply를 해야할까? 그건 아니다.
kubectl edit 명령어를 사용해서도 현재 상태를 변경할 수 있다.
3. kubectl replace 명령어를 통해서 변경하는 경우
replace 명령어를 사용하는 경우에는 --force 옵션 유/무에 따라 동작방법이 달라진다.
3.1 kubectl replace -f 명령어를 통한 경우
kubectl edit과 동일하게 현재 변경분에 대해서만 업데이트가 된다. kubect과 차이가 있다면 kubectl은 yaml 파일 기반으로 하는것이고, kubectl edit은 바로 변경한다는점이다.
3.2 kubectl replace --force -f 명령어를 통한 경우
--force 옵션이 있을 경우 아래와 같이 기존 리소스를 삭제하고 새로운 리소스를 재생성된다.
또한, 리소스가 재생성되기 때문에 UID가 변경되며 이런 경우 기존의 yaml 파일을 사용할 수가 없다. = 유지보수가 어렵다.
이번 게시물에서는 명령형 접근방법 vs 선언형 접근방법에 대해서 알아보았다. 명령형 접근방법은 어떻게 만들것인가에 초점이 맞춰져있기에 이미 리소스가 존재하면 에러가 발생한다. 반면에 선언형 접근방법은 요구사항이 무엇인가에 초점이 맞춰져있기 때문에 현재 리소스가 있더라도 변경분에 대해서만 업데이트가 가능하다.
끝!!
'기술 이모저모 > [K8s] Kubernetes' 카테고리의 다른 글
[k8s] Kubernetes NodeAffinity의 개념정리 (0) | 2022.10.10 |
---|---|
[k8s] Kubernetes Node Taint & Tolerations의 개념정리 (0) | 2022.10.09 |
[k8s] Kubernetes Namespace란? 개념정리 (0) | 2022.10.02 |
[k8s] Service 개념 및 Type 정리 (0) | 2022.09.18 |
[k8s] Pod, Replicaset, Deployment의 관계정리 (0) | 2022.09.18 |