본문으로 건너뛰기

"dns" 태그로 연결된 4개 게시물개의 게시물이 있습니다.

모든 태그 보기

쿠버네티스 환경에서의 Node.js DNS Cache

· 약 5분

쿠버네티스 환경에서는 Node.js 이미지를 올릴 시 종종 아래와 같은 IP 반환 에러메세지가 보인다. 이는 서비스 연결조차 불가능하게 만들어 운영에 지장을 주었다.

Error: getaddrinfo EAI_AGAIN your-service

먼저 Node.js 레벨에서부터 확인을 시작하였다.

UV_THREAD_POOL_SIZE

Node.js Man 을 보면 다음과 같은 주의사항이 있다.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. This can have surprising negative performance implications for some applications, see the UV_THREADPOOL_SIZE documentation for more information.

연관된 UV_HTREADPOOL_SIZE 문서는 다음과 같다.

Asynchronous system APIs are used by Node.js whenever possible, but where they do not exist, libuv's threadpool is used to create asynchronous node APIs based on synchronous system APIs.

스레드 풀을 사용하는 API 는 다음과 같다.

  • all fs APIs, other than the file watcher APIs and those that are explicitly synchronous
  • asynchronous crypto APIs such as crypto.pbkdf2(), crypto.scrypt(), crypto.randomBytes(), crypto.randomFill(), crypto.generateKeyPair()
  • dns.lookup()
  • all zlib APIs, other than those that are explicitly synchronous

이 메소드들을 사용할 때는 병렬 요청과 부하에 신경을 써야하며 UV_THREADPOOL_SIZE 사이즈를 Node.js 기본값인 4에서 적절히 증가시켜줘야한다.

dns.lookup

dns.lookup가 비동기인척하는 동기 메소드임을 확인할 수 있었다. 보통 이 메소드를 직접 사용하는 경우는 거의 없다.

axios 등 http 연결을 하는 라이브러리에서 Hostname 을 IP 로 변경하기 위해 사용한다.

java 는 30s¹, php 는 120s²의 도메인 캐시를 기본으로 제공하지만 Node.js 에서는 그런 것이 없다.

Node.js 커뮤니티에서는 native dns lookup cache 기능이 제안 되었지만, dns.resolve4dns.resolve6 에 서버에서 반환하는 ttl 값을 사용할 수 있게 추가되어 이걸 사용하여 DNS 캐싱을 하게 권장되었다.

alpine

alpine 이미지에는 musl 을 사용하므로 다음과 같은 이슈가 발생할 수 있으나 해당 서비스는 그렇지 않았다.

kube-dns

남은 건 쿠버네티스 환경이었다. kube-dns 대신 dnsmasq 를 사용하자 제안이 있었고, DNS intermittent delays of 5s 이슈와 공식 문서의 NodeLocal DNS Cache Daemonset 으로 이 문제를 해결할 수 있어보였다.

클러스터에서 데몬셋을 통해 캐싱된 DNS 를 리졸브하는 완전한 해결책이였으나 클라우드에는 접근 권한이 없어 이슈 내용을 공유할 수 밖에 없었다.

그렇다면 어플리케이션에서 해결할 방법을 찾아야했다.

cacheable-lookup

Node.js 의 HTTP 모듈에서는 lookup 속성을 지원하며 이는 기본값으로 dns.lookup 을 사용한다. 결국 Node.js(HTTP -> dns.lookup) -> Alpine(getaddrinfo) -> K8S(socket) 의 어느 구간이라도 캐싱을 하면 되는 것이다.

dns.lookup 대신에 dns.resolve4 를 사용하며 Map 기반으로 캐시키를 관리하는 라이브러리로 Cachable Lookup 을 찾을 수 있었다.

axios 라이브러리는 lookup 속성을 지원하지 않으므로 http.globalAgent 에 다음과 같이 추가해야했다.

import CacheableLookup from "cacheable-lookup";

const cacheable = new CacheableLookup();
cacheable.install(http.globalAgent);

전역 agent 를 오염시키는 느낌이라 아예 HTTP 라이브러리를 got 으로 변경하였다. got 에서는 dnsCache: true 를 주어 이 기능을 쉽게 활성화 할 수 있었다.

결론

  • 언어 수준에서의 DNS 캐시는 짧게나마 필요해보였다.
  • deno 에선 reqwest 모듈 위에 HTTP 를 올려놓았는데, trust-dns 란 DNS 캐시 모듈을 활성화하는 옵션은 들어가있지 않았다. 따라서 쿠버네티스 환경에서 같은 오류를 뱉을지 테스트해보고 싶다.

참조

DEV 도메인과 Github Pages 연결하기

· 약 3분

Google Domains 에서 구입한다.

  • 미국 주소가 있어야된다는 말이 나오는데, 무시하고 구매하기를 하자.
  • 도메인 기관에서 연락이 갈 수 있다는 내용에 주소를 대한민국으로 변경 후 입력해주고
  • 결제지 우편번호는 대충 쓰고 미국으로 하고 넘어가면 쉽게 구매할 수 있다.

DNS 설정

DNS > 맞춤 리소스 레코드 탭에서 Github Domain IP 를 A 레코드로 추가한다.

  • 185.199.108.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.199.111.153

http 예외

http 로 서빙하는 경우가 있다면 www.gracefullight.dev 도 사용할 수 있게 CNAME 을 등록하자.

www CNAME 1h gracefullight.github.io.

물론 HSTS 를 적용하는 경우 필요없다.

CNAME 파일 추가

public 경로 아래 CNAME 파일을 생성 후 도메인을 적는다.

CNAME
gracefullight.dev

github pages 설정

github.com/gracefullight/gracefullight.github.io/settings 의 GitHub Pages 탭으로 이동해 Custom domain 에 설정할 도메인을 넣고, Enforce HTTPS 를 체크한다.

아래 문구가 보이면 성공한 것이다.

Your site is published at https://gracefullight.dev/

웹마스터 설정

Google

구글 검색에서 도메인 변경을 다시 인덱싱해주기 위해 마이그레이션이 필요하다. 새로운 사이트를 등록해 준 뒤 이전 버전의 서치콘솔에서 기존 사이트의 설정버튼을 누르면 바로 설정이 가능하다.

주소 변경

기타

네이버와 빙은 같은 site verification 코드가 나와서 사이트만 추가해주면 되는데, 얀덱스의 경우는 코드를 변경하고 빌드해줘야한다.

여담

  • CNAME 변경하면 Github setting의 Custom domain이 빠지기 때문에 다시 등록해줘야하는 번거로움이 있다.
  • 애널리틱스는 도메인만 바꿔주면 바로 연동된다.
  • 애드센스가 도메인 승인이 2주가 걸려서 그전까진 애드-프리 사이트가 될 듯하다.

Temporary failure in name resolution, 일시적인 실패

· 약 1분

모듈 설치시 domain을 사용하거나, telnet 도메인 포트를 호출해봤는데 name resolution에서 일시적인실패 또는 Temporary failure 문구의 에러가 보이는 경우가 있다.

nameserver를 찾지 못해서 발생한다.

해결

Root 계정으로 접속 후 nameserver 설정을 추가한다.

$ vi /etc/resolv.conf

# 아래 내용을 추가
nameserver 58.227.193.227
nameserver 221.143.20.131

저장하면 서비스 재시작이 필요없이 바로 적용된다.

여담

  • 통신사별 DNS 정보 페이지를 첨부한다.
  • 아마존 DNS 오류로 이 페이지의 조회수가 급증했다.

Can't connect to localhost

· 약 1분

웹서버를 크롬에서 띄울시 localhost 가 요청되지 않는 경우가 있다. DNS 에 문제가 있어 연결할 수 없다는 에러가 나온다.

Chrome > 설정 > 개인정보 메뉴에서 네트워크 활동을 예측하여 페이지 로드 성능 개선 기능을 해제한다. image from hexo