본문 바로가기

HS/Round A Round

Round A Round - 3 - Kubevirt Network

 회사에서 Kubevirt를 주제로 발표를 하게 되었다. 입사할 때만 해도 "클라우드 엔지니어"가 무슨 일을 하는지조차 모르고 있었는데 반년 정도만에 add-on까지 공부할 수 있게 된 게 신기하다. 보통 이런 글은 개인 블로그에 작성하는데 100일 프로젝트를 진행 중이므로 이 쪽에 포스팅한다. 블로그 주인님이 틈만 나면 블로그 얘기를 하셔서 무서운 것도 조금 있다.


 Network로 주제를 잡은 이유는 내가 Network에 약하기도 하고 (이전에 안랩에 면접을 보러간적이 있는데 나는 그때까지 서브넷 마스크는 알았어도 CIDR를 알지 못했다) 정리하면서 공부하다 보면 조금 더 이해가 빠르지 않을까 싶어서이다. 주관적인 판단이지만 K8S에서 제일 어려운 부분도 바로 네트워크이다. K8S 기본 네트워크는 이 분야에서 가장 유명하고 내가 존경하는 이 분의 발표를 보면 쉽게 이해할 수 있다.

 

 Kubevirt에 대해 짧게 설명해보자면 K8S 환경에서 VM을 띄울 수 있는 K8S-Addon이다. Docker의 등장 이후로 느리고 무겁기만 한 VM은 사장될 줄 알았는데 왜 VM을 띄우려고 부득불 Kubevirt라는 존재가 나타난 걸까? 그것은 여러 이유가 있다.

 

 1. Host OS에 의존적인 어플리케이션이 존재한다.

 업무를 하다보면 자주 마주칠 수 있는데, 세상은 Ubuntu 18.04 기준으로 돌아가지 않는다. 정말 이전 버전의 OS를 쓰는 곳도 있으며 Window Server를 사용하는 곳도 많다. 서버도 새 거, OS도 새 거, K8S도 최신 스테이블 버전 이어도 위에 올라가는 업무가 OS를 타는 순간 모든 일이 힘들어지기 시작한다. 그런 업무는 컨테이너로 올리려면 개발자들이 여럿 갈려가고 수많은 문제가 생긴다. 

 2. Container와 VM을 같은 환경에서 관리하는 것이 좋다.

 당연한 이야기이다. 편하자고 K8S를 쓰는데 관리 플랫폼이 두 개가 되면 네트워크 문제도 복잡해지고 리소스 관리도 복잡해진다. 

 3. Kubernetes의 장점을 사용할 수 있다.

 K8S의 장점은 많지만 그 중 뽑아보자면 Self-healing, Scheduling 등이 있다. VM에 문제가 생겨도 자동으로 재생성되면 , 데이터를 살릴 수만 있다면 일단 야근은 면한 거다.


 이런 여러 가지 이유로 인해 Kubevirt는 등장했다. 2016년 RedHat에서 시작하였으며 2017년 Opensource로 등록되었다. 이 곳이 kubevirt의 공식 홈페이지이다. 서론은 여기까지만 하고 Kubevirt Network에 대해 간단한 그림을 그려보았다.

 

VM은 Container 위에서 관리되고 있다. VM은 인터페이스로 eth0 하나의 인터페이스를 가지고 있으며 이는 Pod의 vnet0번과 통신한다. 너무 추상적이니까 실제 사례로 한번 보자.

 

띄운 VM pod에 들어가 본다.

root@c1:~# kubectl get pods
virt-launcher-41c0ed0d-h7jnl 1/1 Running 0 2m31s
[root@41c0ed0d /]# ls
augconf  bin  boot  dev  etc  home  lib  lib64  libvirtd.sh  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

[root@41c0ed0d /]# top
top - 06:46:27 up 53 days, 22:52,  0 users,  load average: 2.20, 2.14, 1.87
Tasks:   7 total,   1 running,   6 sleeping,   0 stopped,   0 zombie
%Cpu(s):  6.2 us,  1.2 sy,  0.0 ni, 92.1 id,  0.0 wa,  0.0 hi,  0.4 si,  0.0 st
MiB Mem :  31601.8 total,   7379.1 free,   9494.1 used,  14728.6 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  21467.9 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                              
    1 root      20   0 1716248  56508  32164 S   0.0   0.2   0:00.35 virt-launcher                                                                                                                                        
   25 root      20   0 2085420  56416  31948 S   0.0   0.2   0:00.52 virt-launcher                                                                                                                                        
   45 root      20   0 1526284  41600  31708 S   0.0   0.1   0:00.43 libvirtd                                                                                                                                             
   46 root      20   0   24072  10472   9204 S   0.0   0.0   0:00.02 virtlogd                                                                                                                                             
  134 qemu      20   0 7107724 538872  21772 S   0.0   1.7   1:13.10 qemu-system-x86                                                                                                                                      
 1188 root      20   0    5988   3832   3208 S   0.0   0.0   0:00.01 bash                                                                                                                                                 
 1724 root      20   0    8032   3732   3148 R   0.0   0.0   0:00.00 top

 

libvirtd가 실행 중인 것을 볼 수 있다. 이 virt-launcher pod 위에서 VM이 돌아가고 있는 것이다. 포드 IP와 인터페이스를 살펴본다.

 

 

- virt-launcher pod의 인터페이스

 

root@c1-2:~# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP               NODE   
virt-launcher-4123f711-rm8mq   1/1     Running   0          23m   10.244.253.223   c1

 

[root@4123f711 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue master k6t-eth0 state UP group default 
    link/ether 9a:cd:51:f9:8c:9a brd ff:ff:ff:ff:ff:ff link-netnsid 0
5: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether 9a:cd:51:f9:8c:9a brd ff:ff:ff:ff:ff:ff
    inet 169.254.75.10/32 brd 169.254.75.10 scope global k6t-eth0
       valid_lft forever preferred_lft forever
6: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc fq_codel master k6t-eth0 state UNKNOWN group default qlen 1000
    link/ether fe:cd:51:65:8c:e7 brd ff:ff:ff:ff:ff:ff

 

eth0, k6t-eth0, vnet0이 up 상태이다. 용도가 무엇인지 아직은 모르겠으니 Pod에서 실행 중인 VM을 먼저 찾아가 본다.

 

[root@4123f711 /]# virsh
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh # list
 Id   Name                          State
---------------------------------------------
 1    fbb51545_4123f711   running

 

virsh list에 나타나는 이름은 node에서 kubectl로 조회했을 때 나타나는 이름과 같다.

 

 

- VM의 인터페이스

 

root@c1:~# kubectl get vmi -A
NAMESPACE  NAME       AGE   PHASE     IP                  NODENAME
fbb51545   4123f711   24m   Running   10.244.253.223/32   c1

 

[root@4123f711 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc pfifo_fast state UP qlen 1000
    link/ether 9a:cd:51:65:8c:e7 brd ff:ff:ff:ff:ff:ff
    inet 10.244.253.223/32 brd 10.244.253.223 scope global dynamic eth0
       valid_lft 86312135sec preferred_lft 86312135sec
    inet6 fe80::98cd:51ff:fe65:8ce7/64 scope link 
       valid_lft forever preferred_lft forever

 

 얘는 어차피 하나밖에 안 가지고 있으니 위 그림의 VM의 eth0번이라는 것을 알 수 있다.  하나 캐치해보자면 virt-launcher의 pod ip는 VM의 ip와 동일하다.  외부에서 해당 pod로 접근하면 vm으로 넘겨준다는 것을 알 수 있다.  다시 virt-launcher의 인터페이스를 보자.

 

[root@4123f711 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue master k6t-eth0 state UP group default 
    link/ether 9a:cd:51:f9:8c:9a brd ff:ff:ff:ff:ff:ff link-netnsid 0
5: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default 
    link/ether 9a:cd:51:f9:8c:9a brd ff:ff:ff:ff:ff:ff
    inet 169.254.75.10/32 brd 169.254.75.10 scope global k6t-eth0
       valid_lft forever preferred_lft forever
6: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc fq_codel master k6t-eth0 state UNKNOWN group default qlen 1000
    link/ether fe:cd:51:65:8c:e7 brd ff:ff:ff:ff:ff:ff

 

vnet0는 vm과 연결된 인터페이스며 k6t-eth0은 브릿지이다. 얘는 vnet0과 eth0을 연결해주어 VM이 node와 통신할 수 있도록 도와준다. 그렇다면 노드에 있는 인터페이스는 무엇일까? 이것은 공부해서 2편으로 넘어간다... 오늘 너무 바빠서 쓸 시간이 없다.

'HS > Round A Round' 카테고리의 다른 글

Round A Round - 5 - 메이플에선 갑질하는 내가 회사에선 패치 찐따?!  (0) 2020.04.03
Round A Round - 4 - Kubevirt Network  (0) 2020.04.01
Round A Round - TEST  (1) 2020.04.01
Round A Round - 2  (0) 2020.03.28
Round A Round - 1  (0) 2020.03.27