도커 컨테이너에서 호스트 OS의 hosts 파일을 읽지 못한 문제 해결
해외 서버에서 국내서버의 도메인을 컨테이너에서 호출시 해외 DNS에 해당 도메인이 등록되지 않아 통신할수없었던 이슈를 해결하면서 경험한 내용 및 추가로 학습한 내용을 적어보려한다.
우선 이슈내용은 아래와 같다
문제의 원인은 호스트 OS와 컨테이너의 유저 공간 분리. 도커 컨테이너는 자체적인 유저 공간을 가짐. 호스트 OS의 커널은 공유되지만, 유저 공간은 격리되어 있음.
컨테이너 내에서 호스트 OS의 hosts 파일을 직접 읽을 수 없음.
docker run --add-host=example.com:127.0.0.1 my-container
호스트 OS의 hosts 파일을 수정하지 않고, 특정 호스트 이름과 IP를 정의 가능.
docker run -v /etc/hosts:/etc/hosts my-container
호스트 OS의 hosts 파일을 컨테이너 내에서 직접 읽을 수 있음. 변경 사항 실시간 반영.
도커 컨테이너는 호스트 OS의 커널을 공유하지만 유저 공간은 독립적. 이로 인해 hosts 파일을 읽지 못하는 문제가 발생. 해결 방법은 --add-host 옵션이나 파일 마운트 방식으로 호스트 OS의 hosts 파일을 제공하는 것.
Docker Container와 리눅스 유저 스페이스

도커는 커널을 공유하지만 유저스페이스는 분리하여 마치 내가 새로운 OS를 사용하고 있는것처럼 느끼게 해준다
하지만 이것은 인터페이스만 분리된것이며 실제동작은 커널단을 공유한다.
추가로 공간이 분리되어있기 때문에 파일 시스템또한 별개 공간을 사용한다

즉 컨테이너에서 DNS질의 전에 hosts 파일 참조시 참조하는 파일은 host서버의 파일시스템의 /etc/hosts , /etc/resolv.conf가 아니기 때문에 여기서 등록하여도 조회 할수없음 -> 컨테이너에 직접 등록해주어야한다.
- 그럼 실제 컨테이너에서의 쿼리과정은 어떻게 진행 될까?
getaddrinfo(), gethostbyname() 등의 함수를 호출함 Host 커널로 명령어 전달
이 함수는 /etc/nsswitch.conf 파일을 먼저 확인함 ( Name Service Switch 설정 파일 ) Host 조회하는 파일은 컨테이너의 파일
hosts: files dns // host는 파일 서버 순으로 확인
127.0.0.1 localhost
192.168.1.100 my-internal-service
/etc/hosts에 없다면, DNS 쿼리를 전송할 준비를 함
사용되는 설정 파일: /etc/resolv.conf Host 조회하는 파일은 컨테이너의 파일
nameserver 8.8.8.8
여기에 설정된 nameserver에 DNS 질의 전송
위과정을 통해 이루어 지며 컨테이너에서 함수들의 동작은 커널을통해 이루어지지만 실제 파일시스템은 분리되어 동작됨을 알수있다