서비스 인텐션 구성 항목 참조

서비스 인텐션 구성 항목 참조 (Service Intentions)

서비스 인텐션 구성 항목에 대한 참조 정보를 제공하는 문서예요. 인텐션은 서비스 메시에서 서비스 간 접근을 제어하는 구성이에요. 하나의 서비스 인텐션 구성 항목은 하나의 대상 서비스와 하나 이상의 L4 트래픽 소스, L7 트래픽 소스 또는 이들의 조합을 지정해요.

출처: 문서

본문

이 주제는 서비스 인텐션 구성 항목에 대한 참조 정보를 제공해요. 인텐션은 서비스 메시에서 서비스 간 접근을 제어하는 구성이에요. 하나의 서비스 인텐션 구성 항목은 하나의 대상(destination) 서비스와 하나 이상의 L4 트래픽 소스, L7 트래픽 소스 또는 이들의 조합을 지정해요. 추가 정보는 서비스 메시 인텐션 개요를 참고하세요.

구성 모델 (Configuration model)

다음 개요는 서비스 인텐션 구성 항목을 구성하는 방법을 보여줘요.

HCL 및 JSON 필드 계층:

  • [Kind]: string | 필수 | service-intentions로 설정해야 함
  • [Name]: string | 필수
  • [Namespace]: string | default | 엔터프라이즈
  • [Partition]: string | default | 엔터프라이즈
  • [JWT]: map — [Providers]: 맵 목록(Name string, VerifyClaims 맵 목록의 Path(문자열 목록)와 Value)
  • [Sources]: list | 기본값 없음
    • [Name]: string | 기본값 없음
    • [Peer]: string | 기본값 없음
    • [Namespace]: string | 기본값 없음 | 엔터프라이즈
    • [Partition]: string | 기본값 없음 | 엔터프라이즈
    • [SamenessGroup]: string | 기본값 없음 | 엔터프라이즈
    • [Action]: string | 기본값 없음 | L4 인텐션에 필수
    • [Permissions]: list | 기본값 없음
      • [Action]: string | 기본값 없음 | 필수
      • [HTTP]: map | 필수
        • [PathExact] / [PathPrefix] / [PathRegex]: string
        • [Header]: 맵 목록(Name 필수, Present false, Exact, Prefix, Suffix, Contains, Regex, IgnoreCase false, Invert false)
    • [Type]: string | consul

YAML 필드 계층: apiVersion(consul.hashicorp.com/v1alpha1), kind(ServiceIntentions), metadata(name 필수, namespace default|Enterprise), spec(기본값 없음). spec 아래에는 destination(name 필수, namespace), jwt(providers), sources가 있으며 각 소스는 name, peer, namespace, partition, samenessGroup, action, permissions(각각 action과 http — pathExact/pathPrefix/pathRegex, methods, header), description을 가져요.

완전한 구성 (Complete configuration)

모든 필드가 정의되면 서비스 인텐션 구성 항목은 다음 형태를 가져요:

HCL

Kind =  "service-intentions"
Name = "<name of destination service>"
Namespace = "<destination namespace>"                    # string
Partition = "<destination partition>"                    # string
Meta = {
  "<key-1>" = "<value-1>"
  "<key-2>" = "<value-2>"
  }
JWT = {
    Providers = [
      {
        Name = "<JWT-provider-name>"
        VerifyClaims = [
            {
                Path = ["<claim>"]
                Value = "<api.apps.organization.com>"
            }
        ]
      }
    ]
}
Sources = [
  {
    Name =  "<name of service sending traffic>"            # string
    Peer =  "<name of cluster containing source service>"  # string
    Namespace = "<namespace containing source service>"    # string
    Partition = "<sources-partition>"                      # string
    SamenessGroup = "<group-name>"                         # string
    Action = "allow" or "deny"                             # string for L4 intentions
    Permissions = [
      {
        Action = "allow" or "deny"                   # string for L7 intentions
        HTTP =  {
          PathExact =  "<exact path to match>"       # string
          PathPrefix = "<path prefix to match>"      # string
          PathRegex = "<regex pattern to match>"     # string
          Methods = [
            "<fist http method to match>",           # string
            "<second http method to match>"
          ]
          Header = [
            {
              Name = "<http header name>"              # string
              Present = <true or false>                # boolean
              Invert = <true or false>                 # boolean
            },
            {
              Name = "<http header name>"              # string
              Exact = "<header-value>"                 # boolean
              IgnoreCase = <true or false>             # boolean
              Invert = <true or false>                 # boolean
            },
            {
              Name = "<http header name>"              # string
              Prefix = "<source header value prefix>"  # string
              IgnoreCase = <true or false>             # boolean
              Invert = <true or false>                 # boolean
            },
            {
              Name = "<http header name>"              # string
              Suffix = "<source header value suffix>"  # string
              IgnoreCase = <true or false>             # boolean
              Invert = <true or false>                 # boolean
            },
            {
              Name = "<http header name>"              # string
              Contains = "<value to search for>"       # string
              IgnoreCase = <true or false>             # boolean
              Invert = <true or false>                 # boolean
            },
            {
              Name = "<http header name>"              # string
              Regex = "<regex pattern to match>"       # string
              Invert = <true or false>                 # boolean
            }
         ]
        }
      }
    ]
    Type = "consul"                                     # string
    Description = "<description for API responses>"     # string
    Precedence = <read-only>                            # number
    LegacyID = <read-only>                              # string
    LegacyMeta = <read-only>                            # string
    LegacyCreateTime = <read-only>                      # string
    LegacyUpdateTime = <read-only>                      # string
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: <name of destination service>
  namespace: <destination namespace>
spec:
  destination:
    name: <name of destination service>
    namespace: <destination namespace>
  jwt:
    providers:
      name: <JWT-provider-name>
      verifyClaims:
                path: [<aud>]
                value: <api.apps.organization.com>
  sources:
  - name: <name of service sending traffic>
    peer: <name of cluster containing source service>
    namespace: <namespace containing source service>
    partition: <sources-partition>
    samenessGroup: <group-name>
    action: allow or deny
    permissions:
    - action: allow or deny
      http:
        pathExact: <exact path to match>
        pathPrefix: <path prefix to match>
        pathRegex: <regex pattern to match>
        methods:
        - <fist http method to match>
          <second http method to match>
      header:
      - name: <http header name>
        present: true
        invert: false
      - name: <http header name>
        exact: <header-value>
        ignoreCase: false
        invert: false
      - name: <http header name>
        prefix: <source header value prefix>
        ignoreCase: false
        invert: false
      - name: <http header name>
        suffix: <source header value suffix>
        ignoreCase: false
        invert: false
      - name: <http header name>
        contains: <value to search for>
        ignoreCase: false
        invert: false
      - name: <http header name>
        regex: <regex pattern to match>
        invert: false
  description: <description for API responses>

JSON

{
   "Kind":"service-intentions",
   "Name":"<name of destination service>",
   "Namespace":"<destination namespace>",
   "Partition":"<destination partition>",
   "Meta":{
      "key-1":"<value-1>",
      "key-2":"<value-2>"
   },
   "JWT": {
    "Providers": [
      {
        "Name": "<JWT-provider-name>",
        "VerifyClaims": [
            {
                "Path": ["<aud>"],
                "Value": "<api.apps.organization.com>"
            }
        ]
      }
    ]
   },
   "Sources":[
      {
         "Name":"<name of service sending traffic>",
         "Peer":"<name of cluster containing source service>",
         "Namespace":"<namespace containing source service>",
         "Partition":"<sources-partition>",
         "SamenessGroup":"<group-name>",
         "Action":"allow or deny",
         "Permissions":[
            {
               "Action":"allow or deny",
               "HTTP":{
                  "PathExact":"<exact path to match>",
                  "PathPrefix":"<path prefix to match>",
                  "PathRegex":"<regex pattern to match>",
                  "Methods":[
                     "<fist http method to match>",
                     "<second http method to match>"
                  ],
                  "Header":[
                     {
                        "Name":"<http header name>",
                        "Present":true,
                        "Invert":false
                     },
                     {
                        "Name":"<http header name>",
                        "Exact":"<header-value>",
                        "IgnoreCase":false,,
                        "Invert":false
                     },
                     {
                        "Name":"<http header name>",
                        "Prefix":"<source header value prefix>",
                        "IgnoreCase":false,
                        "Invert":false
                     },
                     {
                        "Name":"<http header name>",
                        "Suffix":"<source header value suffix>",
                        "IgnoreCase":false,
                        "Invert":false
                     },
                     {
                        "Name":"<http header name>",
                        "Contains":"<value to search for>",
                        "IgnoreCase":false,
                        "Invert":false
                     },
                     {
                        "Name":"<http header name>",
                        "Regex":"<regex pattern to match>",
                        "Invert":false
                     }
                  ]
               }
            }
         ],
         "Type":"consul",
         "Description":"<description for API responses>",
         "Precedence":"<read-only-number>",
         "LegacyID":"<read-only-string>",
         "LegacyMeta":"<read-only-string>",
         "LegacyCreateTime":"<read-only-string>",
         "LegacyUpdateTime":"<read-only-string>"
      }
   ]
}

사양 (Specification)

이 섹션은 서비스 인텐션 구성 항목에서 구성할 수 있는 필드에 대한 세부 정보를 제공해요.

HCL/JSON 필드

  • Kind: 구현할 구성 항목의 유형. service-intentions로 설정해야 함. 필수.
  • Name: 구성 항목에 정의된 모든 인텐션의 대상 서비스 이름. 기본값은 항목을 Consul 서버에 쓴 후 노드의 이름. 필수. 또한 인텐션 없는 모든 서비스를 일치시키기 위해 와일드카드 문자(*)를 지정할 수 있지만, L7 [Permissions]을 정의할 때는 와일드카드로 적용된 인텐션이 지원되지 않음.
  • Namespace (Enterprise): 구성 항목이 적용되는 [네임스페이스]. 해당 네임스페이스의 서비스는 인텐션이 허용하거나 거부하는 트래픽의 대상. 기본값: default. 와일드카드(*)로 모든 네임스페이스를 일치시킬 수 있지만 L7 Permissions에서는 와일드카드가 지원되지 않음.
  • Partition (Enterprise): 구성 항목을 적용할 [admin 파티션]. 기본값: default.
  • Meta: 구성 항목이 평가될 때 KV 저장소에 추가할 키-값 쌍. 기본값: 없음. 데이터 유형: 키-값 쌍 맵.
  • JWT: [JWT 프로바이더 구성 항목]에 구성된 JSON Web Token 프로바이더와, 서비스 간 통신을 인가하기 전에 서비스의 JWT를 검증하기 위한 추가 구성. Providers는 하나 이상의 이전에 구성된 JWT 프로바이더 구성 항목의 이름을 지정하며, 이들은 JSON 웹 토큰 검증에 필요한 정보를 포함해요.
    • JWT{}.Providers[].Name: [jwt-provider 구성 항목]의 Name 필드에 정의된 JWT 프로바이더의 이름. 서비스 인텐션에서 참조하기 전에 반드시 Consul에 JWT 프로바이더를 써야 함.
    • JWT{}.Providers[].VerifyClaims: JWT 프로바이더 구성 항목에 구성된 것 외에 추가로 검증할 토큰 정보. JSON 웹 토큰 클레임과 일치할 값의 형태.
      • VerifyClaims[].Path: JSON 웹 토큰의 클레임 경로. JWT 클레임에 대한 자세한 내용은 [IETF 표준 문서]를 참고.
      • VerifyClaims[].Value: Path로 지정된 클레임 검증 시 일치할 값.
  • Sources[]: 인텐션 소스와 소스에 부여된 권한을 정의하는 구성 목록. 소스 구성을 어떤 순서로든 지정할 수 있지만 Consul은 런타임에 역순위(reverse precedence) 순서로 저장하고 평가해요. Precedence 참고.
    • Sources[].Name: 인텐션이 트래픽을 허용하거나 거부하는 소스의 이름. [Type]이 consul이면 값은 Consul 서비스 이름을 가리켜요. 소스는 Consul 카탈로그에 등록될 필요가 없음. 필수.
    • Sources[].Peer: 인텐션이 트래픽을 허용하거나 거부하는 피어링된 Consul 클러스터의 이름. Peer와 Partition 필드는 상호 배타적.
    • Sources[].Namespace (Enterprise): 인텐션이 트래픽을 허용하거나 거부하는 트래픽 소스 네임스페이스. 기본값: [Peer]가 지정되지 않으면 대상 [Namespace]로 기본 설정.
    • Sources[].Partition (Enterprise): 인텐션이 트래픽을 허용하거나 거부하는 admin 파티션의 이름. Peer와 Partition은 상호 배타적. 기본값: [Peer]가 지정되지 않으면 대상 [Partition]으로 기본 설정.
    • Sources[].SamenessGroup (Enterprise): 인텐션이 트래픽을 허용하거나 거부하는 sameness group의 이름.
    • Sources[].Action: 소스가 대상 서비스로 트래픽을 보낼 때 취할 조치. allow 또는 deny. L7 인텐션을 같은 소스에 적용하려면 이 필드를 구성하지 말고 [Permissions]을 구성하세요. L4 인텐션에 필수.
    • Sources[].Permissions[]: L7 트래픽 소스를 위한 권한 목록. 하나 이상의 조치와 각 조치에 대한 일치 기준 집합을 포함. Consul은 구성에 지정된 순서대로 권한을 적용하며, 첫 번째 일치 요청을 적용한 후 나머지 구성에 대한 평가를 중단해요. 정의된 어떤 권한과도 일치하지 않는 요청에는 acl_default_policy 구성에 정의된 인텐션 동작을 적용해요. L4 인텐션에는 이 필드를 구성하지 마세요. Permissions는 호환 가능한 프로토콜을 가진 서비스에만 적용되며, Name 또는 Namespace 필드가 와일드카드로 구성되면 지원되지 않아요.
      • Permissions[].Action: 소스가 대상 서비스로 트래픽을 보낼 때 취할 조치. allow 또는 deny. 필수.

      • Permissions[].HTTP: HTTP 특정 일치 기준 집합. 기준과 일치하는 소스 트래픽에 Action 필드의 조치를 적용. 필수.

        매개변수 설명 데이터 유형 기본값
        PathExact HTTP 요청 경로에서 일치할 정확한 경로. 같은 HTTP 구성에서 PathPrefix나 PathRegex가 구성되면 지정 불가. string none
        PathPrefix HTTP 요청 경로에서 일치할 경로 접두사. 같은 HTTP 구성에서 PathExact나 PathRegex가 구성되면 지정 불가. string none
        PathRegex HTTP 요청 경로에서 일치할 정규 표현식. 같은 HTTP 구성에서 PathExact나 PathPrefix가 구성되면 지정 불가. regex 구문은 프록시별. Envoy 사용 시 [re2 문서] 참고. string none
        Methods HTTP 메서드 목록. 요청이 PathExact/PathPrefix/PathRegex/Header와 일치하고 소스가 지정된 메서드 중 하나로 요청을 보냈으면 권한 적용. 지원되는 요청 헤더 목록은 [Mozilla 문서] 참고. list 모든 요청 메서드
        Header HTTP 요청 헤더의 헤더 이름과 일치 기준. 맵 목록 none
      • Permissions[].HTTP[].Header[]: HTTP 요청 헤더의 헤더 이름과 일치 기준. 요청 헤더가 권한을 적용하기 위해 모든 지정된 기준과 일치해야 함. Header 목록의 각 구성원은 Name 필드와 최소 하나의 일치 기준을 포함하는 맵.

        매개변수 설명 데이터 유형 필수
        Name 일치할 헤더의 이름. string 필수
        Present Name 필드에 구성된 헤더가 요청에 나타나면 일치 활성화. 같은 Header 구성에서 Exact/Prefix/Suffix/Regex가 구성되면 지정 불가. boolean 선택
        Exact Name 필드에 설정된 헤더 키에 대한 값. 요청 헤더 값이 Exact 값과 일치하면 권한 적용. 같은 Header 구성에서 Present/Prefix/Suffix/Regex가 구성되면 지정 불가. string 선택
        Prefix Name 필드에 설정된 헤더 키의 접두사 값. 요청 헤더 값이 Prefix 값으로 시작하면 권한 적용. 같은 Header 구성에서 Present/Exact/Suffix/Regex가 구성되면 지정 불가. string 선택
        Suffix Name 필드에 설정된 헤더 키의 접미사 값. 요청 헤더 값이 Suffix 값으로 끝나면 권한 적용. 같은 Header 구성에서 Present/Exact/Prefix/Regex가 구성되면 지정 불가. string 선택
        Contains Name 필드에 설정된 헤더 키의 포함 값. 요청 헤더 값이 Contains 값을 포함하면 권한 적용. 같은 header 구성에서 Present/Exact/Prefix/Suffix/Regex가 구성되면 지정 불가. string 선택
        Regex Name 필드에 설정된 헤더 키의 값으로 정규 표현식 패턴. 요청 헤더 값이 regex와 일치하면 권한 적용. 같은 Header 구성에서 Present/Exact/Prefix/Suffix/Contains가 구성되면 지정 불가. regex 구문은 프록시별. string 선택
        IgnoreCase Exact/Prefix/Suffix/Contains와 일치할 때 제공된 헤더 값의 대소문자 무시. 기본 false. boolean 선택
        Invert Header에 구성된 일치 논리 반전. 기본 false. boolean 선택
    • Sources[].Precedence: 읽기 전용 정수. Consul은 소스와 대상 서비스의 이름 구성에 따라 값을 생성. [Precedence and matching order] 참고.
    • Sources[].Type: 구성 항목이 적용되는 대상 서비스의 유형. 지원 값은 consul뿐. 기본값: consul.
    • Sources[].Description: 인텐션의 설명. Consul은 네트워크에 통합된 다른 도구를 돕기 위해 API 응답에 설명을 제공.
    • Sources[].LegacyID: 시스템에서 인텐션의 읽기 전용 고유 사용자 ID(UUID). 레거시 API 엔드포인트가 계속 동작하도록 Consul이 생성해 노출. [ID로 특정 인텐션 읽기] 참고.
    • Sources[].LegacyMeta: 인텐션에 첨부할 읽기 전용 임의 키-값 쌍 집합. 레거시 인텐션 API 엔드포인트가 계속 동작하도록 Consul이 생성해 노출.
    • Sources[].LegacyCreateTime: 인텐션 생성의 읽기 전용 타임스탬프.
    • Sources[].LegacyUpdateTime: 가장 최근 인텐션 업데이트를 표시하는 읽기 전용 타임스탬프.

Kubernetes YAML 필드

  • apiVersion: Kubernetes와 통합하기 위한 Consul API 버전. consul.hashicorp.com/v1alpha1이어야 함. 필수.
  • kind: 구현할 구성 항목의 유형. ServiceIntentions로 설정해야 함. 필수.
  • metadata: 구성 항목의 임의 이름과 적용되는 네임스페이스를 포함하는 맵.
    • metadata.name: 구성 항목의 임의 이름. 다른 구성 항목과 달리 서비스 인텐션에서 설정을 적용하는 서비스는 대상이며 [spec.destination.name]에 지정됨. [ServiceIntentions 특수 사례(CE)]와 [ServiceIntentions 특수 사례(Enterprise)] 참고.
    • metadata.namespace (Enterprise): 구성 항목이 적용되는 [네임스페이스]. Consul CE는 metadata.namespace 구성을 무시. 기본값: default.
  • spec: ServiceIntentions 구성 항목의 세부 정보를 포함하는 맵. apiVersion, kind, metadata 필드는 spec 필드의 형제이며 다른 모든 구성은 자식. 필수.
    • spec.destination: 소스 서비스의 접근을 허용하거나 거부하는 대상 이름과 대상 네임스페이스를 식별하는 맵. 필수.
      • spec.destination.name: 인텐션이 적용되는 메시의 대상 서비스 이름. 인텐션 설정이 없는 모든 서비스를 일치시키려면 와일드카드 문자(*)를 지정할 수도 있지만, L7 [permissions]를 정의할 때는 와일드카드로 적용된 인텐션이 지원되지 않음. 필수.
    • spec.jwt: [JWT 프로바이더 구성 항목]의 JSON Web Token 프로바이더와 서비스 간 통신 인가 전 JWT 검증을 위한 추가 구성. spec.jwt.providers, spec.jwt.providers[].name, spec.jwt.providers[].verifyClaims(path, value)는 각각 위 HCL의 JWT, Providers[].Name, Providers[].VerifyClaims와 동일.
    • spec.sources[]: 인텐션 소스와 소스에 부여된 권한을 정의하는 구성 목록. spec.sources[].name, spec.sources[].peer, spec.sources[].namespace, spec.sources[].partition, spec.sources[].samenessGroup, spec.sources[].action, spec.sources[].permissions, spec.sources[].type, spec.sources[].description은 각각 위 HCL의 대응 필드와 동일한 의미를 가짐. spec.sources[].permissions[].action은 allow 또는 deny(필수), spec.sources[].permissions[].http는 pathExact/pathPrefix/pathRegex/methods/header(name 필수, present, exact, prefix, suffix, contains, regex, ignoreCase false, invert false)를 가짐.

예시 (Examples)

다음 예시는 서비스 인텐션 구성 항목의 잠재적 사용 사례를 보여줘요.

특정 소스와 대상에 대한 L4 인텐션 (L4 Intentions for specific sources and destinations)

다음 예시 구성 항목은 web에서 db 서비스 인스턴스로의 트래픽을 거부하지만 api에서 db로의 트래픽은 허용하는 L4 인텐션을 지정해요.

HCL

Kind = "service-intentions"
Name = "db"
Sources = [
  {
    Name   = "web"
    Action = "deny"
  },
  {
    Name   = "api"
    Action = "allow"
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: db
spec:
  destination:
    name: db
  sources:
  - name: web
    action: deny
  - name: api
    action: allow

JSON

{
  "Kind": "service-intentions",
  "Name": "db",
  "Sources": [
    {
      "Action": "deny",
      "Name": "web"
    },
    {
      "Action": "allow",
      "Name": "api"
    }
  ]
}

모든 대상에 대한 L4 인텐션 (L4 intentions for all destinations)

다음 L4 예시에서 대상은 * 와일드카드로 구성됩니다. 결과적으로 web 서비스 인스턴스의 트래픽은 데이터센터의 어떤 서비스에 대해서도 거부됩니다.

HCL

Kind = "service-intentions"
Name = "*"
Sources = [
  {
    Name   = "web"
    Action = "deny"
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: web-deny-all
spec:
  destination:
    name: *
  sources:
  - name: web
    action: deny

JSON

{
  "Kind": "service-intentions",
  "Name": "*",
  "Sources": [
    {
      "Action": "deny",
      "Name": "web"
    }
  ]
}

모든 소스에 대한 L4 인텐션 (L4 intentions for all sources)

다음 L4 예시에서 소스는 * 와일드카드로 구성됩니다. 결과적으로 어떤 서비스의 트래픽도 db 서비스 인스턴스로는 거부됩니다.

HCL

Kind = "service-intentions"
Name = "db"
Sources = [
  {
    Name   = "*"
    Action = "deny"
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: db
spec:
  destination:
    name: db
  sources:
  - name: *
    action: deny

JSON

{
  "Kind": "service-intentions",
  "Name": "db",
  "Sources": [
    {
      "Action": "deny",
      "Name": "*"
    }
  ]
}

REST 접근 (REST access)

다음 예시에서 admin-dashboard와 report-generator 서비스는 REST 호출 시 서로 다른 접근 수준을 가져요.

HCL

Kind = "service-intentions"
Name = "api"
Sources = [
  {
    Name = "admin-dashboard"
    Permissions = [
      {
        Action = "allow"
        HTTP {
          PathPrefix = "/v2"
          Methods    = ["GET", "PUT", "POST", "DELETE", "HEAD"]
        }
      }
    ]
  },
  {
    Name = "report-generator"
    Permissions = [
      {
        Action = "allow"
        HTTP {
          PathPrefix = "/v2/widgets"
          Methods    = ["GET"]
        }
      }
    ]
  }
  # NOTE: a default catch-all based on the default ACL policy will apply to
  # unmatched connections and requests. Typically this will be DENY.
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: api
spec:
  destination:
    name: api
  sources:
    - name: admin-dashboard
      permissions:
        - action: allow
          http:
            pathPrefix: /v2
            methods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD']
    - name: report-generator
      permissions:
        - action: allow
          http:
            pathPrefix: /v2/widgets
            methods: ['GET']
    # NOTE: a default catch-all based on the default ACL policy will apply to
    # unmatched connections and requests. Typically this will be DENY.

JSON

{
  "Kind": "service-intentions",
  "Name": "api",
  "Sources": [
    {
      "Name": "admin-dashboard",
      "Permissions": [
        {
          "Action": "allow",
          "HTTP": {
            "PathPrefix": "/v2",
            "Methods": ["GET", "PUT", "POST", "DELETE", "HEAD"]
          }
        }
      ]
    },
    {
      "Name": "report-generator",
      "Permissions": [
        {
          "Action": "allow",
          "HTTP": {
            "PathPrefix": "/v2/widgets",
            "Methods": ["GET"]
          }
        }
      ]
    }
  ]
}

gRPC

다음 예시에서 Consul은 frontend-web에서 IssueRefund gRPC 서비스로의 요청을 거부해요. gRPC 메서드 호출은 HTTP/2 프로토콜을 사용하므로 HTTP 경로 일치 규칙을 적용해 트래픽을 제어할 수 있어요.

HCL

Kind = "service-intentions"
Name = "billing"
Sources = [
  {
    Name = "frontend-web"
    Permissions = [
      # The frontend website can execute all billing service methods except
      # issuing refunds.
      {
        Action = "deny"
        HTTP {
          PathExact = "/mycompany.BillingService/IssueRefund"
        }
      },
      {
        Action = "allow"
        HTTP {
          PathPrefix = "/mycompany.BillingService/"
        }
      }
    ]
  },
  {
    Name = "support-portal"
    Permissions = [
      # But the support team portal page can execute all methods.
      {
        Action = "allow"
        HTTP {
          PathPrefix = "/mycompany.BillingService/"
        }
      }
    ]
  }
  # A default catch-all based on the default ACL policy applies to
  # unmatched connections and requests. This is typically DENY.
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: billing
spec:
  destination:
    name: billing
  sources:
    # The frontend website can execute all billing service methods except
    # issuing refunds.
    - name: frontend-web
      permissions:
        - action: deny
          http:
            pathExact: /mycompany.BillingService/IssueRefund
        - action: allow
          http:
            pathPrefix: '/mycompany.BillingService/'
    - name: support-protocol
      # But the support team portal page can execute all methods.
      permissions:
        - action: allow
          http:
            pathPrefix: '/mycompany.BillingService/'
  # A default catch-all based on the default ACL policy applies to
  # unmatched connections and requests. This is typically DENY.

JSON

{
  "Kind": "service-intentions",
  "Name": "billing",
  "Sources": [
    {
      "Name": "frontend-web",
      "Permissions": [
        {
          "Action": "deny",
          "HTTP": {
            "PathExact": "/mycompany.BillingService/IssueRefund"
          }
        },
        {
          "Action": "allow",
          "HTTP": {
            "PathPrefix": "/mycompany.BillingService/"
          }
        }
      ]
    },
    {
      "Name": "support-portal",
      "Permissions": [
        {
          "Action": "allow",
          "HTTP": {
            "PathPrefix": "/mycompany.BillingService/"
          }
        }
      ]
    }
  ]
}

L4 및 L7 (L4 and L7)

다음 예시에서 Consul은 hackathon-project에서 api로의 요청을 거부하고 web에서의 요청은 허용하는 애플리케이션 계층 인텐션을 적용해요. 같은 구성 항목에서 Consul은 /v1/reconcile-data HTTP 엔드포인트로 POST 요청을 보내는 nightly-reconciler의 요청을 허용하는 네트워크 계층 인텐션을 적용해요.

HCL

Kind = "service-intentions"
Name = "api"
Sources = [
  {
    Name   = "hackathon-project"
    Action = "deny"
  },
  {
    Name   = "web"
    Action = "allow"
  },
  {
    Name = "nightly-reconciler"
    Permissions = [
      {
        Action = "allow"
        HTTP {
          PathExact = "/v1/reconcile-data"
          Methods   = ["POST"]
        }
      }
    ]
  },
  # A default catch-all based on the default ACL policy applies to
  # unmatched connections and requests. This is typically DENY.
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: api
spec:
  destination:
    name: api
  sources:
    - name: hackathon-project
      action: deny
    - name: web
      action: allow
    - name: nightly-reconciler
      permissions:
        - action: allow
          http:
            pathExact: /v1/reconcile-data
            methods: ['POST']
    # A default catch-all based on the default ACL policy applies to
    # unmatched connections and requests. This is typically DENY.

JSON

{
  "Kind": "service-intentions",
  "Name": "api",
  "Sources": [
    {
      "Name": "hackathon-project",
      "Action": "deny"
    },
    {
      "Name": "web",
      "Action": "allow"
    },
    {
      "Name": "nightly-reconciler",
      "Permissions": [
        {
          "Action": "allow",
          "HTTP": {
            "PathExact": "/v1/reconcile-data",
            "Methods": ["POST"]
          }
        }
      ]
    }
  ]
}

API 게이트웨이 (API gateway)

Consul API 게이트웨이를 사용할 때 인텐션은 Consul 데이터센터에서 실행되는 서비스에 대한 인증된 접근으로 배포를 보호해요. 다음 예시에서 서비스 인텐션 구성 항목은 API 게이트웨이 my-api-gateway가 Consul 서비스 메시 내부에 호스팅된 frontend-service와 통신하도록 인가해요.

HCL

Kind = "service-intentions"
Name = "frontend-service"
Sources = [
  {
    Name   = "my-api-gateway"
    Action = "allow"
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: my-api-gateway
# Allow traffic from api-gateway to frontend-service
spec:
  destination:
    name: frontend-service
  sources:
    - name: my-api-gateway
      action: allow

JSON

{
"Kind": "service-intentions",
"Name": "frontend-service",
"Sources": [
    {
      "Name": "my-api-gateway",
      "Action": "allow"
    }
  ]
}

클러스터 피어링 (Cluster peering)

클러스터 피어링 연결을 사용할 때 인텐션은 원격 데이터센터 간의 인증된 서비스 간 통신으로 배포를 보호해요. 다음 예시에서 서비스 인텐션 구성 항목은 backend-service가 원격 피어 cluster-02에 호스팅된 frontend-service와 통신하도록 인가해요.

HCL

Kind      = "service-intentions"
Name      = "backend-service"

Sources = [
  {
    Name   = "frontend-service"
    Peer   = "cluster-02"
    Action = "allow"
  }
]

Kubernetes YAML

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: backend-deny
spec:
  destination:
    name: backend
  sources:
   - name: "*"
     action: deny
   - name: frontend
     action: allow
     peer: cluster-01 ## The peer of the source service

JSON

{
"Kind": "service-intentions",
"Name": "backend-service",
"Sources": [
    {
      "Name": "frontend-service",
      "Peer": "cluster-02",
      "Action": "allow"
    }
  ]
}

인텐션으로 JWT 검증 (JWT validation with intentions)

다음 예시는 backend라는 서비스가 frontend 서비스에서 요청을 받을 때 요청을 평가하는 서비스 인텐션을 구성해요. 요청이 /admin HTTP 경로로 전송되면 Okta가 제공한 JSON 웹 토큰이 평가됩니다. 별도의 JWT 프로바이더 구성 항목의 검증 요구 사항 외에도, 토큰이 admin 값을 가진 perms 또는 role 클레임을 가지는지 확인하는 추가 검사가 발생해요. 그렇다면 요청이 인가됩니다.

인텐션이 / HTTP 경로에서 오는 요청을 허용하므로 /admin 경로의 요청만 토큰 검증 대상이 돼요.

HCL

Kind = "service-intentions"
Name = "backend"
Sources = [
  {
    Name = "frontend"
    Permissions = [
      {
        HTTP = {
          PathExact = "/admin"
        }
        JWT = {
          Providers = [
            {
              Name = "okta"
              VerifyClaims = [
                {
                  Path = ["perms", "role"]
                  Value = "admin"
                }
              ]
            }
          ]
        }
      },
      {
        Action = "allow"
        HTTP = {
          PathPrefix = "/"
        }
      }
    ]
  }
]

Kubernetes YAML

  apiVersion: consul.hashicorp.com/v1alpha1
  kind: ServiceIntentions
  metadata:
    name: backend
  spec:
    sources:
    - name: frontend
      permissions:
      - http:
          pathExact: /admin
        jwt:
          providers:
          - name: okta
            verifyClaims:
            - path:
                - perms
                - role
              value: admin
      action: allow
      http:
        pathPrefix: /

JSON

{
"Kind": "service-intentions",
"Name": "backend",
"Sources": [
  {
    "Name": "frontend",
    "Permissions": [
      {
        "HTTP": {
          "PathExact": "/admin"
        },
        "JWT": {
          "Providers": [
            {
              "Name": "okta",
              "VerifyClaims": [
                {
                  "Path": ["perms", "role"],
                  "Value": "admin"
                }
              ]
            }
          ]
        }
      },
      {
        "Action": "allow",
        "HTTP": {
          "PathPrefix": "/"
        }
      }
    ]
  }
]
}

더 알아보기 (Learn more)