본문 바로가기

컨테이너/쿠버네티스 네트워크

[KANS] 쿠버네티스 네트워크 (14) Service Mesh (istio) : Traffic Management

목표:

(1) istio 기능 - Traffic Management 

 

  • 4개 서비스 모두 v1 의 서브셋(subset) 에 전송하는 정책 테스트
  • L7 Layer Header을 이용한 지능적 라우팅
  • Fault Injection

정환열 님이 작성해서 공유해주신 Istio 사내 교육용 자료 내용 중 가져왔습니다

동작 소개 : 클라이언트 PC → Istio ingressgateway 파드 → (Gateway, VirtualService + DestinationRule) → Cluster(Endpoint - 파드)

Gateway : 지정한 인그레스 게이트웨이로부터 트래픽이 인입, 프로토콜 및 포트, HOSTS, Proxy 등 설정 가능

VirtualService : 인입 처리할 hosts 설정, L7 PATH 별 라우팅, 목적지에 대한 정책 설정 가능 (envoy route config) 

  • 사용 예시 : 헤더 매칭에 따라서, 각기 다른 destination 으로 라우팅
  • VirtualService 는 DestinationRule 에서 설정된 서브셋(subset)을 사용하여 트래픽 컨트롤을 할 수 있다
  • hosts 필드 : 목적지 주소 - IP address, a DNS name (FQDN), 혹은 k8s svc 이름 , wildcard (”*”) prefixes
  • Routing rules : HTTP 경우 - Match 필드(예, 헤더) , Destination(istio/envoy 에 등록된 대상, subnet 에 DestinationRule 활용)
    • HTTPRoute : redirect , rewrite , fault(장애 주입) , mirror(복제, 기본 100%) , corsPolicy(CORS 삽입) , headers(헤더 조작) 등 - 링크
  •  
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

 

DestinationRule : 실제 도착지(서비스와 1:1 연결)의 정교한 정책(부하분산, 연결 옵션, 서킷 브레이크, TLS 등)을 설정 - 링크

  • 사용예시 : 아래 yaml 참고
  • 3개의 subsets for the my-svc  destination service 에 3개의 subsets 이 있고, 이중 v1/v3 은 RAMDOM 이고 v2 는 ROUND_ROBIN
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3
  • Load balancing options : Round robin(기본값) , Random , Weighted , Least requests - 링크
    • Destination Rule : TrafficPolicy , Subset , ConnectionPoolSettings 등 - 링크
    • 서브셋(subsets)을 정의할 수 있어 마이크로서비스 버전별로 라우팅할 때 사용한다

istio 기능 - Traffic Management 

  • kiali 설치 (모니터링 가시화)
# Install Kiali and the other addons and wait for them to be deployed. : Kiali dashboard, along with Prometheus, Grafana, and Jaeger.
tree ~/istio-$ISTIOV/samples/addons/
kubectl apply -f ~/istio-$ISTIOV/samples/addons # 디렉터리에 있는 모든 yaml 자원을 생성
kubectl rollout status deployment/kiali -n istio-system

# 확인
kubectl get all,sa,cm -n istio-system
kubectl get svc,ep -n istio-system

# kiali 서비스 변경
kubectl patch svc -n istio-system kiali -p '{"spec":{"type":"NodePort"}}'

# kiali 웹 접속 주소 확인
KIALINodePort=$(kubectl get svc -n istio-system kiali -o jsonpath={.spec.ports[0].nodePort})
echo -e "KIALI UI URL = http://$(curl -s ipinfo.io/ip):$KIALINodePort"

# Grafana 서비스 변경
kubectl patch svc -n istio-system grafana -p '{"spec":{"type":"NodePort"}}'

# Grafana 웹 접속 주소 확인 : 7개의 대시보드
GRAFANANodePort=$(kubectl get svc -n istio-system grafana -o jsonpath={.spec.ports[0].nodePort})
echo -e "Grafana URL = http://$(curl -s ipinfo.io/ip):$GRAFANANodePort"

# Prometheus 서비스 변경
kubectl patch svc -n istio-system prometheus -p '{"spec":{"type":"NodePort"}}'

# Prometheus 웹 접속 주소 확인
PROMENodePort=$(kubectl get svc -n istio-system prometheus -o jsonpath={.spec.ports[0].nodePort})
echo -e "Prometheus URL = http://$(curl -s ipinfo.io/ip):$PROMENodePort"

# 4개 서비스 모두 v1 의 서브셋(subset) 에 전송하는 정책 테스트

  • 기본 Destination Rule 적용시 v1으로만 트래픽 전달되는것을 알수 있음.
# 샘플 파일들 확인
cd ~/istio-$ISTIOV/samples/bookinfo/networking
tree

# 기본 DestinationRule 적용
kubectl apply -f destination-rule-all.yaml

# DestinationRule 확인 dr(=destinationrules) : KIALI Services 확인 시 GW, VS, DR 확인
kubectl get dr
NAME          HOST          AGE
details       details       16m
productpage   productpage   16m
ratings       ratings       16m
reviews       reviews       16m

 

# L7 Layer Header을 이용한 지능적 라우팅

  •  virtual-service-reviews-test-v2.yaml 적용
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
# 모든 마이크로서비스에 대해 v1 의 서브셋(subset) 에 전송되게 virtualservices 적용
kubectl apply -f virtual-service-reviews-test-v2.yaml

# jason 로그인 시 로그 확인
kubetail -l app=productpage -f
[productpage-v1-6b746f74dc-7ptpj productpage] INFO:werkzeug:127.0.0.6 - - [13/Feb/2022 09:00:37] "POST /login HTTP/1.1" 302 -
[productpage-v1-6b746f74dc-7ptpj productpage] DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): details:9080
### end-user: jason 확인
[productpage-v1-6b746f74dc-7ptpj productpage] send: b'GET /details/0 HTTP/1.1\r\nHost: details:9080\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nX-B3-TraceId: 5d48ade1f048c3fc7ebe4197c22c3275\r\nX-B3-SpanId: 675da1ab468945b5\r\nX-B3-ParentSpanId: 7ebe4197c22c3275\r\nX-B3-Sampled: 1\r\nend-user: jason\r\nx-request-id: 95907bc3-1a86-9f1d-8963-3723b9fb1e21\r\n\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] reply: 'HTTP/1.1 200 OK\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] header: content-type: application/json
[productpage-v1-6b746f74dc-7ptpj productpage] header: server: envoy
[productpage-v1-6b746f74dc-7ptpj productpage] header: date: Sun, 13 Feb 2022 09:00:37 GMT
[productpage-v1-6b746f74dc-7ptpj productpage] header: content-length: 178
[productpage-v1-6b746f74dc-7ptpj productpage] header: x-envoy-upstream-service-time: 1

[productpage-v1-6b746f74dc-7ptpj productpage] DEBUG:urllib3.connectionpool:http://details:9080 "GET /details/0 HTTP/1.1" 200 178
[productpage-v1-6b746f74dc-7ptpj productpage] DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): reviews:9080
[productpage-v1-6b746f74dc-7ptpj productpage] send: b'GET /reviews/0 HTTP/1.1\r\nHost: reviews:9080\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nX-B3-TraceId: 5d48ade1f048c3fc7ebe4197c22c3275\r\nX-B3-SpanId: 675da1ab468945b5\r\nX-B3-ParentSpanId: 7ebe4197c22c3275\r\nX-B3-Sampled: 1\r\nend-user: jason\r\nx-request-id: 95907bc3-1a86-9f1d-8963-3723b9fb1e21\r\n\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] reply: 'HTTP/1.1 200 OK\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] header: x-powered-by: Servlet/3.1
[productpage-v1-6b746f74dc-7ptpj productpage] header: content-type: application/json
[productpage-v1-6b746f74dc-7ptpj productpage] header: date: Sun, 13 Feb 2022 09:00:37 GMT
[productpage-v1-6b746f74dc-7ptpj productpage] header: content-language: en-US
[productpage-v1-6b746f74dc-7ptpj productpage] header: content-length: 379
[productpage-v1-6b746f74dc-7ptpj productpage] header: x-envoy-upstream-service-time: 32
[productpage-v1-6b746f74dc-7ptpj productpage] header: server: envoy
[productpage-v1-6b746f74dc-7ptpj productpage] DEBUG:urllib3.connectionpool:http://reviews:9080 "GET /reviews/0 HTTP/1.1" 200 379
[productpage-v1-6b746f74dc-7ptpj productpage] INFO:werkzeug:127.0.0.6 - - [13/Feb/2022 09:00:37] "GET /productpage HTTP/1.1" 200 -

istio 기능 - Fault Injection

 

# Fault Injection

 

  • VS를 통해 fault injection 주입
  • fixed Delay 에 대한 Flag는 DC 코드임.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
# virtualservices 적용
kubectl apply -f virtual-service-ratings-test-delay.yaml

# 로그 확인 : product 입장에서 접속 사용자(clinet) 연결을 끊어버림 0 DC downstream_remote_disconnect
kubetail -l app=productpage -f
[productpage-v1-6b746f74dc-7ptpj istio-proxy] [2022-02-13T09:23:01.300Z] "POST /login HTTP/1.1" 302 - via_upstream - "-" 29 285 2 2 "192.168.10.1" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "e6a380e6-7de8-9555-9cbb-d13b70bf6e55" "192.168.10.101:31198" "172.16.158.5:9080" inbound|9080|| 127.0.0.6:56481 172.16.158.5:9080 192.168.10.1:0 outbound_.9080_._.productpage.default.svc.cluster.local default
[productpage-v1-6b746f74dc-7ptpj istio-proxy] [2022-02-13T09:23:01.311Z] "GET /details/0 HTTP/1.1" 200 - via_upstream - "-" 0 178 2 1 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "df1ff5a9-009f-9008-a67e-be495f109dbb" "details:9080" "172.16.158.3:9080" outbound|9080||details.default.svc.cluster.local 172.16.158.5:55976 10.109.236.60:9080 172.16.158.5:45710 - default
[productpage-v1-6b746f74dc-7ptpj productpage] send: b'GET /reviews/0 HTTP/1.1\r\nHost: reviews:9080\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nX-B3-TraceId: bf5f7702da5020ac4d0295dad1fc186d\r\nX-B3-SpanId: 78e269a1d2ed831e\r\nX-B3-ParentSpanId: 4d0295dad1fc186d\r\nX-B3-Sampled: 1\r\nend-user: jason\r\nx-request-id: df1ff5a9-009f-9008-a67e-be495f109dbb\r\n\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): reviews:9080
[productpage-v1-6b746f74dc-7ptpj istio-proxy] [2022-02-13T09:23:01.316Z] "GET /reviews/0 HTTP/1.1" 0 DC downstream_remote_disconnect - "-" 0 0 3003 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "df1ff5a9-009f-9008-a67e-be495f109dbb" "reviews:9080" "172.16.184.1:9080" outbound|9080|v2|reviews.default.svc.cluster.local 172.16.158.5:51808 10.99.123.193:9080 172.16.158.5:57772 - -
[productpage-v1-6b746f74dc-7ptpj productpage] send: b'GET /reviews/0 HTTP/1.1\r\nHost: reviews:9080\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nX-B3-TraceId: bf5f7702da5020ac4d0295dad1fc186d\r\nX-B3-SpanId: 78e269a1d2ed831e\r\nX-B3-ParentSpanId: 4d0295dad1fc186d\r\nX-B3-Sampled: 1\r\nend-user: jason\r\nx-request-id: df1ff5a9-009f-9008-a67e-be495f109dbb\r\n\r\n'
[productpage-v1-6b746f74dc-7ptpj productpage] INFO:werkzeug:127.0.0.6 - - [13/Feb/2022 09:23:07] "GET /productpage HTTP/1.1" 200 -
[productpage-v1-6b746f74dc-7ptpj istio-proxy] [2022-02-13T09:23:04.335Z] "GET /reviews/0 HTTP/1.1" 0 DC downstream_remote_disconnect - "-" 0 0 3003 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "df1ff5a9-009f-9008-a67e-be495f109dbb" "reviews:9080" "172.16.184.1:9080" outbound|9080|v2|reviews.default.svc.cluster.local 172.16.158.5:37756 10.99.123.193:9080 172.16.158.5:57796 - -
[productpage-v1-6b746f74dc-7ptpj istio-proxy] [2022-02-13T09:23:01.307Z] "GET /productpage HTTP/1.1" 200 - via_upstream - "-" 0 3992 6033 6032 "192.168.10.1" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "df1ff5a9-009f-9008-a67e-be495f109dbb" "192.168.10.101:31198" "172.16.158.5:9080" inbound|9080|| 127.0.0.6:37143 172.16.158.5:9080 192.168.10.1:0 outbound_.9080_._.productpage.default.svc.cluster.local default

0 DC downstream_remote_disconnect
6초간 타임아웃 확인!
Flags- DC !!
DC = Downstream connection termination

istio 기능 - Fault Injection

  • 500에러 주입 
  • Flag - FI 코드 발생 
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 100.0
        httpStatus: 500
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
        
        
        
# virtualservices 적용
kubectl apply -f virtual-service-ratings-test-abort.yaml

# 로그 확인
kubetail -l version=v2 -f
[reviews-v2-7bf8c9648f-tn7p9 reviews] Error: unable to contact http://ratings:9080/ratings got status of 500
[reviews-v2-7bf8c9648f-tn7p9 istio-proxy] [2022-02-13T10:03:27.112Z] "GET /ratings/0 HTTP/1.1" 500 FI fault_filter_abort - "-" 0 18 0 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "cb6d8737-9e44-9a16-900c-f8113e135ec9" "ratings:9080" "-" outbound|9080|v1|ratings.default.svc.cluster.local - 10.102.55.86:9080 172.16.184.1:48312 - -
[reviews-v2-7bf8c9648f-tn7p9 istio-proxy] [2022-02-13T10:03:27.105Z] "GET /reviews/0 HTTP/1.1" 200 - via_upstream - "-" 0 425 17 16 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36" "cb6d8737-9e44-9a16-900c-f8113e135ec9" "reviews:9080" "172.16.184.1:9080" inbound|9080|| 127.0.0.6:40455 172.16.184.1:9080 172.16.158.5:41114 outbound_.9080_.v2_.reviews.default.svc.cluster.local default