Docker port 범위 사용 시 cannot allocate memory 오류

Docker 2016.07.28 14:35 Posted by 김한별 behonestar

증상

넓은 범위의 port를 사용하여 container를 실행하려고 하였더니 cannot allocate memory 오류가 발생하였습니다.


version: '2'

services:

  tunnel_http:

    build: ./tunneling

    ports:

      - "30000-30999:30000-30999"


ERROR: for tunnel_http  driver failed programming external connectivity on endpoint docker_tunnel_http_1 (3e88c0459935f2feb125235551af19769359865534da160db348ca5eb536613f): iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 30818 -j DNAT --to-destination 172.18.0.4:30818 ! -i br-843f9c797ae6:  (fork/exec /sbin/iptables: cannot allocate memory)

Traceback (most recent call last):

  File "<string>", line 3, in <module>

  File "compose/cli/main.py", line 63, in main

AttributeError: 'ProjectError' object has no attribute 'msg'


원인

Docker 설정 중 userland-proxy의 기본값은 true입니다. userland-proxy 방식은 메모리를 많이 사용하기 때문에 port 범위가 넓으면 메모리 부족이 발생할 수 있습니다.


대책

userland-proxy를 사용하지 않도록 daemon.json 파일을 생성하고 아래와 같이 입력합니다.

$ sudo vi /etc/docker/daemon.json

{

        "userland-proxy": false

}


userland-proxy는 컨테이너 내부와 외부의 통신을 위해 userland 영역에서의 구현을 제공합니다. userland-proxy를 비활성화 시키면 Docker는 MASQUERADE iptable 규칙과 net.ipv4.route_localnet 커널 파라미터를 사용합니다. 즉, 일반적으로 사용되는 loopback 주소를 통해 host가 container의 expose된 포트로 연결됩니다. 성능 상의 이유로 후자의 방법이 선호되지만, RHEL6/CentOS6에서는 이를 지원하지 않기 때문에 userland-proxy를 사용하는 것이 기본값이라고 하네요.


참고