Ночью в AWS регионе us-east-1 в приложении вылезла ошибка:
PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
Приложение запущено на EC2, который расположен в VPC, а база данных – в MariaDB RDS, в той же VPC.
Судя по тексту ошибки – “Temporary failure in name resolution” – возникла проблема с получением IP от DNS.
Т.к. EC2 запущен в VPC – то DNS используется локальный, в той же VPC, который создаётся и управляется Amazon (см. AmazonDNS и DNS AWS), и он же задаётся в настройках EC2 при каждой перезагрузке:
[simterm]
root@ip-172-31-44-158:~# cat /etc/resolv.conf | grep name nameserver 172.31.0.2
[/simterm]
Сеть VPC 172.31.0.0/16, DNS создан на 172.31.0.2.
Причина ошибки в приложении может быть вызвана либо тем, что DNS на 172.31.0.2 временно ушёл в оффлайн, глюкнул, либо – между ЕС2 и узлом 172.31.0.2 в VPC были проблемы с трафиком.
См. также Domain name resolution.
Т.к. это us-east-1 зона, самая, наверное, проблемная в AWS – то может быть любой из этих вариантов.
Собственно, решение, что бы избежать такой ошибки в будущем, будет заключаться в следующем:
- Домен, который создаёт RDS, вида rdsname.cmia1v1jobli.us-east-1.rds.amazonaws.com, имеет TTL только 5 секунд.
Добавим на AWS Route53 субдомен с TTL 3600 и через CNAME привяжем его к rdsname.cmia1v1jobli.us-east-1.rds.amazonaws.com. Таким образом мы увеличим время кеширования на всех DNS серверах с 5 секунд до часу. - Добавим локальный сервис для кеширования DNS на ЕС2. Можно использовать
systemd-resolve
, но он, как пишут, глючный, либо использоватьdnsmasq
– его и возьмём.
Локальное кеширование DNS запросов поможет в случае если проблема была именно в трафике между EC2 и DNS в VPC. - Обновим
resolv.conf
на ЕС2, и доабвим сервера для резолва:
первым добавим 127.0.0.1 – тут будетdnsmasq
оставим 172.31.0.2
добавим 1.1.1.1 – DNS от CloudFlare, на случай, если проблема таки возникает на стороне DNS VPC (хотяdnsmasq
всё-равно должен будет сработать раньше, чем сервер CloudFlare)
Содержание
Route53
Тут, собственно, особо нечего описывать.
Добавляем субдомен:
[simterm]
root@ip-172-31-44-158:~# dig +nocmd +noall +answer @ns-696.awsdns-23.net backendprod-db.domain.tld backendprod-db.domain.tld. 3600 IN CNAME backendprod.sdcsdc.us-east-1.rds.amazonaws.com.
[/simterm]
3600 – ОК.
dnsmasq
Далее добавляем локальный сервис кеширования, пусть это будет dnsmasq
.
Проверим скорость ответа сейчас:
[simterm]
root@ip-172-31-44-158:~# time dig yandex.ru &> /dev/null real 0m0.181s
[/simterm]
Интересно, что DNS в VPC тоже кеширует запросы. Если вызвать dig
ещё раз – время будет всего 8с:
[simterm]
root@ip-172-31-44-158:~# time dig yandex.ru &> /dev/null real 0m0.008s
[/simterm]
Тем не менее – нам всё-равно нужен локальный кеширующий сервер, на случай если ошибка была вызвана проблемами с доступом к серверу 172.31.0.2.
Устанавливаем dnsmasq
:
[simterm]
root@ip-172-31-44-158:~# apt install dnsmasq
[/simterm]
Редактируем /etc/dnsmasq.conf
, задаём listen-address
:
[simterm]
root@ip-172-31-44-158:~# cat /etc/dnsmasq.conf | grep ^listen listen-address=127.0.0.1
[/simterm]
Там же раскоментируем строку bind-interfaces
, иначе dnsmasq
будет слушать на всех интерфейсах.
Проверяем:
[simterm]
root@ip-172-31-44-158:~# netstat -anpt | grep dnsm tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 2296/dnsmasq
[/simterm]
Проверяем время ответа на первый запрос:
[simterm]
root@ip-172-31-44-158:~# time dig @localhost rtfm.co.ua &> /dev/null real 0m0.263s
[/simterm]
И на второй:
[simterm]
root@ip-172-31-44-158:~# time dig @localhost rtfm.co.ua &> /dev/null real 0m0.008s
[/simterm]
Проверяем кеш dnsmasq
.
Проверка кеша dnsmasq
Очень “оригинальный” способ посмотреть статус dnsmasq
.
Убиваем его:
[simterm]
root@ip-172-31-44-158:~# pkill -USR1 dnsmasq
[/simterm]
Проверяем лог:
May 31 10:21:10 ip-172-31-44-158 dnsmasq[2296]: time 1527762070
May 31 10:21:10 ip-172-31-44-158 dnsmasq[2296]: cache size 150, 0/2 cache insertions re-used unexpired cache entries.
May 31 10:21:10 ip-172-31-44-158 dnsmasq[2296]: queries forwarded 2, queries answered locally 3
May 31 10:21:10 ip-172-31-44-158 dnsmasq[2296]: queries for authoritative zones 0
May 31 10:21:10 ip-172-31-44-158 dnsmasq[2296]: server 172.31.0.2#53: queries sent 2, retried or failed 0
Собственно queries forwarded 2, queries answered locally 3 – ОК, кеширование работает.
Можно ещё несколько раз запустить-запросить-убить dnsmasq
, что бы проверить как работает его кеш.
resolv.conf
Далее надо обновить список DNS, которыми будет пользоваться NSS и glibc.
Т.к. это EC2 – то resolv.conf
будет перезаписан при перезапуске сервера. Что бы задать свои сервера – бновляем /etc/dhcp/dhclient.conf
(работает для Debian, в Ubuntu resolv.conf
перезаписывается иначе, наверно с помощью resolvconf
), добавляем в конце строку:
... supersede domain-name-servers 127.0.0.1, 172.31.0.2, 1.1.1.1;
Первым задаём наш dnsmasq
, вторым – DNS в VPC, и третьим – CloudFlare (или Google – 8.8.8.8).
Перезагружаем машину:
[simterm]
root@ip-172-31-44-158:~# reboot Connection to 52.14.213.3 closed by remote host. Connection to 52.14.213.3 closed.
[/simterm]
Проверяем:
[simterm]
root@ip-172-31-44-158:~# cat /etc/resolv.conf domain us-east-2.compute.internal search us-east-2.compute.internal nameserver 127.0.0.1 nameserver 172.31.0.2 nameserver 1.1.1.1
[/simterm]
И логи dnsmasq
:
[simterm]
root@ip-172-31-44-158:~# journalctl -u dnsmasq -- Logs begin at Thu 2018-05-31 11:20:34 UTC, end at Thu 2018-05-31 11:36:43 UTC. -- May 31 11:20:39 ip-172-31-44-158 dnsmasq[470]: dnsmasq: syntax check OK. May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: started, version 2.76 cachesize 150 May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: compile time options: IPv6 GNU-getopt DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC loop-detect inotify May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: reading /etc/resolv.conf May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: ignoring nameserver 127.0.0.1 - local interface May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: using nameserver 172.31.0.2#53 May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: using nameserver 1.1.1.1#53 May 31 11:20:39 ip-172-31-44-158 dnsmasq[508]: read /etc/hosts - 8 addresses May 31 11:20:39 ip-172-31-44-158 systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server... May 31 11:20:39 ip-172-31-44-158 systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
[/simterm]
Готово.