1
1
Fork 0
dns, systemd-nspawn, ipvlan을 이용한 컨테이너 네트워크 설정기
Go to file
Sangbum Kim 2278737a0c Merge branch 'develop' of ssh://amuz.es:29418/infra/octopus into develop
* 'develop' of ssh://amuz.es:29418/infra/octopus:
  nil ㅂㅓ그 수정
  subnet 찾는 모드 추가

# Conflicts:
#	octopus-outside/main.go
2018-08-22 01:07:06 +09:00
dns 정리 2017-04-06 17:08:25 +09:00
octopus-inside macvlan 설정 가능하도록 함 2017-04-24 00:07:11 +09:00
octopus-outside nil ㅂㅓ그 수정 2018-05-15 03:07:05 +09:00
services subnet 찾는 모드 추가 2018-05-13 18:23:33 +09:00
.gitignore initial gitignore commit 2016-03-01 01:32:42 +09:00
LICENSE README / 라이센스 추가 2017-04-06 19:48:18 +09:00
README.md logo추가 2017-04-06 23:35:31 +09:00
container_inner_macvlan_settings added additional container related settings: 2016-03-01 01:39:35 +09:00
desc.png README / 라이센스 추가 2017-04-06 19:48:18 +09:00
logo.png logo추가 2017-04-06 23:35:31 +09:00
pacstrap_initial_package_settings added additional container related settings: 2016-03-01 01:39:35 +09:00
settings.yml 정리 2017-04-06 17:08:25 +09:00

README.md

Octopus

Octopus Overview

Octopus는 DNS와 systemd-nspawn, ipvlanoverlayfs를 이용한 한 머신내의 가볍고 설정가능한 컨테이너를 구동하는 것이 목표입니다.

개요

프로젝트 구조

기본적으로 컨테이너는 /container/이름의 구조로 존재합니다. 컨테이너는 delta merge work volume의 디렉터리와 settings.yml파일로 구성됩니다.

/container
├── vmname1
│   ├── delta
│   ├── merge
│   ├── work
│   ├── volume
│   └── settings.yml
├── vmname2
│   ├── delta
│   ├── merge
│   ├── work
│   ├── volume
│   └── settings.yml
└── vmname3
    ├── delta
    ├── merge
    ├── work
    ├── volume
    └── settings.yml

delta 디렉터리 : overlayfs의 Upperdir에 속하며 Lowerdir에서 변하는 부분이 저장됩니다.

merge 디렉터리 : overlayfs의 마운트 타겟에 속하며 실제 루트로 사용될 공간입니다.

work 디렉터리 : overlayfs의 workdir에 속하며 커널내부적으로 사용하는 공간이며 비어있어야 합니다.

volume 디렉터리 : 루트의 업데이트와 관리를 편하게 하기위해 루트와 별도로 마운트될 데이터를 따로 저장하는 파일들이 저장되는 부분입니다.

octopus-outside로 구동전에 merge는 마운트 되어있어야되며 /etc/fstab에 아래와 같이 항목을 추가하여 자동으로 마운트 되도록 합니다.

overlay /container/vmname/merge         overlay lowerdir=/container/base:/container/vmname/vanilla,upperdir=/container/vmname/delta,workdir=/container/vmname/work 0 0

settings.yml파일 내용

settings.yml의 내용은 다음과 같다.

mount-point:
    - name: ssh-config
      map: /etc/ssh
      readonly: true
    - name: log-data
      map: /var/log

name : 상대경로로 시작하면 volume안의 디렉터리/파일을 지정합니다., 절대경로로 지정시 시스템의 경로를 따릅니다.

map : 컨테이너 내의 마운트될 절대경로를 지정합니다.

readonly : 기본값은 false이며 true로 지정시 컨테이너내부에서는 이 디렉터리/파일을 수정할 수 없습니다.

ipvlan 네트워크 개요

nic0(실제 인터페이스)
├── ip0(호스트 이더넷 ipvlan)
├── vmname1
│   └── eth0(컨테이너 ipvlan)
├── vmname2
│   └── eth0(컨테이너 ipvlan)
└── vmname3
    └── eth0(컨테이너 ipvlan)

ipvlan은 모든 가상네트워크의 mac address를 동일하게 가져가고 IP만 다르게하는 L3스위치의 역할을 수행함으로 nic를 promiscuous 모드로 설정하지않아 성능상 잇점이 브릿지/macvlan에 비해 크다.

  • 주의 단, ipvlan을 지정한 nic를 호스트에서 직접 이용하면 호스트<-->컨테이너간의 통신이 불가능하니 호스트에도 ipvlan어댑터를 만들어서 이용해야된다. 이때 호스트에 같은 mac address를 가지고 있는 nic가 두개가 됨으로 nic의 arp announce기능을 끄고 arp ignore기능을 켜야된다.

sysctl 설정

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.ip0.arp_ignore = 1
net.ipv4.conf.ip0.arp_announce = 2
net.ipv4.conf.nic0.arp_announce = 2
net.ipv4.conf.nic0.arp_ignore = 1

arp resolve기능도 동일하게 물리 nic에서 꺼준다. 또한 ipv6의 경우 mac address로 link-local address를 구성하므로 해당 기능도 같이 끈다.

networkd 설정

[Match]
Name=nic0

[Link]
ARP=no

[Network]
DHCP=no
IPVLAN=ip0
LinkLocalAddressing=no

octopus-outside 설정

octopus-outside는 해당 컨테이너이름을 기반으로 설정되어있는 DNS서버의 A레코드를 컨테이너의 IP로 인식한다. 또한 서브넷, 게이트웨이는 현재 호스트의 기본서브넷, 기본게이트웨이를 인식하여 컨테이너내부(PID1의 environment variable로 지정)로 전달하며 이 정보를 토대로 octopus-inside가 실행시 네트워크 구성을 수행한다.

이 설정을 바탕으로 systemd-nspawnexecve(2)콜을 수행하며 octopus-outside자신은 시스템에서 사라진다.

  • 주의 DNS서버는 설정하지 않으므로 미리 /etc/resolv.conf를 설정해놓아야한다(TODO?)

octopus-outside의 설정은 다음과 같다.

usage: octopus-outside [<flags>] <nodeName> <bindInterface>

nspawn Bootstrapper.

Flags:
      --help                     Show context-sensitive help (also try --help-long and --help-man).
  -v, --verbose                  Enable verbose mode.
  -p, --clear                    clear os environment.
  -s, --nspawn-path=NSPAWN-PATH  systemd-nspawn location.
  -d, --container-home="/container"
                                 container residence path
  -c, --config-file="settings.yml"
                                 config file name

Args:
  <nodeName>       nodename to spawn.
  <bindInterface>  interface name to bind.

nodeName: 노드이름이며 container-home의 하위 디렉터리의 설정과 루트를 인식한다.

bindInterface: ipvlan으로 연결할 nic이름을 지정한다.

octopus-inside 설정

octopus-inside는 컨테이너 내부에서 PID 1프로세스의 environment variable을 인식하고 다음 3가지 작업을 하고 사라집니다.

  1. ipvlan인터페이스를 찾아 eth0으로 리네임
  2. 건내받은 정보를 토대로 IP주소, 서브넷주소, 게이트웨이주소를 eth0에 설정
  3. eth0을 UP상태로 지정

이후 해당컨테이너는 외부와 통신이 가능하게됩니다.

참고

octopus-inside systemd서비스 파일 octopus-outside systemd서비스 파일

Licensing

별다른 언급이 없는 한 이 프로그램은 GNU GENERAL PUBLIC LICENSE Version 3로 배포됩니다.