✔️ DaemonSet
서비스, 데몬, 서비스 데몬 모두 같은 의미이며 Daemon
이라는 것은 systemctl
로 제어할 수 있고 systemd
에 의해 제어되는 App이다.
백그라운드에서 실행하거나 stop 또는 시스템을 끄기 전까지 계속적으로 실행되는 App을 서비스 데몬이라고 한다.
계속적으로 실행하는 어플리케이션을 제어하는 것이 systemd
이다.
데몬셋은 모든 노드 또는 일부 노드에 파드를 실행한다.
노드가 3개면 3개를 실행하고 노드가 10개면 10개를 실행한다.
우리가 데몬이라고 하는 형태를 생각해보면
지금까지 봤던 여러가지 어플리케이션의 형태도 데몬이라고 할 수 있지 않는가? 라고 생각해볼 수 있다.
아파치도 mysql도 모두 데몬이 아닌가 ?
실제로 백그라운드에서 계속적으로 실행하는 형태의 App이므로 데몬이라고 할 수 있다.
하지만 여기서 말하는 데몬은 조금 다른 의미를 가진다.
RC(ReplicationController), RS(ReplicaSet)에서는 노드가 3개 있다고 하고
복제본이 3개로 구성되어야 한다고 선언하면 각 노드 당 1개씩 배치되는 것이 고가용성이 가장 높은 배치이다.
스케줄러를 조정해서 어떤 파드를 어떤 노드에 배치시킬것인지 작업할 수는 있지만,
기본적으로 RS은 1, 2, 3번 노드가 있다고하더라도 하나씩 배치하는 것이 불가능하다.
스케줄러가 해당되는 노드의 CPU, 메모리 사용량들을 주기적으로 측정하고
그 정보를 바탕으로 파드가 어떤 노드에 배치되면 좋을지를 결정한다.
즉, 스케줄러에 의해서 파드가 특정 노드에 쏠려서 배치될 수도 있다는 것이다.
RS의 입장에서는 선언한대로 3개의 파드를 만들기만 하면 될 뿐 각 노드마다 1개씩 만들어야하는 조건은 없다.
이 때문에 가장 최악의 상황은 하나의 노드에 모든 파드가 배치될 수도 있다.
그래서 데몬셋이라는 것은 복제본 개념이 없이 반드시 하나의 노드에 하나의 파드를 배치한다.
무조건 하나의 노드에 하나의 파드를 배치하는 분산 배치를 보장한다.
다시말하면 RS을 가지고도 스케줄러 정책을 이용해 분산 배치를 구현할 수 있으나
복잡해지며 DS을 쓰는게 더 현명할 수 있다.
클러스터에 노드가 추가되면 파드도 추가된다.
노드가 늘거나 줄면 파드를 추가하거나 제거한다.
3개의 노드가 있고 복제본 3개가 각 노드마다 배치되어 있었다면
노드에 문제가 생겨 복제본 하나를 잃게됐을 때 나머지 2개의 노드 중 하나에 만들어야 한다.
하지만 DS(DaemonSet)은 복제본 컨트롤러가 아니므로 노드에 파드를 한개씩 배치하며
노드가 제거되더라도 다른 노드에 파드를 생성하지 않는다.
데몬셋의 주 용도는 agent이다.
- 모든 노드에서 클러스터 스토리지 데몬 실행
- 모든 노드에서 로그 수집 데몬 실행
- 모든 노드에서 노드 모니터링 데몬 실행
노드와 관련이 있는 것, 노드에서 작업을 해야하는 어플리케이션과 관련있다.
외부의 클라이언트에게 서비스하는 어플리케이션이 아니라
어플리케이션들을 보조하거나 인프라나 플랫폼을 유지, 보수, 관리하기 위한 어플리케이션들을 말한다.
대표적으로 스토리지 어플리케이션이 있다.
예를들어 워커노드가 있고 워커노드에는 스토리지(디스크)가 있다.
디스크를 파드에게 제공하기 위해서는 컨테이너 스토리지 인터페이스가 필요하며 그 때 사용하는 것이 ceph, rook 이다.
이런 것을 관리하기 위해서 데몬이 필요하다. 즉, 스토리지를 관리할 어플리케이션이 필요하다.
docker나 cri-o는 기본적으로 로그가 남으며 로컬에만 저장하면 안되고 다른 스토리지에 저장해야 한다.
(보통 ELK, EFK로 구성한다.) 여기로 전송하기 위한 에이전트가 필요하다. (로그 수집의 용도)
쿠버네티스 클러스터를 모니터하기 위한 프로메테우스도 모니터링을 위한 여러가지 정보를 수집해서 가져가야 한다.
vagrant@k8s-node1 ~ kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 3 3 3 3 3 kubernetes.io/os=linux 2d17h
kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 2d17h
nodelocaldns 3 3 3 3 3 kubernetes.io/os=linux 2d17h
노드가 3개 있으므로 각각의 구성 요소도 3개씩 존재한다.
- kube-proxy - 네트워크 정책을 담당한다.
- calico-node - 실제 네트워크에 전송해주는 구현체이다.
- nodelocaldns - dns 서버이다.
노드 1, 2, 3 모두 네트워크 통신을 해야하므로 그와 관련된 어플리케이션이 배치되어 있는 것이다.
컨트롤 플레인도 노드이다. 그리고 여기에도 kubelet, kube-proxy가 있다.
그래서 컨트롤 플레인, 워커 노드 모두에 kube-proxy가 있어야 하며 이것이 데몬셋으로 구현되어 있다.
즉, 데몬셋은 네트워크 또는 스토리지 관련 로그 수집, 모니터링을 위한 정보 수집을 하는 어플리케이션을 배치시키기위한 용도로 사용한다.
✔️ DaemonSet 명세
vagrant@k8s-node1 ~ kubectl api-resources | grep daemonsets
daemonsets ds apps/v1 true DaemonSet
daemonsets
의 shortname은 ds 이고 apps 그룹에 속해있는 v1 stable 버전이다.
namespace를 사옹하며 kind의 이름은 DaemonSet
이다.
vagrant@k8s-node1 ~ kubectl explain ds.spec
FIELDS:
minReadySeconds <integer>
The minimum number of seconds for which a newly created DaemonSet pod
should be ready without any of its container crashing, for it to be
considered available. Defaults to 0 (pod will be considered available as
soon as it is ready).
revisionHistoryLimit <integer>
The number of old history to retain to allow rollback. This is a pointer to
distinguish between explicit zero and not specified. Defaults to 10.
selector <Object> -required-
A label query over pods that are managed by the daemon set. Must match in
order to be controlled. It must match the pod template's labels. More info:
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
template <Object> -required-
An object that describes the pod that will be created. The DaemonSet will
create exactly one copy of this pod on every node that matches the
template's node selector (or on every node if no node selector is
specified). More info:
https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
updateStrategy <Object>
An update strategy to replace existing DaemonSet pods with new pods.
- minReadySeconds
- revisionHistoryLimit
- selector
- template
- updateStrategy
selector와 template이 필수이다.
✔️ selector
vagrant@k8s-node1 ~ kubectl explain ds.spec.selector
FIELDS:
matchExpressions <[]Object>
matchExpressions is a list of label selector requirements. The requirements
are ANDed.
matchLabels <map[string]string>
matchLabels is a map of {key,value} pairs. A single {key,value} in the
matchLabels map is equivalent to an element of matchExpressions, whose key
field is "key", the operator is "In", and the values array contains only
"value". The requirements are ANDed.
ANDed
- 레이블을 여러개 지정하면 여러개 중 하나만 매칭시키는 것이 아니라 모두 참이어야 한다.
즉, 둘중에 하나라도 매핑이 안되면 매칭되지 않는다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs-set
spec:
replicas: 3
selector:
matchExpressions: # 달라지는 부분
- key: app
operator: In
values:
- web
- key: env
operator: Exists
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
즉, 다음 yaml 파일처럼 레이블이 쌍으로 매칭되어야 한다는 의미이다.
✔️ template
vagrant@k8s-node1 ~ kubectl explain ds.spec.template
FIELDS:
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
template도 metadata
와 spec
이 있다.
RS와 다른 부분은 RS는 replicas가 있지만 DS은 replicas 설정이 없다.
이제 DS를 생성하는 yaml 파일을 작성해보자
myweb-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: myweb-ds
spec:
selector:
matchExpressions:
- key: app
operator: In
values:
- myweb
- key: env
operator: Exists
template:
metadata:
labels:
app: myweb
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
vagrant@k8s-node1 ~/cont/ds kubectl create -f myweb-ds.yaml
daemonset.apps/myweb-ds created
vagrant@k8s-node1 ~/cont/ds kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
myweb-ds 3 3 3 3 3 <none> 4s
vagrant@k8s-node1 ~/cont/ds kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready control-plane,master 2d17h v1.22.8
node2 Ready <none> 2d17h v1.22.8
node3 Ready <none> 2d17h v1.22.8
우리가 선언하지 않았지만 현재 노드가 3개이기 때문에 3개의 DS가 생성된다.
vagrant@k8s-node1 ~/cont/ds kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
myweb-ds 3 3 3 3 3 <none> 13s
이미지를 교체하면 컨테이너를 삭제했다가 재생성해야한다. 그 때 사용하는 정보이다.
UP-TO-DATE
: 최신 이미지를 사용하고 있는 것이 몇개인가AVAILABLE
: 현재 작동하고 있는 컨테이너가 몇개인가
이를 배포 전략이라고 한다.
vagrant@k8s-node1 ~/cont/ds kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myweb-ds-525dt 1/1 Running 0 81s 10.233.90.22 node1 <none> <none>
myweb-ds-jh9wm 1/1 Running 0 81s 10.233.92.31 node3 <none> <none>
myweb-ds-pzjkq 1/1 Running 0 81s 10.233.96.30 node2 <none> <none>
각 노드마다 1개씩 고르게 배치된 것을 확인할 수 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Job (잡) (0) | 2022.05.20 |
---|---|
[Kubernetes] Kubespray로 노드 추가/삭제하기 (0) | 2022.05.20 |
[Kubernetes] ReplicationController & ReplicaSets (0) | 2022.05.19 |
[Kubernetes] Pod의 LifeCycle (파드의 생명주기) (0) | 2022.05.19 |
[Kubernetes] Annotation (어노테이션) (0) | 2022.05.18 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!