ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Istio Ingress gateway 정리(Weighted routing, Canary)
    K8S 2021. 6. 22. 17:28

    k8s의 Ingress는 클러스터 외부에서 접근하고 트래픽을 원하는 서비스로 보낼 수 있는 오브젝트다. 

    그리고 이스티오 서비스 매쉬에서도 ingress gateway라는 모델을 제공하는데 어떤 차이가 있어서 새로운 모델을 제공한걸까?

     

    다음 상황을 통해 이해해보도록 하자. 다음 yaml을 apply 한다. 

     

    < original webapp deployment, experimental webapp deployment, webapp service>

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: api-gateway
    spec:
      selector:
        matchLabels:
          app: api-gateway
      replicas: 1
      template: # template for the pods
        metadata:
          labels:
            app: api-gateway
        spec:
          containers:
          - name: api-gateway
            image: richardchesterwood/istio-fleetman-api-gateway:6
            env:
            - name: SPRING_PROFILES_ACTIVE
              value: production-microservice
            command: ["java","-Xmx50m","-jar","webapp.jar"]
            imagePullPolicy: Always
            
    ---
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: webapp-experimental
    spec:
      selector:
        matchLabels:
          app: webapp
      replicas: 1
      template: # template for the pods
        metadata:
          labels:
            app: webapp
            version: experimental
        spec:
          containers:
          - name: webapp
            image: richardchesterwood/istio-fleetman-webapp-angular:6-experimental
            env:
            - name: SPRING_PROFILES_ACTIVE
              value: production-microservice
            imagePullPolicy: Always
            
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: fleetman-webapp
    spec:
      # This defines which pods are going to be represented by this Service
      # The service becomes a network endpoint for either other services
      # or maybe external users to connect to (eg browser)
      selector:
        app: webapp
      ports:
        - name: http
          port: 80
          nodePort: 30080
      type: LoadBalancer

     

    위 코드를  apply 해주면 다음과 같은 구조의 그래프를 키알리에서 확인할 수 있다. 

     

    생성된 loadbalancer를 이용하여 외부에서 접근이 가능해보면 라운드로빈 방식으로 트래픽이 전달된다. 

    while (true) do curl -s http://[external ip]/ | grep title; sleep 0.1; done

     

    이후, webapp deployment의 weight를 original = 90, experimental = 10 으로 설정한 후 webapp 로드밸런서를 통해 트래픽을 보낸다. 

     

    < virtual service, destination rule >

    kind: VirtualService
    apiVersion: networking.istio.io/v1alpha3
    metadata:
      name: fleetman-webapp
      namespace: default
    spec:
      hosts:      # which incoming host are we applying the proxy rules to???
        - "*" # Copy the value in the gateway hosts - usually a Domain Name
      gateways:
        - ingress-gateway-configuration
      http:
      - route: 
        - destination:
            host: fleetman-webapp
            subset: experimental
          weight: 10
        - destination:
            host: fleetman-webapp
            subset: original
          weight: 90
          
    ---
    
    kind: DestinationRule
    apiVersion: networking.istio.io/v1alpha3
    metadata:
      name: fleetman-webapp
      namespace: default
    spec:
      host: fleetman-webapp
      subsets:
        - labels:
            version: original
          name: original
        - labels:
            version: experimental
          name: experimental
    

     

     

    다음은 apply 해준 키알리 그래프 

     

     

     

    apply 해준 후, 로드밸런서로 트래픽을 보내면, 9대 1의 비율로 트래픽이 전달되지 않고

    라운드 로빈 쯔음으로 동작한다. 

     

    그 이유는 다음과 같은 원인 때문이다. 다음 두 그림을 비교해보자. 

     

    내가 보낸 트래픽이 프록시를 통해서 타겟 컨테이너로 전달된 게 아니라 로드밸런서를 통해 바로 pod로 전달되었기 때문에 weight가 적용되지 않은 것이다. 

     

    그래서 이때 필요한 게 Ingress gateway(Edge proxy)다. 

     

     

    Ingress Gateway pod의 proxy를 통해 트래픽을 전달해야 한다

     

     

    Ingress gateway 적용하기

    Istio를 제일 처음으로 설치하면, istio-system namespace에 ingressgateway를 위한 pod와 service가 생성된다. 

    external ip로 ingress gateway 포드에 접속해보면 기본적으로 모든 트래픽이 차단되기 때문에 404에러를 볼 수 있다. 

     

     

    그리고 이제부터 게이트웨이를 이용하기 위해 Ingress gateway yaml을 작성한다. 

     

    < Gateway, virtual service, destination rule >

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: ingress-gateway-configuration
    spec:
      selector:
        istio: ingressgateway # use Istio default gateway implementation
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"   # Domain name of the external website
        
    ---
    
    kind: VirtualService
    apiVersion: networking.istio.io/v1alpha3
    metadata:
      name: fleetman-webapp
      namespace: default
    spec:
      hosts:      # which incoming host are we applying the proxy rules to???
        - "*" # Copy the value in the gateway hosts - usually a Domain Name
      gateways:
        - ingress-gateway-configuration
      http:
      - route: 
        - destination:
            host: fleetman-webapp
            subset: experimental
          weight: 10
        - destination:
            host: fleetman-webapp
            subset: original
          weight: 90
          
    ---
    
    kind: DestinationRule
    apiVersion: networking.istio.io/v1alpha3
    metadata:
      name: fleetman-webapp
      namespace: default
    spec:
      host: fleetman-webapp
      subsets:
        - labels:
            version: original
          name: original
        - labels:
            version: experimental
          name: experimental
    
    

     

     

    apply 후, 키알리를 통해 확인하면, 그래프 상에서 이스티오 Ingress gateway가 생성되었고 

     

    Ingress gateway로 트래픽을 보낸 결과 위에서 설정한 weight( 9 대 1의 비율)대로 흐르는 것을 알 수 있다.

     

    반응형

    댓글

Designed by Tistory.