Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 715. Windows - WSL 2 환경의 Docker Desktop 네트워크 [링크 복사], [링크+제목 복사],
조회: 8052
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 

(시리즈 글이 7개 있습니다.)
개발 환경 구성: 713. "WSL --debug-shell"로 살펴보는 WSL 2 VM의 리눅스 환경
; https://www.sysnet.pe.kr/2/0/13650

개발 환경 구성: 715. Windows - WSL 2 환경의 Docker Desktop 네트워크
; https://www.sysnet.pe.kr/2/0/13659

Linux: 88. WSL 2 리눅스 배포본 내에서의 pid 네임스페이스 구성
; https://www.sysnet.pe.kr/2/0/13771

Linux: 89. pid 네임스페이스 구성으로 본 WSL 2 배포본의 계층 관계
; https://www.sysnet.pe.kr/2/0/13772

Linux: 90. pid 네임스페이스 구성으로 본 WSL 2 + docker-desktop
; https://www.sysnet.pe.kr/2/0/13773

Linux: 91. Container 환경에서 출력하는 eBPF bpf_get_current_pid_tgid의 pid가 존재하지 않는 이유
; https://www.sysnet.pe.kr/2/0/13774

개발 환경 구성: 729. WSL 2 - Mariner VM 커널 이미지 업데이트 방법
; https://www.sysnet.pe.kr/2/0/13779




Windows - WSL 2 환경의 Docker Desktop 네트워크

지난 글에서 다뤘듯이,

"WSL --debug-shell"로 살펴보는 WSL 2 VM의 리눅스 환경
; https://www.sysnet.pe.kr/2/0/13650

WSL 2 VM에서 네임스페이스를 분리시켜 실행한 "docker-desktop" 컨테이너가 있고, 다시 그것에서 분리해 "LinuxKit" 컨테이너를 실행하고, 다시 분리해 docker 관련 컨테이너들이 실행되는 것입니다.

따라서 실질적인 docker 데몬이 시작한 환경은 "LinuxKit"이고, 그 환경을 조사하고 싶다면, 예전 DockerDesktopVM에 대해서 썼던 바로 그 방식과 유사하게 진입할 수 있습니다.

// Getting a Shell in the Docker for Windows Moby VM
// https://www.bretfisher.com/getting-a-shell-in-the-docker-for-windows-vm/

c:\temp> docker run -it --rm --privileged --pid=host justincormack/nsenter1
~ # ps a | grep docker
   59 root      0:00 /usr/bin/runc run --preserve-fds=3 01-docker
   71 root      0:00 /usr/libexec/docker/docker-init /usr/bin/entrypoint.sh
  143 root      1:05 /usr/local/bin/dockerd --config-file /run/config/docker/daemon.json --containerd /run/containerd/containerd.sock --pidfile /run/desktop/docker.pid --swarm-default-advertise-addr=192.168.65.3 --host-gateway-ip 192.168.65.254
...[생략]...
16183 root      0:00 grep docker




LinuxKit 컨테이너의 네트워크 환경을 살펴볼까요? ^^

우선 그 전에 VM의 네트워크 환경이 있을 것입니다. 해당 VM은 Hyper-V의 "vEthernet (WSL (Hyper-V firewall))" 가상 어댑터로 "vSwitch (WSL (Hyper-V firewall))" 가상 스위치에 연결됩니다. 이후, 그 위에서 생성되는 리눅스 배포본들은 그 환경을 그대로 이어받아 사용하는데요, 그래서 VM의 ifconfig 결과docker-desktop 배포본의 ifconfig 결과는 같습니다.

하지만, LinuxKit 컨테이너 레벨에서는 달라지는데요, 우선, docker는 자신이 사용할 내부 가상 네트워크를 임의로 생성하는 것이 가능합니다. 실졔로 Docker Desktop을 설치하면 기본적으로 3개의 네트워크를 가지는데요,

C:\Windows\System32> docker network ls
NETWORK ID     NAME                       DRIVER    SCOPE
39115851b938   bridge                     bridge    local
29b1107e441f   host                       host      local
1650344b2376   none                       null      local

각각의 네트워크 구성을 "docker network inspect" 명령어로 정리하면 이렇게 나옵니다.

[bridge]
"Driver": "bridge",
"EnableIPv6": false,
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"

[host]
"Driver": "host"
(null)

[none]
"Driver": "null"
(null)

그리고 bridge 네트워크로 연결해 실행한 컨테이너에서 ifconfig 명령어를 수행하면 다음과 같이 나옵니다.

// docker에서 생성한 임의의 컨테이너에서 ifconfig 출력

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ...[생략]...

이와 함께 LinuxKit 컨테이너에서 ifconfig 명령어를 수행하면 이런 결과가 나옵니다.

// LinuxKit 컨테이너에서 실행한 ifconfig 출력 정리

[cni0] inet addr:10.1.0.1  Bcast:10.1.255.255  Mask:255.255.0.0
[docker0] inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
[eth0] inet addr:192.168.65.3  Bcast:192.168.65.255  Mask:255.255.255.0
[lo] inet addr:127.0.0.1  Mask:255.0.0.0
[services1] inet addr:192.168.65.6  Bcast:0.0.0.0  Mask:255.255.255.255

하나씩 볼까요? ^^ 우선 "[cni0]"는 k8s를 함께 설치했을 때 나오는 것입니다.

그다음 "[docker0] inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0" 항목은 낯이 익은 IP 대역인데요, 바로 docker가 기본 구성한 가상 네트워크인 bridge입니다. 다시 말해, Windows Command Shell에서 "docker network create" 명령어를 수행하면 (윈도우가 아닌) LinuxKit 컨테이너 환경 내에서 가상 네트워크를 생성하는 것입니다. (참고로 bridge 네트워크를 추가하면 기본적으로는 172.18.0.1/16, 172.19.0.1/16 등으로 순차 생성됩니다.)

마지막으로 [eth0] 196.168.65.0/24 네트워크가 재미있는데요, 이 구성은 Docker Desktop for Windows의 "Resources" / "Network" 메뉴로 바꿀 수 있습니다. 그러니까, 그것의 기본값이 Docker subnet == "192.168.65.0/24"인 것이고, 해당 네트워크에서 "LinuxKit 컨테이너"의 가상 IP는 "192.168.65.3"이 됩니다.

또한, 위의 환경에서 host.docker.internal, gateway.docker.internal은 ping을 해보면 각각 다음과 같이 나옵니다.

host.docker.internal 192.168.65.254
gateway.docker.internal 192.168.65.1

문서에 따르면, 192.168.65.0/24 네트워크는 (순수) 리눅스 운영체제에서 docker를 호스팅하는 경우에는 만들지 않는다고 합니다. 그런 의미에서, 아마도 192.168.65.0/24는 컨테이너에서 (VM을 건너뛰고) 호스트 네트워크와 연결하기 위한 보조 수단으로써 제공하는 듯합니다. 사실, Docker Desktop은 개발자 친화적으로 만들어진 응용 프로그램이고, 개발자가 주로 머무르는 환경이 (docker를 띄우기 위해 필요한 VM이 아닌) 호스트 운영체제가 되기 때문에 그것과 좀 더 부드럽게 연동하기 위한 네트워크로써 필요했을 것입니다. 실제로 192.168.65.0/24 네트워크는 거의 사용 용도가 없는데요, 제가 찾은 유일한 용도는 docker container 내부에서 "host.docker.internal (192.168.65.254)" 주소가 윈도우 호스트로 연결된다는 점입니다.

// 윈도우 호스트 측에 IIS 서비스를 설치했다면, docker run으로 띄운 컨테이너에서 IIS 80 테스트 가능

C:\temp> docker run -it --rm ubuntil
root@8091c139af60:/# curl host.docker.internal
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
...[생략]...
<body>
<div id="container">
<a href="http://go.microsoft.com/fwlink/?linkid=66138&amp;clcid=0x409"><img src="iisstart.png" alt="IIS" width="960" height="600" /></a>
</div>
</body>

// 위의 "ubuntil" 이미지는 아래의 dockerfile 구성으로 "docker build -t ubuntil ." 명령을 실행해 생성한 이미지라고 가정.
// FROM ubuntu:latest
// RUN apt-get -y update && apt-get -y install net-tools

재미있는 점은, 윈도우의 VM으로 인해 필요하게 된 네트워크이고, host.docker.internal이 윈도우 호스트 측에 매핑된 것인데 그 과정이 필요 없는 리눅스 환경의 docker에서도 해당 DNS를 쓰고 싶다는 요청이 역으로 발생한 듯합니다. 그래서 리눅스의 경우에는 "--add-host=host.docker.internal:host-gateway" 옵션을 적용해 컨테이너를 실행했을 때 host.docker.internal에 대한 이름 풀이가 호스트 측으로 가능해집니다.

혹시 위의 설명 외에 192.168.65.0/24 네트워크에 대한 구체적인 용도를 아시는 분은 덧글 부탁드립니다. ^^




참고로 지난 글에서,

Visual Studio로 개발 시 기본 등록하는 dev tag 이미지로 Docker Desktop k8s에서 실행하는 방법
; https://www.sysnet.pe.kr/2/0/13645

hostPath를 "/run/desktop/mnt/host/c/temp/WebApplication1" 같은 식으로 지정했었는데, 실제로 이 경로는 "LinuxKit 컨테이너"에서 확인할 수 있습니다.

// LinuxKit 컨테이너 내부에서 실행
// docker run -it --rm --privileged --pid=host justincormack/nsenter1

# ls -l /run/desktop/mnt/host
total 0
drwxrwxrwx    1 root     root          4096 Jun 11 23:02 c
drwxrwxrwx    1 root     root          4096 Jun  9 01:52 d
drwxrwxrwt    5 root     root           120 Jun 12 23:26 wsl
drwxrwxrwt    7 root     root           300 Jun 13 15:03 wslg

그런데, 사실 /mnt/host 경로도 존재하긴 합니다. 예상과는 달리 서로 link로 연결되지도 않았는데요,

# ls -l /mnt/host
total 0
drwxrwxrwx    1 root     root          4096 Jun 11 23:02 c
drwxrwxrwx    1 root     root          4096 Jun  9 01:52 d
drwxrwxrwt    5 root     root           120 Jun 12 23:26 wsl
drwxrwxrwt    7 root     root           300 Jun 13 15:03 wslg

반면 권한까지도 완전히 똑같은데, 왜? k8s의 hostPath에는 "/mnt/host"로는 연결이 안 되고 반드시 "/run/desktop"으로만 정상적으로 동작하는 걸까요? (혹시 아시는 분은 덧글 부탁드립니다. ^^)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/2/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 166  167  168  169  170  171  172  173  174  175  176  177  178  179  [180]  ...
NoWriterDateCnt.TitleFile(s)
484정성태3/17/200719480오류 유형: 31. SQL Compact Edition 설치 후 오류
483정성태3/17/200740884오류 유형: 30. x64 환경: .NET + COM 프로젝트 실행 시 오류 - 80040154 [2]
482정성태3/17/200730351Team Foundation Server: 17. 팀 프로젝트 접속 및 사용
481정성태3/17/200724281Team Foundation Server: 16. 팀 프로젝트 읽기 전용 사용자 등록
480정성태3/14/200722400.NET Framework: 86. GC(Garbage Collector)의 변화
479정성태3/14/200726396개발 환경 구성: 25. D820 - ReadyBoost 구동
478정성태3/14/200725734개발 환경 구성: 24. D820 고주파음 문제
477정성태3/14/200735029개발 환경 구성: 23. 비스타 x64 버전에서 서명되지 않은 드라이버 사용 [4]
476정성태3/9/200730415개발 환경 구성: 22. D820 노트북 - 설치 및 BitLocker 구성 [1]
475정성태3/6/200724832.NET Framework: 85. 공용 프로퍼티 자동 생성
474정성태3/5/200723017.NET Framework: 84. Lambda 표현식 응용 사례 [1]
473정성태3/4/200730133디버깅 기술: 14. TFS 오류 추적(TF53010, TF14105)
472정성태3/3/200729238디버깅 기술: 13. 예외 발생 시 Minidump 생성 - WinDBG [3]파일 다운로드1
471정성태3/1/200718427디버깅 기술: 12. Managed Method에 Break Point 걸기
469정성태2/28/200729977디버깅 기술: 11. (Managed) Main Method에 Break Point 걸기 [3]파일 다운로드1
470정성태3/1/200721351    답변글 디버깅 기술: 11.1. (Managed) Main Method에 Break Point 걸기 - 내용 보강
468정성태2/25/200731198COM 개체 관련: 20. 탭 브라우저의 윈도우 핸들 구하기 [3]
466정성태2/22/200722913Windows: 23. 롱혼 서버 코어 버전 [2]
465정성태2/21/200721896오류 유형: 29. TFS 관련 스케줄 작업 실패
464정성태2/25/200723061오류 유형: 28. TF10217, TF53010, TF14105 오류
463정성태2/21/200716101Team Foundation Server: 15. 포탈 사이트의 보고서 주소를 도메인 명으로 적용
462정성태2/13/200743376.NET Framework: 83. 라이브러리에 다국어 리소스 추가 방법 [4]파일 다운로드1
461정성태2/13/200721090오류 유형: 27. DLinq 예제 오류 : error: 26 - Error Locating Server/Instance Specified
460정성태2/13/200721306.NET Framework: 82. Orcas 1월 CTP에서 Linq 소스 컴파일 방법
459정성태2/17/200725323오류 유형: 26. "Automatic Updates" 서비스 CPU 100% 점유 현상 - 두 번째 이야기 [3]
458정성태2/12/200721783.NET Framework: 81. LINQ 개발 환경 설정 [1]
... 166  167  168  169  170  171  172  173  174  175  176  177  178  179  [180]  ...