Isolated Fork/Exec 작업 드라이버 구성하기

Isolated Fork/Exec 작업 드라이버 구성하기

이름: exec

exec 드라이버는 작업을 위해 특정 명령을 실행하는 데 사용돼요. 하지만 raw_exec와 달리 운영 체제의 기본 격리(Isolation) 프리미티브를 사용해 작업의 리소스 접근을 제한해요. 단순하지만 exec 드라이버는 어떤 명령이든 호출할 수 있으므로, 더 높은 수준의 기능을 제공하는 스크립트나 다른 래퍼를 호출하는 데 사용할 수 있어요.

출처: 문서

본문

기능

exec 드라이버는 다음 기능을 구현해요.

Feature Implementation
nomad alloc signal true
nomad alloc exec true
filesystem isolation chroot
network isolation host, group
volume mounting all

클라이언트 요구사항

exec 드라이버는 Linux에서 root로 노마드를 실행할 때만 실행할 수 있어요. exec는 리소스 격리가 현재 Linux에서만 보장되기 때문에 이 구성으로 제한돼요. 또한 드라이버가 동작하려면 호스트에 cgroups가 제대로 마운트되어 있어야 해요.

다음 오류를 받고 있다면:

* Constraint "missing drivers" filtered <> nodes

exec 드라이버를 사용하는 경우 root로 노마드를 실행하고 있는지 확인해 주세요. 이는 -dev 모드로 노마드를 실행하는 경우에도 적용돼요.

플러그인 옵션

  • default_pid_mode (string: optional) — 기본값은 "private"이에요. 작업에 대해 PID 네임스페이스 격리를 기본적으로 활성화하려면 "private"으로, 격리를 비활성화하려면 "host"로 설정해요.

    ⚠️ "host"로 설정하면 같은 사용자로 실행 중인 다른 프로세스가 환경 변수 같은 민감한 프로세스 정보에 접근할 수 있게 돼요.

  • default_ipc_mode (string: optional) — 기본값은 "private"이에요. 작업에 대해 IPC 네임스페이스 격리를 기본적으로 활성화하려면 "private"으로, 격리를 비활성화하려면 "host"로 설정해요.

    ⚠️ "host"로 설정하면 같은 사용자로 실행 중인 다른 프로세스가 예상치 못한 POSIX 신호 보내기 같은 IPC 기능을 사용할 수 있게 돼요.

  • no_pivot_root (bool: optional) — 기본값은 false예요. true일 때 드라이버는 pivot_root 없이 chroot를 사용해 파일시스템 격리를 수행해요. 루트가 램디스크에 있는 시스템에서 유용해요.
  • allow_caps — 허용되는 Linux 기능(capabilities) 목록이에요. 기본값은
    ["audit_write", "chown", "dac_override", "fowner", "fsetid", "kill", "mknod",
     "net_bind_service", "setfcap", "setgid", "setpcap", "setuid", "sys_chroot"]
    
    이며, docker가 기본적으로 허용하는 기능(NET_RAW 제외)을 모델로 해요. 운영자가 cap_add와 cap_drop 옵션으로 작업이 획득할 수 있는 기능을 제어할 수 있게 해요. 운영 체제가 지원하는 모든 기능을 허용 목록에 넣는 단축값으로 "all" 값을 지원해요.

    ⚠️ 기본 이상의 기능을 더 허용하면 신뢰할 수 없는 작업이 호스트 시스템을 손상시킬 수 있는 등 바람직하지 않은 결과를 초래할 수 있어요.

  • denied_host_uids (Optional) — 거부할 쉼표로 구분된 호스트 uid 목록을 지정해요. 범위는 두 포함 끝점을 구분하는 하이픈으로 지정할 수 있어요. 작업 구성에 "user" 값이 지정되어 있고 그 사용자의 user id가 주어진 범위 안에 있으면, 작업은 시작 전에 오류가 나요. Windows 클라이언트에서는 확인되지 않아요.
    config {
      denied_host_uids = "0,10-15,22"
    }
    
  • denied_host_gids (Optional) — 거부할 쉼표로 구분된 호스트 gid 목록을 지정해요. 범위는 두 포함 끝점을 구분하는 하이픈으로 지정할 수 있어요. 작업 구성에 "user" 값이 지정되어 있고 그 사용자가 지정된 범위의 gid를 가진 그룹 중 하나에 속하면, 작업은 시작 전에 오류가 나요. Windows 클라이언트에서는 확인되지 않아요.
    config {
      denied_host_gids = "2,4-8"
    }
    

클라이언트 속성

exec 드라이버는 다음 클라이언트 속성을 설정해요:

  • driver.exec — 드라이버가 사용 가능함을 나타내도록 "1"로 설정돼요.

리소스 격리

제공되는 리소스 격리는 클라이언트의 운영 체제와 구성에 따라 달라져요.

Linux에서 노마드는 cgroups와 chroot를 사용해 프로세스의 리소스를 격리하며, 따라서 노마드 에이전트는 root로 실행해야 해요. 일부 Linux 배포판은 기본적으로 필요한 모든 cgroups를 켜고 부팅하지 않아요. /proc/cgroups를 읽어 어떤 cgroups가 활성화되어 있는지 확인하고, 다음 모든 cgroups가 활성화되어 있는지 검증할 수 있어요:

$ awk '{print $1 " " $4}' /proc/cgroups
#subsys_name enabled
cpuset 1
cpu 1
cpuacct 1
blkio 1
memory 1
devices 1
freezer 1
net_cls 1
perf_event 1
net_prio 1
hugetlb 1
pids 1

노마드는 필요한 컨트롤러가 모두 사용 가능할 때만 cgroup으로 리소스를 제어할 수 있어요. 필요한 cgroup이 하나라도 없으면 노마드는 cgroup이 필요한 리소스 제어를 완전히 비활성화해요. 자세한 내용은 cgroup 컨트롤러 요구사항 문서를 참고해 주세요.

Chroot

Chroot는 현재 프로세스와 모든 자식 프로세스의 루트 디렉터리를 바꿔요. 노마드는 chroot 환경을 사용해 파일시스템 격리를 구현해요.

노마드는 다음 호스트 머신 디렉터리의 데이터로 chroot 환경을 채워요:

[
  "/bin",
  "/etc",
  "/lib",
  "/lib32",
  "/lib64",
  "/run/resolvconf",
  "/sbin",
  "/usr",
]

노마드는 호스트의 데이터를 chroot로 링크하거나 복사해 작업의 chroot 환경을 채워요. 이는 상당한 디스크 공간을 차지할 수 있다는 점을 유의하세요. 클라이언트가 로컬에서 가비지 컬렉션을 관리하므로 이로 인해 생길 수 있는 문제를 완화해요.

⚠️ chroot 제한: 노마드는 기본적으로 /run 디렉터리의 일시적인 런타임 파일을 복사하지 않아요. 예를 들어 Ubuntu에서 /etc/resolv.conf는 /run/systemd/resolve/stub-resolv.conf에 대한 심볼릭 링크이므로, 노마드는 resolv.conf를 chroot 환경에 복사하지 않아요.

이런 경우 각 chroot 작업을 위해 작업의 네트워크 블록을 구성해 주세요.

에이전트 클라이언트의 chroot_env 속성으로 chroot 환경 목록을 구성해요.

CPU

노마드는 CPU 공유(shares)를 기준으로 exec 작업의 CPU를 제한해요. CPU 공유는 컨테이너가 CPU 한도를 넘어 버스트할 수 있게 해요. CPU 한도는 리소스에 경합이 있을 때만 부과돼요. 호스트에 로드가 걸리면 프로세스가 가진 공유 수에 따라 QoS를 안정화하기 위해 스로틀될 수 있어요. NOMAD_CPU_LIMIT를 읽으면 프로세스에 사용 가능한 CPU 공유 수를 알 수 있어요. 1000 공유는 약 1GHz와 같아요.

노마드에서 워크로드를 로드 테스트할 때 CPU 공유의 의미를 염두에 두세요.

resources.cores가 설정되면 작업에 사용할 격리된 예약 CPU 코어 집합이 주어져요. 작업이 실행될 수 있는 전체 코어 집합은 전용 집합과 예약되지 않은 코어의 가변 집합을 합친 것이에요. 전용 CPU 코어 집합은 NOMAD_CPU_CORES를 읽으면 프로세스에 사용 가능해요.

다음 단계

작업에서 Isolated Fork/Exec 작업 드라이버를 사용해요.

더 알아보기 (Learn more)