nodeName
nodeName은 어피니티 또는 nodeSelector보다 더 직접적인 형태의 노드 선택 방법이다. nodeName은 파드 스펙의 필드 중 하나이다. nodeName 필드가 비어 있지 않으면, 스케줄러는 파드를 무시하고, 명명된 노드의 kubelet이 해당 파드를 자기 노드에 배치하려고 시도한다. nodeName은 nodeSelector 또는 어피니티/안티-어피니티 규칙보다 우선적으로 적용(overrule)된다.
nodeName을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
- 만약 명명된 노드가 없으면, 파드가 실행되지 않고 따라서 자동으로 삭제될 수 있다.
- 만약 명명된 노드에 파드를 수용할 수 있는 리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다. 예: OutOfmemory 또는 OutOfcpu.
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나 안정적인 것은 아니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: kube-01
위 파드는 kube-01 노드에서만 실행될 것이다.
노드셀렉터(nodeSelector)
파드 스펙에 nodeSelector 필드를 추가하고, 타겟으로 삼고 싶은 노드가 갖고 있는 노드 레이블을 명시한다. 쿠버네티스는 사용자가 명시한 레이블을 갖고 있는 노드에만 파드를 스케줄링한다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
disktype=ssd 레이블이 있는 노드에 파드가 스케줄 될 것이라는 것을 의미한다.
노드 어피니티
노드 어피니티는 개념적으로 nodeSelector와 비슷하며, 노드의 레이블을 기반으로 파드가 스케줄링될 수 있는 노드를 제한할 수 있다. 노드 어피니티에는 다음의 두 종류가 있다.
- requiredDuringSchedulingIgnoredDuringExecution: 규칙이 만족되지 않으면 스케줄러가 파드를 스케줄링할 수 없다. 이 기능은 nodeSelector와 유사하지만, 좀 더 표현적인 문법을 제공한다.
- preferredDuringSchedulingIgnoredDuringExecution: 스케줄러는 조건을 만족하는 노드를 찾으려고 노력한다. 해당되는 노드가 없더라도, 스케줄러는 여전히 파드를 스케줄링한다.
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1
- antarctica-west1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: registry.k8s.io/pause:2.0
파드간 어피니티와 안티-어피니티(파드간 집중 / 분산)
파드간 어피니티와 안티-어피니티를 사용하여, 노드 레이블 대신, 각 노드에 이미 실행 중인 다른 파드의 레이블을 기반으로 파드가 스케줄링될 노드를 제한할 수 있다.
파드간 어피니티와 안티-어피니티 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행 중인 경우 이 파드는 X에서 실행해야 한다(또는 안티-어피니티의 경우에는 "실행하면 안 된다")"의 형태이며,
여기서 X는 노드, 랙, 클라우드 제공자 존 또는 리전 등이며 Y는 쿠버네티스가 충족할 규칙이다.
파드간 어피니티 및 안티-어피니티 종류
노드 어피니티와 마찬가지로 파드 어피니티 및 안티-어피니티에는 다음의 2 종류가 있다.
- requiredDuringSchedulingIgnoredDuringExecution
- preferredDuringSchedulingIgnoredDuringExecution
예를 들어, requiredDuringSchedulingIgnoredDuringExecution 어피니티를 사용하여 서로 통신을 많이 하는 두 서비스의 파드를 동일 클라우드 제공자에게 배치하도록 스케줄러에게 지시할 수 있다.
비슷하게, preferredDuringSchedulingIgnoredDuringExecution 안티-어피니티를 사용하여 서비스의 파드를 여러 클라우드 제공자에게 퍼뜨릴 수 있다.
- 파드간 어피니티를 사용하려면, 파드 스펙에 affinity.podAffinity 필드를 사용한다.
- 파드간 안티-어피니티를 사용하려면, 파드 스펙에 affinity.podAntiAffinity 필드를 사용한다.
Taints, Tolerations
특정 노드에는 아무 Pod가 할당할 수 없도록 하는 것
node 1은 높은 그래픽이 필요한 app을 돌리는 용도로 gpu를 할당시켜 놨고 taint를 설정했다고 가정,
- 일반적인 pod는 스케줄러가 node 1로 할당 X
- node 1로 지정해도 할당 X
- but 톨러레이션을 설정하면 할당 O
kubectl taint를 사용하여 노드에 테인트를 추가한다. 예를 들면 다음과 같다.
kubectl taint nodes node1 key1=value1:NoSchedule
node1 노드에 테인트를 배치한다.
테인트에는 키 (key1), 값 value1 및 테인트 이펙트 NoSchedule 이 있다.
이는 일치하는 톨러레이션이 없으면 Pod를 node1에 스케줄 할 수 없음을 의미한다.
톨러레이션을 사용하는 Pod의 예는 다음과 같다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"