Docker Network

  • Docker가 시작되면 docker0 이라는 이름의 virtual 인터페이스를 만들어 컨테이너와 호스트 머신이 통신한다. [1]
    • private 범위에서 사용하지 않는 IP를 자동으로 선택해서 docker0 에 할당한다.
  • 디폴트로 --net=bridge 옵션으로 실행되며, bridge로 통신한다.
    • --net=container:NAME_or_ID 옵션으로 다른 컨테이너에게 위임이 가능하다.
    • 이렇게 되면 첫번째 컨테이너와 같은 IP주소, 포트를 공유하고. loopback 인터페이스로 통신이 가능함.
  • docker run 으로 컨테이너가 시작되면.
    • docker0 의 IP주소공간에서 이 컨테이너의 IP가 할당됨.
    • docker0 과 연결된 veth* 인터페이스가 만들어지고 컨테이너에 할당됨.
    • 컨테이너 쪽에서는 이게 eth0 으로 보임.
    • 내 생각에는 아래와 같이 통신하는 것으로 이해했다.
      • 컨테이너1의 eth0veth*docker0호스트의 eth0
  • --bip 옵션으로 docker0 의 IP주소범위를 지정 가능함. [2]
  • Kubernetes(이하 k8s) 에서는 Docker를 실행할때 DOCKER_OPTS="--bridge cbr0 --iptables=false" 이 옵션으로 실행함. [3]
    • cbr0 은 바깥으로 나가는 트래픽을 위한 NAT역할만 하는 bridge임.
    • bridge가 아니라 flannel [4] 을 써서 docker0 끼리 직접 연결하는 구조도 가능한 듯.

1개의 머신 내부 컨테이너 간 통신

  • Docker에서는 iptables을 사용한다.
  • EXPOSEdocker0 에 포트를 노출할 수 있다.
  • docker run 할때 --link 컨테이너이름:별명 옵션으로 다른 컨테이너와 연결할 수 있다. [5]
  • 이 옵션이 하는 일은 환경변수와 /etc/hosts 에 연결정보를 추가해주는 일을 함.
    • 환경변수 별칭_PORT 를 사용하여 연결 가능함.
    • /etc/hosts 를 사용하여 연결 가능함.
  • 나는 보통 link를 써야할 일이 있으면 fig를 사용함. [6]

2개 이상의 머신에서 컨테이너 간 통신

  • 각 호스트에 Ambassador Container를 만들고. ambassador 가 forward 하는 방법. [7]
    • 아래와 같이 통신한다.
    • (consumer) --> (redis-ambassador) ---network---> (redis-ambassador) --> (redis)
  • etcd 를 사용하는 방법. [8] 글을 내가 이해한걸 짧게 요약하면
    • 서비스 제공자는 연결정보를 etcd에 쓰고.
    • 서비스 소비자는 etcd에서 연결정보를 읽어서 서비스 제공자에 연결한다.
  • Docker 전용 overlay network 를 구성하는 방법.
    • 모든 컨테이너를 동일 네트워크에 있는것 처럼 구성.
    • weave [9]
    • k8s 도 이 방법을 사용.
    • 이것을 GCE가 아닌 다른 곳에서도 쓸 수 있게 만든것이 coreos의 flannel

coreos의 flannel

  • k8s를 위해 만들어진, 각 머신 별로 subnet 을 주기위한 overlay network. [10]
  • 지정한 IP주소 대역으로 각 호스트가 /24씩 잘라서 할당됨.
  • 이 정보를 etcd에 저장하고.
    • 실제 IP와 매핑.

google의 cAdvisor

  • Container Advisor 의 약자.
  • 구글이 공개함.
  • 실행중인 컨테이너들의 자원 사용량과 성능 특이점을 수집하여 컨테이너 사용자에게 보여주는 목적의 도구. [11]
  • 수집해서 정보를 보내는 역할의 cadvisor daemon을 docker container들이 돌아가는 machine에 띄우면
    • 해당 machine의 모니터링 정보와 해당 machine에서 돌아가는 docker container들의 정보를 아래의 방법으로 알 수 있음.
    • 웹UI (디폴트 8080포트)
    • REST API
  • raw 데이터와 가공된 통계 데이터를 REST API로 제공함. [12]
  • 공식 go client 라이브러리를 제공함. [13]
  • k8s 에서는 디폴트로 실행되고 4194포트로 통신함. [14], [15]

만약 machine에 8004 포트로 cadvisor를 올렸다면, 아래와 같은 REST API로 machine에서 실행중인 docker containers 들의 cpu, network 등의 사용량을 알 수 있다.

$ curl http://localhost:8004/api/v1.2/docker
{
  /docker/2f0fad0378402d0fdc2b4515ded4cca92232c2e6feec3febf27af1cfd97b9c51: {
    ...
    aliases: [mysql_1, 2f0fad0378402d0fdc2b4515ded4cca92232c2e6feec3febf27af1cfd97b9c51]
    stats: [
      { timestamp: ..., cpu: ..., memory: ..., network: ...}
      ...
    ]
  }
  /docker/602b7986fc363dab0c924acfef7ed9f2ed8c88fa7fed7fda28c98cd5b2ab4aa4: { ... }
  /docker/a73c6c51a9f7131130af31c1006ea880566a44987cc74473f3f09c8fd1b490f2: { ... }
}