Search

Imperative vs Declarative

Created
2023/09/29 16:00
Tags
k8s
CKA
Mumshad Mannambeth
Core Concept

1) About

인프라를 다루는 세계에선 인프라를 제어하는 2가지 방법이 있는데, 명령적 접근법 (Imperative Approach)과 선언적 접근법 (Declarative Approach)으로 나뉨
명령적 접근법의 경우, 어떻게가 중요하고 이에 대한 절차를 기술
선언적 접근법의 경우 단계별 지시가 아닌, 최종 목표에 대한 선언인 무엇이 중요하여 이를 기술
이와 같은 접근법이 구분되는 이유는 인프라를 다루는 과정 중에서 프로비저닝 (인프라의 준비) 단계에서 인프라를 코드 (IaC)로 다룰 때 차이가 나타나기 때문
** 어떻게 구현되었지의 관점으로 들어가면 두 접근법의 차이가 모호하므로, 이용하는 관점에서 바라봐야 나음
예를 들어 명령적 접근법을 사용하여 Nginx를 띄우는 경우, 아래와 같이 웹 서버를 위한 VM을 구동부터 Nginx를 띄우기 위한 단계별 설정을 하나 하나 다 나열
1. VM 프로비저닝 2. Nginx 설치 3. 8080 포트의 설정을 수행 4. 요청 응답을 위한 경로 설정을 수행 5. Git Repo로부터 웹 페이지를 로드 6. Nginx 시작
Plain Text
복사
반면에 선언적 접근법은 Nginx를 띄우기 위해 필요한 것들을 기재하고, 아래처럼 적힌 선언에 대해선 별도의 소프트웨어가 이를 처리
VM Name: WS Package: Nginx Port: 8080 Path: /var/www/nginx Code: Git Repo
Plain Text
복사
** 쿠버네티스 내에서의 두 접근법 차이가 떠오르지 않는다면, 인프라를 쿠버네티스 없이 설정하던 상황과 쿠버네티스와 같은 컨테이너 환경에서 설정하는 상황과의 비교를 생각해보면 명령적 접근법과 선언적 접근법의 차이가 명확하게 드러남
** 선언적 접근법을 충분히 받쳐줄 툴이 있다면 상당히 많은 작업을 줄여주는데, 명령적 접근법을 수행할 때 기존 환경에서의 충돌을 모두 풀어주는 과정을 고려한다면 선언적 접근법이 꽤나 가치 있음을 느낄 수 있음
** 물론 구체적인 작업을 세세하게 설정하려면 명령적 접근법이 필요할 수 있으며 선언적 접근법이 절대적으로 명령적 접근법보다 좋은 것은 아니지만, 인프라의 특징을 생각해보면 자동화, 안정성, 예측 가능성, 복잡성 감소 등의 장점 때문에 선언적 접근법이 선호도가 높음
** 선언적 접근법은 특정 용도의 명령어들의 조합을 감추고 한 단계 더 추상화 된 것이라고 볼 수 있음

2) kubectl

kubectl의 레이어에서도 명령적 접근법과 선언적 접근법을 나눌 수 있음
** 요약하자면 간단한 작업을 수행해보는 정도면 명령적 접근법이 괜찮을 수 있지만, 결국 복잡한 환경이나 운영에서는 명령적 접근법을 통해 객체를 각각의 파일로 운용하는 것이 좋음

Imperative

kubectl run --image=nginx nginx kubectl create deployment --image=nginx nginx kubectl expose deployment nginx --port 80 kubectl edit deployment nginx kubectl scale deployment nginx --relicas=5 kubectl set image deployment nginx nginx=nginx:1.18 kubectl create -f nginx.yaml kubectl replace -f nginx.yaml kubectl delete -f nginx.yaml
Plain Text
복사
단순 명령어처럼 느껴질 수 있으나, 목표는 Nginx를 띄우는 것이고 이에 대한 과정이 kubectl로 단계적으로 이뤄지는 것을 볼 수 있음
** 즉발성이 있어서 자격증 시험에선 유용할 수 있으나, 명령어 자체가 갖는 단점이라든가 단발성이라는 점은 결국 운영 환경에서의 한계점으로 작용
** 명령적 접근법으로 이용하더라도 과거 이력이 로컬 yaml 파일에 남지 않는 edit 명령어보다는 파일에 기록이 남는 replace를 이용하는 것이 더 나음
** replace가 edit에 비해 조금 더 선언적이라고 볼 수는 있지만, 그럼에도 이와 같이 목적이 명확한 명령어들은 여전히 처리 과정이 필요함 → create의 경우 기존 객체가 있으면 오류, replace의 경우 기존 객체가 없으면 오류

Declarative

kubectl apply -f nginx.yaml
Plain Text
복사
apply 명령어의 경우 기존 명령어들을 한 번 더 감싼 형태로 동작하며, 선언적으로 작성한 파일을 통해 쿠버네티스가 스스로 판단하고 작업을 수행
이전에 작성된 단계들의 값이 선언적으로 파일 내에 작성되어 있다면, 이를 기존 설정과 바뀐 설정의 비교를 통해 변경점을 적용하는 형태로 동작
** 자격증 시험에서는 조금 둘러가는 형태가 될 수 있지만, 특정 선언을 기반으로 하기 때문에 객체가 어떻게 만들어졌는지를 시간이 지나도 명확하게 알 수 있음
** 이전의 명령적 접근법과 달리 동작을 수행할 때 기존 객체 유무에 대한 처리를 내부적으로 모두 수행