Overview
오늘은 Kubernetes Resource에 대해서 공부해보려고 한다.
먼저 리소스의 종류는 아래와 같다.
- Deployments
- ReplicaSet
- StatefulSets
- DaemonSet
- Jobs
- Automatic Cleanup for Finished Jobs
- CronJob
- ReplicationController
Deployment & ReplicaSet & Pod
1. ReplicatSet
ReplicaSet은 Pod의 원하는 수의 복제본(인스턴스)이 지정된 시간에 실행되도록 하는 리소스이다.
실행 중인 포드의 수가 원하는 수보다 적으면 ReplicaSet은 원하는 수를 유지하기 위해 새 포드를 생성한다.
마찬가지로 실행 중인 Pod가 너무 많으면 ReplicaSet가 추가 Pod를 종료한다.
ReplicaSet는 ReplicaSet에서 관리하는 Pod의 원하는 상태를 정의하는 Pod 템플릿을 기반으로 작동한다.
2. Deployment
Deployment는 애플리케이션의 원하는 상태를 관리하는 리소스이다.
이를 통해 주어진 시간에 실행하려는 컨테이너화된 애플리케이션의 복제본 수를 정의할 수 있으며 RollingUpdate(업데이트) 또는 Rollback(롤백) 과 같은 애플리케이션 업데이트를 관리한다.
Deployment는 ReplicaSet를 사용하여 애플리케이션을 구성하는 기본 pod를 관리한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- 위와 같이 Deployment yaml을 apply하면 replicaset이 자동으로 생긴다.
- 즉, Deployment에 replicaset 포함되어 있다고 볼 수 있다.
RollingUpdate
kubectl set image deployment/<deployment name> app=<image repo address>/<image name>:<image Tag> -n <namespace>
ex. kubectl set image deployment/nginx-deployment app=nginx:1.16.1 -n <namespace>
or
# kubectl edit deployment/nginx-deployment 해서 image 부분 변경해줘도 된다.
# 아래의 명령어로 image 상태를 확인할 수 있다.
kubectl rollout status deployment/nginx-deployment
# 이미지가 update 중이면 아래와 같이 메세지가 뜬다.
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
# 이미지 update가 완료되었따면 아래와 같이 메세지가 뜬다.
deployment "nginx-deployment" successfully rolled out
# 이미지 업데이트가 완료되면 아래의 명령어로 확인해준다.
kubectl get deployments -n <namespace>
kubectl get rs -n <namespace>
kubectl ger po -n <namespace>
Checking Rollout History of a Deployment
Rollout 방법은 위의 RollingUpdate의 방법과 동일하다.
Rollout은 여러개의 pod를 모두 죽이지않고 순차적으로 업데이트하는 방식이다!
--record 옵션을 붙여서 apply 한 deployment의 경우 revision이 생긴다.
또는 set image 명령어를 사용해 이미지를 변경해줘도 revision이 생긴다.
따라서 Rollout History 확인 방법과 되돌리는 방법에 대해서 알아보려고 한다.
kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.161
# 원하는 버전으로 Rollback 하기
kubectl rollout history deployment/nginx-deployment --revision=2
# 이전 버전으로 Rollback 하기
kubectl rollout undo deployment/nginx-deployment
3. pod
Pod는 Kubernetes 개체 모델에서 가장 작고 가장 기본적인 단위이다.
이는 클러스터에서 실행 중인 애플리케이션의 단일 인스턴스를 나타내며 서로 밀접하게 결합된 하나 이상의 컨테이너로 구성된다. Pod 내의 컨테이너는 동일한 네트워크 네임스페이스를 공유하며 'localhost'를 사용하여 서로 통신할 수 있다. Pod가 실패하더라도 다른 노드에서 자동으로 다시 예약되지 않는다. ReplicaSet이 작동하여 원하는 수의 Pod가 유지된다.
Daemonset & Statefulset
1. Daemonset
DaemonSet은 특정 Pod가 클러스터의 모든(또는 하위 집합) 노드에서 실행되도록 하는 Kubernetes 리소스이다.
각 작업자 노드에서 단일 포드가 실행되도록 설계되었다 . 즉, 노드에서 daemonset 포드를 확장할 수 없다.
그리고 어떤 이유로 데몬셋 포드가 노드에서 삭제되면 데몬셋 컨트롤러가 이를 다시 생성한다.
적절한 기능을 위해 각 노드에서 실행해야 하는 로그 수집기, 모니터링 에이전트 또는 네트워킹 구성 요소와 같은 시스템 수준 서비스를 배포하는 데 유용하다.
k get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 6 6 6 6 6 kubernetes.io/os=linux 364d
kube-proxy 6 6 6 6 6 kubernetes.io/os=linux 364d
nodelocaldns 6 6 6 6 6 kubernetes.io/os=linux 364d
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# these tolerations are to have the daemonset runnable on control plane nodes
# remove them if your control plane nodes should not run pods
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
How Daemon Pods are scheduled
그렇다면 Daemonset pod는 어떻게 Scheduled 될까?
아래 그림에서 보이듯이 NodeSelector, NodeAffinity, PriorityClass, Taints & Tolerations를 고려하여 Scheduled 된다.
2. StatefulSet
StatefulSet은 상태 저장 애플리케이션, 즉 안정적인 네트워크 ID와 영구 스토리지가 필요한 애플리케이션의 배포 및 확장을 관리하는 Kubernetes 리소스이다. 생성된 각 Pod가 색인을 기반으로 web-0, web-1 등과 같은 고유하고 안정적인 호스트 이름을 얻도록 한다. 이를 통해 안정적인 네트워크 ID가 필요하거나 배포 및 확장 순서에 의존하는 애플리케이션을 더 쉽게 관리할 수 있다.
StatefulSet은 또한 데이터베이스 또는 분산 시스템과 같은 상태 저장 애플리케이션에 필수적인 Pod의 순서 및 고유성에 대한 보장을 제공한다. 영구 스토리지와 함께 사용할 수 있으므로 특정 Pod와 연결된 데이터가 다른 노드로 다시 예약된 경우에도 해당 Pod에 남아 있도록 한다. Redis와 같은 상태 저장 애플리케이션, 데이터베이스(예: PostgreSQL, MySQL 또는 MongoDB) 및 RabbitMQ와 같은 메시지 대기열을 배포하는 데 사용한다.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
minReadySeconds: 10 # by default is 0
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
Job & CronJob
1. Job
Job은 완료될 때까지 실행되는 유한 작업 또는 배치 프로세스를 나타내는 Kubernetes 리소스이다. 지정된 작업을 수행하기 위해 하나 이상의 포드를 생성하고 Job이 완료되면 포드가 종료된다. 데이터 처리, 일괄 처리 또는 일회성 스크립트 또는 명령 실행과 같은 작업에 Job을 사용할 수 있다.
Job은 작업의 전반적인 진행 상황과 상태를 추적하여 지정된 수의 완료가 달성되었는지 확인한다. Pod가 실패하거나 리소스 제약으로 인해 제거되는 경우 Job은 Pod를 대체할 새 Pod를 만들고 성공적으로 완료되거나 Job이 백오프 제한에 도달할 때까지 작업을 다시 시도한다.
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
2. CronJob
CronJob은 일반적으로 자동 시스템 유지 관리 또는 관리에 사용된다. 예를 들어 백업 생성 전략을 쉽게 준비하거나 오래된 리소스를 얻을 수 있다. 일반적으로 특정 작업을 주기적으로 실행해야 하는 응용 프로그램에 유용하다.
Kubernetes 크론 작업과 Linux의 주요 차이점은 컨테이너 사용이다. Linux CronJob은 기본 시스템(OS)의 일부로 실행되어 모든 중요한 서비스에 대한 액세스 권한을 얻고 리소스와 파일 시스템을 공유하며 Kubernetes를 사용하면 모든 작업이 포드 내에서 발생한다. 즉, 작업이 격리되고 전용 리소스가 있을 뿐만 아니라 다른 Kubernetes 포드의 모든 기능을 상속하므로 원하는 경우 단일 포드 내에서 여러 컨테이너를 실행할 수도 있다.
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-cronjob
spec:
schedule: "*/10 * * * *"
concurrencyPolicy: Allow
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date;
restartPolicy: OnFailure
- CronJob specification은 batch/v1Kubernetes API 이다.
- CronJob의 이름은 hello-cronjob 이다.
- 작업은 10분마다 실행되도록 예약되었다.
- concurrencyPolicy는 3가지 옵션이 있다.
- Allow: 여러 작업을 동시에 실행할 수 있다.
- Forbid: 여러 cron 작업이 동시에 실행되는 것을 중지한다.
- Replace: 현재 실행 중인 작업을 새 작업으로 대체한다.
- Docker Hub에서 가져온 busybox 컨테이너 이미지를 사용한다.
- IfNotPresent정책은 기본적으로 설정되며 컨테이너 이미지가 아직 노드에 없는 경우 컨테이너 이미지를 가져오도록 kubelet에 알린다.
imagePullPolicy : IfNotPresent vs Always
- IfNotPresent는 이미지가 없을 때만 다운로드하라는 의미
- Always는 이미지가 있든 없든 무조건 다운로드하라는 의미
Reference
https://jayendrapatil.com/tag/statefulsets/
https://devopscube.com/kubernetes-daemonset/
'Container Orchestration > Kubernetes' 카테고리의 다른 글
Kubernetes Secret이란? (0) | 2023.05.09 |
---|---|
MetalLB란? (2) | 2023.05.03 |
Kubernetes 플러그인 매니저 Krew란? (0) | 2023.04.30 |
Kubernetes API Server, Group / RBAC란? (2) | 2023.04.19 |
K8S 인증서 10년 만기 생성 방법 (2) | 2022.09.23 |