【Istio】Traffic Managementまとめ

# Gateway / Virtual Service / Destination Rule

 - [Istio Reference](https://istio.io/latest/docs/reference/config/networking/)

### Gateway

```gateway.yml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway　 # default istio gateway proxy
  servers:
  - port:  # L7設定
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - uk.bookinfo.com  # DNSホスト
```

### Virtual Service

```virtualservice.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo-rule
  namespace: default
spec:
  hosts:
  - uk.bookinfo.com  # Routingルールの適用先
  gateways:
  - default/my-gateway  # 上のgateway.ymlで作成するgateway
  http:
  - match:
    - uri:
        prefix: /reviews/
    route:
    - destination:
        port:
          number: 3000  # serviceポート
        host: reviews.prod.svc.cluster.local
```

### 確認コマンド

```
$ kubectl get virtualservice,gateway
```

### Destination Rule

```destinationrule.yml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: bookinfo-ratings
spec:
  host: reviews.prod.svc.cluster.local  # k8sのService名（virtualservice.ymlと同じ）
  trafficPolicy:
    loadBalancer:  # round robin / random / least connectionの3択
      simple: LEAST_CONN
  subsets:
  - name: v1
    labels:
      version: v1 # podにつけたlabel（負荷分散用）
  - name: v2
    labels:
      version: v2   # podにつけたlabel（負荷分散用）
```

### 確認コマンド

```
$ kubectl get dr
```

#### VirtualService Canary設定

```virtualservice_canary.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
  - mesh  # Gatewayに限らず、それぞれのEnvoy Proxyにもルールを適用する
  http:
  - route:
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v1 # podにつけたlabel（負荷分散用）
      weight: 25
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v2　
      weight: 75
```

### 確認コマンド

```
$ kubectl get vs
```

### ユーザーリクエストのルーティング指定

```virtualservice_indentity.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
  - mesh  # Gatewayに限らず、それぞれのEnvoy Proxyにもルールを適用する
  http:
  - match:  # 下記ユーザーからのリクエストに対してルーティングを行う
    - headers:
       end-user:
         exact: log-in-as-this-user  # ユーザー
  - route:
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v1 # podにつけたlabel（負荷分散用）
      weight: 25
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v2　
      weight: 75
```

### fault injection（Delay）

```virtualservice_faultinjection_delay.yml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers: 
        end-user:
          exact: tester  # fault_injection用のテストユーザー
  - fault:
      delay:  # Delayを追加する
        fixedDelay: 10s  # Delay：10秒
        percentage:
          value: 100  # リクエストのうち、何%に対してDelayを実行するか
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
```


### fault injection（HTTPリターンコード）

```virtualservice_faultinjection_http.yml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers: 
        end-user:
          exact: tester  # fault_injection用のテストユーザー
  - fault: 
      abort:  # HTTPのリターンコード
        httpStatus: 400  # リターンコード
        percentage:
          value: 100.0  # リクエストのうち、何%に対してDelayを実行するか
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
```

### タイムアウト設定

```virtualservice_timeout.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
  - mesh  # Gatewayに限らず、それぞれのEnvoy Proxyにもルールを適用する
  http:
  - timeout: 1s  # 1秒以内にreturnしない場合、HTTPエラーコードが表示される
  - route:
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v1 # podにつけたlabel（負荷分散用）
      weight: 25
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v2　
      weight: 75
```


### fault injection（Retry）

```virtualservice_faultinjection_retry.yml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - retries:
      attempts: 3  # 何回リトライするか
      perTryTimeout: 2s
      retryOn: gateway-error,connect-failure,refused-stream  # リトライの発動条件
  - match:
    - headers: 
        end-user:
          exact: tester  # fault_injection用のテストユーザー
  - fault:
      delay:  # Delayを追加する
        fixedDelay: 10s  # Delay：10秒
        percentage:
          value: 100  # リクエストのうち、何%に対してDelayを実行するか
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
```

### リクエストのミラーリング設定

```virtualservice_mirror.yml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
  - mesh  # Gatewayに限らず、それぞれのEnvoy Proxyにもルールを適用する
  http:
  - mirror:  # v3からv1へリクエストを100%ミラーリングする
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v1 # podにつけたlabel（負荷分散用）
    mirror_percent: 100.0
    route:
    - destination:
        host: reviews.prod.svc.cluster.local # k8sのService名（virtualservice.ymlと同じ）
        subset: v3　
      weight: 100.0
```

### サーキットブレーカ有効化

```destination_rules_circuit_breaker.yml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-cb-policy
spec:
  host: reviews.prod.svc.cluster.local
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100  # hostへのHTTP/TCPの最大接続数
      http:
        http2MaxRequests: 1000  # バックエンドへの最大接続数
        maxRequestsPerConnection: 10  # バックエンド接続毎のリクエスト最大数
    outlierDetection:
      consecutive5xxErrors: 7  # 7回以上エラーの場合
      interval: 5m  # 5分毎にスキャン
      baseEjectionTime: 15m  # 15分間退去
```

# Istioをk8sにデプロイ

### profileリストを確認
 
 ```
$ istioctl profile list
$ istioctl profile dump demo > profile_demo_config.yaml  // demoプロファイルをアウトプット
```

### Istio込みのk8s Manifestファイルを生成
 
```
 $ istioctl manifest generate \
  --set profile=demo \
  --set values.gateways.istio-ingressgateway.sds.enabled=true \
  > generated-manifest-demo.yaml
 ```

### k8s Manifestファイルをapply

```
$ istioctl install --set profile=demo
```

### apply結果確認

```
$ kubectl get pod,svc -n istio-system
$ kubectl get pod -n istio-system -l istio=ingressgateway
```

### Istio Sidecar Injection有効化

```
$ kubectl describe ns default
$ kubectl label namespace default istio-injection=enabled
```

# kiali Dashboard

### kialiインストール
```
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.10/samples/addons/kiali.yaml
```

### 確認
```
$ kubectl -n istio-system get svc kiali
```

### kiali 起動
```
$ istioctl dashboard kiali
```

# 参考文献
 - [米シリコンバレーDevOps監修！Istio Service Mesh ハンズオン+Kubernetes AWS EKS](https://www.udemy.com/course/istio-service-mesh-kubernetes-aws-eks-2020-handson/)
 - [Istio Documentation](https://istio.io/latest/docs/)