티스토리 뷰
먼저 해당 기능을 사용하게 된 이유는 master node에 pod가 스케줄링 되지 않게 NodeAffinity 옵션을 사용하였는데도 계속 master node에 pod가 스케줄링 되는 상황을 직면하였습니다. 사용한 NodeAffinity 속성은 다음과 같습니다.
아래의 속성에 관련된 Affinity 속성을 간단하게 정리해보았습니다.
□ Affinity
라벨링 기반의 스케줄링은 단순히 키 값이 같은지만을 비교해서 노드를 할당하기 때문에 활용 방법이 비교적 제한되어 있습니다. nodeSelector 대비 더 유연한 표현식으로 Node를 지정하고 싶을때 affinity나 inter pod affinity를 이용하면 됩니다. 위의 Taints가 Pod가 배포되지 못하도록 하는 정책이라면, affinity는 Pod를 특정 Node에 배포되도록 하는 정책입니다.
□ NodeAffinity
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
requiredDuringSchedulingRequiredDuringExecution
preferredDuringSchedulingRequiredDuringExecution
required(hard affinity) & preferred(soft affinity)는 반드시 포함해야 하는지 또는 우선시하되 필수는 아닌지를 결정하는 조건입니다. 파란색으로 표시된 부분 Ignored & Required는 운영 중(Runtime) Node의 Label이 변경되면 무시할 것인지(Ignore) 또는 즉시 Eviction 처리(Required)하여 재기동을 수행할 것인지를 결정합니다.
아래의 affinity속성에 대해 간단히 말하자면, nodeSelectorTerms 부분에 matchExpressions을 사용하여 label set-based selector 문법을 이용하여 아래같이 작성하면 되며, requiredDuringSchedulingIgnoredDuringExecution의 경우 아래 요구조건이 일치하는 node에 적용하겠다는 의미로 matchExpressions로 정의 된 key 값이 label의 [key], values 값이 label의 [value]와 일치해야 합니다. 여기서 operator라는 항목이 있는데 nodeAffinity에서 사용할 수 있는 operator에는 NotIn 외에도 In, Exists, DoesNotExist, Gt, Lt 등을 활용할 수 있습니다.
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/master
operator: NotIn
values:
- 'true'
본론으로 다시 돌아와서 아래의 노드1(master1) 정보를 확인해보니 label에 node-role.kubernetes.io/master= 라는 라벨이 들어가있지만 value값이 없어서 적용이 안된거 같습니다. value가 있든 없든 위의 옵션에서 values에 true를 넣어주면 적용되게 하라고 작성한거 같은데, master node로 pod가 스케줄링 되는게 확인되었으므로 위의 내용은 잘못된 것이라고 판단되었습니다.
[admin@hskim-bastion ~]$ kc describe node node1
Name: node1
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=node1
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 192.168.100.161/24
projectcalico.org/IPv4IPIPTunnelAddr: 172.18.154.0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Wed, 07 Apr 2021 10:46:10 +0900
Taints: <none>
하지만, kubernetes 클러스터를 구성하면 위의처럼 Taints에 none이 아니라, 기본적으로 NoSchedule 옵션이 들어가있지만 왜 안들어가있나 확인해봤더니, 현재 kubernetes 클러스터를 구성할때 kubespary를 사용하여 구성했습니다. https://github.com/kubernetes-sigs/kubespray
해당 github 내용을 바탕으로 구성을 진행하면서 hosts.yaml에 아래와 같이 kube node에 master를 포함한 모든 node를 넣어서 Taints가 추가가 안되고 master node포함하지말고 worker node만 넣어서 구성을 하게 되면 master node에 Taints가 정상정으로 추가된다고 합니다 (회사 팀원분이 알려주심)
all:
hosts:
node1:
ansible_host: 192.168.100.161
ip: 192.168.100.161
access_ip: 192.168.100.161
node2:
ansible_host: 192.168.100.162
ip: 192.168.100.162
access_ip: 192.168.100.162
node3:
ansible_host: 192.168.100.163
ip: 192.168.100.163
access_ip: 192.168.100.163
node4:
ansible_host: 192.168.100.164
ip: 192.168.100.164
access_ip: 192.168.100.164
node5:
ansible_host: 192.168.100.165
ip: 192.168.100.165
access_ip: 192.168.100.165
node6:
ansible_host: 192.168.100.166
ip: 192.168.100.166
access_ip: 192.168.100.166
children:
kube_control_plane:
hosts:
node1:
node2:
node3:
kube-node:
hosts:
node1:
node2:
node3:
node4:
node5:
node6:
etcd:
hosts:
node1:
node2:
node3:
k8s-cluster:
children:
kube_control_plane:
kube-node:
calico-rr:
hosts: {}
따라서, master1 노드에 node-role.kubernetes.io/master= 해당 label에 적절한 values값을 추가하고 위의 nodeAffinity속성에서 values값을 변경해주면 정상적으로 master node에는 배포되지 않을꺼라고 생각합니다.
하지만, kubernetes에서 Taint & Toleration 옵션도 있어서 공부도 할겸 해당 옵션으로 master node에 pod가 스케줄링 되지 않도록 구성해봤습니다.
□ Taint & Toleration 옵션 설명
Taint & Toleration
- taint: 노드마다 설정가능하며 설정한 노드에는 pod가 스케줄되지 않습니다.
- toleration: taint를 무시하고 pod에 설정하면 해당 규칙대로 pod 스케줄링 가능
Taint Options
- NoSchedule: toleration이 없으면 pod가 스케줄되지 않습니다. 단, 기존 실행되는 pod에는 적용 안됩니다.
- PreferNoSchedule: toleration이 없으면 pod를 스케줄링안하려고 합니다.
따라서 현재 master 1,2,3를 사용하고 있으므로 아래처럼 master 노드에 적용시켰습니다.
[admin@hskim-bastion ~]$ kubectl taint node node1 node=no:NoSchedule
node/node1 tainted
[admin@hskim-bastion ~]$ kubectl taint node node2 node=no:NoSchedule
node/node2 tainted
[admin@hskim-bastion ~]$ kubectl taint node node3 node=no:NoSchedule
node/node3 tainted
아래처럼 Taints에 옵션 잘 들어가는 것을 확인하였습니다.
[admin@hskim-bastion ~]$ kc describe node node1
Name: node1
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=node1
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 192.168.100.161/24
projectcalico.org/IPv4IPIPTunnelAddr: 172.18.154.0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Wed, 07 Apr 2021 10:46:10 +0900
Taints: node=no:NoSchedule
이제 실제로 daemonset으로 테스트를 진행해보겠습니다, 원래 옵션이 적용안되었다면 모든 노드에 하나씩 떠야하지만 아래처럼 worker 노드에만 스케줄링 되는걸 확인할 수 있습니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: cirrus-test
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- 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
[admin@hskim-bastion test]$ kc get -n cirrus-test all
NAME READY STATUS RESTARTS AGE
pod/fluentd-elasticsearch-9295h 1/1 Running 0 57s
pod/fluentd-elasticsearch-nvfzq 1/1 Running 0 57s
pod/fluentd-elasticsearch-w6kcz 1/1 Running 0 57s
□ Taint해제 뒤에 "-" 추가
kubectl taint nodes {해제할 노드 이름} key=value:NoSchedule-
'DevOps > kubernetes' 카테고리의 다른 글
Kubernetes & Gitlab Runner 연동 (.gitlab-ci.yml 스크립트) (3) | 2021.05.24 |
---|---|
Kubernetes Service Mesh (istio / kiali / jaeger) (0) | 2021.05.10 |
Kubernetes Ingress TLS(HTTPS 이슈) (0) | 2021.03.29 |
[NaverCloud] Kubernetes PV / PVC / StorageClass (0) | 2021.01.11 |
[NBP] K8S kubectl / helm3 / nginx ingress install (0) | 2020.09.25 |