Transparent Proxy 모드에서 서비스 온보딩
Transparent Proxy 모드에서 서비스 온보딩 (Onboard Services While in Transparent Proxy Mode)
이 주제는 transparent proxy 모드가 활성화되었을 때 기존 애플리케이션을 Consul 서비스 메시에 안전하게 온보딩할 수 있도록 Consul을 허용적(permissive) mTLS 모드로 실행하는 방법을 설명해요.
출처: 문서
본문
이 주제는 transparent proxy 모드가 활성화되었을 때 기존 애플리케이션을 Consul 서비스 메시에 안전하게 온보딩할 수 있도록 Consul을 허용적(permissive) mTLS 모드로 실행하는 방법을 설명해요.
배경 (Background)
transparent proxy 모드가 활성화되면 모든 서비스 간 트래픽이 mTLS로 보호돼요. 네트워크에 추가하려는 서비스가 완전히 온보딩될 때까지 네트워크에 mTLS 및 비 mTLS 트래픽이 혼합될 수 있으며, 이는 서비스 간 통신이 깨질 수 있어요. 이 상황은 기존 메시 서비스의 사이드카 프록시가 아직 온보딩되지 않은 서비스의 트래픽을 거부하기 때문에 발생해요.
온보딩 단계 동안 기존 비 mTLS 서비스 간 트래픽이 허용되도록 permissive mTLS 모드를 활성화할 수 있어요. permissive mTLS 모드는 사이드카 프록시가 애플리케이션에 대한 mTLS 및 비 mTLS 트래픽을 모두 수락할 수 있게 해요. 이 모드를 사용하면 다운타임 없이, 그리고 애플리케이션을 재구성하거나 재배포할 필요 없이 온보딩할 수 있어요.
허용적 mTLS를 임시 운영 모드로 활성화할 것을 권장해요. 온보딩이 완료된 후에는 모든 서비스 간 통신이 Consul 서비스 메시에 의해 자동으로 보호되도록 모든 서비스를 strict mTLS 모드로 재구성해야 해요.
보안 경고: 서비스 온보딩 후 서비스에 대한 비 mTLS 연결을 방지하기 위해 허용적 mTLS 모드를 비활성화할 것을 권장해요. 의도(intentions)는 적용되지 않으며 비 mTLS 연결에 대해 암호화가 활성화되지 않아요.
워크플로 (Workflow)
mTLS 설정을 구성하는 워크플로는 온보딩하는 애플리케이션과 온보딩하려는 순서에 따라 달라지지만, 다음 단계가 일반적인 워크플로를 설명해요:
- 전역 설정 구성: 메시의 서비스가 메시 밖의 서비스에 비 mTLS 메시지를 보낼 수 있도록 메시를 구성해요. 또한 메시의 서비스가 허용적 mTLS 모드를 사용하도록 메시를 구성해요.
- 허용적 mTLS 모드 활성화: 관련 다운스트림 서비스보다 먼저 업스트림 서비스를 온보딩한다면 service defaults 구성 항목에서 허용적 mTLS 모드를 활성화해요. 이렇게 하면 서비스를 Consul에 등록할 때 업스트림 서비스가 메시에서 암호화된 메시지를 보낼 수 있어요.
- 의도 구성: 의도는 메시의 서비스 간 트래픽을 인가하는 컨트롤이에요. Transparent proxy는 의도를 사용해 Envoy 프록시 간 트래픽 경로를 추론해요. 프록시가 허용적 mTLS 모드에 있는 동안 이루어진 비 mTLS 연결에는 Consul이 의도를 적용하지 않지만, 온보딩 과정을 완료하려면 의도가 필요해요.
- 서비스 등록: 서비스 정의를 만들고 사이드카 프록시를 구성하고 배포해요.
- 메시 재보안: 허용적 mTLS 모드를 활성화했다면 strict mTLS 모드로 전환하고 전역 설정을 되돌려 서비스 메시에서 비 mTLS 트래픽을 비활성화해요.
요구 사항 (Requirements)
허용적 mTLS는 transparent proxy 모드에서 실행되는 서비스에만 지원돼요. Transparent proxy 모드는 Kubernetes 배포에서만 사용할 수 있어요.
제한 사항 (Limitations)
의도와 일부 Envoy 확장 같은 L7 Envoy 기능은 비 mTLS 트래픽에 대해 지원되지 않아요.
전역 설정 구성 (Configure global settings)
이미 메시에 있는 서비스가 메시 밖의 서비스에 비 mTLS 메시지를 보낼 수 있도록 Consul을 구성해요. 또한 서비스가 허용적 mTLS 모드에서 실행되도록 Consul을 구성할 수도 있어요. 서비스 메시 프록시 동작을 정의하는 전역 구성인 mesh 게이트웨이 구성 항목에 두 구성 모두를 설정해요.
아웃바운드 비 mTLS 트래픽 허용 (Allow outgoing non-mTLS traffic)
메시의 서비스가 메시 밖의 서비스에 비 mTLS 메시지를 보낼 수 있게 하는 전역 설정을 구성할 수 있어요.
mesh 구성 항목에 MeshDestinationsOnly 속성을 추가하고 속성을 false로 설정해요. 서비스가 여러 관리 파티션에 속한다면 각 파티션에 설정을 적용해야 해요:
HCL:
Kind = "mesh"
TransparentProxy {
MeshDestinationsOnly = false
}
YAML:
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
name: mesh
spec:
transparentProxy:
meshDestinationsOnly: true
JSON:
{
"Kind": "mesh",
"TransparentProxy": [
{
"MeshDestinationsOnly": false
}
]
}
또는 아웃바운드 포트 제외를 구성해 서비스별로 아웃바운드 트래픽을 선택적으로 허용할 수도 있어요. 이 설정은 transparent proxy가 부과하는 트래픽 리디렉션에서 아웃바운드 트래픽을 제외해요. 이 설정을 변경할 때는 애플리케이션을 재배포해야 해요.
인바운드 트래픽에 대한 허용적 mTLS 모드 허용 (Allow permissive mTLS modes for incoming traffic)
메시의 서비스가 인바운드 트래픽에 허용적 mTLS 모드를 사용할 수 있도록 mesh 구성 항목에서 AllowEnablingPermissiveMutualTLS 매개변수를 true로 설정해요. 이 매개변수는 서비스가 허용적 mTLS를 사용하도록 지시하지 않아요. 서비스가 허용적 mTLS 모드에서 실행될 수 있게 하는 전역 매개변수예요.
HCL:
Kind = "mesh"
AllowEnablingPermissiveMutualTLS = true
TransparentProxy {
MeshDestinationsOnly = false
}
YAML:
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
name: mesh
spec:
allowEnablingPermissiveMutualTLS: true
transparentProxy:
meshDestinationsOnly: false
JSON:
{
"Kind": "mesh",
"AllowEnablingPermissiveMutualTLS": true,
"TransparentProxy": [
{
"MeshDestinationsOnly": false
}
]
}
현재 허용적 모드로 실행 중인 서비스가 있더라도 이 설정을 언제든지 false로 변경할 수 있어요. 이렇게 하면 온보딩 과정 중 어느 시점에 서비스가 허용적 mTLS 사용을 중단하도록 할지 결정할 수 있어요. MeshDestinationOnly가 false로 설정되면 메시에 추가되는 모든 새 서비스는 Consul이 메시 전체에서 트래픽을 안전하게 라우팅하도록 MutualTLSMode=strict로 구성해야 해요.
허용적 mTLS 모드 활성화 (Enable permissive mTLS mode)
온보딩하는 서비스에 따라 허용적 mTLS 모드를 활성화할 필요가 없을 수도 있어요. 서비스가 인바운드 트래픽을 수락하지 않거나 이미 서비스 메시의 일부인 다운스트림 서비스의 트래픽을 수락한다면 허용적 mTLS 모드는 계속하는 데 필요하지 않아요.
서비스에 대해 허용적 mTLS 모드를 활성화하려면 서비스의 service defaults 구성 항목에서 MutualTLSMode=permissive를 설정해요. 다음 예시는 example-service라는 서비스에 대해 이 설정을 구성하는 방법을 보여줘요.
HCL:
Kind = "service-defaults"
Name = "example-service"
MutualTLSMode = "permissive"
YAML:
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: example-service
spec:
mutualTLSMode: "permissive"
JSON:
{
"Kind": "service-defaults",
"Name": "example-service",
"MutualTLSMode": "permissive"
}
모든 설정에 대한 정보는 service defaults 구성 참조를 참고해요.
이 서비스에 대한 인바운드 트래픽에 mTLS가 필요하도록 언제든지 이 설정을 strict로 변경할 수 있어요.
의도 구성 (Configure intentions)
서비스 의도는 메시의 서비스 간 트래픽을 제어하는 Consul의 메커니즘이에요.
서비스가 필요한 트래픽만 수락하도록 제한하는 의도를 만들 것을 권장해요. 메시에 추가하려는 서비스에 메시지를 보내는 다운스트림 서비스를 식별한 다음 다운스트림에서 해당 서비스로의 트래픽을 허용하는 의도를 만들어야 해요.
transparent proxy가 활성화되고 MutualTLSMode 매개변수가 permissive로 설정되면 다운스트림 서비스에서 다른 업스트림 서비스로의 인바운드 트래픽은 해당 업스트림 관계가 Consul에 알려지지 않는 한 mTLS로 보호되지 않아요. Consul이 의도에서 업스트림 관계를 추론할 수 있도록 의도를 정의하거나, 다운스트림의 서비스 정의의 일부로 명시적 업스트림을 포함해야 해요.
의도가 어떻게 작동하고 어떻게 만드는지에 대한 추가 정보는 서비스 의도를 참고해요.
메시에 서비스 추가 (Add the service to the mesh)
카탈로그에 서비스를 등록하고 사이드카 프록시를 배포하도록 애플리케이션을 업데이트해요. 또한 구성을 확인하기 위해 서비스를 모니터링해야 해요. 추가 정보는 Kubernetes 서비스 메시 개요를 참고해요.
메시 트래픽 재보안 (Re-secure mesh traffic)
새로 추가된 서비스가 온보딩을 위해 허용적 mTLS 모드로 배치되었다면 안전할 때 strict 모드로 전환해야 해요. 또한 서비스가 비 mTLS 트래픽을 보내고 받을 수 있게 하는 전역 설정도 되돌려야 해요.
허용적 mTLS 모드 비활성화 (Disable permissive mTLS mode)
서비스가 더 이상 인바운드 비 mTLS 트래픽을 수신하지 않으면 서비스가 strict mTLS 모드로 동작하도록 구성해요. 이 서비스에 메시지를 보내는 다운스트림 서비스가 모두 메시에 온보딩된 후에는 이 서비스가 더 이상 비 mTLS 트래픽을 수신해서는 안 돼요.
사이드카가 비 mTLS 트래픽을 수신하는지 확인하려면 사이드카 프록시에 대한 다음 Envoy 리스너 통계를 확인해요:
tcp.permissive_public_listener.*통계는 비 mTLS 트래픽을 나타내요. 이러한 메트릭이 충분한 시간 동안 정적이면 사이드카가 비 mTLS 트래픽을 수신하지 않고 있음을 나타내요.tcp.public_listener.*통계는 mTLS 트래픽을 나타내요. 이 서비스에 인바운드 트래픽이 예상되고 이러한 통계가 변경되고 있다면 사이드카가 mTLS 트래픽을 수신하고 있는 것이에요.
추가 정보는 서비스 메시 관찰성 개요와 Kubernetes용 Consul 메트릭 구성 문서를 참고해요.
서비스가 여전히 비 mTLS 트래픽을 수신한다면 다음 단계를 완료해 비 mTLS 트래픽의 소스를 결정해요:
- 다운스트림 서비스 목록을 확인해요. 선택적으로 Envoy 액세스 로깅을 활성화해 인바운드 트래픽의 소스 IP 주소를 결정하고 그 IP 주소를 네트워크의 서비스와 교차 참조할 수 있어요.
- 각 다운스트림이 서비스 메시에 온보딩되었는지 확인해요. 다운스트림이 온보딩되지 않았다면 다음에 온보딩하는 것을 고려해요.
- 각 다운스트림에 업스트림 서비스로 트래픽을 보낼 수 있게 하는 의도가 있는지 확인해요.
서비스를 strict 모드로 전환하는 것이 안전하다고 판단한 후 service defaults 구성 항목에서 MutualTLSMode=strict를 설정해요.
HCL:
Kind = "service-defaults"
Name = "example-service"
MutualTLSMode = "strict"
YAML:
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: example-service
spec:
mutualTLSMode: "strict"
JSON:
{
"Kind": "service-defaults",
"MutualTLSMode": "strict",
"Name": "example-service"
}
비 mTLS 트래픽 비활성화 (Disable non-mTLS traffic)
모든 서비스가 온보딩된 후 비 mTLS 트래픽을 허용하는 전역 설정을 되돌리고 메시에서 허용적 mTLS 모드가 사용되지 않는지 확인해요.
mesh 구성 항목에서 AllowEnablingPermissiveMutualTLS=false와 MeshDestinationsOnly=true를 설정해요.
HCL:
Kind = "mesh"
AllowEnablingPermissiveMutualTLS = false
TransparentProxy {
MeshDestinationsOnly = true
}
YAML:
apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
name: mesh
spec:
allowEnablingPermissiveMutualTLS: false
transparentProxy:
meshDestinationsOnly: true
JSON:
{
"Kind": "mesh",
"AllowEnablingPermissiveMutualTLS": false,
"TransparentProxy": [
{
"MeshDestinationsOnly": true
}
]
}
Consul 배포의 각 네임스페이스, 관리 파티션, 데이터센터에 대해 consul config list 및 consul config read 명령을 실행해 어떤 서비스도 permissive mTLS 모드를 사용하지 않는지 확인해요.
다음 명령은 'MutualTLSMode = "permissive"'를 포함하는 service defaults 구성 항목을 반환해요:
$ consul config list -kind service-defaults -filter 'MutualTLSMode == "permissive"'
각 관리 파티션과 데이터센터에서 proxy defaults 구성 항목에 MutualTLSMode = "permissive"가 설정되지 않았는지 확인해요. MutualTLSMode가 비어 있거나 구성 항목을 찾을 수 없으면 모드는 기본적으로 strict예요.
다음 명령은 proxy defaults 구성 항목을 가져와요:
$ consul config read -kind proxy-defaults -name global
{
"Kind": "proxy-defaults",
"Name": "global",
"Partition": "default",
"Namespace": "default",
"TransparentProxy": {},
"MutualTLSMode": "",
"MeshGateway": {},
"Expose": {},
"AccessLogs": {},
"CreateIndex": 26,
"ModifyIndex": 30
}