Docker 와 User Space

장현진·2025년 4월 6일

도커 컨테이너에서 호스트 OS의 hosts 파일을 읽지 못한 문제 해결

해외 서버에서 국내서버의 도메인을 컨테이너에서 호출시 해외 DNS에 해당 도메인이 등록되지 않아 통신할수없었던 이슈를 해결하면서 경험한 내용 및 추가로 학습한 내용을 적어보려한다.
우선 이슈내용은 아래와 같다

문제 발생

  • 해외 DNS에 도메인이 없어 조회 불가능, 간단하게 사용할 API였기 때문에 hosts 파일이 Domain:IP 추가하여 사용
  • 하지만 도커 컨테이너에서 호스트 OS의 hosts 파일을 읽지 못하는 문제가 발생.

문제 원인

  • 문제의 원인은 호스트 OS와 컨테이너의 유저 공간 분리. 도커 컨테이너는 자체적인 유저 공간을 가짐. 호스트 OS의 커널은 공유되지만, 유저 공간은 격리되어 있음.

  • 컨테이너 내에서 호스트 OS의 hosts 파일을 직접 읽을 수 없음.

해결법

  • --add-host 옵션 사용
docker run --add-host=example.com:127.0.0.1 my-container
호스트 OS의 hosts 파일을 수정하지 않고, 특정 호스트 이름과 IP를 정의 가능.
  • /etc/hosts 파일을 컨테이너에 마운트
docker run -v /etc/hosts:/etc/hosts my-container
호스트 OS의 hosts 파일을 컨테이너 내에서 직접 읽을 수 있음. 변경 사항 실시간 반영.

결론

도커 컨테이너는 호스트 OS의 커널을 공유하지만 유저 공간은 독립적. 이로 인해 hosts 파일을 읽지 못하는 문제가 발생. 해결 방법은 --add-host 옵션이나 파일 마운트 방식으로 호스트 OS의 hosts 파일을 제공하는 것.


- 이제 문제 해결을 통해 배운점과 추가로 학습하고자 했던 부분들에 대해 서술하고자 한다.

Docker Container와 리눅스 유저 스페이스

Docker 컨테이너의 구조

  • 도커 컨테이너는 리눅스에서 host OS 커널을 공유하며 아래와 같은 구조를 가진다

  • 보통 도커를학습할때 많이 보이는 그림이다.
  • 여기서 중요한것은 컨테이너는 결국 서버의 자원을 공유하는데 왜 서버의 /etc/hosts의 파일을 참조하지 못하냐이다

유저스페이스 공간 분리

  • 도커는 커널을 공유하지만 유저스페이스는 분리하여 마치 내가 새로운 OS를 사용하고 있는것처럼 느끼게 해준다

  • 하지만 이것은 인터페이스만 분리된것이며 실제동작은 커널단을 공유한다.

  • 추가로 공간이 분리되어있기 때문에 파일 시스템또한 별개 공간을 사용한다

  • 즉 컨테이너에서 DNS질의 전에 hosts 파일 참조시 참조하는 파일은 host서버의 파일시스템의 /etc/hosts , /etc/resolv.conf가 아니기 때문에 여기서 등록하여도 조회 할수없음 -> 컨테이너에 직접 등록해주어야한다.


서버에서의 DNS Query과정

  • 그럼 실제 컨테이너에서의 쿼리과정은 어떻게 진행 될까?

1. 애플리케이션이 도메인 요청

  • ping example.com 실행     Host 커널로 명령어 전달

2. 리눅스의 glibc 라이브러리가 동작

  • getaddrinfo(), gethostbyname() 등의 함수를 호출함     Host 커널로 명령어 전달

  • 이 함수는 /etc/nsswitch.conf 파일을 먼저 확인함 ( Name Service Switch 설정 파일 )     Host 조회하는 파일은 컨테이너의 파일

	hosts: files dns // host는 파일 서버 순으로 확인

3. /etc/hosts 파일 확인

  • 호스트명이 /etc/hosts에 존재하면, 여기서 바로 IP 주소를 반환     Host 조회하는 파일은 컨테이너의 파일
  127.0.0.1 localhost
  192.168.1.100 my-internal-service

4. DNS 쿼리 준비

  • /etc/hosts에 없다면, DNS 쿼리를 전송할 준비를 함

  • 사용되는 설정 파일: /etc/resolv.conf     Host 조회하는 파일은 컨테이너의 파일

  nameserver 8.8.8.8
  여기에 설정된 nameserver에 DNS 질의 전송

5. DNS 클라이언트 → DNS 서버로 쿼리 전송

  • UDP 또는 TCP 53번 포트를 통해 DNS Query 전송     Host 커널로 명령어 전달

위과정을 통해 이루어 지며 컨테이너에서 함수들의 동작은 커널을통해 이루어지지만 실제 파일시스템은 분리되어 동작됨을 알수있다

0개의 댓글