Cloud Service Mesh 1.5 이상에서는 자동 상호 TLS(자동 mTLS)가 기본적으로 사용 설정됩니다. 자동 mTLS를 사용하면 클라이언트 사이드카 프록시가 서버에 사이드카가 있는지 자동으로 감지합니다. 클라이언트 사이드카는 사이드카가 있는 워크로드에는 mTLS를 전송하고, 사이드카 없는 워크로드에는 일반 텍스트를 전송합니다. 하지만 서비스는 일반 텍스트와 mTLS 트래픽을 모두 수락합니다. 포드에 사이드카 프록시를 삽입할 때에도 mTLS 트래픽만 허용하도록 서비스를 구성하는 것이 좋습니다.
Cloud Service Mesh를 사용하면 단일 YAML 파일을 적용하여 애플리케이션 코드 외부에서 mTLS를 적용할 수 있습니다. Cloud Service Mesh는 전체 서비스 메시, 네임스페이스, 개별 워크로드에 인증 정책을 적용할 수 있는 유연성을 제공합니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
이 튜토리얼을 마치면 만든 리소스를 삭제하여 비용이 계속 청구되지 않도록 할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.
GKE 클러스터에 Cloud Service Mesh를 설치하고 인그레스 게이트웨이를 배포합니다. 이 튜토리얼의 클러스터를 설정해야 하는 경우 이를 안내하는 관리형 Cloud Service Mesh 컨트롤 플레인 프로비저닝을 참고하세요.
Online Boutique 액세스
kubectl
의 현재 컨텍스트를, Online Boutique를 배포한 클러스터로 설정합니다.gcloud container clusters get-credentials CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
frontend
네임스페이스의 서비스를 나열합니다.kubectl get services -n frontend
frontend-external
은LoadBalancer
이며 외부 IP 주소를 포함합니다. 샘플 애플리케이션에는 부하 분산기에 해당하는 서비스가 포함되어 Cloud Service Mesh가 없는 GKE에 배포될 수 있습니다.frontend-external
서비스의 외부 IP 주소를 사용하여 브라우저에서 애플리케이션을 방문합니다.http://FRONTEND_EXTERNAL_IP/
Cloud Service Mesh는 인그레스 게이트웨이를 배포하는 기능을 제공합니다. 또한 인그레스 게이트웨이의 외부 IP 주소를 사용하여 Online Boutique에 액세스할 수 있습니다. 게이트웨이의 외부 IP를 가져옵니다. 자리표시자를 다음 정보로 바꿉니다.
- GATEWAY_SERVICE_NAME: 인그레스 게이트웨이 서비스의 이름입니다. 샘플 게이트웨이를 수정하지 않고 배포한 경우 또는 기본 인그레스 게이트웨이를 배포한 경우 이름은
istio-ingressgateway
입니다. - GATEWAY_NAMESPACE: 인그레스 게이트웨이를 배포한 네임스페이스입니다. 기본 인그레스 게이트웨이를 배포한 경우 네임스페이스는
istio-system
입니다.
kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE
- GATEWAY_SERVICE_NAME: 인그레스 게이트웨이 서비스의 이름입니다. 샘플 게이트웨이를 수정하지 않고 배포한 경우 또는 기본 인그레스 게이트웨이를 배포한 경우 이름은
브라우저에서 다른 탭을 열고 인그레스 게이트웨이의 외부 IP 주소를 사용하여 애플리케이션을 방문합니다.
http://INGRESS_GATEWAY_EXTERNAL_IP/
다음 명령어를 실행하여 다른 포드의 일반 HTTP로
frontend
서비스를curl
합니다. 서비스가 서로 다른 네임스페이스에 있으므로frontend
서비스의 DNS 이름을 curl해야 합니다.kubectl exec \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -c istio-proxy -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
기본적으로 TLS 및 일반 텍스트 트래픽이 모두 수락되므로 요청이
200
상태로 성공합니다.
네임스페이스당 상호 TLS 사용 설정
kubectl
을 사용해 PeerAuthentication
정책을 적용하여 mTLS를 적용합니다.
다음 인증 정책을
mtls-namespace.yaml
로 저장합니다.cat <<EOF > mtls-namespace.yaml apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "namespace-policy" spec: mtls: mode: STRICT EOF
YAML의
mode: STRICT
줄에서 mTLS만 허용하도록 서비스를 구성합니다. 기본적으로mode
는PERMISSIVE
이며 일반 텍스트와 mTLS를 모두 허용하도록 서비스를 구성합니다.인증 정책을 적용하여 모든 Online Boutique 서비스에서 mTLS만 수락하도록 구성합니다.
for ns in ad cart checkout currency email frontend loadgenerator \ payment product-catalog recommendation shipping; do kubectl apply -n $ns -f mtls-namespace.yaml done
예상 출력:
peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created peerauthentication.security.istio.io/namespace-policy created
브라우저에서
frontend-external
서비스의 외부 IP 주소를 사용하여 Online Boutique에 액세스하는 탭으로 이동합니다.http://FRONTEND_EXTERNAL_IP/
페이지를 새로고침합니다. 브라우저에 다음 오류가 표시됩니다.
페이지를 새로고침하면 일반 텍스트가
frontend
서비스로 전송됩니다.STRICT
인증 정책으로 인해 사이드카 프록시는 서비스에 대한 요청을 차단합니다.브라우저에서
istio-ingressgateway
의 외부 IP 주소를 사용하여 Online Boutique에 액세스하는 탭으로 이동하고 정상적으로 표시되는 페이지를 새로고침합니다. 인그레스 게이트웨이를 사용하여 Online Boutique에 액세스하면 요청은 다음 경로를 사용합니다.mTLS 인증 흐름은 다음과 같습니다.
- 브라우저에서 서버로 일반 텍스트 HTTP 요청을 보냅니다.
- 인그레스 게이트웨이 프록시 컨테이너가 요청을 가로챕니다.
- 인그레스 게이트웨이 프록시는 서버 측 프록시(이 예시에서는 프런트엔드 서비스)와 TLS 핸드셰이크를 수행합니다. 이 핸드셰이크에는 인증서 교환이 포함됩니다. 이러한 인증서는 Cloud Service Mesh를 통해 프록시 컨테이너에 사전 로드됩니다.
- 인그레스 게이트웨이 프록시는 서버 인증서의 보안 이름 확인을 실행하여 승인된 ID가 서버를 실행 중인지 확인합니다.
- 인그레스 게이트웨이와 서버 프록시는 상호 TLS 연결을 설정하며, 서버 프록시는 요청을 서버 애플리케이션 컨테이너(프런트엔드 서비스)로 전달합니다.
다음 명령어를 실행하여 다른 포드의 일반 HTTP로
frontend
서비스를curl
합니다.kubectl exec \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -c istio-proxy -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
모든 Online Boutique 서비스가
STRICT
mTLS로 설정되고 사이드카 프록시가 서비스에 대한 요청을 차단하기 때문에 요청이 실패합니다.예상 출력:
000 command terminated with exit code 56
mTLS 상태 보기
Google Cloud 콘솔에서 인증 정책을 포함한 GKE Enterprise 보안 기능의 상태를 볼 수 있습니다.
Google Cloud 콘솔에서 GKE Enterprise 개요 페이지로 이동합니다.
메뉴 바의 프로젝트 목록에서 Google Cloud 프로젝트를 선택합니다.
정책 상태 카드에서 해당 구성에 따라 정책 보기 또는 정책 사용 설정을 클릭합니다. 정책 컨트롤러 대시보드가 열립니다.
위반 탭을 클릭합니다.
리소스 종류에서 포드 체크박스를 선택합니다. 정책을 위반하는 포드 목록이 표시됩니다.
인증 정책 찾기 및 삭제하기
서비스 메시의 모든
PeerAuthentication
정책 목록을 보려면 다음을 실행하세요.kubectl get peerauthentication --all-namespaces
출력은 다음과 비슷합니다.
NAMESPACE NAME MODE AGE ad namespace-policy STRICT 17m cart namespace-policy STRICT 17m checkout namespace-policy STRICT 17m currency namespace-policy STRICT 17m email namespace-policy STRICT 17m frontend namespace-policy STRICT 17m loadgenerator namespace-policy STRICT 17m payment namespace-policy STRICT 17m product-catalog namespace-policy STRICT 17m recommendation namespace-policy STRICT 17m shipping namespace-policy STRICT 17m
모든 Online Boutique 네임스페이스에서 인증 정책을 삭제합니다.
for ns in ad cart checkout currency email frontend loadgenerator payment \ product-catalog recommendation shipping; do kubectl delete peerauthentication -n $ns namespace-policy done;
예상 출력:
peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted peerauthentication.security.istio.io "namespace-policy" deleted
frontend-external
서비스의 외부 IP 주소를 사용하여 Online Boutique에 액세스하고 페이지를 새로 고칩니다. 페이지가 예상한 대로 표시됩니다.다음 명령어를 실행하여 다른 포드의 일반 HTTP로
frontend
서비스를curl
합니다.kubectl exec \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -c istio-proxy -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
기본적으로 TLS 및 일반 텍스트 트래픽이 모두 수락되므로 요청이
200
상태로 성공합니다.
Google Cloud 콘솔에서 워크로드 목록을 표시하는 페이지를 새로 고치면 mTLS 상태가 Permissive
로 표시됩니다.
워크로드당 상호 TLS 사용 설정
특정 워크로드의 PeerAuthentication
정책을 설정하려면 selector
섹션을 구성하고 원하는 워크로드와 일치하는 라벨을 지정해야 합니다.
하지만 Cloud Service Mesh는 아웃바운드 mTLS 트래픽에 대한 워크로드 수준 정책을 서비스로 집계할 수 없습니다. 이 동작을 관리하려면 대상 규칙을 구성해야 합니다.
특정 워크로드에 인증 정책을 적용합니다. 다음 정책에서 어떻게 라벨 및 선택기를 사용하여 특정
frontend
배포를 타겟팅하는지 확인하세요.cat <<EOF | kubectl apply -n frontend -f - apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "frontend" namespace: "frontend" spec: selector: matchLabels: app: frontend mtls: mode: STRICT EOF
예상 출력:
peerauthentication.security.istio.io/frontend created
일치하는 대상 규칙을 구성합니다.
cat <<EOF | kubectl apply -n frontend -f - apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "frontend" spec: host: "frontend.demo.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
예상 출력:
destinationrule.networking.istio.io/frontend created
frontend-external
서비스의 외부 IP 주소를 사용하여 Online Boutique에 액세스하고 페이지를 새로 고칩니다.frontend service
가STRICT
mTLS로 설정되어 있고 사이드카 프록시가 요청을 차단하기 때문에 페이지가 표시되지 않습니다.다음 명령어를 실행하여 다른 포드의 일반 HTTP로
frontend
서비스를curl
합니다.kubectl exec \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -c istio-proxy -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
56
상태 코드와 함께 요청이 실패합니다.Google Cloud 콘솔에서 워크로드 목록을 표시하는 페이지를 새로 고치면
frontend
서비스의 mTLS 상태가Strict
로 표시되고 다른 서비스는Permissive
로 설정됩니다.인증 정책을 삭제합니다.
kubectl delete peerauthentication -n frontend frontend
예상 출력:
peerauthentication.security.istio.io "frontend" deleted
대상 규칙을 삭제합니다.
kubectl delete destinationrule -n frontend frontend
예상 출력:
destinationrule.networking.istio.io "frontend" deleted
메시 전체 mTLS 적용
메시의 모든 서비스에서 일반 텍스트 트래픽을 허용하지 않도록 하려면 mTLS 모드를 STRICT
로 설정하여 메시 전체 PeerAuthentication
정책을 설정합니다.
메시 전체 PeerAuthentication
정책에 선택기가 없어야 하며 정책이 루트 네임스페이스 istio-system
에 적용되어야 합니다. 정책을 배포하면 워크로드가 서로 인증할 수 있도록 컨트롤 플레인이 TLS 인증서를 자동으로 프로비저닝합니다.
메시 전체 mTLS를 적용합니다.
kubectl apply -f - <<EOF apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "mesh-wide" namespace: "istio-system" spec: mtls: mode: STRICT EOF
예상 출력:
peerauthentication.security.istio.io/mesh-wide created
frontend-external
서비스의 외부 IP 주소를 사용하여 Online Boutique에 액세스하고 페이지를 새로 고칩니다. 페이지가 표시되지 않습니다.다음 명령어를 실행하여 다른 포드의 일반 HTTP로
frontend
서비스를curl
합니다.kubectl exec \ $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \ -c istio-proxy -n product-catalog -- \ curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
56
상태 코드와 함께 요청이 실패합니다.mesh-wide
정책을 삭제합니다.kubectl delete peerauthentication -n istio-system mesh-wide
예상 출력:
peerauthentication.security.istio.io "mesh-wide" deleted
Google Cloud 콘솔에서 페이지를 새로 고치면 모든 서비스의
mTLS
세부정보에Permissive
가 표시됩니다.
삭제
이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.
추가 요금이 청구되지 않도록 하려면 클러스터를 삭제하세요.
gcloud container clusters delete CLUSTER_NAME \ --project=PROJECT_ID \ --zone=CLUSTER_LOCATION
클러스터를 유지하고 Online Boutique를 삭제하려면 다음 안내를 따르세요.
- 애플리케이션 네임스페이스를 삭제합니다.
kubectl delete -f online-boutique/kubernetes-manifests/namespaces
예상 출력:
namespace "ad" deleted namespace "cart" deleted namespace "checkout" deleted namespace "currency" deleted namespace "email" deleted namespace "frontend" deleted namespace "loadgenerator" deleted namespace "payment" deleted namespace "product-catalog" deleted namespace "recommendation" deleted namespace "shipping" deleted
- 서비스 항목을 삭제합니다.
kubectl delete -f online-boutique/istio-manifests/allow-egress-googleapis.yaml
예상 출력:
serviceentry.networking.istio.io "allow-egress-googleapis" deleted serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
다음 단계
PeerAuthentication
정책 구성에 대한 일반적인 가이드는 전송 보안 구성을 참조하기