정책 기반 부하 분산
퍼블릭 및 프라이빗 애플리케이션 부하 분산 장치 모두 구성된 정책과 규칙에 따라 데이터 트래픽이 분산되는 레이어 4 및 레이어 7 부하 분산 기능을 지원합니다. 정책은 수신 요청이 해당 정책과 연관된 규칙과 일치하는 경우에 수행할 조치(즉, 트래픽이 분배되는 방법)를 정의합니다.
7단계 정책
HTTP 및 HTTPS 리스너에 대한 정책을 정의할 수 있습니다. 각각의 정책에 대해 하나 이상의 규칙을 정의해야 합니다. 정책은 모든 규칙이 일치하는 경우에만 적용됩니다.
리스너에 둘 이상의 정책을 연결할 수 있습니다. 일반적으로 우선순위가 가장 낮은 정책이 가장 먼저 평가됩니다. 각각의 정책은 우선순위가 서로 달라야 합니다.
수신 요청이 정책에 대한 규칙과 일치하지 않으면 시스템 요청은 구성된 HTTPS 경로 재지정 리스너로 경로 재지정됩니다(해당 경우). 그렇지 않으면 시스템은 요청을 리스너의 기본 풀로 경로 재지정됩니다. HTTPS 경로 재지정은 HTTP 리스너의 기본 풀보다 우선순위가 높습니다.
7계층 정책의 경우 다음과 같은 조치가 지원됩니다.
- 거부 - 요청이 403 응답과 함께 거부됩니다.
- 경로 재지정 - 요청이 구성된 URL 및 응답 코드로 경로 재지정됩니다.
- 풀로 전달- 요청이 특정 백엔드 풀로 전송됩니다.
- 수신자에게 전달- 요청이 특정 프런트엔드 수신자에게 전송됩니다.
- HTTPS 경로 재지정 - HTTP 요청이 HTTPS 리스너로 경로 재지정됩니다.
정책 특성
| 특성 | 설명 |
|---|---|
| 이름 | 정책의 이름입니다. 이름은 리스너에서 고유해야 합니다. |
| 조치 | 모든 정책 규칙이 일치하는 경우에 수행할 조치입니다. 허용되는 값은 reject, redirect, forward_to_pool, forward_to_listener 및 https_redirect 입니다. |
| 우선순위 | 정책은 우선순위의 오름차순으로 평가됩니다. |
| 우선순위 | 정책은 우선순위의 오름차순으로 평가됩니다. |
| URL | 조치가 redirect로 설정된 경우 요청을 경로 재지정할 URL입니다. URL 를 전부 제공하거나 URI의 매개 변수를 제공해야 합니다. URL 를 사용할 때, 들어오는 모든 트래픽이 이 URL 로 리디렉션됩니다. URI 매개변수를 사용하는 경우 들어오는 트래픽 요청의 값은 매개변수의 들어오는 값을 사용하여 유지될 수 있습니다. URI 매개변수의 기본값은 원래 수신 값과 동일합니다. 들어오는
값을 유지하려면 다음과 같이 제공하십시오.{protocol},{port},{host},{path}, 그리고 {query}. 예를 들어, 들어오는 요청의 호스트가 ibm.com 인 경우, 기본값은 들어오는 ibm.com 값과 동일한 {host} 입니다. |
| HTTP 상태 코드 | 조치가 redirect 또는 https_redirect로 설정된 경우 애플리케이션 로드 밸런서가 리턴한 응답의 상태 코드입니다. 허용 가능한 값은 301, 302, 303, 307 또는 308입니다. |
| 대상 | 동작이 forward_to_pool 으로 설정된 경우 요청은 가상 서버 인스턴스의 백엔드 풀로 전달됩니다. 또는 동작을 forward_to_listener 으로 설정하면 요청이 동일한 ALB의 프런트엔드 리스너로 전달됩니다. |
| 리스너 | 조치가 https_redirect로 설정된 경우 요청이 경로 재지정되는 HTTPS 리스너입니다. |
| URI | 조치가 https_redirect인 경우 요청이 경로 재지정되는 상대 URI입니다. 이 특성은 선택적입니다. |
계층 7 규칙
규칙은 요청이 어떻게 매칭되는지를 정의합니다. URI 기반 라우팅 및 매개변수 기반 라우팅이 모두 지원됩니다. 다음과 같은 다섯 가지 규칙 유형이 지원됩니다.
| 유형 | 설명 |
|---|---|
hostname |
이 요청은 api.my_company.com 과 같이 지정된 hostname 과 일치합니다. |
header |
이 요청은 HTTP header 의 필드 및 값과 일치하며, 예를 들어 Cookie: xxxx 와 같습니다. |
path |
이 요청은 hostname 뒤의 URL 에 있는 path 와 일치합니다. 예를 들어, /index.html 와 같은 경우입니다. |
query |
이 요청은 URL 에 있는 “ query ” 문자열과 일치합니다. 예를 들어, x=y 와 같은 경우입니다. query 문자열은 퍼센트 인코딩되어야 하며, 대소문자를 구분합니다. |
body |
POST 요청에 대한 body 요청은 폼 인코딩 방식으로 전송됩니다. 요청이 본문과 일치합니다(예: key=value). 대소문자를 구분합니다. |
sni_hostname |
TLS 협상 과정에서 “서버 이름 표시(SNI)” 확장 기능에 포함된 서버가 지정된 SNI 호스트명과 일치합니다. |
요청을 일치시키려면 규칙에 condition문이 정의되어 있어야 합니다. 다음 네 가지 조건이 지원됩니다.
| 조건 | 평가 유형 |
|---|---|
contains |
type 를 기준으로 추출된 값에 value 에 지정된 문자열이 포함되어 있는지 확인합니다. |
equals |
type 를 기반으로 추출된 값이 value 에 지정된 문자열과 동일한지 확인합니다. |
matches_regex |
type 를 기반으로 추출된 값을 value 에 지정된 정규 표현식과 대조합니다. |
starts_with |
type 를 기반으로 추출된 값이 value 에 지정된 문자열로 시작하는지 확인합니다. |
규칙 특성
이 표는 레이어 7 정책 규칙의 속성을 설명합니다.
| 특성 | 설명 |
|---|---|
type |
규칙의 유형을 지정합니다. 허용되는 값은 hostname, header, path, query 또는 body 입니다. |
condition |
규칙을 평가하는 데 사용되는 조건을 지정합니다. 지원되는 값은 contains, equals 또는 matches_regex 입니다. |
field |
필드 이름을 지정합니다. 이 필드는 header query 및 body 규칙 유형에만 적용되며 정규식 및 와일드카드 문자를 지원하지 않습니다. 예를 들어 HTTP 헤더의 쿠키를 일치시키기 위해 이 필드를 cookie로 설정할 수 있습니다. 규칙 유형이 query 및 body인 경우
이 필드는 선택적입니다. 이 속성은 sni_hostname 규칙 유형에는 적용되지 않습니다. |
value |
일치시킬 문자열입니다. 이 필드는 와일드카드 문자를 지원하지 않습니다. condition 가 matches_regex 로 설정된 경우 정규 표현식이 지원됩니다. |
참고:
- 규칙 유형이
header인 경우field및value:"(),/:;<=>?@[\]{}'문자는 허용되지 않습니다. - 규칙 유형이
body이면field문자 및 공백이value및"'=,()&에 허용되지 않습니다. - 규칙 유형이
query이면field및value가 백분율로 인코딩된 문자열이어야 합니다.
예: 정책 및 규칙 작성
다음 7계층 예제는 정책 및 규칙이 작성되어 리스너와 연관되는 방법을 보여줍니다.
예제 1: 경로 재지정 정책이 포함된 HTTPS 리스너 작성
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" \
-d '{
"certificate_instance": {
"crn": "crn:v1:bluemix:public:cloudcerts:us-south:a/1111111111111111111111111111:22222222-3333-4444-5555-666666666666:certificate:77777777777777777777777777777777"
},
"connection_limit": 2000,
"port": 443,
"protocol": "https",
"policies": [
{
"name": "hostname_header",
"action": "redirect",
"priority": 1,
"target": {
"url": "https://www.examples.com/",
"http_status_code": 307
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "hostname",
"value": "abc.com"
}
]
},
{
"name": "header_cookie",
"action": "redirect",
"priority": 5,
"target": {
"url": "https://www.mycookies.com/",
"http_status_code": 302
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"name": "path_hostname",
"action": "redirect",
"priority": 10,
"target": {
"url": "https://www.myexamples.com/",
"http_status_code": 301
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "abc"
},
{
"condition": "equals",
"value": "/test",
"type": "path"
}
]
},
{
"name": "uri_redirect",
"action": "redirect",
"priority": 10,
"target": {
"url": "https://{host}:8080/{path}?{query}",
"http_status_code": 301
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "pqr"
}
]
}
]
}'
예제 2: 요청을 풀로 전달한 후 기존 리스너와 연관시키는 정책 작성
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners/$listenerId/policies" \
-d '{
"policies": [
{
"action": "forward",
"priority": 1,
"target": {
"id": "7df616da-4dd6-43d3-881d-801ae29e29fe"
},
"rules": [
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"action": "forward",
"priority": 5,
"target": {
"id": "0738-8061c411-0d50-4c79-b475-102666796434"
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
}
]
},
{
"action": "forward",
"priority": 10,
"target": {
"id": "0738-62914e09-3928-4d89-b7f7-1bb7a6d7fe85"
},
"rules": [
{
"condition": "matches_regex",
"type": "hostname",
"value": "abc[a-z]*.com"
}
]
},
{
"action": "forward",
"priority": 6,
"target": {
"id": "0738-62914e09-3928-4d89-b7f7-1bb7a6d7fe85"
},
"rules": [
{
"condition": "equals",
"type": "path",
"value": "/test/testtest"
}
]
}
]
}'
예제 3: HTTP 리스너를 HTTP 경로 재지정 정책으로 작성
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" \
-d '{
"connection_limit": 2000,
"port": 80,
"protocol": "http",
"policies": [
{
"name": "hostname_header",
"action": "https_redirect",
"priority": 1,
"target": {
"listener": {
"id": "0134-d578be10-31e3-46b3-8513-79babb852319"
},
"http_status_code": 307
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "hostname",
"value": "abc.com"
}
]
},
{
"name": "header_cookie",
"action": "https_redirect",
"priority": 2,
"target": {
"listener": {
"id": "0456-a578be10-31e3-46b3-8513-79babb852398"
},
"http_status_code": 302
},
"rules": [
{
"condition": "contains",
"type": "header",
"field": "aheader",
"value": "avalue"
},
{
"condition": "equals",
"type": "header",
"field": "cookie",
"value": "flavor=oatmeal"
}
]
},
{
"name": "path_hostname",
"action": "https_redirect",
"priority": 5,
"target": {
"listener": {
"id": "0386-d898be10-21e3-66b3-9513-69babb852390"
},
"http_status_code": 301,
"uri": "/test/sample"
},
"rules": [
{
"condition": "contains",
"type": "hostname",
"value": "abc"
},
{
"condition": "equals",
"value": "/test",
"type": "path"
}
]
}
]
}'
레이어 4 정책
TCP 리스너에 대한 정책을 정의할 수 있습니다. 각각의 정책에 대해 하나 이상의 규칙을 정의해야 합니다. 레이어 7 정책과 마찬가지로 레이어 4 정책은 지정된 모든 규칙이 일치하는 경우에만 우선순위가 가장 낮은 정책부터 적용됩니다.
수신된 요청이 어떤 정책의 규칙과도 일치하지 않는 경우, 클라이언트 측에서 ‘ SSL ’ 오류가 발생할 수 있습니다.
레이어 4 정책에 대해 지원되는 작업은 다음과 같습니다:
- 풀로 전달- 요청이 특정 백엔드 풀로 전송됩니다.
- 수신자에게 전달 - 요청이 특정 프런트엔드 수신자에게 전송됩니다.
레이어 4 규칙
계층 4 규칙은 계층 7 규칙과 동일하게 요청이 일치하는 방식을 정의합니다. 단, sni_hostname 유형만 지원되며 field 은 적용되지 않으며 condition 및 value 속성은 레이어 7 규칙과 동일합니다.
"SNI 호스트 이름" 규칙은 TCP 리스너에서만 작동합니다.
IBM Cloud ALB의 SNI는 리스너에 연결되며 호스트 이름을 기반으로 트래픽을 다른 백엔드 풀로 라우팅할 수 있습니다. 풀 내에서 트래픽은 항상 선택한 알고리즘(라운드 로빈, 최소 연결 수 등)을 사용하여 모든 구성원 간에 로드 밸런싱됩니다. SNI를 사용하여 풀 내에서 특정 멤버를 선택할 수는 없습니다.
프로토콜 HTTP 또는 HTTP를 사용하는 백엔드 풀을 사용하는 경우 클라이언트 요청을 백엔드 풀로 전달할 때 ALB는 SNI를 설정하지 않습니다. 이는 ALB가 SNI를 사용하여 전달 결정을 내릴 때(레이어 7 규칙이 구성된 경우)에만 SNI를 활용하며, ALB는 백엔드와 별도의 TLS 핸드셰이크를 수행하기 때문입니다(이는 클라이언트의 핸드셰이크와는 다릅니다).
백엔드에 HTTP 또는 HTTPS 대신 TCP 프로토콜을 사용하는 경우, ALB는 클라이언트가 전송한 SNI를 설정합니다. 이는 TLS 의 핸드셰이크가 ALB와 백엔드 간이 아닌, 클라이언트와 백엔드 간에 직접 이루어지기 때문입니다.
HTTP / HTTPS SNI가 있는 리스너를 사용하는 경우 다음 해결 방법 중 하나를 사용하세요:
- 가상 호스트에서 와일드카드 인증서를 사용합니다. 그런 다음 별도의 백엔드 포트에 단일 호스트 이름만 구성합니다. 예를 들어 호스트 이름별로 개별 서버로 라우팅하려는 경우 각 호스트 이름에 대해 별도의 풀을 생성하고 SNI를 사용하여 올바른 풀로 라우팅할 수 있습니다.
- 백엔드 프로토콜로 HTTPS 대신 TCP 모드를 사용하십시오. TCP 이 모드는 SNI를 올바르게 전달하며, 설정을 통해 SNI 호스트명 규칙에 기반한 부하 분산을 계속 사용할 수 있습니다.
예시: sni_hostname 규칙을 사용하는 TCP 리스너 생성
curl -H "Authorization: Bearer $iam_token" -X POST
"$vpc_api_endpoint/v1/load_balancers/$lbId/listeners" -d '{
"connection_limit": 2000,
"port": 443,
"protocol": "tcp",
"policies": [
{
"action": "forward_to_listener",
"name": "listener-forward-policy",
"priority": 4,
"rules": [
{
"condition": "equals",
"type": "sni_hostname",
"value": "www.example.com"
}
],
"target": {
"id": "r006-20275400-825e-4d9b-8177-076fdb4134cc"
}
}
]
}'