IT 이모저모

Mac os 내 경량 Linux 환경 구성하기 feat. linuxkit

직장인B 2022. 9. 2. 23:42

 Mac os에서 Docker를 사용하는건 불가능하지 않다. 허나 Docker의 기본 설계 사상을 고려하자면 불가능하나 일이어야 하는게 맞다. Docker는 Linux Kernel을 이용하여 컨테이너를 구동하기 때문. Mac은 Linux 배포판들과는 다른 Kernel 시스템을 가진다. 그럼 Mac용 Docker는 Mac Kernel을 사용하는걸까? 싶지만 그렇지 않다. Mac용 Docker는 Mac에 경량의 linux 가상 머신을 띄운 후 이걸 이용해 도커를 구동한다. 이때 사용하는 것이 바로 linuxkit 이다..!

 

 linuxkit은 커스텀 linux 배포판을 가상머신으로 띄우는데 사용하는 도구로 Mac 만을 위한 건 아니다. 다만 포스팅에선 Mac os 내 경량 Linux 환경을 구성하는 것에 집중하고자 한다. 

 

LinuxKit/LinuxKit

오픈소스이며 Apache-2.0 라이센스를 가진다. 

https://github.com/linuxkit/linuxkit

 

GitHub - linuxkit/linuxkit: A toolkit for building secure, portable and lean operating systems for containers

A toolkit for building secure, portable and lean operating systems for containers - GitHub - linuxkit/linuxkit: A toolkit for building secure, portable and lean operating systems for containers

github.com

 

Installation

 brew를 이용해서 간단히 설치할 수 있다. 

brew tap linuxkit/linuxkit
brew install --HEAD linuxkit

 설치 후 버전 Check는 대한 국룰!

linuxkit version

 

Build Image 

 머신을 띄울 때 사용할 이미지를 만들어야한다. yaml 파일로 kernel과 모듈들을 정의하자. 아래에선 linuxkit의 공식 기본 kernel을 사용했지만 centos나 ubuntu 등 다른 배포판의 kernel도 사용할 수 있다. 이때 정의서에 명시된 image들은 docker image들이며 dockerhub에서 각각 찾아서 고치거나 수정할 수 있다. 

  • https://github.com/linuxkit/linuxkit/blob/master/examples/sshd.yml
  • https://github.com/linuxkit/linuxkit/blob/master/docs/yaml.md
  • https://hub.docker.com/search?q=linuxkit
kernel:
  image: linuxkit/kernel:5.10.104
  cmdline: "console=tty0 console=ttyS0 console=ttyAMA0 console=ttysclp0"
init:
  - linuxkit/init:8f1e6a0747acbbb4d7e24dc98f97faa8d1c6cec7
  - linuxkit/runc:f01b88c7033180d50ae43562d72707c6881904e4
  - linuxkit/containerd:de1b18eed76a266baa3092e5c154c84f595e56da
  - linuxkit/ca-certificates:c1c73ef590dffb6a0138cf758fe4a4305c9864f4-s390x
onboot:
  - name: sysctl
    image: linuxkit/sysctl:10b6637dc4c202d3be8644473dd7c92013da2cae
  - name: rngd1
    image: linuxkit/rngd:4f85d8de3f6f45973a8c88dc8fba9ec596e5495a
    command: ["/sbin/rngd", "-1"]
services:
  - name: getty
    image: linuxkit/getty:76951a596aa5e0867a38e28f0b94d620e948e3e8
    env:
     - INSECURE=true
  - name: rngd
    image: linuxkit/rngd:4f85d8de3f6f45973a8c88dc8fba9ec596e5495a
  - name: dhcpcd
    image: linuxkit/dhcpcd:52d2c4df0311b182e99241cdc382ff726755c450

이미지를 빌드한다. 컴포넌트 이미지들을 pulling 하는데 약간 시간이 걸린다. 확인해보면 부팅 Disk img 용량이 약 77Mb 정도되는데 굉장히 경량인 편..! 빌드 command 는 다음과 같다.

linuxkit build -name <name> <yaml>

format 옵션을 사용해 여러 유형의 이미지로 빌드할 수 있다. Default는 'kernel+initrd' ! 

Booting Imaga Formats

 

Image Run

 이제 가상머신을 띄울 차례다. 명령어는 다음과 같다. 이때 가상머신을 관리할 하이퍼바이저를 설정할 수 있다. 각 os 별 Default 값이 있는데 Mac의 경우엔 Viratulization.framework를 기본으로 사용한다. 원한다면 vmware 등 다른 하이퍼바이저를 사용할 수 있다. 

linuxkit run <hypervisor> <name>

 부팅 과정을 세세히 파악할 순 없었지만 대략 'kernel 모듈 세팅 -> 네트워크 설정 -> yaml에서 등록한 설정에 맞춰 부팅 -> 서비스 구동' 순으로 진행되는 것 같다. 이미지가 문제 없다면 이쁜 고래 그림과 함께 구동 성공 메세지가 출력된다. 

 터미널로 구동을 진행시 서버 접속까지 자동으로 진행된다. 부팅이 성공하고 출력이 멈춰있다면 엔터를 한 번 눌러주자...!

linuxkit-env ➤ linuxkit run virtualization _linux
start VM is running
...

Welcome to LinuxKit

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
          {                       /  ===-
           \______ O           __/
             \    \         __/
              \____\_______/

...

linuxkit-3eabe867f240 login: root (automatic login)

Welcome to LinuxKit!

NOTE: This system is namespaced.

...

 

Explore Server

 서버를 구동해보고 곧바로 끝내긴 아쉬우니 몇몇 정보들을 탐색해보자. 우선 서버의 os/커널 정보를 출력해보자. linuxkit kernel 을 사용하는 linux os 라는 걸 확인할 수 있다. 

 놀랍게도 mac에서 도커로 컨테이너를 띄운 다음에 os/커널 정보를 출력하면 비슷한 출력값을 같는다. 아래는 mac에서 awslinux 공식 이미지를 띄운 후 명령어를 날린 결과다. 이건 해당 이미지가 linuxkit kernel을 사용하기 때문이 아니라 mac용 docker이 host 서버에  linuxkit 커널을 사용한 linux 가상 서버를 띄우고 거기에 컨네이터를 구동함에 따른 결과다. 알다시피 docker의 컨테이너는 일종의 프로세스다. 그와 달리 linuxkit은 독자적인 커널을 사용하는 가상 머신이다.!

 

 다음으로 서버의 프로세스 정보를 출력해보자. init 프로세스가 메인 프로세스로 구동되고 containerd, dhcpcd, getty가 구동된다. 딱 봐도 초초경량 리눅스 시스템이다. linuxkit은 기본적으로 서비스를 containerd를 이용해서 구동한다. 이 옵션을 바꿀 수 있는지는 잘 모르겠다. 물론 초기 프로세스는 yaml 파일로 커스텀할 수 있다. 

 

 linuxkit 서버의 네트워크는 L2 bridge에 연결된다고 한다.  따라서 독자적인 ip를 가질 수 있고 당연하게 tcp 통신도 가능하다. 포트포워딩도 가능할 것인데 그게 옵션으로 지원되는 것인지 직접 설정을 해야하는지는 잘 모르겠다. 서버의 네트워크 설정을 보면 다음과 같다. dhcp에 따라서 ip는 자동할당된다. 192.168.64.x 로 설정되는게 기본 옵션인 걸로 추정된다. 

 아래는 호스트와 tcp 통신을 한 결과다. 매우매우 잘된다..! 

>>> linuxkit server
(ns: getty) linuxkit-3eabe867f240:~# nc -l -p 5000

>>> host server
~ ➤ nc -z 192.168.64.13 5000
Connection to 192.168.64.13 port 5000 [tcp/commplex-main] succeeded!

 

 

더 흥미로운 점이 많겠지만 이만 글을 줄인다. 

 

 

Trouble shooting... 

1. linuxkit -> Virtualization.framework 인증 문제

 아무 준비 없이 이미지를 run 했을 때 다음과 같은 오류가 뜰 것이다. Mac os에선 Virtualization.framework 라는 가상머신 생성 & 관리 API를 제공하는데, max os에서 linuxkit를 돌리면 이걸 Default로 사용한다. 문제는 linuxkit이 Virtualization.framework API를 사용할 수 있도록 코드 서명을 직접 해주어야 한다는 점이다..!

[코드 서명 절차]

  • KeyChain 접근 App을 연 후 우측 상단 메뉴 [키체인 접근] -> [인증서 지원] -> [인증서 생성] Click !
  • 알기 쉽게 이름을 정하고 인증서 유형엔 '코드 서명'을 선택한다. 그리고 생성 ! (이하 인증서 이름 : linuxkit)
  • KeyChain App에서 방금 만든 linuxkit 인증서를 검색하고 더블 클릭을 한다. 창이 나오면 왼쪽에 '신뢰' 드롭다운 메뉴를 누른다. 여기서 '코드 서명' 항목의 옵션을 '항상 신뢰'로 바꿔준다. 
  • 생성된 키체인은 '기본 키체인/로그인' 항목에 있을 것이다. 이걸 시스템 키체인으로 옮겨야 한다. 로그인 영역에 있는 인증서를 Desktop 바깥으로 드래그해서 옮기고 '시스템 키체인/시스템' 항목 안에 다시 드래그해서 넣으면 된다. 
  • 방금 인증서를 복사하는 과정에서 Desktop에 linuxkit 인증서 파일이 생겼을 것이다. 이를 이용해 인증서 정책을 작성한다. 아래의 코드를 똑같이 쓰면 된다.
sudo security add-trust -d -r trustRoot -p basic -p codeSign -k /Library/Keychains/System.keychain ~/Desktop/linuxkit.cer
  • 인증서 등록을 위해 Reboot !
  • 이제 linuxkit 에 자격증명을 더할 것이다. 메모장을 이용해서 자격증명등록 파일을 작성한다. Linuxkit이 mac Virtualization.framework API를 사용할 수 있게하는 자격증명이다. 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.virtualization</key>
    <true/>
</dict>
</plist>
  • 아래의 코드로 자격증명을 등록한다.
codesign --entitlements entitlements.xml -fs linuxkit $(which linuxkit)

## 등록 화인 cmd
codesign -d --entitlements - $(which linuxkit)

그럼 끝..! 만약 이 과정이 번거롭다면 vmware를 깔아서 linuxkit이 vmware로 가상머신을 띄우도록 하면된다. linuxkit run 시 하이퍼바어져 옵션을 지정해 줄 수 있다. 

 

 

 

참조 )

https://superuser.com/questions/1436370/how-to-codesign-gdb-on-os-x-mojave

https://cdmana.com/2021/01/20210128135648669W.html

https://github.com/linuxkit/linuxkit/blob/master/docs/platform-virtualization-framework.md

https://collabnix.com/building-your-own-customised-kernel-with-linuxkit/