증상
넓은 범위의 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를 사용하는 것이 기본값이라고 하네요.
참고
- https://github.com/docker/docker/issues/23166
- https://docs.docker.com/v1.7/articles/networking/#binding-ports
'Docker' 카테고리의 다른 글
실행중인 docker 컨테이너 환경변수 변경 (3) | 2018.01.08 |
---|---|
Dockerfile for gstreamer 1.10.4 (0) | 2017.02.28 |
docker-compose ports 적용이 안되는 경우 (1) | 2016.07.27 |
Docker 윈도우 공유 폴더 마운트 (4) | 2016.06.16 |
Putty로 윈도우 Docker 이미지 접속하기 (0) | 2016.06.16 |