Kubernetes Object를 생성하는 방식은 크게 두가지이다. Shell에서 직접 명령어를 실행하거나, 별도의 파일에 Object를 정의하는 방식이다. Infrastructure as Code 관점에선 이를 각각 Imperative(명령형) 접근, Declarative(선언형) 접근으로 구분한다. 예를 들어 Imperative 방식은 택시 기사에게 직진, 좌회전, 우회전 등으로 경로를 일일이 설명하면서 목적지까지 도착하는 반면, Declarative 방식은 기사에게 자신의 목적지를 알려주면 구체적인 설명없이도 알아서 도착하는 것으로 생각할 수 있다.
Infrastructure as Code
보다 프로그래밍적인 예시로, nginx 서버를 가상머신에 배포하는 과정을 Code로 비교해보자.
Imperative
일반적으로 다음과 같은 과정을 사람이 수행하거나, 스크립트로 자동화한다.
- 'web-server' VM Provisioning
- VM에 nginx 설치
- 8080번 포트와 '/var/www/nginx' 경로를 사용하도록 설정 파일 수정
- repository 'abc'로부터 웹페이지 로드
- nginx 서버 가동
사실 위에 나열한 동작만으로는 부족하며, 이미 'web-server' VM이 존재하거나 중간에 실패한 경우 등 모든 예외사항에 대해서도 대비가 필요하다. 따라서, 시스템 규모가 커지고 구성이 복잡해질 수록 자동화 스크립트 역시 가독성이 떨어지고 내용 수정이 어려워진다.
Declarative
Ansible, Puppet과 같은 IaC Tool을 사용하되, 아래와 같은 정보를 포함하는 Configuration File을 작성한다.
- VM: web-server
- Service: nginx
- Port: 8080
- Path: /var/www/nginx
- Code: repository 'abc'
우리가 원하는 Spec만 알려주면 IaC Tool이 알아서 처리해주기 때문에, File 내용이 상당히 단순하며 관리가 쉬워진다. 또한 해당 File을 Git 등의 SCM으로 관리할 경우, 변경 이력 추적과 복원까지 가능하다(GitOps).
Kubernetes
Kubernetes는 Imperative, Declarative 방식을 모두 지원한다. 다음과 같은 nginx 서비스를 각각의 방식으로 K8s에 배포하는 예시이다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
tier: frontend
spec:
containers:
- name: nginx
image: nginx
<nginx.yaml>
Imperative
#Object 생성
kubectl run --image=nginx nginx
kubectl create deployment --image=nginx nginx
kubectl expose deployment nginx --port 80
#Object 업데이트
kubectl edit deployment nginx
kubectl scale deployment nginx --replicas=5
kubectl set image deployment nginx nginx=nginx:1.18
#Object 생성
kubectl create -f nginx.yaml
#Object 교체
kubectl replace -f nginx.yaml
YAML 파일을 사용하지 않고도, nginx Pod 또는 Deployment 그리고 Service까지 kubectl 명령어로 직접 생성할 수 있으며, edit 또는 set, scale 등으로 이미 생성한 Deployment의 Image 태그와 Replica 갯수 변경도 가능하다. 간단한 서비스 생성이나, 테스트 등의 용도로 사용하기 좋지만 적용된 모든 내용이 K8s의 Memory 상에서만 존재할 뿐, 업데이트한 내용이 Manifest 파일과는 일치하지 않는 문제가 발생한다.
또한 이미 Object가 존재하는 상태에서 create 명령어를 수행하거나, 반대로 Object가 존재하지 않는 상태에서 replace, delete 명령어 수행시 에러가 발생한다.
Declarative
kubectl apply -f nginx.yaml
Object의 모든 내용은 Manifest 파일을 통해서만 반영되며, 생성과 업데이트 모두 apply 명령어로 수행한다. Object가 존재하지 않는 상태에서 실행시, Spec에 맞게 새롭게 생성한다. 이미 존재하는 경우, 변경된 내용(ex: Image Tag, Volumes)이 있으면 업데이트가 이루어지며 그렇지 않은 경우, 아무 동작도 수행하지 않는다.
다만 Manifest 파일에 문제(Syntax Error, Immutable Field 등)가 있는 경우엔, 에러를 발생하며 마찬가지로 아무 동작을 수행하지 않는다.
참고
'Kubernetes' 카테고리의 다른 글
Open Policy Agent (0) | 2021.05.05 |
---|---|
ETCD Encryption (0) | 2021.04.21 |
Container Runtime과 Docker (0) | 2021.03.09 |
Calico IPAM (0) | 2021.01.31 |
Calico 설치 및 Mode 변경 (2) | 2021.01.29 |