서버는 AWS EC2(Ubuntu 16.04) + RDS 를 사용하고 있습니다. 일단, 문제의 발단은 다음 에러였습니다.

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

PDO쪽에서 Exception이 발생했는데 처음보는 메시지였습니다. 네트워크 쪽에 능통하신 분들이라면 아마도 쉽게 해결하셨겠지만 네트워크를 눈대중으로 배운 저에게는 당황스러울 수 밖에 없었죠.

일단 에러 원인부터 이야기하자면 RDS에서 사용하는 Host 이름을 찾을 수 없기 때문에 발생하는 에러였습니다. 보통 RDS Host는 myrds.abcdefghijkl.ap-northeast-2.rds.amazonaws.com 이런식으로 생겼으니까요. :-)

가장 쉽게 해결하는 방법은 /etc/hosts에 아이피와 해당 호스트를 직접 입력하면 해결이 됩니다.

그런데..!!

해결되지 않았습니다. DB는 접속에러는 해결되었습니다. 하지만 다른 API를 요청하는 부분에서 에러를 내고 있었습니다. 페이스북 연동이라던가, 트위터 연동 등등에서 말입니다. 즉, 특정 domain을 못찾는게 아니고 DNS를 조회하는 쪽이 잘못 동작하고 있었습니다.

우리의 컴퓨터는 어떻게 도메인 주소를 찾아가는가?

그렇다면 좀더 근본적으로 어떻게 우리의 서버는 도메인에 해당하는 아이피를 받아오는지 알 필요가 있었습니다.

DNS 서버에서 해당 도메인을 조회해서 아이피를 받아옵니다.

다들 이정도는 알고있습니다. 솔직하게 이야기하자면 제가 딱 이정도”만” 알고있었습니다. 살짝 단계를 나누면 다음과 같은 과정을 거쳐서 조회합니다.

  1. 로컬 캐시 조회
  2. /etc/hosts 조회
  3. DNS 조회

그렇다면 우리의 서버는 어떤 DNS를 조회하지? 이 질문에 대한 답을 전혀 모르고 있었습니다. AWS EC2(Ubuntu 16.04) 기준으로 이야기하면 /etc/resolv.conf 파일안에 해당 정보가 들어있었습니다. (그리고 대부분의 리눅스 배포판은 동일합니다.)

파일을 열어보면 다음과 같이 기본값이 작성되어있습니다.

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 172.31.0.2
search ap-northeast-2.compute.internal

일단 네임서버가 172.31.0.2로 되어있습니다. 172.* 로 시작하는 아이피는 일단 내부망 아이피입니다. 이 서버에서 장애가 발생한다면 아무것도 처리할 수 없게됩니다. 아무래도 조금 더 보강해야할 것 같았습니다.

DNS 서버를 통해 도메인 조회하기

그런데 해당 네임서버가 제대로 동작하는지는 어떻게 알 수 있을까요? nslookup 명령어를 사용하면 됩니다. 위의 172.31.0.2 서버를 통해 우리의 RDS 도메인을 찾을 수 있는지 조회해봅시다.

nslookup myrds.abcdefghijkl.ap-northeast-2.rds.amazonaws.com 172.31.0.2

위 명령어에서 찾는데 실패하면(혹은 너무 오래 걸리면) DNS가 정상동작하지 않는다고 이야기 할 수 있습니다. 위 도메인을 구글신님의 DNS에 조회해봅시다. (아이피가 너무 단순합니다. 8.8.8.8!!!!)

nslookup myrds.abcdefghijkl.ap-northeast-2.rds.amazonaws.com 8.8.8.8

바로 결과가 출력되었습니다. 그렇다면 172.31.0.2 말고 8.8.8.8을 같이 사용하는 방향으로 문제를 해결하면 됩니다.

DNS 설정 바꾸기

참고 : resolv.conf - ArchWiki

위 링크를 참고하여 resolv.conf 파일을 다음과 같이 작성할 수 있었습니다.

nameserver 172.31.0.2
search ap-northeast-2.compute.internal

# Google IPv4 nameservers
nameserver 8.8.8.8
nameserver 8.8.4.4

# Google IPv6 nameservers
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844

더더 세부적인 설정은 자세한건 man resolv.conf을 참고하면 됩니다. (RTFM.. 괜히 이야기하는게 아닌가 봅니다.)

서버 재부팅시 resolv.conf 초기화 되는 문제

그런데!! 네트워크 서비스를 재시작(당연히 재부팅도 포함)하면 처음의 resolv.conf로 돌아가게 됩니다. 대충 resolvconf 관련 파일(/etc/resolvconf/update.d/libc)을 열어보니 어떻게 resolv.conf 파일이 만들어지는지 알 수 있었습니다.

다음 파일을 열고,

vi /etc/resolvconf/resolv.conf.d/tail

다음 내용을 추가합시다.

# Google IPv4 nameservers
nameserver 8.8.8.8
nameserver 8.8.4.4

# Google IPv6 nameservers
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844

이제 네트워크 서비스를 재시작 해봅시다. 그냥 저는 다음 명령어를 사용하였습니다.

sudo service resolvconf restart

그리고 resolv.conf 파일을 열어보니 잘 반영된 것을 알 수 있었습니다.

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 172.31.0.2
search ap-northeast-2.compute.internal

# Google IPv4 nameservers
nameserver 8.8.8.8
nameserver 8.8.4.4

# Google IPv6 nameservers
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844

추가로 보면 좋은 자료들

참고자료