WSL2 관련 정리

WSL2 관련하여 간단히 정리해 보았다.

참고 페이지

WSL2 소개

Microsoft는 Windows10 2015년부터 Pro 이상 버전에서 WSL(Windows Subsystem for Linux)을 지원하기 시작하였다.
그런데 WSL1에서는 Linux 커널을 사용하는 것이 아니라, 에뮬레이터 아키텍처 기반으로 리눅스 바이너리를 구동하는 호환 레이어를 만들고 이를 Windows 커널 위에서 동작시켰다. 따라서 속도도 느렸고 공식적으로 32bit가 완벽히 지원되지 않았고 (특히 회사에서 사용하는 cross 툴체인에 32bit 전용이 있었음), 동작하지 않는 서비스가 많은 등 제약과 불편이 많았었다.

이후 Windows 2004 버전부터는 WSL2를 지원하였다. WSL2는 Hyper-V 기반의 가상화 기술을 이용하여 실제로 Linux 커널을 직접 탑재하여 온전한 시스템 콜 호환성을 완성하였고 파일 I/O도 빨라지는 등 많은 발전이 있었다. (사용한 Linux 커널의 소소는 공개되어 있고, 사용자가 이 커널을 수정/빌드하여 사용할 수도 있음)
한편 Pro 이상의 버전이 필요했던 WSL1과는 달리 이제는 Home 버전에서도 지원였고, 또한 2020 후반에는 1903, 1909 버전에 대해서도 backport 작업을 해서 이 버전들에서도 WSL2를 지원하게 되었다. (마이크로소프트가 WSL을 미는 모양새. Microsoft 🧡🐧)

나는 WSL이 지원된 이후로 Linux에서의 테스트가 필요한 경우나 (기존 서버에 설치하여 테스트하기 전에) 또는 나만의 환경 구축이 필요한 경우에 WSL이 VirtualBox에 비해서 빠르고 편리해서 WSL을 많이 이용한다. (사실 이 블로그도 외부 dependency가 있는 패키지가 많은 관계로 처음부터 WSL 환경에서 local 웹서버 띄워서 결과를 확인한 후에 Github에 올리고 있음)

WSL 사전 설치 준비

  1. Powershell 관리자 모드에서 아래와 같이 실행하여 WSL과 “가상 머신 플랫폼” 옵션 기능을 사용하도록 설정한다.
    PS C:\> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    PS C:\> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    

    이후 시스템을 재부팅한다.

  2. Linux 커널 업데이트 패키지 페이지에서 WSL2 Linux 커널 업데이트 패키지를 다운로드한 후, 설치한다. 이로써 사전 설치 준비는 완료되었다.

WSL 설치

  1. 새로운 배포판을 설치시에 디폴트로 WSL2를 사용하도록 설정하려면 아래와 같이 하면 된다. (굳이 WSL1을 사용할 필요가 없으므로 무조건 설정해 놓는 것이 편함)
    C:\>wsl --set-default-version 2
    
  2. 이제 Microsoft Store에서 WSL을 검색해서 원하는 배포판을 설치한다.
  3. 현재 설치된 Linux 배포판은 아래와 같이 확인할 수 있다. (-l은 배포판 list, -v 옵션은 자세한 정보를 표시되게 함)
    C:\>wsl -l -v
    
  4. 만약에 기존 WSL1으로 Linux 배포판을 설치하였으면, 아래와 같이 Linux 배포판 이미지를 WSL을 WSL2로 변환시킬 수 있다. (맨 끝의 2는 WSL 버전 2를 나타냄)
    C:\>wsl --set-version <배포판 이름> 2
    

    결과로 “변환이 완료되었습니다” 라는 메시지가 출력되면, 정상적으로 전환이 완료된 것이다.

WSL 실행

WSL 설치가 끝나면 WSL 아이콘이 생성되고 이것을 실행하면 터미널이 뜨고 WSL에 로그인되고, 사용자 home 디렉토리로 이동한다.
또는 Windows console에서 아래와 같이 wsl.exe를 실행시켜도 된다. (단, 배포판이 여러 개 설치된 경우에는 -d <배포판 이름> 옵션을 추가해야 함)

C:\>wsl

그런데 이 방법은 현재 경로가 /mnt/c 경로로 되고, home 디렉토리로 이동하려면 별도의 cd 명령을 입력해야 하므로, 약간 불편하다. 그래서 나는 아래와 같이 실행하는데, 이렇게 하면 home 디렉토리로 바로 이동한다. (단, 배포판이 여러 개 설치된 경우에는 -d <배포판 이름> 옵션을 추가해야 함)

C:\>wsl ~

나는 보통 Windows console 보다는 좀 더 많은 기능을 제공하는 Windows Terminal이나 MobaXterm을 사용하는데, 이것들은 자동으로 WSL을 인식하고 그외 많은 기능을 제공한다. 참고로 아래는 Windows Terminal의 내 profile 설정 예이다.

{
    "acrylicOpacity" : 0.5,
    "closeOnExit" : "graceful",
    "colorScheme" : "One Half Dark",
    "commandline" : "wsl.exe ~ -d Ubuntu-18.04",
    "cursorColor" : "#FFFF00",
    "cursorShape" : "vintage",
    "fontFace" : "D2Coding",
    "fontSize" : 12,
    "guid": "{c6eaf9f4-32a7-5fdc-b5cf-066e8a4b1e40}",
    "historySize" : 9001,
    "icon" : "ms-appdata:///roaming/ubuntu_32px.png",
    "name": "WSL 18.04",
    "padding" : "5, 5, 5, 5",
    "snapOnInput" : true,
    "source": "Windows.Terminal.Wsl",
    "useAcrylic" : true
},

WSL 종료

보통은 실행 중인 Linux를 별도로 종료시킬 필요는 없겠지만, 필요에 따라 아래와 같이 종료시킬 수 있다.

C:\>wsl --shutdown

위와 같이 하면 모든 배포판의 실행 중인 Linux가 종료되고, 아래와 같이 하면 해당 배포판만 종료된다.

C:\>wsl -d <배포판 이름> --shutdown

이제 wsl -l -v 명령으로 확인해 보면, stopped 되었음을 확인할 수 있다. 다시 wsl을 실행시키면 해당 배포판이 다시 실행된다.

WSL 배포판 삭제

WSL 배포판 삭제는 일반적인 앱 제거와 마찬가지로 Windows 설정 메뉴의 -> 앱 및 기능에서 (즉, 프로그램 추가/제거) 하면 된다.
단순히 WSL list에서만 나오지 않게 하려면 아래와 같은 커맨드로 할 수 있다.

C:\>wsl --unregister <배포판 이름>

WSL 배포판 업데이트

WSL 배포판은 디폴트로 LTS 버전을 검사해서 업데이트하게 되어 있는데, LTS 버전만이 아닌 normal 버전으로도 업데이트 가능하게 하려면 아래와 같이 하면 된다.

  1. /etc/update-manager/release-upgrades 파일에서 Prompt 값을 디폴트 lts에서 아래와 같이 수정한다.
    Prompt=normal
    
  2. 이후 아래와 같이 실행하면 normal 버전으로도 업데이트할 수 있다.
    $ sudo apt-get update
    $ sudo apt-get dist-upgrade
    $ sudo do-release-upgrade
    
  3. 업데이트가 끝나면 아래와 같이 확인해 볼 수 있다.
    $ lsb_release -a
    

WSL Kernel 수정하기

보통은 Kernel을 수정할 일이 없긴 하지만, Kernel config를 수정하거나 소스를 수정해야 하는 경우에는 Kernel 소스를 다운받아서 직접 빌드할 수 있다. (나 같은 경우에는 nandsim을 사용하기 위하여 configuration을 수정한 후 재빌드해서 사용하였다. WSL1에서는 Kernel 수정이 불가능한 일이었는데, WSL2에서는 직접 Kernel을 수정 및 빌드할 수 있으니 너무 좋다. 😋)
아래와 같이 하면 된다.

  1. WSL2-Linux-Kernel 페이지에서 사용하려는 버전의 Kernel 소스를 다운받아서 압축을 풀거나, 아래와 같이 Git으로 clone 받고 해당 디렉토리로 이동한다.
    $ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
    $ cd WSL2-Linux-Kernel/
    
  2. 아래와 같이 빌드에 필요한 패키지를 설치한다.
    $ sudo apt install build-essential libncurses-dev flex bison libelf-dev libssl-dev
    
  3. 소스 디렉토리에서 아래와 같이 config 파일을 복사한 후, menu config를 실행하여 configuration 한 후 저장한다.
    $ cp Microsoft/config-wsl .config
    $ make menuconfig
    

    이후 아래와 같이 빌드한다.

    $ make -j4
    

    참고로 위 방법 대신에 아래와 같이 .config 파일을 이용하지 않고, Microsoft/config-wsl 파일을 직접 이용할 수도 있다.

    $ make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl
    $ make -j4 KCONFIG_CONFIG=Microsoft/config-wsl
    
  4. 결과로 arch/x86/boot/bzImage 파일이 생성되는데, 이 파일을 Windows 드라이브로 복사한 후, 아래와 같이 WSL을 종료시킨다.
    C:\>wsl --shutdown
    
  5. 복사한 bzImage 파일을 C:\Windows\System32\lxss\tools\ 디렉토리에 있는 kernel 파일로 overwrite 한다.

    참고로 %HOMEPATH%\.wslconfig 파일을 아래 예와 같이 작성하여 Kernel 경로를 변경할 수 있는데, 이 경우에는 해당 디렉토리로 복사하면 된다.

    [wsl2]
    kernel=C:\\Users\\myCustomKernel # Kernel image
    
  6. 이제 다시 WSL을 시작한 후, uname 명령으로 빌드된 Kernel이 적용되었는지 확인해 본다.

기타 팁

  • Visual Studio Code
    VS Code로 WSL에 있는 소스를 개발하는 경우에는 Remote - WSL extension을 설치하여 사용하는 것이 편하다.
  • WSL2 전역 설정
    설정 파일은 %HOMEPATH%\.wslconfig 파일로 아래 예와 같이 Kernel 이미지, memory, processors 등을 설정할 수 있다.
    [wsl2]
    kernel=C:\\Windows\\System32\\lxss\\tools\\kernel # Kernel image
    memory=4GB # Limits VM memory in WSL 2 to 4 GB
    processors=2 # Makes the WSL 2 VM use two virtual processors
    
  • WSL2 startup 시 실행시키고 싶은 명령어 추가하기
    Linux 배포판의 /etc/wsl.conf 파일에서 아래 예와 같이 추가하면 된다.
    [boot]
    command="echo your command"
    
  • Windows에서 WSL로 SSH 접속하기 (옵션 사항)
    WSL로 직접 접속하면 되므로, 굳이 SSH로 접속할 필요가 없기는 하나, WSL2에서 SSH 서버를 재설치한 후, WSL2 내의 리눅스 IP로 접속할 수 있다.
    아래와 같이 SSH server 패키지를 재설치한다.
    $ sudo apt-get purge openssh-server
    $ sudo apt-get install openssh-server
    

    이후, /etc/ssh/sshd_config 파일에서 아래 주석을 해제한다.

    PermitRootLogin prohibit-password
    

    아래와 같이 ssh 서버를 재시작 시킨다.

    $ sudo service ssh --full-restart
    

    이제 아래와 같이 Windows에서 Linux eth0 IP 주소로 ssh 접속할 수 있다.

    C:\>ssh -l <user_id> <WSL eth0 IP>
    
  • PATH에서 Windows 경로 제거하기
    설치 후에 Linux에서 PATH를 확인해 보면, Linux PATH 이후에 자신의 Windows PATH가 뒤에 덧붙여져 있음을 확인할 수 있다. 만약 Windows PATH가 붙는 것이 싫으면, Linux 배포판에서 /etc/wsl.conf 파일을 아래와 같이 작성한 후, 다시 실행하면 된다.
    [interop]
    appendWindowsPath = false
    

    이 경우 Windows PATH가 모두 제거되었으므로, Windows의 탐색기나 VS Code 실행을 위해서는 ~/.bashrc 파일에서 아래 예와 같이 alias와 PATH를 추가하는 것이 편하다.

    alias code='/mnt/c/Program\ Files/Microsoft\ VS\ Code/bin/code'
    export PATH=$PATH:"/mnt/c/Windows"
    
  • 네트워크 드라이브로 연결하기
    탐색기에서 \\wsl$를 입력하면 설치된 배포판들이 디렉토리로 나오는데, 연결하려는 배포판을 선택한 후, 마우스 우클릭하여 “네트워크 드라이브 연결”을 실행하면 된다. (예: \wsl$\Ubuntu-18.04)
  • USB 저장 장치 마운트
    • 아래 예와 같이 마운트시킬 수 있다. (예로 E 드라이브를 /mnt/e 경로에 마운트)
      $ sudo mkdir /mnt/e
      $ sudo mount -t drvfs E: /mnt/e
      
    • 아래와 같이 언마운트시킬 수 있다. (예로 /mnt/e 경로를 언마운트)
      $ sudo umount /mnt/e
      
  • 32bit 지원하기
    WSL1에서는 공식적으로 지원되지 않아서 쉽지 않았으나, WSL2에서는 일반 Linux 배포판과 마찬가지로 아래 예와 같이 쉽게 32bit 지원을 할 수 있다. (이제 32bit cross 툴체인도 잘 된다. 😋)
    $ sudo dpkg --add-architecture i386
    $ sudo apt update
    $ sudo apt install libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386
    
  • GUI 프로그램 실행하기
    • X server를 이용하면 되는데, Windows에서 사용 가능한 X server에는 VcXSrv, Xming 등이 있다. (참고로 나는 WSL도 지원하고 자체적으로 X server를 내장하고 있는 데다가 기타 기능도 많은 MobaXterm 프로그램을 애용하고 있음)
    • 또는 WSL2를 지원하는 GWSL 앱도 편하다. 이것은 Microsoft store에서 설치할 수 있는데, 최초 실행시 방화벽에 허용 추가를 해 주고, GWSL 메뉴 -> Dashboard에서 WSL 배포판 선택 및 auto export display를 선택해 주면 된다. (참고로 Linux에서 DISPLAY 환경 변수를 확인해 보면 자동으로 세팅되어 있음을 확인할 수 있음)
    • 또는 Windows의 원격 데스크톱을 이용할 수 있는데, Linux에서 아래와 같이 설치 및 실행한다.
      $ sudo apt install xfce4
      $ sudo apt install xrdp
      $ sudo systemctl enable xrdp
      $ echo xfce4-session > ~/.xsession
      $ sudo service xrdp restart
      

      이후 Windows에서 “원격 데스크톱 연결”을 실행해서 Linux의 eth0 IP 주소로 연결하면 된다.

    • 하지만 아무래도 WSL에서 자체적으로 지원하지 않아서 불편한 점이 있다. 원래 2020년에 GUI 및 GPU를 지원하기로 예정되어 있었는데, GPU는 공식 지원되었으나 아직 GUI는 공식 지원되지 않고 있다. 2021년에 GUI도 공식 지원되면 이 부분도 훨씬 편해질 것이다.
  • Docker 사용하기
    WSL1은 Linux 커널을 사용한 것이 아니었으므로, docker 데몬을 직접 지원하지 않고 Windows의 docker 데몬을 WSL에서 호출하였었다. 이로 인해 Windows에서도 별도의 설치가 필요하였으나, WSL2에서는 Linux 자체에만 docker를 설치해서 동작시킬 수 있다.
    물론 WSL2에서도 여전히 Docker Desktop for Windows를 이용할 수 있으나, Windows에서 docker를 구동시키지 않는 환경이라면, 아래처럼 Linux에서만 docker를 설치하는 방법이 훨씬 편리하다.
    1. WSL2에 로그인하여 아래와 같이 설치 및 세팅을 한다.
      $ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
      $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
      $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
      $ sudo apt-get update
      $ sudo apt-get install docker-ce
      
    2. 설치가 완료 되었으면, 아래와 같이 docker service를 실행시킨다.
      $ sudo service docker start
      
    3. 아래와 같이 실행하면 docker 명령시 sudo 명령을 생략할 수 있으므로 편리하다.
      $ sudo usermod -aG docker $(whoami)
      
    4. 부팅시 docker 서비스를 자동으로 start 시키려면 /etc/sudoers 파일에 아래와 같이 추가한다. (즉, service 명령어를 root 권한으로 암호없이 실행시킴)
      %sudo ALL=(ALL:ALL) NOPASSWD: /usr/sbin/service
      

      이후 ~/.bashrc 파일에 아래와 같이 추가한다.

      service docker status > /dev/null || sudo service docker start > /dev/null
      

      참고로 만약에 /etc/sudoers 파일이 잘못되면 이후 sudo 명령을 사용하지 못하게 되는데, 이 경우에는 C:\>wsl -u root 명령으로 root로 로그인하여 /etc/sudoers 파일을 올바르게 수정하면 된다.

  • NFS 서버 설치
    이 방법은 알아내기가 쉽지 않았다. 기본적으로 WSL2의 네트워크는 NAT를 사용하기 때문에 172 대역의 내부 IP를 동적으로 할당받고, 따라서 Windows에서는 잘 접근이 되지만, 외부에서는 접근이 되지 않는다. 대안으로 NAT 대신에 아래와 같이 bridge 모드를 이용할 수 있다.
    1. WSL2의 네트워크는 Hyper-V 가상화 기반으로 동작하므로, Hyper-V 관리자를 관리자 권한으로 실행시킨 후 (사전에 Windows 기능 켜기/끄기에서 Hyper-V 항목이 설치되어 있어야 함), “가상 스위치 관리자” 항목을 클릭한다.
    2. 가상 스위치 항목 중에서 “WSL” 항목을 선택한 후, 연결 형식을 “외부 네트워크“로 변경한다. 제대로 설정되었으면 “제어판 -> 네트워크 및 인터넷 -> 네트워크 연결” 메뉴에서 “vEthernet (WSL)” 항목을 확인해 보면 bridge 모드로 연결되었음을 확인할 수 있다.
    3. 변경 내용이 적용되었으면 WSL을 새로 띄운 후, ifconfig로 확인해 본다. IP를 올바르게 할당받지 못하였으면, 아래와 같이 해서 새로 받아본다.
      $ sudo ip addr flush dev eth0
      $ sudo dhclient eth0
      

      결과로 eth0 이더넷 장치가 IP를 192.168.0.XXX과 같은 주소로 할당받는다.

    4. 이후 아래와 같이 NFS 서버를 실행시킨다.
      $ sudo service rpcbind start
      $ sudo /etc/init.d/nfs-kernel-server start
      
    5. 이제 NFS 클라이언트 장치에서 eth0 IP 주소로 NFS 마운트해 본다. 만약 마운트가 잘 안되면 (예: “Connection refused” 에러), Linux의 /etc/hosts 파일에서 필요없는 부분을 제거해 본다.

GUI app 지원

2021년 4월에 드디어 Windows 10 Insiders preview 빌드 21364에 WSLg 이름으로 포함되었다. 자세한 내용은 GitHub WSLg를 참조하자.
2021년 10월 5일에 발표된 Windows 11에는 WSLg가 기본으로 포함되어 있다. 실제로 해 보니, 속도도 아주 빠르게 바로 GUI app이 실행된다. 🥂

참고로 Windows10인 경우에는 WSL2를 설치하더라도 WSLg를 설치할 수는 없는데, 따라서 현재로써는 Windows10인 경우에는 (Windows11의 WSLg보다는 복잡하지만) GWSL을 이용하는 것이 가장 간단히 GUI app을 실행하는 방법인 것 같다.

🆗 Windows10에서도 드디어 22H2 버전부터는 WSLg를 지원하게 되었다. 😊
Windows10 사용자는 아래와 같이 WSL을 업데이트시키면 된다.

C:\>wsl --update

이후 아래와 같이 WSL 버전을 확인해 보면 WSLg 버전 항목을 확인할 수 있다.

C:\>wsl --version
...
WSLg 버전: 1.0.47
...

카테고리:

업데이트: