CNI 플러그인과 커스텀 브리지 네트워킹
CNI 플러그인과 커스텀 브리지 네트워킹 (CNI plugins and custom bridge networking)
Linux 배포판에 Container Network Interface (CNI) 참조 플러그인을 설치하고 Nomad 클라이언트에 커스텀 CNI 브리지 네트워킹을 구성하는 과정을 알아봐요.
출처: 문서
본문
이 페이지는 Linux 배포판에 Container Network Interface (CNI) 참조 플러그인을 설치하고 Nomad 클라이언트에 커스텀 CNI 브리지 네트워킹을 구성하는 과정을 설명해요.
이 가이드의 워크플로우를 CNI Specification을 준수하는 모든 네트워크 플러그인 설치에 적용할 수 있지만, 프로덕션에 배포하기 전에 플러그인 호환성을 Nomad와 확인해야 해요.
배경
CNI 사양은 관리자를 위한 네트워크 구성 형식을 정의해요. 구성에는 오케스트레이터와 플러그인이 소비할 지시문이 모두 포함돼요. Nomad는 CNI 참조 플러그인 바이너리와 CNI 구성 파일의 조합으로 커스텀 네트워킹을 구현해요. 브리지 네트워크 모드와 Consul 서비스 메시 같은 네트워킹 기능은 CNI 참조 플러그인을 활용해 워크로드 네트워킹을 구성하는 운영 체제 비종속적 인터페이스를 제공해요.
Nomad는 cni_config_dir(기본값 /opt/cni/config)에서 다음 확장자를 읽어요.
요구 사항
- CNI 참조 플러그인에 익숙해요.
- Nomad가 브리지 네트워킹에 Container Network Interface (CNI) 플러그인을 사용하는 방법에 익숙해요.
- Linux에서 Nomad를 실행하고 있어요.
CNI 플러그인과 브리지 네트워킹 워크플로우
CNI 플러그인을 클라이언트별로 설치하고 구성해요. Nomad는 클라이언트의 cni_path에 주어진 경로를 참조해 CNI 플러그인 실행 파일을 찾아요.
각 Nomad 클라이언트에서 다음을 수행해요.
Nomad 클라이언트를 구성하고 재시작한 후 작업 구성은 작업과 함께 CNI 네트워크 사용하기를 참고해요.
CNI 참조 플러그인 설치
Nomad는 bridge 네트워크 모드를 사용할 때 네트워크 네임스페이스를 구성하기 위해 CNI 플러그인을 사용해요. 네트워크 네임스페이스를 사용하는 모든 Linux Nomad 클라이언트 노드에 CNI 플러그인을 설치해야 해요. 개별 플러그인에 대한 자세한 내용은 CNI Plugins 외부 가이드를 참고해요.
다음 일련의 명령은 운영 체제 아키텍처를 결정하고, CNI 1.6.2 릴리스를 다운로드한 뒤 CNI 플러그인 바이너리를 /opt/cni/bin 디렉토리로 추출해요. 다른 릴리스 버전을 사용하려면 CNI_PLUGIN_VERSION 값을 갱신해요.
$ export ARCH_CNI=$( [ $(uname -m) = aarch64 ] && echo arm64 || echo amd64)
$ export CNI_PLUGIN_VERSION=v1.6.2
$ curl -L -o cni-plugins.tgz "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGIN_VERSION}/cni-plugins-linux-${ARCH_CNI}-${CNI_PLUGIN_VERSION}".tgz && \
sudo mkdir -p /opt/cni/bin && \
sudo tar -C /opt/cni/bin -xzf cni-plugins.tgz
Linux 배포판의 패키지 관리자가 CNI 참조 플러그인을 제공할 수 있지만, 알려진 버그 수정이 포함된 최신 안정 버전을 설치하는 것을 권장해요.
Nomad는 기본적으로 /opt/cni/bin 디렉토리에서 CNI 플러그인 바이너리를 찾아요. 그러나 바이너리를 다른 디렉토리에 설치한 다음 cni_path 속성으로 구성할 수 있어요.
브리지 모듈이 iptables로 트래픽을 라우팅하도록 구성
Nomad의 태스크 그룹 네트워크는 브리지 네트워킹과 iptables를 사용해 컨테이너 간 트래픽을 보내서 Consul의 서비스 메시와 통합돼요.
경고: Ubuntu 24.04 같은 새 Linux 버전은 기본적으로 브리지 네트워킹을 활성화하지 않을 수 있어요. 브리지 모듈이 없으면 sudo modprobe bridge로 로드해요.
Linux 커널 브리지 모듈에는 iptables가 브리지를 통과하는 트래픽을 처리할지 여부를 제어하는 세 가지 조정 가능한 파라미터가 있어요. RedHat, CentOS, Fedora를 포함한 일부 운영 체제는 이러한 조정 파라미터가 VM 워크로드에 최적화되어 있어 게스트 트래픽에 대해 iptables 규칙이 올바르게 구성되지 않을 수 있어요.
Linux 운영 체제 배포판이 iptables가 컨테이너 트래픽을 브리지 네트워크로 라우팅하도록 구성되었는지 확인해요. 다음 명령을 실행해 브리지 네트워크에 대한 iptables 처리를 허용하도록 조정 파라미터를 설정해요.
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-arptables
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
$ echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
클라이언트 노드 시작 시 이 설정을 유지하려면 /etc/sysctl.d/에 파일을 추가하거나 Linux 배포판이 해당 디렉토리에 두는 파일을 제거해요. 다음 예시는 클라이언트 노드에 대한 조정 파라미터를 구성해요.
/etc/sysctl.d/bridge.conf
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
CNI 플러그인으로 커스텀 브리지 모드 구성 만들기
Nomad 자체는 loopback, bridge, firewall, portmap CNI 참조 플러그인을 함께 구성해 Nomad의 브리지 네트워크를 만들어 bridge 네트워크 모드의 기본 구현으로 사용해요.
브리지 네트워크를 설정할 때 Nomad는 CNI Specification의 예시 구성에 기반한 구성 템플릿을 사용해요. 필드에 대한 완전한 설명은 그 문서를 참고해요.
기본 구성에서 지원되지 않는 옵션에 접근해야 하는 경우 다음 템플릿을 자체 CNI 기반 브리지 네트워크 구성의 기초로 사용할 수 있어요.
구성 파일
Default, IPv6, Transparent Proxy의 세 가지 예시가 있어요. 이 예시는 Nomad 클라이언트 구성의 두 기본값을 사용해요.
- bridge_network_name의 기본값은 bridge 플러그인 이름의 값이에요.
- 브리지 서브넷의 기본값 bridge_network_subnet은 bridge 플러그인 서브넷이에요.
NOMAD-ADMIN 내부 상수는 iptablesAdminChainName의 값을 제공해요. 자체 구성에서는 iptablesAdminChainName을 고유한 값으로 변경해야 해요.
{
"cniVersion": "1.0.0",
"name": "nomad",
"plugins": [
{
"type": "loopback"
},
{
"type": "bridge",
"bridge": "nomad",
"ipMasq": true,
"isGateway": true,
"forceAddress": true,
"hairpinMode": false,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "172.26.64.0/20"}]
],
"routes": [
{"dst": "0.0.0.0/0"}
],
"dataDir": "/var/run/cni"
}
},
{
"type": "firewall",
"backend": "iptables",
"iptablesAdminChainName": "NOMAD-ADMIN"
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"snat": true
}
]
}
예시 범위 2001:db8::/112를 사용해 Nomad 클라이언트 에이전트에서 IPv6를 구성하면 Nomad가 구성에 두 줄을 더 추가해요.
{
"cniVersion": "1.0.0",
"name": "nomad",
"plugins": [
{
"type": "loopback"
},
{
"type": "bridge",
"bridge": "nomad",
"ipMasq": true,
"isGateway": true,
"forceAddress": true,
"hairpinMode": false,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "172.26.64.0/20"}],
[{"subnet": "2001:db8::/112"}]
],
"routes": [
{"dst": "0.0.0.0/0"},
{"dst": "::/0"}
],
"dataDir": "/var/run/cni"
}
},
{
"type": "firewall",
"backend": "iptables",
"iptablesAdminChainName": "NOMAD-ADMIN"
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"snat": true
}
]
}
transparent_proxy 블록을 사용하는 작업은 CNI 구성의 맨 아래에 consul-cni 플러그인을 추가해요.
이 기능을 위해 노드가 올바르게 구성되었는지 확인하려면 Nomad의 Consul 서비스 메시 문서의 transparent proxy 섹션을 참고해요.
{
"cniVersion": "1.0.0",
"name": "nomad",
"plugins": [
{
"type": "loopback"
},
{
"type": "bridge",
"bridge": "nomad",
"ipMasq": true,
"isGateway": true,
"forceAddress": true,
"hairpinMode": false,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "172.26.64.0/20"}]
],
"routes": [
{"dst": "0.0.0.0/0"}
],
"dataDir": "/var/run/cni"
}
},
{
"type": "firewall",
"backend": "iptables",
"iptablesAdminChainName": "NOMAD-ADMIN"
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"snat": true
},
{
"type": "consul-cni",
"log_level": "debug"
}
]
}
이 구성은 다음 CNI 참조 플러그인을 사용해요.
- loopback: loopback 플러그인은 브리지 네트워크의 네트워크 네임스페이스 내부에 만들어진 기본 로컬 인터페이스 lo0를 UP으로 설정해요. 이렇게 하면 네임스페이스 내부에서 실행되는 워크로드가 네임스페이스별 loopback 인터페이스에 바인딩할 수 있어요.
- bridge: bridge 플러그인은 호스트 네트워크 네임스페이스에 있는
nomad라는 브리지(가상 스위치)를 만들어요. Nomad는 이 브리지가 할당에 네트워크 연결을 제공하기 위한 것이므로isGateway를true로 설정해 게이트웨이로 구성해요. 이는 플러그인에 브리지 인터페이스에 IP 주소를 할당하라고 알려줘요. 브리지 플러그인은 같은 호스트의 할당들을 호스트 네트워크 네임스페이스에 있는 가상 스위치 브리지로 연결해요. 기본적으로 Nomad는 각 클라이언트에 단일 브리지를 만들어요. Nomad의 브리지 네트워크는 할당에 네트워크 연결을 제공하도록 설계됐으므로, Nomad는ipam구성을 사용해 주소를 제공해 나가는 트래픽의 게이트웨이로 브리지 인터페이스를 구성해요. 기본 구성은 브리지 호스트 쪽의172.26.64.0/20서브넷에172.26.64.1을 호스트-로컬 주소로 만들어요. 할당을 브리지에 연결할 때 Nomad는 host-local 플러그인을 사용해 같은 서브넷에서 할당 주소를 만들어요. 구성은 또 할당에 대한 기본 경로를 호스트 쪽 브리지 주소로 지정해요. - firewall: firewall 플러그인은 호스트 네트워크를 통해 할당의 IP 주소로부터/로 트래픽을 허용하는 방화벽 규칙을 만들어요. Nomad는 firewall 플러그인에 iptables 백엔드를 사용해요. 이 구성은 filter 테이블에
CNI-FORWARD와NOMAD-ADMIN이라는 두 개의 새 iptables 체인을 만들고 주어진 인터페이스가 트래픽을 보내고 받을 수 있게 하는 규칙을 추가해요. firewall은iptablesAdminChainName값(이 예시에서는NOMAD-ADMIN)을 사용해 관리 체인을 만들어요. 관리 체인은 firewall 플러그인이 관리하는 규칙보다 먼저 실행되는 커스텀 규칙을 위한 사용자 제어 체인이에요. firewall 플러그인은 관리 체인의 규칙을 추가, 삭제, 수정하지 않아요. Nomad는FORWARD체인에CNI-FORWARD라는 새 체인을 추가해요.CNI-FORWARD는 Nomad가 할당을 만들 때 규칙을 추가하고 그 할당이 중지되면 규칙을 제거하는 체인이에요.CNI-FORWARD체인은 먼저 모든 트래픽을NOMAD-ADMIN체인으로 보내요. 각 체인의 iptables 규칙을 나열하려면iptables명령을 사용해요.$ sudo iptables -L - portmap: Nomad는 호스트의 특정 포트를 할당 네임스페이스에서 실행 중인 태스크에 매핑할 수 있어야 해요. portmap 플러그인은 네트워크 주소 변환(NAT) 규칙을 사용해 호스트의 하나 이상의 포트에서 할당으로 트래픽을 전달해요. 이 플러그인은 두 개의 체인·규칙 시퀀스를 설정해요. 하나는 대상을 다시 쓰는 기본 대상 NAT(DNAT) 시퀀스, 다른 하나는 필요에 따라 트래픽을 마스커레이드하는 소스 NAT(SNAT) 시퀀스예요. NAT 테이블의 iptables 규칙을 나열하려면
iptables명령을 사용해요.$ sudo iptables -t nat -L
브리지 네트워크 구성 파일을 Nomad가 접근할 수 있는 디렉토리에 저장해요. 기본적으로 Nomad는 /opt/cni/config 디렉토리에서 구성 파일을 로드해요. 그러나 cni_config_dir 파라미터로 다른 위치를 구성할 수 있어요. 예시는 Nomad 클라이언트 구성하기 섹션을 참고해요.
Nomad 클라이언트 구성
플러그인 실행 시점에 Nomad는 CNI 네트워크 구성을 해석해 플러그인의 인자로 변환해요.
Nomad는 cni_config_dir 파라미터(기본값 /opt/cni/config)에서 다음 파일을 읽어요.
- .conflist: Nomad가 플러그인 구성 목록을 포함하는 네트워크 구성으로 로드해요.
- .conf 및
.json: Nomad가 특정 네트워크에 대한 개별 플러그인 구성으로 로드해요.
각 클라이언트의 client.hcl 파일에 cni_path와 cni_config_dir 속성을 추가해요.
이 예시는 두 속성 모두에 기본값을 사용해요.
/etc/nomad.d/client.hcl
client {
enabled = true
cni_path = "opt/cni/bin"
cni_config_dir = "opt/cni/config"
}
다음 단계
작업 구성 세부 사항은 작업과 함께 CNI 네트워크 사용하기를 참고해요.