Consul ACL 통합
Consul ACL 통합 (Integrate Consul ACL)
Consul ACL 시스템은 클러스터를 승인되지 않은 접근으로부터 보호해요. 활성화되면 통합이 작동하도록 Consul과 Nomad를 모두 적절히 구성해야 해요.
출처: 문서
본문
Nomad 에이전트는 자체 Consul ACL 토큰으로 구성되어야 하며, Consul은 Nomad에서 실행되는 태스크와 서비스의 워크로드 아이덴티티를 수락하도록 구성되어야 해요.
Consul과 Nomad 통합에 대한 자세한 내용은 다음을 참고해요:
- Nomad와 Consul 구성을 위한 에이전트 구성의
consul블록 - Consul 서비스 디스커버리·서비스 메시 통합에 대한 자세한 내용은 Consul 네트워킹 통합 가이드
Nomad 에이전트
Nomad 에이전트는 서비스 카탈로그에 자신을 등록하고 자동 클러스터링을 위해 서비스 디스커버리를 통해 다른 Nomad 에이전트를 발견하기 위해 Consul에 접근해야 해요. Nomad 클라이언트는 Workload Identity의 Consul 토큰을 사용해 서비스와 체크를 등록하지만, 등록 해제(deregister)하려면 자체 토큰에 대한 권한이 필요해요. Nomad 서버는 Consul Service Mesh용 구성 항목(Configuration Entries)도 만들므로, Nomad 서버와 클라이언트 간에 특정 권한이 약간 달라요. 다음 Consul ACL 정책은 Nomad 서버와 클라이언트가 필요로 하는 최소 권한을 나타내요.
Nomad 서버:
policy = "read"
}
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "write"
}
acl = "write"
mesh = "write"
Nomad 클라이언트:
policy = "read"
}
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "write"
}
Nomad 워크로드 아이덴티티
Nomad 클라이언트는 태스크나 서비스의 워크로드 아이덴티티를 사용해 Consul에 인증하고 서비스나 태스크 고유의 ACL 토큰을 얻을 수 있어요. Nomad 워크로드 아이덴티티를 사용하면 모든 할당이 자체 Consul ACL 토큰을 가져요.
워크로드 아이덴티티가 없으면 할당은 Nomad 클라이언트 에이전트 자체의 Consul 토큰을 사용하도록 폴백해요. 이는 더 간단한 접근 방식이지만 같은 노드의 모든 워크로드가 Consul의 동일한 데이터에 접근할 수 있게 해요. 이 방식이 환경에 적합하다면 [워크로드 아이덴티티가 없는 Consul]을 참고해요.
기본적으로 Nomad는 서비스에 대한 워크로드 아이덴티티를 생성하지 않으며, 태스크는 template 블록에서 Variables를 읽는 것처럼 Nomad 자체의 데이터에 접근하는 데 사용할 수 있는 아이덴티티만 받아요. 워크로드 아이덴티티로 Consul에 접근하려면 작업에 identity 블록으로 정의된 추가 워크로드 아이덴티티가 있어야 해요.
모든 작업에 이러한 추가 아이덴티티를 추가하지 않으려면 Nomad 서버를 consul.service_identity 및 consul.task_identity 에이전트 구성으로 설정할 수 있어요. 작업 등록 시 Nomad 서버는 consul 블록이 있는 태스크와 Consul 서비스 공급자를 사용하는 서비스를 이러한 기본 아이덴티티로 업데이트해요.
template 블록을 포함하는 작업 명세에는 Nomad가 템플릿 데이터의 내용을 해독할 수 없기 때문에 기본 아이덴티티가 제공되지 않아요. 작업 명세에서 Consul에 필요한 아이덴티티를 지정해야 해요. 자세한 내용은 identity 블록 문서의 Consul용 워크로드 아이덴티티 섹션을 참고해요.
작업에서 직접 Consul용 아이덴티티를 지정할 수도 있어요. 제공되면 Nomad 서버 구성을 재정의해요. 자세한 내용은 identity 블록 문서의 Consul용 워크로드 아이덴티티 섹션을 참고해요.
Consul 인증 구성
Nomad의 워크로드 아이덴티티를 받고, 검증하고, 신뢰하도록 Consul을 구성해야 해요. 이 아이덴티티는 JSON Web Tokens (JWTs)로 인코딩되므로 JWT ACL auth method를 만들어야 해요. auth method는 Nomad가 워크로드 아이덴티티를 Consul ACL 토큰으로 교환하는 데 사용할 수 있는 엔드포인트예요.
자세한 내용은 Consul의 Auth Methods Overview 문서를 참고해요.
Consul Auth Method
auth method 구성은 Nomad의 JSON Web Key Set (JWKS) URL을 가리켜요. Consul 서버는 이 URL을 호출해 Nomad가 워크로드 아이덴티티를 서명하는 데 사용하는 공개 키를 검색해요. 이 키로 Consul은 그 기원을 검증하고 실제로 Nomad가 만들었음을 확인할 수 있어요.
Nomad는 삭제된 Consul 토큰을 재생성할 수 없어요. auth method 구성에서 MaxTokenTTL 필드는 절대 설정하면 안 돼요. auth method에서 TokenLocality: "global"을 설정하지 않는 한 Consul 토큰은 Consul 데이터센터에 로컬이에요. 기본값인 로컬 토큰을 사용하는 것이 권장돼요. 글로벌 토큰은 할당이 시작될 때 기본 Consul 데이터센터를 사용할 수 있어야 해요.
auth-method.json:
"JWKSURL": "https://nomad.example.com:4646/.well-known/jwks.json",
"JWTSupportedAlgs": ["RS256"],
"BoundAudiences": ["consul.io"],
"ClaimMappings": {
"nomad_namespace": "nomad_namespace",
"nomad_job_id": "nomad_job_id",
"nomad_task": "nomad_task",
"nomad_service": "nomad_service"
}
}
JWKSURL 주소는 모든 Consul 서버가 도달할 수 있어야 하며, 단일 장애 지점을 피하기 위해 여러 Nomad 에이전트로 확인되어야 해요. Nomad 서버와 클라이언트 모두 이 요청을 처리할 수 있어요.
JWKSURL 값 구성 방법에 대한 추가 정보는 JWKS URL에 관한 중요 고려 사항 섹션을 참고해요.
Consul에 접근해야 하는 할당이 시작되면 이를 실행하는 Nomad 클라이언트가 태스크와 서비스에 대한 Nomad 워크로드 아이덴티티를 Consul ACL 토큰으로 교환해요.
또한 auth method는 승인된 audience 값 목록을 정의하며, 이 목록은 Nomad 워크로드 아이덴티티 aud 파라미터에 정의된 값과 최소 하나 이상 일치해야 해요. 보안상의 이유로 단일 audience 값만 정의하는 것이 권장돼요.
auth-method.json:
"JWKSURL": "http://nomad.example.com:4646/.well-known/jwks.json",
"JWTSupportedAlgs": ["RS256"],
"BoundAudiences": ["consul.io"],
"ClaimMappings": {
"nomad_namespace": "nomad_namespace",
"nomad_job_id": "nomad_job_id",
"nomad_task": "nomad_task",
"nomad_service": "nomad_service"
}
}
Nomad 워크로드 아이덴티티에는 Consul ACL 구성에서 동적 값으로 참조할 수 있는 일련의 클레임(claims)이 있어요. auth method는 이러한 클레임 중 어느 것을 나머지 구성에서 사용할 수 있게 할지 결정해요.
auth-method.json:
"JWKSURL": "http://nomad.example.com:4646/.well-known/jwks.json",
"JWTSupportedAlgs": ["RS256"],
"BoundAudiences": ["consul.io"],
"ClaimMappings": {
"nomad_namespace": "nomad_namespace",
"nomad_job_id": "nomad_job_id",
"nomad_task": "nomad_task",
"nomad_service": "nomad_service"
}
}
Consul 바인딩 규칙
Consul auth method는 바인딩 규칙을 사용해 생성된 ACL 토큰에 적용되는 정책 집합을 결정해요. Nomad 워크로드 아이덴티티는 두 가지 주요 목적, 즉 서비스 등록과 태스크의 template 블록을 사용해 Consul에서 구성 값·서비스 주소 검색에 사용될 수 있어요. 각 목적에는 서로 다른 권한의 토큰이 필요하므로 Nomad에는 두 개의 바인딩 규칙이 필요해요.
첫 번째 바인딩 규칙은 Consul ACL 토큰을 서비스 아이덴티티와 연관시켜 토큰이 특정 서비스를 등록하고 수명주기를 관리할 수 있게 해요. 이 바인딩 규칙은 nomad_service 클레임이 있는 것은 서비스뿐이므로 서비스에 대한 Nomad 워크로드 아이덴티티에만 적용돼요.
-method 'nomad-workloads' \
-bind-type 'service' \
-bind-name '${value.nomad_service}' \
-selector '"nomad_service" in value'
-bind-name 플래그는 토큰이 Nomad 워크로드 아이덴티티 클레임에 정의된 것과 같은 이름의 서비스만 수정할 수 있도록 제한해요. -selector 플래그는 이 바인딩 규칙이 서비스에 대한 워크로드 아이덴티티에만 적용되도록 해요.
두 번째 바인딩 규칙은 Consul ACL 토큰을 ACL 역할과 연관시켜요. ACL 역할은 토큰이 수행할 수 있는 작업을 정의하는 ACL 정책의 모음이에요. 이 바인딩 규칙은 Consul에서 정보에 접근하기 위한 태스크에 대한 Nomad 워크로드 아이덴티티에 적용돼요. 정확한 ACL 정책 규칙은 태스크가 요구하는 접근 수준에 따라 달라져요(일반적으로 template 블록으로 서비스 주소와 KV에 접근).
-method 'nomad-workloads' \
-bind-type 'role' \
-bind-name 'nomad-tasks-${value.nomad_namespace}' \
-selector '"nomad_service" not in value'
-bind-name 플래그는 토큰에 사용되는 역할을 정의해요. Nomad 워크로드 아이덴티티의 클레임 값을 참조하여 다른 태스크에 다른 역할을 적용할 수 있어요. 서비스에 대한 바인딩 규칙과 유사하게, -selector 플래그는 nomad_service 클레임이 없으므로 이 바인딩 규칙이 태스크에 대한 워크로드 아이덴티티에만 적용되도록 해요.
전체 구성 구조는 다음 다이어그램에 설명되어 있어요.
consul.service_auth_method 및 consul.task_auth_method 구성은 Nomad가 서비스와 태스크에 대한 Consul ACL 토큰을 검색하는 데 사용하는 auth method를 정의해요.
기본적으로 둘 다 위에 설명된 구조를 따르며 둘 다 단일 auth method를 사용하지만, 결과로 나오는 각각의 Consul ACL 토큰에 예상되는 서비스 아이덴티티와 역할이 적용된다면 두 개의 서로 다른 auth method를 사용할 수도 있어요.
Consul 네임스페이스 규칙 (Enterprise)
Consul Enterprise는 여러 네임스페이스를 지원하며, Nomad Enterprise는 작업이 consul.namespace 파라미터를 사용해 서비스를 등록하고 다른 Consul 네임스페이스의 KV 데이터를 읽을 수 있게 해요.
Nomad Enterprise에서 namespace 값이 있는 consul 블록의 범위 내에 배치된 태스크와 서비스의 워크로드 아이덴티티에는 워크로드에 대해 Nomad에 정의된 Consul 네임스페이스를 나타내는 consul_namespace라는 추가 클레임이 있어요. 다중 네임스페이스 환경에서는 auth method가 consul_namespace 클레임 매핑을 포함하도록 구성해야 해요.
auth-method.json:
"JWKSURL": "https://nomad.example.com:4646/.well-known/jwks.json",
"JWTSupportedAlgs": ["RS256"],
"BoundAudiences": ["consul.io"],
"ClaimMappings": {
"consul_namespace": "consul_namespace",
"nomad_namespace": "nomad_namespace",
"nomad_job_id": "nomad_job_id",
"nomad_task": "nomad_task",
"nomad_service": "nomad_service"
}
}
default Consul 네임스페이스에 auth method와 바인딩 규칙을 만들고, 일련의 NamespaceRules로 auth method를 구성해야 해요.
-name 'nomad-workloads' \
-type 'jwt' \
-config '@auth-method.json' \
-namespace-rule-selector '"consul_namespace" in value' \
-namespace-rule-bind-namespace '${value.consul_namespace}'
바인딩 규칙과 유사하게, 네임스페이스 규칙에는 규칙을 적용할 시기를 결정하는 Selector 표현식과 사용되는 Consul 네임스페이스를 정의하는 BindNamespace 값이 있어요.
네임스페이스 규칙이 있는 auth method는 해당 Consul 네임스페이스에 Consul 토큰을 만들어요. -bind-type role인 바인딩 규칙도 같은 Consul 네임스페이스의 역할과 연결된 정책을 대상으로 해요. 따라서 default Consul 네임스페이스에 auth method와 바인딩 규칙을 만들고, 역할과 정책은 대상 Consul 네임스페이스에 만들어야 해요.
example.nomad.hcl:
group "cache" {
network {
port "db" {
to = 6379
}
}
consul {
namespace = "prod"
}
service {
port = "db"
name = "redis"
provider = "consul"
}
task "redis" {
driver = "docker"
config {
image = "redis:7"
ports = ["db"]
}
}
}
}
consul 블록이 정의되지 않으면 Nomad가 어떤 Consul 네임스페이스를 사용할지 결정할 수 없으므로 워크로드 아이덴티티에는 consul_namespace 클레임이 없어요. consul 블록이 없으면 Nomad는 서비스에만 기본 아이덴티티를 적용하고 태스크에는 적용하지 않는다는 점을 기억해요.
자세한 내용은 Consul 네임스페이스 섹션을 참고해요.
JWKS URL에 관한 중요 고려 사항
권장 구성은 Consul 서버가 JSON Web Key Set 정보를 검색하기 위해 Nomad 에이전트(클라이언트 또는 서버)에 연결할 수 있다고 가정해요.
이 섹션에서는 Consul과 Nomad 클러스터가 구성·배포되는 방식에 따라 고려해야 할 추가 측면을 다뤄요.
Nomad의 상호 TLS (Mutual TLS)
프로덕션 Nomad 배포에서는 상호 TLS를 사용하는 것이 매우 권장돼요. mTLS가 활성화되면 Consul auth method에 클라이언트 인증서를 제공할 수 없으므로 tls.verify_https_client 구성은 false로 설정해야 해요.
또는 Nomad에 대한 상호 TLS 연결을 처리하고 표준 TLS로 JWKS URL 엔드포인트를 노출하는 프록시나 로드 밸런서에서 Nomad의 JWKS URL을 노출할 수도 있어요.
Consul 서버가 Nomad에 연결할 수 없는 경우
Consul 서버가 Nomad의 JWKS URL에 도달할 수 없는 경우, Nomad의 /.well-known/jwks.json 엔드포인트에서 공개 키를 읽어 JWTValidationPubKeys 파라미터를 사용해 auth method에 직접 제공할 수 있어요. 키는 JWKS에서 PEM 형식으로 변환해야 해요.
또한 Nomad의 JWKS JSON 응답을 Consul 서버가 도달할 수 있는 외부 위치에 호스팅하고, 그 주소를 JWKSURL 값으로 사용할 수도 있어요.
Nomad 키는 주기적으로 회전된다는 점을 기억하는 것이 중요해요, 따라서 두 접근 방식 모두 자동화되어 지속적으로 수행되어야 해요. 회전 빈도는 Nomad 서버의 server.root_key_rotation_threshold 구성으로 제어돼요. 키는 회전 임계값의 절반에 미리 게시(prepublished)돼요.
추가 참조
Consul ACL with Nomad Workload Identities 튜토리얼은 워크로드 아이덴티티를 위해 Consul과 Nomad를 구성하는 방법에 대한 안내 지침을 제공해요.
nomad setup consul 명령과 hashicorp-modules/nomad-setup/consul Terraform 모듈은 Consul 클러스터에 구성을 적용하는 프로세스를 자동화하는 데 도움을 줄 수 있어요.
워크로드 아이덴티티가 없는 Consul
워크로드 아이덴티티가 없으면 Nomad 클라이언트는 자체 Consul ACL 토큰을 사용해 서비스를 등록하고, template 블록에 대한 서비스·KV를 읽고, Consul 서비스 메시를 구성해요.
서비스 등록과 Consul 서비스 메시의 경우 클라이언트는 서버로부터 Consul용 워크로드 아이덴티티가 없는 모든 워크로드에 대해 자체 Consul 토큰을 사용하도록 자동으로 폴백해요. 여기에는 서버가 워크로드 아이덴티티를 사용하도록 구성되기 전에 생성된 모든 할당이 포함돼요.
template 블록의 경우 작업 템플릿 블록이 태스크가 엄격히 필요로 하는 것보다 더 넓은 기능을 가질 수 있는 Nomad 클라이언트 토큰을 사용하도록 허용하려면 추가 구성이 필요해요. 템플릿 러너가 토큰에 접근할 수 있도록 Nomad 클라이언트의 에이전트 구성에서 client.template.use_client_consul_token = true를 설정해요. Nomad 클라이언트가 template 블록에서 Consul KV 데이터를 읽을 수 있도록 Nomad 클라이언트가 사용하는 Consul 정책에 다음 블록을 추가해요.
policy = "read"
}
Consul과 함께 워크로드 아이덴티티 사용으로 마이그레이션
Nomad 1.7.0은 Workload Identity 인증을 도입하고 job run 명령에 전달된 토큰으로 인증하는 방식을 지원 중단했어요. 그 후 Nomad 1.10.0에서 토큰 인증을 제거했어요. 워크로드가 에이전트의 Consul 토큰을 사용하는 레거시(1.7 이전) 워크플로우에서 마이그레이션하려면 Consul 클러스터와 Nomad 서버 에이전트의 구성이 필요해요. 실행 중인 Nomad 작업을 업데이트할 필요는 없어요. 마이그레이션하려면:
- Consul 클러스터에 Consul auth method와 바인딩 규칙을 만들어요.
- Nomad 서버 에이전트 구성에서
consul.service_identity블록을 활성화해요. - Nomad 서버 에이전트 구성에서
consul.task_identity블록을 활성화해요. - Nomad 클라이언트 에이전트 구성에서
client.template.use_client_consul_token = true를 활성화해요. - (선택적으로) auth method와 바인딩 규칙이 구성된 방식 때문에 다른 아이덴티티를 사용하려면 작업에
identity블록을 추가해요.
모든 작업이 워크로드 아이덴티티로 최소 한 번 재배포되고 모든 할당이 교체되면 클라이언트 에이전트에서 client.template.use_client_consul_token = true를 제거할 수 있어요.