Kubernetes Object yaml
다음과 같은 yaml 파일이 있다고 가정해보자. 이때 yaml 파일의 각 구성요소 의미는 다음과 같다.
apiVersion: apps/v1
kind: Pod
metadata:
name: nginx
uid: 432432dkfdf-dflsf-sdfks-2erdsfnsdlk
labels:
app: nginx
env: dev
stack: frontend
spec:
containers:
- name: nginx
image: nginx:latest
apiVersion
: 어떤 쿠버네티스 api를 객체 생성에 사용할지를 결정한다.kind
: 생성하고자 하는 객체를 명시한다.metadata
: 쿠버네티스 객체를 구분할 수 있는 ID나 네임스페이스 등을 명시한다.uid
: 쿠버네티스에 의해 자동으로 생성된다. 따라서 어떤 객체든 같은 uid를 가지는 것은 불가능하다.labels
: key-value 페어로, 객체를 태그하는 데 사용된다.kubectl get pods --selector=app=nginx
등으로 레이블을 지정하여 리소스를 사용할 수 있다.
YAML 파일은 버전 관리 레포지토리에 저장하는 것이 좋다. 그래야만 해당 파일의 버전을 관리하고 되돌리거나 수정하기 간편하다. GCP 상에서는 Cloud Source Repository를 사용하는 경우가 많다.
Object names
쿠버네티스 네임은 네임스페이스의 각 객체에 고유해야 한다. 그러나 해당 네임을 쓰던 기존의 객체가 삭제된다면 이를 재활용할 수 있다.
그런데 만약 우리가 하나의 pod마다 각각 yaml 파일을 만들어서 관리한다고 하면 어떻게 될까? pod가 몇 백 개가 되면 관리하기 너무 힘들어질 것이다. 또한 포드는 스스로 에러를 고칠 수 없고, 영원히 작동하는 것도 아니다. 파드는 life cycle이 존재하기 때문에 running 상태에 있다가도 죽을 수 있다. 따라서 이를 관리하기 위한 더 괜찮은 방법이 필요하다. 이를 위해서 우리는 controller 객체를 생성하여 pod의 상태를 관리하게 만들 수 있다. 이들은 deployment, StatefulSets, daemonSets, job
등등이다.
Controller object
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
- name: nginx
image: nginx:latest
deployment
: 웹 서버처럼 오랫동안 작동해야 하는 서비스에 적합하다. 특히 파드를 그룹으로 관리하고 싶을 때 유용하다.kube-scheduler
가 배포를 위해 파드를 스케쥴링하면,kube-apiserver
에 이를 알리게 된다. 이러한 변경은 배포 컨트롤러에 의해 지속적으로 모니터링 되며, 만약 어느 파드가 죽게 된다면 컨트롤러는 원하는 상태와 현 상태를 비교하고 새로운 파드를 실행시켜 문제점을 해결하려고 한다.- 배포를 통해 얼마나 파드를 띄워야 할지, 어떤 컨테이너를 사용해야 할 지 등을 정의할 수 있다. 또한 CPU나 RAM을 얼마나 사용할 지를 정의할 수 있다.
Namespace
namespace
: 포드의 이름은 하나의 네임스페이스에서 유니크해야 한다. 네임스페이스는 주로 리소스 사용을 제한하고 싶을 때 사용된다. 만약 새로운 기능을 테스트하고 싶다면, test 네임스페이스를 만드는 것이 네임 충돌을 막기 때문에 안전하다.- 기본적으로 새 개의 네임스페이스가 생성된다. 하나는 default로, 네임스페이스를 명시하지 않은 경우 사용하는 네임스페이스이다. 다른 둘은
kube-system
과kube-public
으로, 각각 쿠버네티스 시스템에 의해 생성된 객체와, 모든 사용자에게 제공할 수 있는 정보를 가지고 있다.
# 명령어로 적용 - 권장(yaml 파일을 flexible하게 만들어줌)
kubectl -n deme apply -f mypod.yaml
# yaml 파일에 적용 - 직접 명시할 경우 하나의 yaml 파일을 가지고 여러 네임스페이스를 flexible하게 사용하기 어려움
apiVersion: apps/v1
kind: Pod
metadata:
name: nginx
namespaces: demo
네임스페이스는 위와 같이 명령어로 적용할 수도 있고, yaml 파일에 직접 명시할 수도 있다. 그러나 명령어로 네임스페이스를 지정하는 것을 권장하는데, 그 이유는 yaml 파일에 직접 적용할 경우 하나의 파일을 가지고 여러 네임스페이스를 flexible하게 사용하는 것이 불가능하기 때문이다. 따라서 관리 측면에서 명령어로 네임스페이스를 적용하는 것이 효율적이다.