Cloud Service Mesh 예시: 승인


이 튜토리얼에서는 승인의 정의, 샘플 애플리케이션에서 Cloud Service Mesh를 사용하여 승인을 사용 설정하는 방법, 마이크로서비스에 승인 정책을 사용 설정하는 방법을 알아봅니다. 우선 AuthorizationPolicy를 생성하여 마이크로서비스에 대한 액세스를 DENY한 후에, AuthorizationPolicy를 생성하여 마이크로서비스에 대한 특정 액세스를 ALLOW하게 될 것입니다.

승인이란 무엇인가?

인증은 신원을 확인합니다. - 이 서비스의 주체가 본인이 맞는가? 승인은 권한을 확인합니다. - 이 서비스가 그 작업을 해도 되는가? ID는 이 아이디어의 기본입니다. Cloud Service Mesh를 사용하면 AuthorizationPolicies는 보안과 액세스가 개선될 수 있도록 메시에서 워크로드 간 통신을 제어할 수 있습니다.

네트워크 경계를 넘어 호출이 이루어지는 마이크로서비스 아키텍처에서는 기존 IP 기반 방화벽 규칙으로는 워크로드 간 액세스 보호에 충분하지 않은 경우가 많습니다. Cloud Service Mesh를 사용하면 다음을 위한 승인 규칙을 설정할 수 있습니다.

  • 워크로드 간 또는 최종 사용자와 워크로드 간 메시 내 워크로드 액세스 제어
  • 필요에 따라 광범위하게 또는 세부적으로 정책 정의. 정책과 권장사항을 구성하는 방법에 대한 자세한 내용은 Cloud Service Mesh로 승인을 참조하세요.

비용

이 튜토리얼에서는 다음과 같은 Google Cloud 구성요소를 사용하며 여기에는 비용이 청구될 수 있습니다.

이 튜토리얼을 마치면 만든 리소스를 삭제하여 비용이 계속 청구되지 않도록 할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

  • 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
    cd anthos-service-mesh-samples
    

인그레스 게이트웨이 배포

  1. kubectl의 현재 컨텍스트를 클러스터로 설정합니다.

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. 인그레스 게이트웨이에 대해 네임스페이스를 만듭니다.

    kubectl create namespace asm-ingress
    
  3. 네임스페이스의 삽입을 사용 설정합니다. 이 단계는 Cloud Service Mesh 유형(관리형 또는 클러스터 내)에 따라 다릅니다.

    관리됨

    네임스페이스에 asm-managed 버전 라벨을 적용합니다.

    kubectl label namespace asm-ingress \
      istio-injection- istio.io/rev=asm-managed --overwrite
    

    이 라벨은 Cloud Service Mesh 버전에 대한 현재 관리형 Cloud Service Mesh 출시 채널에 해당합니다.

    클러스터 내

    1. 다음 명령어를 사용하여 istiod에서 버전 라벨을 찾습니다.

      kubectl get deploy -n istio-system -l app=istiod -o \
        jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. 네임스페이스에 버전 라벨을 적용합니다. 다음 명령어에서 REVISION은 이전 단계에서 확인한 istiod 버전 라벨의 값입니다.

      kubectl label namespace asm-ingress \
        istio-injection- istio.io/rev=REVISION --overwrite
      
  4. anthos-service-mesh-samples 저장소에 게이트웨이 예시를 배포합니다.

    kubectl apply -n asm-ingress \
    -f docs/shared/asm-ingress-gateway
    

    예상 출력:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

Online Boutique 샘플 애플리케이션 배포

  1. 아직 설정하지 않은 경우 kubectl의 현재 컨텍스트를 클러스터로 설정합니다.

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. 샘플 애플리케이션의 네임스페이스를 만듭니다.

    kubectl create namespace onlineboutique
    
  3. Envoy 프록시를 자동으로 주입하도록 onlineboutique 네임스페이스에 라벨을 지정합니다. 자동 사이드카 주입 사용 설정 단계를 따릅니다.

  4. 샘플 앱, 프런트엔드용 VirtualService, 워크로드의 서비스 계정을 배포합니다. 이 튜토리얼에서는 마이크로서비스 데모 앱인 Online Boutique를 배포합니다.

    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/virtual-service.yaml
    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/service-accounts
    

서비스 보기

  1. onlineboutique 네임스페이스의 포드를 확인합니다.

    kubectl get pods -n onlineboutique
    

    예상 출력:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    애플리케이션의 모든 포드가 작동되고 READY 열의 2/2를 사용해서 실행됩니다. 이것은 포드에 Envoy 사이드카 프록시가 성공적으로 주입된 것을 나타냅니다. 몇 분 후에도 2/2가 표시되지 않는다면 문제 해결 가이드를 방문하세요.

  2. 외부 IP를 가져오고 이를 변수로 설정합니다.

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    다음과 비슷한 출력이 표시됩니다.

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. 웹브라우저에서 EXTERNAL-IP 주소를 방문합니다. 브라우저에 Online Boutique 매장이 표시될 것으로 예상됩니다.

    Online Boutique 프런트엔드

워크로드에 대한 모든 승인 거부

이 섹션에서는 통화 서비스에 대한 모든 수신 트래픽을 거부하는 AuthorizationPolicy를 추가합니다. AuthorizationPoliciesAuthorizationPolicies를 Envoy가 읽을 수 있는 구성으로 변환하고 구성을 사이드카 프록시에 적용합니다. 이렇게 하면 Envoy 프록시가 서비스에 대한 수신 요청을 승인하거나 거부할 수 있습니다.

  1. currencyserviceAuthorizationPolicy를 적용합니다. YAML 파일의 currencyservice 라벨과 일치하는 항목을 확인합니다.

    kubectl apply -f docs/authorization/currency-deny-all.yaml -n onlineboutique
    
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: currency-policy
    spec:
      selector:
        matchLabels:
          app: currencyservice
  2. 웹브라우저에서 Online Boutique를 보려면 게이트웨이의 EXTERNAL-IP에 액세스합니다. currency service의 승인 오류(500 내부 서비스 오류)가 표시됩니다.

    authz rbac 500 오류

사이드카 프록시 로그 관찰

사이드카 프록시에서 발생하는 상황을 확인하려면 포드에서 로그를 검토할 수 있습니다.

  1. currencyservice 포드의 이름을 가져옵니다.

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. trace 수준 로그를 허용하도록 Envoy 프록시를 설정합니다. 기본적으로 차단된 승인 호출은 로깅되지 않습니다.

    kubectl exec -it $CURRENCY_POD -n onlineboutique -c istio-proxy -- curl -X POST "http://localhost:15000/logging?level=trace"
    

    예상 출력: active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

  3. curl을 사용하여 트래픽을 EXTERNAL_IP로 보내 로그를 생성합니다.

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. istio-proxy에서 역할 기반 액세스 제어(RBAC) 관련 로그를 봅니다.

    kubectl logs -n onlineboutique $CURRENCY_POD -c istio-proxy | grep -m5 rbac
    

    예상 출력:

    2022-07-08T14:19:20.442920Z     debug   envoy rbac      checking request: requestedServerName: outbound_.7000_._.currencyservice.onlineboutique.svc.cluster.local, sourceIP: 10.8.8.5:34080, directRemoteIP: 10.8.8.5:34080, remoteIP: 10.8.8.5:34080,localAddress: 10.8.0.6:7000, ssl: uriSanPeerCertificate: spiffe://christineskim-tf-asm.svc.id.goog/ns/onlineboutique/sa/default, dnsSanPeerCertificate: , subjectPeerCertificate: OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US, headers: ':method', 'POST'
    2022-07-08T14:19:20.442944Z     debug   envoy rbac      enforced denied, matched policy none
    2022-07-08T14:19:20.442965Z     debug   envoy http      [C73987][S13078781800499437460] Sending local reply with details rbac_access_denied_matched_policy[none]
      ```
    

currencyservice가 인바운드 요청을 차단하도록 설정되어 있음을 보여주는 enforced denied 메시지가 로그에 표시됩니다.

제한된 액세스 허용

DENYALL 정책 대신 특정 워크로드에 대한 액세스를 허용하도록 설정할 수 있습니다. 이는 승인된 서비스만 서로 통신할 수 있도록 하려는 마이크로서비스 아키텍처와 관련이 있습니다.

이 섹션에서는 frontendcheckout 서비스가 currency 서비스와 통신하는 기능을 사용 설정합니다.

  1. 아래 파일에서 특정 source.principal(클라이언트)이 currencyservice에 액세스하도록 허용 목록에 추가되었는지 확인합니다.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: currency-policy
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/checkoutservice"]

정책을 적용합니다.

kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
  1. 웹브라우저에서 EXTERNAL-IP를 방문하면 이제 Online Boutique에 액세스할 수 있습니다.

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 프로젝트를 삭제하거나 개별 리소스를 삭제하면 됩니다.

프로젝트 삭제

Cloud Shell에서 프로젝트를 삭제합니다.

gcloud projects delete PROJECT_ID

리소스 삭제

  • 클러스터를 유지하고 Online Boutique를 삭제하려면 다음 안내를 따르세요.

    1. 애플리케이션 네임스페이스를 삭제합니다.

      kubectl delete namespace onlineboutique
      

      예상 출력:

      namespace "onlineboutique" deleted
      
    2. 인그레스 게이트웨이 네임스페이스를 삭제합니다.

      kubectl delete namespace asm-ingress
      

      예상 출력:

      amespace "asm-ingress" deleted
      
  • 추가 요금이 청구되지 않도록 하려면 클러스터를 삭제하세요.

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    

다음 단계