CKA 공부 5일차
in Devops on Kubernetes
Imperative vs Declartive
Imperative는 스텝바이스텝으로 길을 찾아가는 접근법
Declartive는 목적지만을 놓고 어떻게 갈 것인가를 고민하는 접근법
Imperative와 Declartive를 코드로 비교하면 다음과 같다.
Imperative
웹서버라는 이름의 VM을 프로비저닝한다.
그 VM에 nginx를 설치한다.
8080 포트를 수정한다.
패스를 수정한다.
nginx를 시작한다.
Declartive
VM Name: web-server
Database: nginx
port: 8080
path: /var/www/nginx
Code: Git Repo -x
Imperative의 접근과 Declartive 접근
Imperative는 kubectl create
나 kubectl edit
, kubectl replce
와 같이 명령어로 실행하는 것을 의미한다.
Imperative 접근은 관리자로써 매우 비싼 비용을 갖는다.
왜냐하면 kubectl create
를 할 때 이미 오브젝트가 존재한다던지, kubectl replace
를 할 때 오브젝트가 존재하지 않는다거나 하면 에러가 발생한다.
이러한 에러를 일일이 다루는 것은 관리자로써 꽤 귀찮은 일이다.
그래서, Declartive
접근을 더 우선하는데, 그 명령어가 바로 kubectl apply -f
이다.
apply
는 object configuration file
의 변화와 현재 사용중인 k8s의 상태를 고려해서 적절하게 상태를 적용해준다.
또한 여러 개의 k8s 파일이 존재하는 경우 path만 적어주면 (kubectl apply -f /path
) 해당 path 아래에 있는 모든 설정 파일들을 반영해준다.
이미 존재한다면 업데이트를, 없다면 생성을 해준다.
kubectl apply는 내부적으로 어떻게 동작하는가
apply 명령어는 쿠버네티스에 동작중인 오브젝트 정의의 로컬 스토리지 파일을 참고한다.
그리고 최근 반영된 설정이 만들어진다.
apply 명령어가 실행되고 나서 오브젝트가 존재하지않는다면 오브젝트는 생성되며, 오브젝트 내부에서도 우리가 만든 설정 파일과 비슷하게 쿠버네티스 내부 메모리에도 비슷한 설정 파일이 만들어진다.
# 내가 만든 설정 파일
# Local Object Configuration라고 부름
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end-service
spec:
containers:
- name: nginx-container
image: nginx:1.1.8
# k8s가 관리하는 설정 파일
# Live Object Configuration라고 부름
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end-service
spec:
containers:
- name: nginx-container
image: nginx:1.1.8
status:
conditions:
- lastProbeTime: null
status: 'True'
type: Initialized
- apply 명령을 실행하고 생성된 이후 추가적인 동작이 있는데, 바로 Yaml 버전의 로컬 오브젝트 설정 파일이 JSON 포멧으로 바뀌며 이 JSON은
last applied configuration
에 저장된다.
{
"apiVersion": "v1",
"kind": "Pod",
...
...
}
가령 위의 nginx 버전이 1.1.9로 변경한 후 apply 명령이 실행하면
Live Object Configuration
에서 해당 변경을 감지해서 업데이트 하고 나서last applied configuration
에도 업데이트를 진행한다.나는 이 작업을
last applied configuration
에서 할 줄 알았다. 그러나 아니었다. 그렇다면last applied configuration
는 왜 존재하는 것일까?last applied configuration
는Local Object Configuration
에서 특정 필드가 사라지면last applied configuration
는 여전히 해당 필드가 남아있을테니 이것을 보고 필드가 삭제되었음을 알아차리고Live Object Configuration
에도 똑같이 필드를 지워줄 수 있게 되는 것이다.즉,
last applied configuration
는 어떤 필드가 사라졌는지를 알아차리게 해주는 역할을 담당한다.이제 우리는
Local Object Configuration
이 우리의 로컬 저장소에,Live Object Configuration
가 쿠버네티스 메모리에 저장된다는 것을 알게 되었다.그러면
last applied configuration
얘는 어디에 저장될까? 이 친구는 전부Live Object Configuration
의 필드로 저장된다. 그래서 아래와 같이 저장된다.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
annotation:
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion": "v1","kind": "Pod",...}
labels:
app: myapp
type: front-end-service
spec:
containers:
- name: nginx-container
image: nginx:1.1.8
status:
conditions:
- lastProbeTime: null
status: "True"
type: Initialized
- create나 replace는 위와 같이
laset-applied-configuration
을 저장하지 않는다.