최근 CentOS7 서버에서 겪었던 Docker 설치 후 무한 대기하는 현상 관련해서 공유하고자 합니다.

TL;DR: 결론적으로 이런 경우 iptable_nat 커널 모듈이 서버에 정상적으로 로딩되어있는지 체크하시기 바랍니다. (modprobe를 통해 체크 가능) 이는 OS 레벨의 퍼포먼스 튜닝목적으로 NAT를 disable한 경우일 수 있습니다.

현상

먼저 리눅스 서버에서 CLI를 통해 아래와 같이 Docker 패키지를 설치할 수 있습니다. (repository 방식)

# https://docs.docker.com/engine/install/centos/#install-using-the-repository
# on root user

yum install -y yum-utils
yum-config-manager \
  --add-repo \
  https://download.docker.com/linux/centos/docker-ce.repo
 
yum install -y docker-ce docker-ce-cli containerd.io
groupadd docker
systemctl start docker

패키지 설치 후 Docker 데몬이 정상적으로 실행 되었다면 CLI로 docker 명령어도 수행이 가능합니다.

하지만 이상하게도 docker 명령어를 실행했을 때 아무런 반응이 없고 무한정 기다리는 상황이 발생했습니다. 따라서 Docker 데몬에 이상이 있는지 확인하기 위해 systemd의 status 로그를 확인해봤습니다.

Active 항목이 activating (start)로 나타나고, 명령어 중 dockerd 위에 iptables 명령어가 수행되고 있는 것으로 보입니다.

정상적이라면 Active 항목에 active (running)으로 초록색 불이 들어와야 하는데, 아마도 어떤 원인(iptables 명령어로 의심)으로 인해 hanging 상태에서 진행되지 않고 있는 것이라고 추측, 자세한 상황을 파악하기 시작했습니다.

원인 파악

먼저 systemd 로그에서 보이는 iptables의 명령어를 그대로 실행했고, 실제로 iptables 명령어 자체가 진행되지 않고 멈춰있는 것을 볼 수 있었습니다. 또한, iptables 키워드로 프로세스를 grep해보니 아래와 같이 조회되었습니다.

modprobe -q -- iptable_nat라는 명령어가 다수 보여, 해당 명령어를 조사해보기 시작했습니다.

modprobe 문서를 통해 일부 커널 모듈의 블랙리스트 지정이 가능하다는 것을 알았고, iptable_nat라는 모듈이 블랙리스트에 들어있다는 사실이 확인 되었습니다.

이는 NAT를 사용하지 않는 리눅스 서버에서 퍼포먼스 튜닝을 목적으로 구성한 것으로 추측됩니다. (관련 문서 참고)

결론

도커를 정상적으로 수행하기 위해서는 NAT 구성이 필수적으로 필요합니다. 따라서, modprobe의 blacklist에 설정되어있는 iptable_nat 관련 값들을 제거하고, 리눅스 서버를 재기동 함으로써 iptable_nat 모듈의 로딩을 수행해줘야 합니다.

참고로, docker에서 NAT를 왜 사용해야만 하는지 공식 문서를 통해 확인 가능합니다. (호스트와 docker의 네트워크 격리를 위함이라고 함)