프로그래밍/쿠버네티스

[쿠버네티스] 7. 파일로 쿠버네티스 사용하기

riroan 2023. 5. 7. 14:01

지금까지 우리는 쿠버네티스를 구성하면서 터미널에 명령어를 입력하여 사용하는 명령적(Imperative)접근방식을 이용했다. 쿠버네티스는 선언적(Declarative)접근방식도 지원하는데 이번엔 이 방식을 사용해보자.

선언적 접근방식

선언적 접근방식은 터미널에 입력했던 설정들을 파일로 작성하여 실행하는 방식이다. 해당 방식은 IaC(Infrastructure as a Code)로도 잘 알려져있어 널리 쓰이고 있다. 이 방식의 장점은 편리하고 수정이 용이하다는 것이다. 

 

우선 해당 방식을 사용하기 위해 지금까지 사용한 모든 객체를 삭제한다.

kubectl delete deployment/server
kubectl delete service/server

파일 작성

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment

 

Deployments

A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new Rep

kubernetes.io

해당링크에 deployment를 정의한 파일 예시가 있다. 이 내용을 참고해도 된다.

# deployment.yaml

# 버전) 공식문서가 가장 최신
apiVersion: apps/v1

# 생성하려는 객체
kind: Deployment

# 추가적인 정보
metadata:
  name: server

# deployment 구성
spec:
  # scaling
  replicas: 2

  # deployment가 제어할 pod 정보
  selector:
    matchLabels:
      app: server

  # pod 정보
  template:
    metadata:
      labels:
        app: server
    spec:
      containers:
        - name: myfastapi
          image: riroan/myserver:0.2
          ports:
            - containerPort: 8000

쿠버네티스 구성파일은 yaml형식으로 작성한다. 파일명은 임의로 정해도 된다. 위에서 작성한 파일은 기본적인 구조이고 해당하는 파일이 하는 역할은 아래 명령어와 같다.

kubectl create deployment server --image=riroan/server0.2

명령적으로 실행했을 때는 replicas를 따로 설정할 수 없었는데 (deployment를 생성 후 scale했어야 함) 선언적으로 하면 생성시에 replicas를 설정할 수 있다는 점이 눈에 띈다.

또 다른 독특한 점은 selector이다.

# deployment.yaml
...
  # deployment가 제어할 pod 정보
  selector:
    matchLabels:
      app: server

  # pod 정보
  template:
    metadata:
      labels:
        app: server
...

메타데이터는 키-값쌍의 레이블을 지정할 수 있다. pod에 레이블을 지정하고 selector로 제어할 pod를 지정하였다. 이렇게 해서 현재 deployment는 app: server라는 레이블을 가진 pod를 제어한다고 알려준다.

이제 위 파일대로 설정된 deployment를 생성해보자.

kubectl apply -f deployment.yaml

정상적으로 2개의 pod를 가진 deployment가 생성되었다. 하지만 아직 접속할 수 없다. service가 없기 때문이다. service에 해당하는 설정파일도 만들어서 실행하자.

# service.yaml

apiVersion: v1

kind: Service

metadata:
  name: server

spec:
  selector:
    app: server

  ports:
    - protocol: 'TCP'
      port: 8000
      targetPort: 8000

  type: LoadBalancer

이것도 역시 명령적으로 실행했을 때와 비교해보면 쉽게 이해할 수 있다.

kubectl expose deployment server --type=LoadBalancer --port=8000

눈에 띄는 것은 selector인데 selector에 있는 key-value 쌍은 위에서 정의한 pod이다. 해당하는 pod를 위한 서비스객체를 생성한다는 뜻이다.

이제 service.yaml도 적용하고 접속하면 정상적으로 접속되는 것을 확인할 수 있다.

kubectl apply -f service.yaml
minikube service server

다중 config vs 단일 config

현재 deployment와 service를 만들기 위해 2개의 파일을 만들었다. 하지만 이 두 파일을 하나의 파일로 합칠 수 있다. 합칠때는 ---로 구분한다.

# master.yaml

# 버전) 공식문서가 가장 최신
apiVersion: apps/v1

# 생성하려는 객체
kind: Deployment

# 추가적인 정보
metadata:
  name: server

# deployment 구성
spec:
  # scaling
  replicas: 2

  # deployment가 제어할 pod 정보
  selector:
    matchLabels:
      app: server

  # pod 정보
  template:
    metadata:
      labels:
        app: server
    spec:
      containers:
        - name: myfastapi
          image: riroan/myserver:0.2
          ports:
            - containerPort: 8000

---

# 버전) 공식문서가 가장 최신
apiVersion: v1

kind: Service

metadata:
  name: server

spec:
  selector:
    app: server

  ports:
    - protocol: 'TCP'
      port: 8000
      targetPort: 8000

  type: LoadBalancer

역시 파일명은 임의로 정하면 된다. 기존에 존재하는 객체를 삭제하고 정상적으로 동작하는지 확인하자.

kubectl delete -f deployment.yaml -f service.yaml
kubectl apply -f master.yaml

정상적으로 deployment와 service가 생성된 것을 확인할 수 있다.