글 목록

DevOps

Windows에서 Linux 개발 환경 구축하기: WSL 제대로 이해하기

Windows를 떠나지 않고 Linux 개발 환경을 사용할 수 있게 해주는 WSL의 구조와 WSL 1·2의 차이, 설치 방법부터 실제 개발 환경 구성까지 정리합니다.

Windows에서 Linux를 사용한다는 것

Windows를 메인 운영체제로 사용하면서 개발하다 보면 한 번쯤 이런 상황을 만나게 됩니다.

개발에 사용하는 IDE나 업무용 프로그램은 Windows에 있는데, 실제 애플리케이션이 실행되는 서버는 Linux인 경우입니다.

물론 VirtualBox나 VMware 같은 Virtual Machine을 설치할 수도 있고, 별도의 Linux 머신을 사용할 수도 있습니다. 하지만 단순히 Linux CLI와 개발 도구가 필요한 상황이라면 가상 머신 전체를 관리하는 것은 다소 부담스럽습니다.

이 문제를 꽤 자연스럽게 해결해 주는 기능이 WSL(Windows Subsystem for Linux) 입니다.

WSL을 사용하면 Windows 환경을 유지하면서 Ubuntu와 같은 Linux distribution을 설치하고 Bash, SSH, Git, Python, Node.js 등의 Linux 도구를 사용할 수 있습니다.

$ uname -a
Linux ...

$ cat /etc/os-release
NAME="Ubuntu"
...

Windows Terminal 하나를 열었을 뿐인데 그 안에서는 Linux 환경이 동작하는 셈입니다.

하지만 WSL을 단순히 "Windows에서 Linux 명령어를 실행해 주는 프로그램"이라고 이해하면 조금 부족합니다.

특히 현재 일반적으로 사용하는 WSL 2는 실제 Linux kernel을 기반으로 동작합니다.

WSL 1과 WSL 2는 무엇이 다를까?

WSL을 이해할 때 가장 먼저 구분해야 하는 것이 WSL 1과 WSL 2입니다.

두 버전 모두 Windows에서 Linux 환경을 제공한다는 목적은 같지만 내부 구조에는 상당한 차이가 있습니다.

WSL 1

WSL 1은 Linux system call을 Windows가 이해할 수 있는 형태로 변환하는 방식으로 동작합니다.

대략적인 흐름을 단순화하면 다음과 같습니다.

Linux Application
       ↓
Linux System Call
       ↓
WSL Translation Layer
       ↓
Windows Kernel

별도의 Linux kernel을 실행하는 것이 아니라 Windows 위에서 Linux system call을 처리하는 구조입니다.

덕분에 VM을 직접 실행하는 것과 비교하면 가볍다는 장점이 있었지만, Linux kernel의 모든 동작을 완벽하게 구현하기 어렵다는 한계도 있었습니다.

WSL 2

WSL 2에서는 구조가 크게 바뀌었습니다.

Windows
   │
   └── Lightweight Virtual Machine
            │
            └── Linux Kernel
                   │
                   └── Linux Distribution
                         ├── Ubuntu
                         ├── Debian
                         └── ...

WSL 2는 virtualization 기술을 이용한 경량 VM 내부에서 실제 Linux kernel을 실행합니다.

따라서 Linux system call compatibility가 크게 향상되었고, Docker처럼 Linux kernel 기능에 의존하는 도구도 훨씬 자연스럽게 사용할 수 있게 되었습니다.

새로운 개발 환경을 구성한다면 특별한 이유가 없는 한 WSL 2를 선택하는 편이 좋습니다.

WSL 설치하기

최근 Windows에서는 관리자 권한 PowerShell 또는 Windows Terminal에서 다음 명령 하나로 WSL 설치를 시작할 수 있습니다.

wsl --install

설치가 끝난 뒤 시스템을 재부팅하고 Linux distribution 설정을 완료하면 됩니다.

현재 설치된 distribution과 WSL 버전은 다음 명령으로 확인할 수 있습니다.

wsl --list --verbose

또는 짧게:

wsl -l -v

예를 들어 다음과 같은 결과를 확인할 수 있습니다.

  NAME      STATE           VERSION
* Ubuntu    Running         2

VERSION이 2라면 해당 distribution이 WSL 2 환경에서 실행되고 있다는 의미입니다.

기본 WSL 버전을 2로 지정하려면 다음 명령을 사용할 수 있습니다.

wsl --set-default-version 2

원하는 Linux distribution 설치하기

WSL이 반드시 Ubuntu만 지원하는 것은 아닙니다.

설치 가능한 distribution은 다음 명령으로 확인할 수 있습니다.

wsl --list --online

원하는 distribution을 찾았다면 -d 옵션으로 지정해 설치할 수 있습니다.

wsl --install -d Ubuntu

설치된 Linux 환경으로 바로 들어가려면:

wsl

특정 distribution을 실행하려면:

wsl -d Ubuntu

이렇게 Windows Terminal에서 Linux shell로 바로 진입할 수 있습니다.

Windows 파일은 어디에서 보일까?

처음 WSL을 사용하면 가장 헷갈리는 부분 중 하나가 파일 시스템입니다.

WSL 안에서는 Windows 드라이브가 /mnt 아래에 mount됩니다.

Windows의 다음 경로가 있다고 가정해 보겠습니다.

C:\Users\username\Documents

WSL에서는 다음처럼 접근할 수 있습니다.

cd /mnt/c/Users/username/Documents

즉,

Windows
C:\Users\username

        ↕️

WSL
/mnt/c/Users/username

와 같은 관계입니다.

반대로 Windows에서도 WSL의 Linux 파일 시스템에 접근할 수 있습니다.

File Explorer 주소창에서 다음 경로를 사용할 수 있습니다.

\\wsl$

덕분에 Windows와 Linux 사이에서 파일을 별도로 복사하지 않아도 양쪽 환경에서 접근할 수 있습니다.

그런데 프로젝트는 어디에 두어야 할까?

여기서 중요한 점이 하나 있습니다.

WSL에서 Linux 기반 개발 도구를 주로 사용한다면 프로젝트를 /mnt/c/...가 아니라 WSL의 Linux filesystem 안에 두는 것이 일반적으로 권장됩니다.

예를 들어:

mkdir -p ~/workspace
cd ~/workspace

git clone https://github.com/example/project.git

프로젝트 구조는 다음과 같이 가져갈 수 있습니다.

/home/user/
└── workspace/
    ├── backend/
    ├── frontend/
    └── infrastructure/

Windows 파일 시스템과 Linux 파일 시스템을 넘나드는 파일 I/O에는 추가 비용이 발생할 수 있기 때문입니다.

특히 node_modules처럼 작은 파일을 대량으로 읽고 쓰는 프로젝트에서는 파일 시스템 위치에 따라 개발 경험의 차이가 커질 수 있습니다.

따라서 간단하게 기준을 잡으면 다음과 같습니다.

Linux 도구로 개발할 프로젝트라면 Linux filesystem에 저장한다.

이 원칙만 기억해도 WSL 환경에서 발생하는 상당수의 성능 문제를 피할 수 있습니다.

VS Code와 WSL 연결하기

WSL의 장점이 크게 느껴지는 부분이 IDE와의 연동입니다.

예를 들어 WSL 안에서 프로젝트 디렉터리로 이동한 뒤 다음과 같이 실행할 수 있습니다.

cd ~/workspace/my-project
code .

그러면 VS Code의 UI 자체는 Windows에서 실행하면서 터미널, extension, runtime 등 개발에 필요한 작업은 WSL 환경을 기준으로 구성할 수 있습니다.

개념적으로는 다음과 같습니다.

Windows
└── VS Code UI
       │
       └── WSL Integration
               │
               └── Linux Environment
                    ├── source code
                    ├── git
                    ├── node
                    ├── python
                    └── shell

이 구조가 생각보다 편합니다.

브라우저나 Slack 같은 데스크톱 프로그램은 Windows에서 사용하고, 실제 개발 도구는 Linux 환경에서 실행할 수 있기 때문입니다.

WSL에서 개발 환경 구성하기

WSL 안으로 들어왔다면 이후 과정은 일반적인 Linux 머신을 설정하는 것과 크게 다르지 않습니다.

먼저 package 정보를 업데이트합니다.

sudo apt update
sudo apt upgrade

Git도 설치할 수 있습니다.

sudo apt install git

확인해 보면:

git --version

SSH key 역시 Linux 환경에서 별도로 생성할 수 있습니다.

ssh-keygen -t ed25519

Node.js, Python, Java 등의 runtime도 Linux 환경에 맞춰 설치하면 됩니다.

여기서 중요한 것은 Windows에 설치된 runtime과 WSL에 설치된 runtime을 별개의 환경으로 생각하는 것입니다.

예를 들어 Windows PowerShell에서:

node --version

을 실행한 결과와 WSL에서:

node --version

을 실행한 결과는 서로 다를 수 있습니다.

둘은 같은 컴퓨터에서 실행되지만 동일한 개발 환경은 아닙니다.

WSL과 Docker

WSL 2가 개발자들에게 특히 유용한 이유 중 하나는 container 개발 환경입니다.

Docker Desktop은 WSL 2 backend와 통합해 Windows에서도 Linux container 기반의 개발 환경을 구성할 수 있습니다.

전체적인 구조를 단순화하면 다음과 같습니다.

Windows
   │
   ├── VS Code
   ├── Browser
   └── Docker Desktop
          │
          └── WSL 2
                │
                └── Linux Kernel
                       │
                       ├── Container A
                       ├── Container B
                       └── Container C

Windows에서 코드를 작성하면서 Linux container를 기반으로 애플리케이션을 실행할 수 있다는 의미입니다.

개발 환경과 production 환경이 모두 Linux라면 OS 차이에서 발생하는 문제도 줄이는 데 도움이 됩니다.

WSL에서 자주 사용하는 명령어

WSL을 관리할 때는 Linux shell뿐 아니라 Windows 쪽의 wsl 명령어도 알아두면 편합니다.

설치된 distribution 확인:

wsl --list --verbose

실행 중인 WSL 종료:

wsl --shutdown

특정 distribution 종료:

wsl --terminate Ubuntu

WSL 상태 확인:

wsl --status

WSL 업데이트:

wsl --update

설치 가능한 distribution 확인:

wsl --list --online

특정 distribution 실행:

wsl -d Ubuntu

문제가 발생했을 때 의외로 자주 사용하게 되는 명령은 다음 두 개입니다.

wsl --shutdown
wsl --update

WSL 전체를 종료한 뒤 다시 실행하는 것만으로 해결되는 경우도 있기 때문입니다.

WSL을 사용하면서 주의할 점

WSL은 편리하지만 Windows와 Linux의 경계를 완전히 없애 주는 기술은 아닙니다.

오히려 두 환경이 연결되어 있기 때문에 어디에서 무엇을 실행하고 있는지 명확하게 이해하는 것이 중요합니다.

예를 들어 다음 항목을 확인하는 습관이 도움이 됩니다.

which node
which python
which git

예상하지 못한 runtime이나 executable이 사용되고 있다면 다음 명령도 확인해 볼 수 있습니다.

echo $PATH

특히 Windows용 Node.js와 WSL용 Node.js를 동시에 설치하거나 여러 package manager와 version manager를 섞어 사용하면 PATH 문제를 만나기 쉽습니다.

그래서 WSL을 메인 개발 환경으로 사용할 계획이라면 개발에 필요한 runtime과 CLI도 가능하면 WSL 내부에서 일관되게 관리하는 편이 좋습니다.

WSL은 VM일까, 아닐까?

WSL을 설명하다 보면 자주 나오는 질문입니다.

WSL 1만 생각하면 일반적인 VM과 상당히 다른 구조였지만, WSL 2는 virtualization을 사용하고 실제 Linux kernel을 실행합니다.

그렇다고 우리가 흔히 사용하는 VirtualBox의 Ubuntu VM과 완전히 같은 경험을 제공하는 것도 아닙니다.

WSL 2는 Windows와의 긴밀한 integration을 전제로 설계되어 있습니다.

사용자가 직접 VM을 생성하고 CPU, 메모리, 가상 디스크, 네트워크를 하나씩 설정하는 대신 이러한 부분의 상당수를 WSL이 관리합니다.

그래서 개발자의 관점에서는 이렇게 이해하는 것이 가장 편합니다.

WSL 2는 Windows 안에서 Linux 개발 환경을 최대한 자연스럽게 사용할 수 있도록 관리되는 경량 가상화 환경이다.

실제로 WSL을 사용해 보니 중요한 것은

WSL을 처음 접하면 설치 방법이나 명령어에 집중하게 됩니다.

하지만 어느 정도 사용하고 나면 중요한 것은 명령어 자체가 아니라 Windows와 Linux 사이의 경계를 이해하는 것이라는 생각이 듭니다.

지금 실행하고 있는 node가 Windows의 Node.js인지 WSL의 Node.js인지, 프로젝트 파일이 NTFS 쪽에 있는지 Linux filesystem 쪽에 있는지, Docker container가 어느 환경과 연결되어 있는지를 알고 있으면 대부분의 문제를 훨씬 쉽게 추적할 수 있습니다.

Windows
│
├── Desktop Applications
│   ├── Browser
│   ├── Windows Terminal
│   └── VS Code
│
└── WSL 2
    │
    └── Linux
        ├── Git
        ├── Node.js
        ├── Python
        ├── SSH
        └── Project Files

WSL의 목적은 Windows를 Linux처럼 만드는 것이 아닙니다.

Windows의 장점을 그대로 사용하면서 개발에 필요한 Linux 환경을 가까이에 두는 것에 가깝습니다.

그래서 Windows를 업무 환경으로 사용하면서 Linux 서버, Docker, Kubernetes, Node.js 또는 Python 기반 서비스를 개발하고 있다면 WSL 2는 꽤 실용적인 선택지가 됩니다.

처음에는 Windows 안에 Linux가 있다는 구조가 조금 낯설 수 있습니다. 하지만 파일 시스템과 실행 환경의 경계만 제대로 이해하면, Windows와 Linux 중 하나를 선택하는 대신 두 환경의 장점을 함께 활용할 수 있습니다.

Tags

태그

WSLWSL2WindowsLinuxUbuntu