node에 기존에 있는 pod 옮기기
kubectl drain <node-name>
- worker-1에 실행되고 있던 기존 잡들을 다른 노드로 옮기기위해 drain 명령을 실행합니다. drain 이 실행되면 cordon의 과정이 포함되므로 어떤 파드도 스케줄링되지 않습니다.
- 다른 node에 pod가 이동하는 것으로 보이지만 실제로는 기존 노드에서 실행되고 있던 파드들을 삭제한 후 다른 노드에서 재생성하는 과정이 진행됩니다. 이때, replica set에 있는 pod들은 다른 노드에서 살아나지만, 그렇지 않은 pod들은 복원되지 못한다는 것에 주의해야합니다.
- -ignore-daemonsets=true option을 설정하면 데몬세트로 실행한 파드들을 무시하고 드레인 설정을 적용할 수 있습니다.
kubectl uncordon <node-name>
- 원하는 작업을 수행한 후 cordon된 node를 해제하기 위해 uncordon 명령을 실행합니다.
kubeflow dsl을 사용한 pod scheduling
taint & toleration
먼저, 해당 노드에 taint를 추가합니다.
kubectl taint nodes <node-name> <key>=<value>:<effect>
만약, taint를 삭제하고 싶을 경우 아래와 같은 명령어를 사용합니다.
kubectl taint nodes <node-name> <key>=<value>:<effect>-
taint가 제대로 설정되어있는지 describe명령어로 확인합니다.
kubectl describe node <node-name>
이제 kubeflow dsl 에서 원하는 Pod에 특정 taint에 대한 toleration을 주도록 하겠습니다.
기존 파이썬으로 만든 컴포넌트에 add_toleration을 통해 toleration를 추가할 수 있습니다. 이때 Toleartion은 kubernetes client 객체를 사용하여 아래와 같이 입력해야합니다.
...
from kubernetes.client.models.v1_toleration import V1Toleration
def my_job():
print("Hi")
my_component = components.create_component_from_func(func=my_job, base_image='my_image')
@dsl.pipeline(
name="my_pl",
description = "example pipelime"
)
def my_pipeline():
...
toleration = kubernetes.client.models.v1_toleration.V1Toleration(
key='key',
value='experiment',
operator='Equal',
effect='NoSchedule'
)
my_task = my_component().add_toleration(toleration)
taint&toleration 설정 후 kubectl get pods -n kubeflow -o wide 명령어로 해당 파이프라인이 해당 node에 할당되었는지 확인합니다.
NodeAffinity
node affinity를 통해 파드의 생명주기에 따라 특정노드에 파드가 스케줄링 될 수 있도록 설정할 수 있습니다.
먼저, nodeselector로 사용할 label을 추가합니다.
kubectl label nodes <node-name> <key>=<value>
이제 kubeflow dsl에서 affinity를 설정하도록 하겠습니다.
toleraion과 마찬가지로 kubernetes client 객체를 사용해야합니다. affinity는 toleration보다는 조금 복잡합니다.
Nodeselector에 들어갈 expression을 V1NodeSelectorRequirement를 사용하여 생성하고, 이것을V1NodeSelectorTerm으로 받아서 V1NodeSelector 에 넣어준 후 원하는 상태를 선언하고 V1NodeAffinity 에 넣어서 V1Affinity 클래스로 만들어 dsl 매개변수로 넣어주면 됩니다.
예제 코드는 다음과 같습니다.
...
from kubernetes.client.models.v1_node_selector import V1NodeSelector
from kubernetes.client.models.v1_node_selector_term import V1NodeSelectorTerm
from kubernetes.client.models.v1_affinity import V1Affinity
from kubernetes.client.models.v1_node_affinity import V1NodeAffinity
from kubernetes.client.models.v1_node_selector_requirement import V1NodeSelectorRequirement
def my_job():
print("Hi")
my_component = components.create_component_from_func(func=my_job, base_image='my_image')
@dsl.pipeline(
name="my_pl",
description = "example pipelime"
)
def my_pipeline():
...
affinity = V1Affinity(
node_affinity=V1NodeAffinity(
required_during_scheduling_ignored_during_execution=V1NodeSelector(
node_selector_terms=[V1NodeSelectorTerm(
match_expressions=[V1NodeSelectorRequirement(
key='key',
operator='In',
values=['experiment'])])])))
my_task = my_component().add_affinity(affinity)
<참>
operator 필드를 사용하여 쿠버네티스가 규칙을 해석할 때 사용할 논리 연산자를 지정할 수 있습니다. In, NotIn, Exists, DoesNotExist, Gt 및 Lt 연산자를 사용할 수 있습니다.
Reference
'공부기록 > MLOps | Infra' 카테고리의 다른 글
[k8s] python sdk를 이용해 Pod 내에서 Kubernetes API 사용하기 (0) | 2022.10.06 |
---|---|
[k8s] Backup and Restore Methods (0) | 2022.08.29 |
[k8s] Cluster Upgrade Process (0) | 2022.08.29 |
[k8s] drain and cordon (0) | 2022.08.28 |
[k8s] Multi Container PODs (0) | 2022.08.28 |