ACL 정책 개요

ACL 정책 개요 (ACL policy overview)

Nomad는 데이터와 API에 대한 접근을 제어하는 데 사용할 수 있는 선택적 ACL(Access Control List) 시스템을 제공해요. ACL 시스템은 기능(capability) 기반이며, 어떤 세분화된 규칙을 적용할 수 있는지 결정하는 정책과 연관된 토큰에 의존해요.

출처: 문서

본문

ACL 정책은 HashiCorp Configuration Language (HCL)로 작성돼요. 이 언어는 사람이 읽기 쉽도록 설계됐어요. HCL 인터프리터는 JSON도 파싱하므로 기계 생성 구성의 사용을 용이하게 해요.

ACL 정책은 하나 이상의 규칙을 포함해요. 규칙은 거친 수준(coarse-grained)의 정책 처분(policy disposition)을 포함해요. 규칙에는 일반적으로 여러 정책 처분이 있어요:

  • read: 리소스를 읽을 수는 있지만 수정할 수는 없게 허용해요.
  • write: 리소스를 읽고 수정할 수 있게 허용해요.
  • deny: 리소스를 읽거나 수정하지 못하게 해요. 여러 정책이 토큰과 연관될 때 deny가 우선해요.
  • list: 리소스를 나열할 수는 있지만 상세히 검사할 수는 없게 허용해요. 플러그인에만 적용돼요.

namespace와 host_volume 같은 일부 규칙은 정책 설계자가 거친 수준의 정책 처분, 세분화된(fine-grained) 기능, 또는 둘의 조합으로 정책을 지정할 수 있게 해요.

ACL 정책 명세

ACL 정책은 하나 이상의 규칙의 조합이에요. HCL 형식의 명세는 다음과 같아요:

namespace "default" {
  policy = "read"
}

# Allow writing to the `foo` namespace
namespace "foo" {
  policy = "write"
}

agent {
  policy = "read"
}

node {
  policy = "read"
}

quota {
  policy = "read"
}

같은 정책의 JSON 표현:

  "namespace": {
    "default": {
      "policy": "read"
    },
    "foo": {
      "policy": "write"
    }
  },
  "agent": {
    "policy": "read"
  },
  "node": {
    "policy": "read"
  },
  "quota": {
    "policy": "read"
  }
}

ACL Policy API는 규칙 섹션의 내용을 정의하는 데 HCL 또는 JSON을 사용할 수 있게 해요. HCL은 운영자에게 더 친숙하고 주석을 허용하도록 설계되었으므로, 이 튜토리얼에서는 모든 예제와 스니펫에 HCL을 사용할 거예요.

네임스페이스 규칙

Nomad는 운영자가 여러 네임스페이스를 만들어 클러스터 리소스에 대한 세분화된 접근을 제공할 수 있게 해요.

namespace 규칙은 네임스페이스에 대한 접근을 제어해요. 네임스페이스는 클러스터의 활성 작업 대부분을 담고 있어요 — Jobs API, Deployments API, Allocations API, Evaluations API.

  policy = "write"
}

namespace "sensitive" {
  policy = "read"
}

네임스페이스 규칙은 적용되는 네임스페이스 이름으로 키가 지정돼요. 네임스페이스가 지정되지 않으면 "default" 네임스페이스가 사용돼요. 예를 들어 위 정책은 default 네임스페이스에 쓰기 접근을, sensitive 네임스페이스에 읽기 접근을 부여해요. 모든 네임스페이스에 접근을 부여하려면 와일드카드 네임스페이스("*")를 사용할 수 있어요.

세분화된 기능 (Fine-grained capabilities)

거친 수준의 policy 처분 외에도 namespace 스탠자는 더 세분화된 capabilities 목록을 설정할 수 있게 해요.

  • deny — 여러 정책이 토큰과 연관될 때 deny가 우선하고 모든 기능을 방지해요.
  • list-jobs — 작업을 나열하고 거친 수준의 상태를 볼 수 있게 해요.
  • parse-job — 작업을 HCL에서 JSON으로 파싱할 수 있게 해요.
  • read-job — 작업을 검사하고 세분화된 상태를 볼 수 있게 해요.
  • submit-job — 작업을 제출, 업데이트, 중지할 수 있게 해요.
  • dispatch-job — 작업을 디스패치할 수 있게 해요.
  • read-logs — 작업과 연관된 로그를 볼 수 있게 해요.
  • read-fs — 연관된 할당의 파일시스템을 볼 수 있게 해요.
  • alloc-exec — 운영자가 실행 중인 할당에 연결해 명령을 실행할 수 있게 해요.
  • alloc-node-exec — 운영자가 raw_exec 작업과 같이 파일시스템 격리 없이 실행되는 할당에 연결해 명령을 실행할 수 있게 해요.
  • alloc-lifecycle — 운영자가 개별 할당을 수동으로 중지할 수 있게 해요.
  • csi-register-plugin — 자신을 CSI 플러그인으로 등록하는 작업을 제출할 수 있게 해요.
  • csi-write-volume — CSI 볼륨을 등록하거나 등록 해제할 수 있게 해요.
  • csi-read-volume — CSI 볼륨을 검사하고 세분화된 상태를 볼 수 있게 해요.
  • csi-list-volume — CSI 볼륨을 나열하고 거친 수준의 상태를 볼 수 있게 해요.
  • csi-mount-volume — CSI 볼륨을 요구하는 작업을 제출할 수 있게 해요.
  • list-scaling-policies — 스케일링 정책을 나열할 수 있게 해요.
  • read-scaling-policy — 스케일링 정책을 검사할 수 있게 해요.
  • read-job-scaling — 작업의 현재 스케일링을 검사할 수 있게 해요.
  • scale-job: 작업을 위아래로 스케일링할 수 있게 해요.
  • sentinel-override — soft mandatory 정책을 재정의할 수 있게 해요.

거친 수준의 정책 처분은 다음과 같은 세분화된 네임스페이스 기능의 축약형이에요:

정책 기능
deny deny
read list-jobs, parse-job, read-job, csi-list-volume, csi-read-volume, list-scaling-policies, read-scaling-policy, read-job-scaling
write list-jobs, parse-job, read-job, submit-job, dispatch-job, read-logs, read-fs, alloc-exec, alloc-lifecycle, csi-write-volume, csi-mount-volume, list-scaling-policies, read-scaling-policy, read-job-scaling, scale-job
scale list-scaling-policies, read-scaling-policy, read-job-scaling, scale-job

정책 축약형과 기능 목록이 모두 제공되면 기능이 병합돼요. 다음 정책은 submit-job 기능을 read 정책 처분에 추가하여 list-job과 read-job 기능을 제공해요:

# jobs to this namespace, without allowing access to view log output or inspect
# the filesystem.
namespace "default" {
  policy       = "read"
  capabilities = ["submit-job"]
}

이 정책은 다음과 같이 표현할 수도 있어요:

# jobs to this namespace, without allowing access to view log output or inspect
# the filesystem.
namespace "default" {
  capabilities = [
    "csi-read-volume",
    "csi-list-volume",
    "submit-job",
    "list-jobs",
    "read-job",
    "parse-job",
    "read-job-scaling",
    "list-scaling-policies",
    "read-scaling-policy",
  ]
}

네임스페이스 정의에는 와일드카드 기호(glob)도 포함될 수 있어 단일 정책 정의가 네임스페이스 집합에 적용되게 할 수 있어요. 예를 들어 아래 정책은 대부분의 프로덕션 네임스페이스에 읽기 접근을 허용하지만 "production-api" 네임스페이스에는 쓰기 접근을, "production-web" 네임스페이스에는 모든 접근을 거부해요.

  policy = "read"
}

namespace "production-api" {
  policy = "write"
}

namespace "production-web" {
  policy = "deny"
}

네임스페이스 규칙은 하나만 적용될 수 있어요. Nomad가 ACL 정책에 대해 작업을 확인할 때, 먼저 *정확히 일치(exact match)*하는지 확인한 다음 glob 기반 조회로 대체해 네임스페이스 규칙을 선택해요. glob로 네임스페이스를 조회할 때 Nomad는 일치하는 문자가 가장 많은 규칙을 선택해요. 즉 Nomad는 문자 차이가 가장 작은 규칙, 즉 일치 문자가 가장 많은 규칙을 선택해요.

이 예제에서 'production-web' 네임스페이스가 있다고 가정해요. "*-web" 규칙의 경우 9개 문자가 일치해요. 문자 차이는 4예요. "*" 규칙의 경우 일치하는 문자가 없어요. 문자 차이는 13이에요. Nomad는 일치 문자가 가장 많으므로 "*-web" 규칙을 선택해요.

  policy = "deny"
}

namespace "*" {
  policy = "write"
}

더 세분화된 기능 (Finer-grained capabilities)

또한 더 세분화된 capabilities가 존재하여 submit-job 기능으로 부여되는 명시적 능력을 부여할 수 있어요. 이러한 기능은 더 구체적인 API 작업에 매핑되며 조합하여 특정 능력 집합을 허용할 수 있어요.

  • register-job — 새 작업을 실행하거나 등록할 수 있게 해요.
  • revert-job — 작업을 이전 버전으로 되돌릴 수 있게 해요.
  • deregister-job — 작업을 중지할 수 있게 하지만 수동 제거(purge)는 허용하지 않아요. 작업은 여전히 가비지 컬렉션 중 제거돼요.
  • purge-job — 작업을 중지하고 제거할 수 있게 해요.
  • evaluate-job — 작업에 대한 평가를 할 수 있게 해요.
  • plan-job — 작업을 계획할 수 있게 해요.
  • tag-job-version — 작업 버전에 태그를 지정할 수 있게 해요.
  • stable-job — 작업 버전을 안정적(stable)으로 표시할 수 있게 해요.
  • fail-deployment — 배포를 실패 처리할 수 있게 해요.
  • pause-deployment — 배포를 일시 중지할 수 있게 해요.
  • promote-deployment — 배포를 승격(promote)할 수 있게 해요.
  • unblock-deployment — 배포의 차단을 해제할 수 있게 해요.
  • cancel-deployment — 배포를 취소할 수 있게 해요.
  • set-alloc-health-deployment — 배포에서 할당의 상태를 수동으로 설정할 수 있게 해요.
  • force-periodic-job — 주기적 작업을 수동으로 일시 중지할 수 있게 해요. Enterprise
  • pause-allocation — 할당을 일시 중지할 수 있게 해요. Enterprise
  • gc-allocation — 할당을 수동으로 가비지 컬렉션할 수 있게 해요. 보통 운영자가 사용해요.
  • delete-service-registration — 개별 서비스 등록을 삭제할 수 있게 해요. 보통 운영자가 사용해요.

노드 규칙

node 규칙은 노드를 나열하거나 노드 드레인을 트리거하는 것 같은 Node API에 대한 접근을 제어해요. 노드 규칙은 node 키를 사용해 모든 노드에 대해 지정돼요:

  policy = "read"
}

Nomad ACL 정책당 노드 규칙은 하나만 허용되며, 그 값은 정책 처분 중 하나로 설정돼요.

에이전트 규칙

agent 규칙은 join과 leave 같은 Agent API의 유틸리티 작업에 대한 접근을 제어해요. 에이전트 규칙은 agent 키를 사용해 모든 에이전트에 대해 지정돼요:

  policy = "write"
}

Nomad ACL 정책당 에이전트 규칙은 하나만 허용되며, 그 값은 정책 처분 중 하나로 설정돼요.

운영자 규칙

operator 규칙은 Operator API에 대한 접근을 제어해요. 운영자 규칙은 다음과 같아요:

  policy = "read"
}

Nomad ACL 정책당 운영자 규칙은 하나만 허용되며, 그 값은 정책 처분 중 하나로 설정돼요. 위 예제에서 토큰은 진단 목적으로 operator 엔드포인트를 쿼리하는 데 사용할 수 있지만 어떤 변경도 할 수 없어요.

할당량 규칙

quota 정책은 할당량 생성·삭제 같은 Quota API의 할당량 명세 작업에 대한 접근을 제어해요. 할당량 규칙은 quota 키를 사용해 모든 할당량에 대해 지정돼요:

  policy = "write"
}

Nomad ACL 정책당 할당량 규칙은 하나만 허용되며, 그 값은 정책 처분 중 하나로 설정돼요.

호스트 볼륨 규칙

host_volume 정책은 호스트 볼륨의 마운트와 접근을 제어해요.

  policy = "write"
}

host_volume "prod-*" {
  policy = "deny"
}

host_volume "prod-ca-certificates" {
  policy = "read"
}

호스트 볼륨 규칙은 적용되는 볼륨 이름으로 키가 지정돼요. 네임스페이스와 마찬가지로 와일드카드를 사용해 볼륨 집합에 동일한 구성을 재사용할 수 있어요. 거친 수준의 정책 명세 외에도 host_volume 스탠자는 더 세분화된 기능 목록을 설정할 수 있게 해요. 여기에는 다음이 포함돼요:

  • deny — 사용자가 볼륨을 어떤 방식으로든 마운트하지 못하게 해요.
  • mount-readonly — 사용자가 볼륨을 readonly로만 마운트할 수 있게 해요.
  • mount-readwrite — host_volume 구성이 허용한다면 사용자가 볼륨을 readonly 또는 readwrite로 마운트할 수 있게 해요.

거친 수준의 정책 권한은 세분화된 기능의 축약형이에요:

  • deny 정책 — ["deny"]
  • read 정책 — ["mount-readonly"]
  • write 정책 — ["mount-readonly", "mount-readwrite"]

정책 축약형과 기능 목록이 모두 제공되면 기능이 병합돼요.

참고: 호스트 볼륨 정책은 볼륨을 사용하려고 할 때 적용돼요. 이 구성과 관계없이 Node API에 접근할 수 있는 사용자는 nomad node status 명령이나 API 호출로 사용 가능한 볼륨을 나열할 수 있어요.

플러그인 규칙

plugin 정책은 플러그인을 나열하거나 플러그인 상태를 가져오는 것 같은 CSI 플러그인에 대한 접근을 제어해요. 플러그인 규칙은 plugin 키를 사용해 모든 플러그인에 대해 지정돼요:

  policy = "read"
}

Nomad ACL 정책당 플러그인 규칙은 하나만 허용되며, 그 값은 정책 처분 중 하나로 설정돼요. 위 예제에서 토큰은 진단 목적으로 plugin 엔드포인트를 쿼리하는 데 사용할 수 있어요. 플러그인 등록은 플러그인 작업의 네임스페이스에 대한 csi-register-plugin 정책으로 제어된다는 점에 유의해요.

다음 단계 (Next steps)

이제 Nomad ACL 정책의 기본 구성 요소를 배웠으니, 다음 섹션에서 이 지식을 실천에 옮길 수 있어요.

더 알아보기 (Learn more)