이전까지는 명령어 접근방식으로 진행해왔습니다. docker-compose처럼 yaml파일을 통해 선언 방식으로 deployment를 설정할 수 있습니다.
공식문서에서 다양한 리소스를 확인할 수 있습니다.
공식문서 : https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#deployment-v1-apps
(아래의 모든 설명과 더 다양하고 자세한 모든 내용은 공식문서에 있으니 공식 문서를 같이 보면서 공부할 것)
# [deployment.yaml]
apiVersion: apps/v1
kind: Deployment
# deployment 객체에 대한 메타데이터
metadata:
# unique한 deployment 이름 설정
name: <deployment-name>
# deployment에 대한 스펙
spec:
# 유지할 pod 갯수
replicas: 3
# deployment가 pod를 찾는 방법을 정의
selector:
# 키-값 쌍으로 찾기
matchLabels:
# 키-값 설정
app: <app-name>
tier: <backend etc...>
# 생성할 pod 정의.
template:
# pod 객체에 대한 메타데이터.
# template는 항상 pod 정의이므로 kind 설정이 따로 없음.
metadata:
labels:
# 키-값 설정 (키,값 모두 커스텀 값)
app: <app-name>
# pod에 대한 스펙
spec:
# 아래 image에서 앞에 `-`가 없는건 동일한 컨테이너에 대한 것이기 때문.
containers:
- name: <container-name>
image: <image-name>
selector은 제어할 pod를 찾는 부분입니다.
위의 예시의 경우, app
,tier
의 키-값이 맞는 레이블을 가진 pod들을 전부 관리하겠다는 의미입니다. 여러 개일 경우 or연산입니다.
selector의 matchLabels
와 다른 방법은 matchExpression
이 있습니다. 좀 더 정확하고 다양하게 선언할 수 있습니다.
matchExpression:
- {key:key_name, operator:option_name, value: [value_list]
key
: 체크해볼 key를 의미합니다.operator
: In,NotIn, Exists, DoNotExist
가 있고 실행할 연산자를 의미합니다.values
: 해당 키 값에 대응하는 값들 중 체크해볼 값을 리스트로 선언합니다.좀 더 자세하지만 간단하게 선언가능한 matchLabels
를 보통 더 자주 사용합니다.
# [service.yaml]
apiVersion: v1
kind: Service
metadata:
name: <service-name>
spec:
# deployment와는 다르게 selector이 키-값 레이블밖에 선택권이 없음.
# 바로 키-값 설정
selector:
app: <app-name>
ports:
- protocol: 'TCP'
# 외부 포트. 노출하고자 하는 포트
port: 80
# 컨테이너 내부 포트
# 앱이 수신 대기중인 포트이기에 targetPort
targetPort: 8080
# - protocol: 'TCP'
# port: 443
# targetPort: 443
type: LoadBalancer
작성 후 apply
명령어 실행
$ kubectl apply -f deployment.yaml
$ kubectl apply -f service.yaml
$ kubectl delete -f deployment.yaml
위 2개가 아닌 통합된 하나의 파일을 가지고 싶다면 한 파일에 모두 붙여넣어서 몰아넣을 수 있습니다.
단 각 파일내용마다 구분기호로 ---
를 넣어주어야만 합니다(무조건 3개!, yaml 구문).
# [master-deployment.yaml]
# [service.yaml]
apiVersion: v1
kind: Service
metadata:
name: <service-name>
spec:
selector:
app: <app-name>
ports:
- protocol: 'TCP'
port: 80
targetPort: 8080
# - protocol: 'TCP'
# port: 443
# targetPort: 443
type: LoadBalancer
---
# [deployment.yaml]
apiVersion: apps/v1
kind: Deployment
metadata:
name: <deployment-name>
spec:
replicas: 3
selector:
matchLabels:
app: <app-name>
tier: <backend etc...>
template:
metadata:
labels:
app: <app-name>
spec:
containers:
- name: <container-name>
image: <image-name>
service 파일을 먼저 배치하는 것이 권장됩니다.
service의 selector가 앱의 생성, 제거를 모니터링하면서 selector label의 레이블과 일치하는 부분이 생성되면 service에 추가됩니다. 그래서 흐름상 더 자연스러운 구성이라 볼 수 있습니다.
이후 같은 명령어로 yaml파일을 동일하게 실행(및 삭제)합니다.
$ kubectl apply -f master-deployment.yaml
pod와 컨테이너 리소스에 대한 기본 사항을 선언했다면 생성된 pod와 컨테이너가 정상인지 아닌지의 여부를 확인해볼수 있습니다.
디폴트로 작동하는 걸 앞에서 볼 수 있었지만 직접 선언이 가능합니다.
deployment의 containers의 구성요소로 들어갑니다.
containers:
- name: <container-name>
image: <image-name>
livenessProbe:
httpGet:
path: /
port: 8080
periodSeconds: 10
initialDelaySeconds: 5
저장 후 적용한 다음, $ minikube service <service-name>
으로 새로운 활성프로브가 적용된 상태를 확인할 수 있습니다.
디폴트 헬스체크에 반응하지 않는 부분을 확인할 때 사용해볼수 있고, 종종 사용하는 경우로는 예시처럼 /
가 아닌 뒤에 추가적인 api가 붙는 경우를 확인할 때 사용합니다.
docker에서는 최신 이미지로 업데이트를 하면 latest
태그로 적용이 가능했지만 쿠버네티스는 이미지와 태그에 변경사항이 없다면 구별하지 못한다고 했습니다. 해당 설정을 통해 태그를 지정하지 않고 항상 최신 이미지를 가져올 수 있습니다.
containers:
- name: <container-name>
image: <image-name>
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /
port: 8080
periodSeconds: 10
initialDelaySeconds: 5
물론 Never
,IfNotPresent
등의 여러 설정이 있고 이는 공식문서에서 확인이 가능합니다.