런타임 클래스
런타임 클래스 (Runtime Class)
RuntimeClass는 파드의 컨테이너를 실행하는 데 사용되는 컨테이너 런타임 구성을 선택하는 기능이에요. 서로 다른 파드에 서로 다른 런타임 구성을 적용하는 방법을 옆에서 차근차근 설명드릴게요.
동기 (Motivation)
RuntimeClass를 사용하면 서로 다른 파드에 서로 다른 런타임 구성을 설정해서 성능과 보안 사이의 균형을 맞출 수 있어요. 예를 들어 정보 보안 보장 수준이 높은 워크로드의 일부라면, 하드웨어 가상화를 사용하는 컨테이너 런타임에서 실행되도록 해당 파드들을 스케줄링할 수 있습니다.
또한 동일한 컨테이너 런타임을 사용하지만 다른 설정으로 여러 파드를 실행하는 데도 RuntimeClass를 사용할 수 있어요.
설정 (Setup)
- 노드에서 CRI 구현을 구성합니다(런타임에 따라 다름).
- 해당하는 RuntimeClass 리소스를 생성합니다.
1. 노드에서 CRI 구현 구성
RuntimeClass를 통해 사용할 수 있는 구성은 CRI(Container Runtime Interface) 구현에 따라 달라요. 사용 중인 CRI 구현의 해당 문서를 참조해 구성 방법을 확인하세요.
참고: RuntimeClass는 기본적으로 클러스터 전체에 걸쳐 균일한 노드 구성을 가정해요(모든 노드가 컨테이너 런타임에 관해 동일하게 구성됨). 이질적인 노드 구성을 지원하려면 아래의 스케줄링(Scheduling)을 참고하세요.
구성에는 RuntimeClass가 참조하는 해당 handler 이름이 있으며, handler는 유효한 DNS 라벨 이름이어야 해요.
2. 해당 RuntimeClass 리소스 생성
1단계에서 설정한 구성에는 각각 구성 식별에 사용되는 handler 이름이 있어야 해요. 각 handler에 대해 해당 RuntimeClass 객체를 생성합니다.
RuntimeClass 리소스는 현재 두 개의 중요한 필드만 가지고 있어요. 바로 RuntimeClass 이름(metadata.name)과 handler(handler)입니다. 객체 정의는 이렇게 생겼어요.
# RuntimeClass는 node.k8s.io API 그룹에 정의됩니다.
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# RuntimeClass가 참조될 이름입니다.
# RuntimeClass는 네임스페이스가 없는(non-namespaced) 리소스입니다.
name: myclass
# 해당 CRI 구성 핸들의 이름입니다.
handler: myconfiguration
참고: RuntimeClass 쓰기 작업(create/update/patch/delete)은 클러스터 관리자로 제한하는 것이 좋습니다. 이것이 보통 기본 동작이에요.
사용 (Usage)
클러스터에 RuntimeClass가 구성되면, 파드 스펙에 runtimeClassName을 지정해서 사용할 수 있어요. 예를 들어:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
이렇게 하면 kubelet이 지정된 RuntimeClass를 사용해 이 파드를 실행하도록 지시합니다. 지정된 RuntimeClass가 없거나 CRI가 해당 handler를 실행할 수 없으면 파드는 Failed 터미널 단계에 들어갑니다. 오류 메시지를 위한 해당 이벤트를 찾아보세요.
runtimeClassName이 지정되지 않으면 기본 RuntimeHandler가 사용되며, 이는 RuntimeClass 기능이 비활성화된 경우와 동일한 동작입니다.
CRI 구성
CRI 런타임 설정에 대한 자세한 내용은 CRI 설치 문서를 참고하세요.
containerd
런타임 핸들은 containerd의 구성인 /etc/containerd/config.toml을 통해 구성됩니다. 유효한 핸들은 runtimes 섹션 아래에 구성됩니다.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.${HANDLER_NAME}]
CRI-O
런타임 핸들은 CRI-O의 구성인 /etc/crio/crio.conf를 통해 구성됩니다. 유효한 핸들은 crio.runtime 테이블 아래에 구성됩니다.
[crio.runtime.runtimes.${HANDLER_NAME}]
runtime_path = "${PATH_TO_BINARY}"
스케줄링 (Scheduling)
기능 상태:
Kubernetes v1.16 [beta]
RuntimeClass의 scheduling 필드를 지정하면, 이 RuntimeClass로 실행되는 파드가 이를 지원하는 노드에 스케줄링되도록 제약을 설정할 수 있어요. scheduling이 설정되지 않으면 이 RuntimeClass는 모든 노드에서 지원되는 것으로 간주됩니다.
파드가 특정 RuntimeClass를 지원하는 노드에 착지하도록 보장하려면, 해당 노드 집합에 공통 라벨이 있어야 하고 그것을 runtimeclass.scheduling.nodeSelector 필드로 선택해야 해요. RuntimeClass의 nodeSelector는 입장(admission) 시 파드의 nodeSelector와 병합되어, 사실상 각각이 허용하는 노드 집합의 교집합을 취합니다.
지원 노드가 다른 RuntimeClass 파드가 노드에서 실행되지 않도록 taint되어 있다면 RuntimeClass에 tolerations를 추가할 수 있어요. nodeSelector와 마찬가지로 tolerations도 입장 시 파드의 tolerations와 병합되어, 각각이 허용하는 노드 집합의 합집합을 효과적으로 취합니다.
파드 오버헤드 (Pod Overhead)
기능 상태:
Kubernetes v1.24 [stable]
파드 실행과 관련된 오버헤드 리소스를 지정할 수 있어요. 오버헤드를 선언하면 클러스터(스케줄러 포함)가 파드와 리소스에 대한 결정을 내릴 때 이를 고려할 수 있습니다.
파드 오버헤드는 RuntimeClass의 overhead 필드로 정의됩니다. 이 필드를 사용해 이 RuntimeClass를 활용하는 파드 실행의 오버헤드를 지정하고, Kubernetes에서 이러한 오버헤드가 계산되도록 보장할 수 있어요.