created at 2019.11.09
Kubevirt 가 뭘까? 아! kube 클러스터에서 libvirt를 사용할 수 있게 하는 모델이구나! VM을 kube cluster 에 띄우고 싶다 이거지. 이름 한번 간결하고 좋다. 어떻게 모듈을 붙일까? 하고 보니 Operatorhub.io 사이트에 당당히 이름이 올라있구나. 우선 Operator lifecycle manager 를 설치하고 허브에서 kubevirt operator 를 설치하면 간단하겠구나.
Operator 는 kube 에서 서드파티 앱들을 위해 제공하는 패턴으로, 커스텀 컨트롤러를 제작하는데 사용한다. 컨트롤러라 하면 kube 에서 declarative 명령으로 제시되는 desired state 를 유지시킬 때 사용되는 kube Object 를 일컫는다. 가령 Kind: ReplicaSet 을 보면, ReplicaSet 이라는 컨트롤러가 해당 yaml에 명시되어있는 state 를 꾸준히 돌도록 해준다. 이 이미지의 pod 를 3개 유지해줘 하고 요청하면 다음과 같은 과정으로 그 상태를 꾸준히 유지하도록 해준다.
기본적으로 제공되는 컨트롤러(pods, services 등의 kube 기본 오브젝트를 제어) 외에 application specific 하게 kube 를 운영할 수도 있는데, 이 때 사용하는 것이 CRD(custom resource definition) 과 Operator 패턴이다. kube 에 ceph 를 운용하고 싶다고 하면 osd는 몇 개가 있어야하고 mon 몇 개가 있어야하고… 하는 특정 application 에 특화된 custom resource 를 정의하고 그대로 유지하도록 도와주는 것이지 (Rook ceph 프로젝트 참조). 비슷하게 kubevirt 는 libvirt 와 kvm 을 이용하게 할 수 있도록 도와주는 crd 와 operator 를 제공하는 놈인 것이겠지.
인터넷에서 찾은 구조인데, kubect"i" 를 보고 신뢰도가 떨어진 이미지.
구조를 얼추 보니, kvm hypervisor를 제어하는 libvirtd를 이용하여 VM을 띄우면서, kube 의 선언적 desired state 를 유지하기 위해 각종 구성요소를 pod 으로 띄우고 그 pod가 VM을 띄우는, 그러니까 VM을 kube가 직접 제어하는 것이 아니고 VM 를 제어할 수 있는 각종 모듈을 kube가 제어할 수 있도록 Virt API 를 구성해서 kube 에 붙여놓은 그런 구조로 보인다.
구성요소:
virt-api-server
kubernetes 의 api server 와 연동하는 api 서버. kubevirt 와 관련된 명령어가 kubectl 을 통해 들어오면 kube api server 는 해당 명령어를 virt-api-server 로 보내 수행. kubevirt 의 메인 엔트리포인트로 사용되고, vm 의 초기화 및 유효성 검사 등을 담당.
VMI
kubevirt 의 CustomResourceDefinitions 중 하나. VM이 사용하는 모든 properties를 필드로 가질 수 있다. 가령 Machin type, Cpu type, amount of RAM/vCPUs, number and type of NICs, … 등의 명세를 가진다.
virt-controller
kube의 libvirt 특화 custom controller 로, virt-handler 및 virt-launcher pods를 관리하는 놈이다.
virt-handler
DaemonSet 으로, kubevirt 설치 시에 모든(혹은 클러스터 중 vm 이 구동될 일부) 노드에 뜨는 pod. vm 자체는 kube 와 관련이 없으므로 kubelet 이 담당하고 있는 watching changes 역할을 vm에 대하여 수행하고 있음. required desired state 를 만족하게 하기 위한 것들을 모두 관찰하는 놈.
virt-launcher
VM 프로세스가 사용할 cgroup 및 namespace 를 지정해놓는 요소. 이 런쳐가 가진 cgroup 및 namespace 를 이용하여 VM 이 뜬다. virt-handler 가 vm 상태를 관찰하고 하다가 수정/생성/삭제 요청을 virt-launcher 에게 날리면 런처가 그 요청을 받아 VM을 제어한다.
libvirtd instance
모든 VM pod 에 들어 있는 기본 container. 컨트롤러든 핸들러든 런쳐든 libvirtd 가 필요하니깐…
Default Procedure:
client 는 VM 명세가 담긴 VMI 를 만든 후 apply 해서 custom resource를 create 한다.
virt-controller 는 VMI 오브젝트가 생성된 것을 확인하고 해당 명세에 맞는 pod (virt-launcher) 를 만들고, k8s 에서 스케쥴링 해준다.
virt-controller 는 pod 이 생성된 것을 보고 VMI 오브젝트에 nodeName 필드를 업데이트해주고, virt-handler 으로 관할을 넘김
virt-handler 는 자기 노드에 k8s 가 VM 파드를 할당한 것을 확인하고, VMI 스펙에 명시된 대로 correspondind libvirt domain 을 형성하도록 virt-launcher 에 signal 을 보낸다.
스토리지 및 네트워크 관련해서는 KubeVirt 에 직접 있는 것이 아니고 다른 모듈들을 붙여서 사용할 수 있다고 명시되어 있으나, 내 생각에 이대로 따라하면 백프로 안되고 수많은 시행착오를 거쳐야 할 것 같은 수준으로 문서가 되어있었다. 두려우니 시도는 나중에….
즉, 피치 못할 사정으로 인해 vm 을 띄우고 싶을 때도 kubevirt를 이용해 구성해놓은 kube cluster 에 띄우고, 선언적 명령을 지켜주는 환경에 편입시켜 관리를 편하게 할 수도 있게 만들어주는 것이다. VM에 대한 수요는 어쩐지 모르겠으나, Operatorhub.io 에 있는 다른 샘플들보다는 훨씬 더 kube의 근본에 영향을 줄 수 있는 플러그인으로 보인다. 어쩌면 일개 CRD/Operator 가 아니라 kube 속으로 직접 편입할 수도 있을 것 같은 모듈이라고 생각된다. 구글 트렌드 검색을 보면 그건 요원해 보이기는 하지만.
study의 다른 글 보기