Kubernetes · Concepts ·
[Kubernetes] Affinity
Affinity? #
- Affinity란 선호도란 뜻이다. Pod는 항상 Node에서 띄워져야 하는데, 이러한 배치를 함에 있어 선호하는 Node나 Pod를 설정할 수 있는 리소스이다.
Affinity 종류 #
- nodeAffinity는 어떤 Node를 선호할 것인가? 에 관련한 리소스이다. 즉, Pod를 배치할 때 어떤 Node에 스케쥴링할지 설정을 해준다.
- podAffinity는 Pod가 배치될 때, 실행 중인 Pod들 중에 선호하는 Pod를 찾아 해당 Pod와 동일한 Node로 배치하는 걸 설정해준다.
- podAnitAffinity는 실행 중인 Pod들 중에, 선호하지 않은 Pod가 실행 중인 Node는 피해서 배치를 하겠다는 걸 설정해준다.
nodeAffinity? #
- 선호하는 노드를 설정하는 방법으로, nodeSelector 보다 확장된 Label Selector 기능을 지원한다. 그래서 좀 더 실무환경에 적합한 Pod 배치 전략이다.
- matchExpressions 사용 가능하다. (In, NotIn, Exists, DoesNotExist, Gt, Lt 등의 옵션이 있다.)
- 여러 유즈케이스에 활용 가능한 2가지 옵션이 있는데. Hard, Soft로 나뉜다. 매우 조건이 길기 때문에 2등분해서 의미를 이해하면 좋다.
- 반드시 충족해야 하는 조건 (Hard)
- requiredDuringSchedulingIgnoredDuringExecution :
스케쥴링하는 동안 꼭 필요한조건- 즉, 스케쥴링되는 워크로드에는 필수 조건이고, 실행 중인 워크로드는 조건을 무시한다는 의미이다.
- requiredDuringSchedulingIgnoredDuringExecution를 구성하는 매니페스트 파일
1 ...✂... 2 affinity: 3 nodeAffinity: 4 requiredDuringSchedulingIgnoredDuringExecution: 5 nodeSelectorTerms: 6 - matchExpressions: 7 - key: disktype 8 operator: In 9 values: 10 - ssd
- requiredDuringSchedulingIgnoredDuringExecution :
- 선호하는 조건 (Soft)
- preferredDuringSchedulingIgnoredDuringExecution :
스케쥴링하는 동안 만족하면 좋은조건입니다. 꼭 이 조건을 만족해야하는 것은 아니라는 의미입니다.- 즉, 스케쥴링되는 워크로드에는 선호 조건이고, 실행 중인 워크로드는 조건을 무시한다는 의미이다.
1 ...✂... 2 affinity: 3 nodeAffinity: 4 preferredDuringSchedulingIgnoredDuringExecution: 5 - weight: 10 6 preference: 7 - matchExpressions: 8 - key: disktype 9 operator: In 10 values: 11 - hdd
- preferredDuringSchedulingIgnoredDuringExecution :
- 용어 설명:
- IgnoredDuringExecution: 실행 중인 워크로드에 대해서는 해당 규칙을 무시한다.
- RequiredDuringExecution: 위와 반대개념으로 실행 중인 워크로드에 대해서 해당 규칙을 반드시 필요로 한다.
- 반드시 충족해야 하는 조건 (Hard)
| key 필드 값 | 설명 |
|---|---|
| In | values[] 필드에 설정한 값 중 레이블에 있는 값과 일치하는 것이 하나라도 있는지 확인합니다. |
| Notln | In과 반대로 values[]에 있는 값 모두와 맞지 않는 지 확인합니다. |
| Exists | key 필드에 설정한 값이 레이블에 있는지만 확인합니다. (values[] 필드가 필요 없습니다.) |
| DoseNotExist | Exists와 반대로 노드의 레이블에 key 필드 값이 없는지만 확인합니다. |
| Gt | Greater than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 큰 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다. |
| Lt | Lower than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 작은 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다. |
nodeAffinity 세팅 #
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: node-affinity-required
5spec:
6 replicas: 3
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 nodeAffinity:
25 requiredDuringSchedulingIgnoredDuringExecution:
26 nodeSelectorTerms:
27 - matchExpressions:
28 - key: team
29 operator: In
30 values:
31 - blue
32 - red- operator In은 or 연산자라고 이해하면 된다. 즉, key가 team이고, value가 blue 혹은 red인 조건을 필수로 한다.
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: node-affinity-preferred
5spec:
6 replicas: 4
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 nodeAffinity:
25 preferredDuringSchedulingIgnoredDuringExecution:
26 - weight: 40
27 preference:
28 matchExpressions:
29 - key: team
30 operator: In
31 values:
32 - green- operator In은 or 연산자라고 이해하면 된다. 즉, key가 team이고, value가 green인 조건을 선호 한다.
- preferred는 weight가 있고, 각각에 matchExpressions을 넣는 구조로 되어 있다.
- weight는 0~100 사이의 값을 가질 수 있다. 각각의 rule을 기반으로 weight를 설정해서 점수를 줌으로써 Pod가 어떤 Node에 최종 배치될지 우선순위를 설정하는 것으로 이해하면 된다.
- 즉, weight는 여러개 설정할 수 있고, 점수를 매겨 우선순위를 결정하는 데 쓰이는 것이다.
1kubectl label node kube-01 --overwrite team=green
2kubectl label node kube-02 --overwrite team=red
3kubectl label node kube-03 --overwrite team=blue- 특정 node 각각에 label(key-valu)를 지정하는 set-node-labels.sh 스크립트이다.
1kubectl get nodes --show-labels
2kubectl get nodes --label-columns team
podAffinity? #
- 선호하는 파드를 설정하는 방법으로, 사용법은 nodeAffinity와 거의 동일하다.
- 역시 여러 유즈케이스에 활용 가능한 2가지 옵션을 제공하며, Hard, Soft로 나뉜다. nodeAffinity와 동일하여 자세한 설명은 생략한다.
- 반드시 충족해야 하는 조건 (Hard)
- requiredDuringSchedulingIgnoredDuringExecution
- 선호하는 조건 (Soft)
- preferredDuringSchedulingIgnoredDuringExecution
- 반드시 충족해야 하는 조건 (Hard)
- podAffinity의 가장 중요한 부분은 다음의 개념이다.
- 토폴로지 키 (Topology Key)
- 쿠버네티스 Node에 설정된 Label에 대해서, Label Selector를 수행할 노드의 범위를 결정한다.
- Topology Key는 노드의 레이블 key를 설정하는 것이며, 어떠한 값을 key name으로 넣어도 상관없지만 다음과 같은 3가지 key를 주로 쓴다.
- Node 단위: kubernetes.io/hostname
- zone 단위: topology.kubernetes.io/zone
- AZ(Availablity Zone: 가용영역)
- region 단위: topology.kubernetes.io/region
- 지역 (서울, 도쿄 등)
podAffinity 세팅 #
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: mysql
5spec:
6 selector:
7 matchLabels:
8 app: mysql
9 template:
10 metadata:
11 name: mysql
12 labels:
13 app: mysql
14 spec:
15 containers:
16 - name: mysql
17 image: mariadb:latest
18 env:
19 - name: MYSQL_ROOT_PASSWORD
20 value: setting_password
21 - name: MYSQL_DATABASE
22 value: kubernetes
23 ports:
24 - name: http
25 containerPort: 3306
26 protocol: TCP 1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: pod-affinity-required
5spec:
6 replicas: 3
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 podAffinity:
25 requiredDuringSchedulingIgnoredDuringExecution:
26 - labelSelector:
27 matchExpressions:
28 - key: app
29 operator: In
30 values:
31 - mysql
32 topologyKey: kubernetes.io/hostname
33 # topologyKey: topology.kubernetes.io/zone
34 # topologyKey: topology.kubernetes.io/region 1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: pod-affinity-preferred
5spec:
6 replicas: 4
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 podAffinity:
25 preferredDuringSchedulingIgnoredDuringExecution:
26 - weight: 100
27 podAffinityTerm:
28 labelSelector:
29 matchExpressions:
30 - key: app
31 operator: In
32 values:
33 - mysql
34 topologyKey: kubernetes.io/hostname
35 # topologyKey: topology.kubernetes.io/zone
36 # topologyKey: topology.kubernetes.io/regionpodAntiAffinity? #
- 선호하지 않는 파드를 설정하는 방법으로, podAffinity를 podAntiAffinity로만 변경하면 사용법 동일하다.
- 역시 여러 유즈케이스에 활용 가능한 2가지 옵션을 제공하며, Hard, Soft로 나뉜다. podAffinity와 동일하여 자세한 설명은 생략한다.
- 반드시 충족해야 하는 조건 (Hard)
- requiredDuringSchedulingIgnoredDuringExecution
- 선호하는 조건 (Soft)
- preferredDuringSchedulingIgnoredDuringExecution
- 반드시 충족해야 하는 조건 (Hard)
- 토폴로지 키 (Topology Key)도 podAffinity와 같은 방식이다. 자세한 건 3번 챕터(podAffinity)를 참고하면 된다.
podAntiAffinity 세팅 #
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: pod-anti-affinity-required
5spec:
6 replicas: 3
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 podAntiAffinity:
25 requiredDuringSchedulingIgnoredDuringExecution:
26 - labelSelector:
27 matchExpressions:
28 - key: app
29 operator: In
30 values:
31 - mysql
32 topologyKey: kubernetes.io/hostname
33 # topologyKey: topology.kubernetes.io/zone
34 # topologyKey: topology.kubernetes.io/region 1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: pod-anti-affinity-preferred
5spec:
6 replicas: 4
7 selector:
8 matchLabels:
9 app: hello
10 template:
11 metadata:
12 name: hello
13 labels:
14 app: hello
15 spec:
16 containers:
17 - name: nginx
18 image: nginxdemos/hello:plain-text
19 ports:
20 - name: http
21 containerPort: 80
22 protocol: TCP
23 affinity:
24 podAntiAffinity:
25 preferredDuringSchedulingIgnoredDuringExecution:
26 - weight: 100
27 podAffinityTerm:
28 labelSelector:
29 matchExpressions:
30 - key: app
31 operator: In
32 values:
33 - mysql
34 topologyKey: kubernetes.io/hostname
35 # topologyKey: topology.kubernetes.io/zone
36 # topologyKey: topology.kubernetes.io/regionAdvertisement