데몬셋에 대해서 알아보는 시간을 갖겠습니다.
지난 글들은 아래를 참고 해주시면 됩니다.
- 쿠버네티스 1편 : 설치 가이드
- 쿠버네티스 2편 : pod
- 쿠버네티스 3편 : service
- 쿠버네티스 4편 : deployment
- 쿠버네티스 5편 : pod 설정
- 쿠버네티스 6편 : 배포 전략
- 쿠버네티스 7편 : volume
- 쿠버네티스 8편 : daemonset
- 쿠버네티스 9편 : 테라폼을 통한 클러스터 구성
- 쿠버네티스 10편 : eks에서 volume 사용하기
- 쿠버네티스 11편 : helm
- 쿠버네티스 12편 : helm chart template
- 쿠버네티스 13편 : helm deploy
- 쿠버네티스 14편 : fluentd를 통한 log수집
- 쿠버네티스 15편 : chartmuseum
- 쿠버네티스 16편 : 배포툴(ArgoCD 설치방법/사용법)
- 쿠버네티스 17편 : 배포툴(ArgoCD 구성/알람)
- 쿠버네티스 18편 : 쿠버네티스 Autoscailing
- 쿠버네티스 19편 : 쿠버네티스 로깅 아키텍처
DaemonSet은 모든(혹은 몇몇의 지정된) Node들에 특정 Pod 한개를 유지시켜주는 Controller입니다.
동작방식은 Node들이 Cluster내에 추가될 때, DaemonSet으로 정의된 Pod가 자동으로 생성됩니다. 반대로 Node가 Cluster내에서 삭제 가 된다면, DaemonSet에 대한 Pod가 자동적으로 제거가 됩니다.
보통 이런 특성 때문에 DaemonSet은 Cluster내의 logging 및 자원 모니터링과 같은 곳에 효과적으로 사용될 수 있습니다.
쉽게 이야기해서, Node가 신규로 Cluster내에 들어올때 Monitoring과 같은 Container를 띄워서 내부 Pod들을 감시하도록 설계하는 것입니다. 모든 노드의 Pod들을 모니터링하는 역할은 반드시 필요하겠지요?
그래서 데몬셋은 Node에 무조건적으로 있어야하고 특수한 역할을 하는 Container에 대해서 적합합니다.
1. 데몬셋 스펙 작성
DaemonSet의 Spec은 앞서서의 Deployment, Pod의 스펙과 크게 다르지 않습니다.- ## 데몬셋 생성
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch # DaemonSet의 Name
namespace: kube-system # DaemonSet이 배포되는 namespace
labels:
k8s-app: fluentd-logging
spec:
# DaemonSet이 관리해야할 Pod를 지정하는 Label selector입니다.
# 아래의 Label과 Pod의 Lavel이 매칭되는 Pod가 관리대상입니다.
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
# Pod의 Lavel(위의 Lavel selector에 매칭됩니다.)
labels:
name: fluentd-elasticsearch
# DaemonSet은 Pod를 관리하는 Object이므로 하위는 Pod의 Spec과 동일합니다.
spec:
tolerations: # tolerations에 해당되는 Node를 포함하여 스케쥴링합니다.
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: k8s.gcr.io/fluentd-elasticsearch:1.20
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
작성한 daemonset yaml파일을 쿠버네티스 클러스터에 배포합니다.
확인 결과
root@master:/lab/daemonset# kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 3 3 3 3 3 85m
root@master:/lab/daemonset# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
fluentd-elasticsearch-b7pw7 1/1 Running 0 13m 10.38.0.1 master
fluentd-elasticsearch-kt5cm 1/1 Running 0 13m 10.32.0.2 node2
fluentd-elasticsearch-qfmbt 1/1 Running 0 13m 10.40.0.3 node1
2. 특정 노트에서의 Pods 실행
데몬셋 자체는 Pod를 관리한다는 점에서 Deployment와 유사하지만, 모든 노드 혹은 특정노드에만 스케쥴링이 가능하다는 장점이 있습니다.- node selector
- node affinity
- taint & toleration
- node selector Selector로 지정된 label 과 Node에 지정된 label이 매칭되는 Node에만 Pod를 배포
- node affinity affinity로 지정된 Node 명과 일치된 Node명에만 Pod가 배포
- taint & toleration Taints가 지정된 Node에는 tolerations이 매칭되는 Pod만 배포할 수 있음.
- Node에 app: dev라는 레이블을 추가합니다.
root@master:/lab/daemonset# kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 78d v1.12.2
node1 Ready 78d v1.12.2
node2 Ready 78d v1.12.2
root@master:/lab/daemonset# kubectl edit node node1
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Node
metadata:
annotations:
kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: "0"
volumes.kubernetes.io/controller-managed-attach-detach: "true"
creationTimestamp: 2018-12-16T23:50:44Z
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/hostname: node1
app: dev
name: node1 <--추가
- DaemonSet Controller에 app:dev을 추가합니다.
root@master:/lab/daemonset# kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 3 3 3 3 3 94m
kube-proxy 3 3 3 3 3 78d
weave-net 3 3 3 3 3 78d
root@master:/lab/daemonset# kubectl edit daemonset fluentd-elasticsearch -n kube-system
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{},"labels":{"k8s-app":"fluentd-logging"},"name":"fluentd-elasticsearch","namespace":"kube-system"},"spec":{"selector":{"matchLabels":{"name":"fluentd-elasticsearch"}},"template":{"metadata":{"labels":{"name":"fluentd-elasticsearch"}},"spec":{"containers":[{"image":"k8s.gcr.io/fluentd-elasticsearch:1.20","name":"fluentd-elasticsearch","resources":{"limits":{"memory":"200Mi"},"requests":{"cpu":"100m","memory":"200Mi"}},"volumeMounts":[{"mountPath":"/var/log","name":"varlog"},{"mountPath":"/var/lib/docker/containers","name":"varlibdockercontainers","readOnly":true}]}],"terminationGracePeriodSeconds":30,"tolerations":[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master"}],"volumes":[{"hostPath":{"path":"/var/log"},"name":"varlog"},{"hostPath":{"path":"/var/lib/docker/containers"},"name":"varlibdockercontainers"}]}}}}
creationTimestamp: 2019-03-05T00:53:14Z
generation: 1
labels:
k8s-app: fluentd-logging
name: fluentd-elasticsearch
namespace: kube-system
resourceVersion: "3057"
selfLink: /apis/extensions/v1beta1/namespaces/kube-system/daemonsets/fluentd-elasticsearch
uid: 0eafcd79-3ee1-11e9-9e3c-080027b0aab8
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
creationTimestamp: null
labels:
name: fluentd-elasticsearch
spec:
nodeSelector:
app: dev <-- 노드 셀렉터 지정
- daemonset, pod를 조회해 결과를 확인해보면 Pod의 갯수가 1개로 줄어들었음을 확인 할 수 있습니다.
root@master:/lab/daemonset# kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 1 1 1 0 1 app=dev 97m
kube-proxy 3 3 3 3 3 78d
weave-net 3 3 3 3 3 78d
root@master:/lab/daemonset# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-576cbf47c7-rdxfv 1/1 Running 0 78d
coredns-576cbf47c7-wp2x6 1/1 Running 0 78d
etcd-master 1/1 Running 0 78d
fluentd-elasticsearch-fhnbf 1/1 Running 0 43s
kube-apiserver-master 1/1 Running 0 78d
kube-controller-manager-master 1/1 Running 0 78d
kube-proxy-8q8qn 1/1 Running 0 78d
kube-proxy-9qpxw 1/1 Running 0 78d
kube-proxy-ck4xq 1/1 Running 0 78d
kube-scheduler-master 1/1 Running 0 78d
weave-net-j6p5r 2/2 Running 0 78d
weave-net-k7b4k 2/2 Running 0 78d
weave-net-l5wgs 2/2 Running 0 78d
- ## .spec.template.spec.affinity
affinity: # nodeAffinity를 추가합니다. kubernetes.io/hostname=node1
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node1 <-- 노드명 지정
- ## taint & toleration
# kubectl describe node master
...
Taints: node-role.kubernetes.io/master:NoSchedule
...
만약 master node에도 컨테이너를 배포하기 위해서는 pod에 master node에 설정된 taint에 해당되는 toleration을 추가해 주어야합니다.
즉 toleration을 가진 Pod들만 taint를 가진 Node를 포함한 모든 노드에 스케쥴링이 가능합니다.
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
3. 마치며...
이번시간에는데몬셋 에 대해서 알아보는 시간을 갖었습니다. 데몬셋을 활용하면, Node가 추가 되더라도 기본적으로 수행되어야 하는 업무(로깅, 모니터링 등)에 대해서 수행하는 Pod를 띄울 수 있습니다.
또한, 그 Pod가 어떠한 특정 노드에서만 실행되게도 제어가 가능합니다. 이렇게 기본 Pod를 셋팅하고 특정 노드까지 제어해줌으로써 자동적으로 worker 노드가 Join이 되어도 기본적인 업무 수행이 가능해집니다.
다음 이시간에는 Helm에 대해서 알아보는 시간을 갖도록 하겠습니다.
함께 보면 좋은 글
- [Kubernetes] Helm Chart Template 정리
- [Kubernetes] AWS EKS에 볼륨 마운트 해보기
- [Kubernetes] k8s master 서버 HA 구성하기
- [Kubernetes] 테라폼을 통한 Cluster 구성 자동화
새 글이 올라오면 Threads @wonizz.ai 에도 올립니다. 팔로우해 두면 피드에서 바로 볼 수 있습니다.