Hooni's Playground

Assign Public IP to Docker Container (MACVLAN)

HPE DL380에는 LAN포트가 4개나 있다.
그냥 두고쓰기에는 조금 찜찜한 감이 있어서 Docker를 올려 컨테이너별로 IP를 부여하고싶었다.
Xen같은 경우는 XenServer에서 쉽게 설정할 수 있는데
Docker는 뭔가 좀 까다로워서 이렇게 글을 남긴다.

1. As-is

기본적으로 Docker의 컨테이너는 별도의 Private IP를 부여받는다.
이렇게 되면 당연히 host와 컨테이너, 컨테이너와 컨테이너간 통신이 안된다.
그렇기 때문에 Docker에는 서로가 통신할 수 있도록 Bridge 인터페이스가 존재한다.

다시말해 Bridge 인터페이스는

물론 이런 설정이라면 외부에서 내부의 특정 컨테이너에 접속하기는 불가능하다.
이를 위해 docker에서는 –port 옵션으로 포트포워딩을 지원한다.
또는 –expose 옵션으로 host의 포트와 연결할 수도 있다.

이 경우 여러 장단점이 있다.
간단하기도 하고, 포트포워딩만 해놓으면 알아서 다 해주니 편하기도 하다.
하지만 host가 병목이 된다는 중요한 문제가 있다.
게다가 내가 하고싶은 것은 포트포워딩이 아니라 IP의 할당이다.

2. To Be

macvlan은 물리 NIC에 가상의 sub-interface를 여러개 부여하는 기법이다.
이 경우 sub-interface들이 host와 통신을 못한다는 단점이 있으나
macvlan에 연결된 컨테이너들(sub-interface)끼리는 통신이 가능하다.

이 점이 bridge 네트워크와는 다른 점이다.
bridge 네트워크의 경우에는 컨테이너와 host가 서로 통신이 됐으나, macvlan은 그렇지 못하다.
macvlan은 애초에 sub-interface를 만드는 기술이지 NAT 등을 수행하는 기술은 아니기 때문이다.
이는 VM이 host와 통신하지 못하는 이유와 동일하다. (그래서 VM에도 bridge interface를 둔다.)

그렇다고 macvlan이 안좋은 것인가라고 하기에는 아직 이르다.
macvlan이 bridge에 비해 좋은 점은

macvlan도 내부의 컨테이너들이 어떻게 통신하느냐에 따라 네 가지(Private, VEPA, Bridge, PassThru)의 Mode로 구분하는데, docker는 그 중 bridge방식밖에 지원하지 않는다.
더 자세한건 나도 잘 모르므로 이런 블로그를 참고하면 된다.

서론이 길었고, 실제로 컨테이너에 공인IP를 부여해보자

순서는 다음과 같다

host와 컨테이너 간 통신할 수 있게 하는건 보안에 큰 위협이 된다.
필자는 웹서비스를 올릴 생각이라 host와 컨테이너 간 통신은 설정하지 않았다.

2-1. macvlan 인터페이스 생성

우선 필요한 것은 부여할 공인 ip의 subnet과 gateway 정보를 파악하는 것이다.
그리고 부모 인터페이스로 삼을 네트워크 인터페이스(eth0, eno0 등)를 선정한다.

docker network create -d \
  macvlan -o macvlan_mode=bridge \
  --subnet=192.168.0.0/24 \
  --gateway=192.168.0.1 \
  -o parent=eno1 \
  macvlan_bridge

이를 통해 macvlan_bridge라는 이름의 macvlan 인터페이스를 할당했다.

2-2. 컨테이너 생성

위에서 만든 macvlan_bridge에 컨테이너를 붙여본다.
아래와 같이 단순히 –net 옵션을 지정하는 것만으로 sub-interface가 생성된다.

docker run -dit \
  --net macvlan_bridge \
  --ip 192.168.0.10 \
  --publish 192.168.0.10:3306:3306 \
  --name db \
  --env MYSQL_ROOT_PASSWORD=123456789 \
  mysql

간단하게 MySQL 컨테이너를 올려보았다.
이 컨테이너는

지금 이 상태만으로도 외부, 즉 192.168.0.x 네트워크에서 이 컨테이너에 192.168.0.10:3306으로 접근할 수 있다.
물론 할당한 ip가 공인 ip라면 인터넷을 통해 접근할 수도 있다.

2-3. host – 컨테이너 통신

만약 host와 컨테이너 간 통신이 필요한 상황이라면 이 둘을 통신할 수 있도록 인터페이스를 하나 더 두어야 한다.
인터페이스를 두어 host와 컨테이너가 통신할 수 있도록 iptable을 변경하면 된다.

앞서 말했듯이 보안에 취약하다.
그래도 설정하고 싶다면 이 블로그를 참고하면 된다.
설정이 어렵진 않다.

Exit mobile version