본문 바로가기
  • 오늘처럼
소프트웨어 아키텍처

Container Network Interface : CNI

by bluefriday 2021. 9. 3.
반응형

 

Container Network Interface : CNI

컨테이너는 자신만의 격리된 공간을 가지게 되며, 이 경우 특정 컨테이너는 컨테이너 안에서 내부적으로 독립된 네트워크 환경을 가지고 있는 것으로 보인다. 즉 외부의 다른 네트워크 환경을 전혀 알 수가 없게 되는 것인데, 여러 개의 컨테이너를 관리하거나 혹은 2개 이상의 모듈로 동작하는 시스템을 각각 컨테이너화 한 경우에는 컨테이너 간의 네트워킹도 필요하게 된다. 이를 위해서 컨테이너에게 가상의 네트워크 리소스를 부여하고 이를 관리해주는 것이 CNI 이다.

CNI는 CNCF(Cloud Native Computing Foundation) 에서 관리되는 프로젝트로, 네트워크 인터페이스를 구성하기 위해 필요한 플러그인과 스펙 및 라이브러리로 구성되어 있다. 수행하는 주 역할은 다음과 같다.

  • 컨테이너들의 네트워크 연결
  • 컨테이너 삭제 시 할당된 자원 제거

어플리케이션의 컨테이너화는 빠르게 발전되고 있고, 여러 경우에서의 네트워크 환경이 다르기 때문에 해결되야 하는 문제들 또한 다양한 형태로 존재하게 된다. Docker, containerd 와 같은 컨테이너 진영과 k8s 와 같은 오케스트레이터 진영에서는 이러한 다양한 문제들을 해결하기 위하여 네트워크 인터페이스를 플러그인의 형태로 만들고 있다. 또한 플러그인 간의 중복되는 기능을 피하기 위해 위해, 플러그인과 이를 실행하는 컨테이너 런타임(네트워크 네임스페이스) 사이에 공통된 인터페이스를 규정하였다. 이렇게 볼 때,  CNI 프로젝트는 아래와 같이 2가지 의미로 생각할 수 있다.

  1. 위 2가지 기능을 포함하여 컨테이너가 네트워크 플러그인을 실행하기 위한 공통의 인터페이스 규칙 (specification)
  2. 1번을 구현한 실제 네트워크 플러그인 솔루션 (3rd party plugins)

추가로 1번의 스펙은 다음같은 특징을 갖는다.

  • 특정 벤더에 의존하지 않으며, 이에 사실상의 컨테이너 오케스트레이션 표준인 Kubernetes 만을 위한 것은 아님
  • Mesos, CloudFoundary, podman, CRI-O 등에서도 사용
  • 네트워크의 동작에 대한 기본적인 실행 흐름 & 설정 양식 규정
  • 단순하며, 이전 버전과의 하위 호환성(backward compatible)을 유지

 

 

런타임과 CNI

CNI 가 컨테이너의 네트워크 리소스를 추가해준다고 했지만 컨테이너가 생성될 때는 실제로 런타임에 의해서 CNI 호출된다. 흐름으로 보면 컨테이너 런타임이 사용자나 혹은 오케스트레이션 툴에게 컨테이너 생성에 대한 요청을 받게 되는데, 이 때 각 컨테이너 런타임이 가지고 있는 고유의 런타임 설정 파일을 참조하게 된다.

예를 들어 containerd 를 컨테이너 런타임으로 사용하는 경우 /etc/containerd/config.toml 을 참조하게 되는데, 이 config.toml 파일에 cni 의 설정파일의 경로나 cni 실행 파일의 경로 등에 해당하는 설정값들을 포함하게 된다. 즉 컨테이너 런타임의 설정에 CNI 를 지정해주는 것이다.

이렇게 런타임의 설정에서 CNI와 관련된 설정을 찾게 되면 컨테이너 런타임은 해당 경로에서 cni의 설정을 확인하게 되고, 플러그인 형식으로 cni 바이너리 파일을 호출하여 생성한 컨테이너에 네트워크 자원을 할당해주게 된다.

 

 

CNI 의 설정 양식

위에서 언급한 설정 양식에 대해서 조금 더 살펴보자. CNI의 네트워크 구성은 하단 표와 같이 JSON 기반의 설정을 따르게 된다.

{
    "cniVersion": "1.0.0",
    "name": "dbnet",
    "plugins": [
        {
            "type": "bridge",
            // plugin specific parameters
            "bridge": "cni0",
            "keyA": ["some more", "plugin specific", "configuration"],
            "ipam": {
                "type": "host-local",
                // ipam specific
                "subnet": "10.1.0.0/16",
                "gateway": "10.1.0.1",
                "routes": [
                    {"dst": "0.0.0.0/0"}
                ]
            },
            "dns": {
               "nameservers": [ "10.1.0.1" ]
            }
        },
        {
            "type": "tuning",
            "capabilities":{
                "mac": true
            },
            "sysctl": {
                "net.core.somaxconn": "500"
            }
        },
        {
           "type": "portmap",
           "capabilities": {"portMappings": true}
        }
    ]
}


위 코드의 최상단에서 name, cniVersion, plugins 의 3개 key를 확인할 수 있다.

  • 'name' : 네트워크 설정의 이름으로, 호스트 상의 모든 네트워크 구성에서 유일해야 한다. 영문/숫자로 시작해야 하며 하나 이상의 영문/숫자, 밑줄(_), 점(.), 하이픈이 올 수 있다.
  • 'cniVersion' : 이 설정이 준수하는 CNI 스펙(사양)의 Semver(유의적 버전) 으로 현재는 1.0.0 버전을 사용한다.
  • 위 표에는 포함되어 있지 않지만 선택적으로 'disableCheck' 키가 존재하여 사용하지 않는 설정의 경우 런타임이 이 네트워크 구성을 CHECK 하지 않도록 한다.
  • 'plugins' : CNI 플러그인 및 해당 설정의 목록으로 하위 레벨에서 해당 플러그인의 상세 설정을 포함한다. 위에 정의된 필드 외에도 추가 필드를 포함할 수 있다.

 

 

이렇게 CNI 의 스펙으로 구현한 CNI 3rd project 로는 Calico, Weave, Cilium 등이 있는데 각각 지원하는 기능의 범위가 다르고 고유의 장단점 등을 가지고 있다. 운영하려는 환경에 필요한 네트워크 요건을 파악하고 적절한 CNI를 선택하도록 하자. 

 

 

 

댓글