- 쿠버네티스에서는 파드를 어떤 노드에 실행할 것인지에 관한 다양한 옵션이 있다.
- 이 옵션을 조합해서 사용자가 원하는 구조대로 클러스터 안에 파드들을 배치할 수 잇다.
- 특정 파드들을 노드 하나에 모아두거나 특정 IP대역의 노드들에서만 실행할 수도 있고, 반대로도 설정할 수 있다.
- 같은 기능이 있는 파드들이 노드 하나에 몰려있지 않게 골고루 분산해서 실행할 수도 있다.
- 관리가 필요한 노드가 있을 때 해당 노드에 있는 파드들을 다른 노드로 옮길 수도 있다.
1. 노드 셀렉터
- 가장 간단한 스케줄링 옵션으로는 파드의.spec 필드에 설정할 수 있는 노드셀렉터가 있다.
- 용어 그대로 노드를 선택하는 기능
- 파드가 클러스터 안 어떤 노드에서 실행될지를 키-값 쌍으로 설정한다.
- kubectl get nodes --show-labels 명령으로 클러스터 안 노드 레이블에 어떤 키-값 쌍이 있는지 확인
- kubecel label nodes docker-desktop disktype=ssd 명령으로 docker-desktop 노드에 disktype=ssd라는 키-값 쌍을 추가
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-nodeselector-pod
spec:
containers:
- name: kubernetes-nodeselector-pod
image: nginx
ports:
- containerPort: 8080
nodeSelector:
desktype: ssd
2. 테인트와 톨러레이션
- 테인트를 설정한 노드에는 파드들을 스케줄링하지 않는다.
- 테인트를 설정한 노드에 파드들을 스케줄링하려면 톨러레이션을 설정해야 한다.
- 그럼 테인트는 톨러레이션에서 설정한 특정 파드들만 실행하고 다른 파드는 실행하지 못하게 한다.
- 테인트와 톨러레이션은 주로 노드를 특정 역할만 하도록 만들 때 사용한다.
- 예를 들어 데이터베이스용 파드를 실행한 후 노드 전체의 CPU나 RAM 자원을 독점해서 사용할 수 있도록 설정하는 것이다.
- GPU가 있는 노드에는 실제로 GPU 를 사용하는 파드들만 실행되도록 설정할 수도 있다.
- 테인트는 키, 값, 효과의 세 가지로 구성된다.
- kubectl taint nodes 노드이름 키=값:효과 형식으로 명령을 작성한다.
$ kubectl taint nodes docker-desktop key01=value01:NoSchedule
node/docker-desktop tainted
- 테인트 설정은 kubectl taint nodes 노드이름 키:효과- 명령으로 삭제한다.
$ kubectl taint nodes docker-desktop key01:NodeSchedule-
node/docker-desktop untainted
tolerations 설정 예제
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-simple-app
labels:
app: kubernetes-simple-app
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-simple-app
template:
metadata:
labels:
app: kubernetes-simple-app
spec:
containers:
- name: kubernetes-simple-app
image: nginx
prots:
- containerPort: 8080
tolerations:
- key: "key01"
operator: "Equal"
value: "value01"
effect: "NoSchedule"
- effect 필드 값은 NoSchedule, PreferNoSchedule, NoEscute로 설정한다.
- NoSchedule: 톨러레이션 설정이 없으면 파드를 스케줄링 하지 않는다. 기존에 실행되던 파드에는 적용되지 않는다.
- PreferNoSchedule: 톨러레이션 설정이 없으면 파드를 스케줄링 하지 않는다. 하지만 클러스터 안 자원이 부족하면 테인트를 설정한 노드에서도 파드를 스케줄링할 수 있다.
- NoExcute: 톨러레이션 설정이 없으면 새로운 파드를 스케줄링하지 않으며, 기존 파드도 테인트 설정을 무시할 수 있는 톨러레이션 설정이 없으면 종료시킨다.
- operator 필드 값으로 Exist만 설정하면 어떤 테인트 설정이 있든 파드를 스케줄링해서 실행한다.
- Exist로 설정하고 key필드 값만 설정할 수도 있다. 이때는 effect 필드 값을 무시하고 key 필드 값에 해당하는 모든 테인트에 파드를 스케줄링해서 실행한다.
3. 어피니티와 안티 어피니티
노드 어피니티
- 노드 어피니티는 노드셀렉터와 비슷하게 노드의 레이블 기반으로 파드를 스케줄링한다.
- 노드 어피니티와 노드셀렉터를 함께 설정할 수도 있으며 이때는 노드 어피니티와 노드셀렉터의 조건을 모두 만족하는 파드를 스케줄링한다.
- 노드 어피니티에는 두 가지 필드가 있다.
- requiredDuringSchedulingIgnoredDuringExecution: 스케줄링하는 동안 꼭 필요한 조건
- preferredDuringSchedulingIgnoredDuringExecution: 스케줄링하는 동안 만족하면 좋은 조건. 꼭 이 조건을 만족해야 하는 것이 아니라는 뜻
- 두 필드는 실행 중에 조건이 바뀌어도 무시한다.
- 파드가 이미 스케줄링되어 특정 노드에서 실행 중이라면 중간에 해당 노드의 조건이 변경되더라도 이미 실행 중인 파드는 그대로 실행된다는 뜻
파드의 어피니티와 안티 어피니티
- 파드 사이의 어피니티와 안티 어피니티는 디플로이먼트나 스테이트풀세트로 파드를 배포했을 때 개별 파드 사이의 관계를 정의하는 용도로 사용한다.
- 실제 서비스를 운영할 때 요긴하다.
- 컨테이너로 서비스를 운영하다 보면 서비스 A의 파드와 서비스 B의 파드 사이에 자주 통신할 때가 있다. 어피니티는 이런 상황에서 서비스 A와 서비스 B의 파드들을 같은 노드에 속하게 만들어 효율을 높인다.
- 가장 흔한 예로 데이터베이스나 캐시 같은 서비싀와 통신하는 앱 컨테이너를 같은 노드에 두어 네트워크 통신 비용을 줄이는 것이 있다.
- 안티 어피니티는 CPU나 네트워크 같은 하드웨어 자원을 많이 사용하는 앱 컨테이너가 있을 때 여러 노드로 파드를 분산하는 것이다.
- 안티 어피니티가 설정되지 않으면 파드 개수를 늘려도 이미 시스템 사용률이 높은 노드에 다시 같은 역할을 하는 파드를 추가로 실행할 수 있다. 자원 사용량 문제를 해결하려고 파드 개수를 늘렸는데 효과가 없거나 오히려 더 성능이 낮아질 수도 있다는 것이다.
클러스터를 관리하는 커든과 드레인
- 쿠버네티스 클러스터를 사용하다 보면 특정 노드에 있는 파드들을 모두 다른 노드로 옮기거나 특정 노드에 파드들을 스케줄링하지 않도록 제한할 필요가 있다.
- kubectl에는 이러한 기능을 제공하는 cordon과 drain이라는 명령어가 있다. 앞에서 살펴봤던 taint도 같은 용도의 명령어이다.
- 데몬세트로 실행한 파드가 있거나, 컨트롤러로 실행하지 않은 파드가 있는 경우에는 드레인을 사용할 수 없다.
'클라우드 > Kubernetes(쿠버네티스)' 카테고리의 다른 글
[kubernetes] dnsutils, nslookup (0) | 2021.09.08 |
---|---|
[kubernetes] Volume (0) | 2021.08.25 |
[kubernetes] 사용자 권한 (keycloak) (0) | 2021.07.25 |
[kubernetes] Jenkins vs Jenkins X (0) | 2021.07.25 |
[kubernetes] Tekton (0) | 2021.07.25 |