EKSにistioをインストールして使う


# istio
- サービスメッシュを提供
- ネットワーク機能を拡張
- 各PodのネットワークI/OがサイドカーコンテナのEnvoy Proxyを経由するようになり、経由したときの情報をistioマネージャ的なものに逐一送る


https://www.eksworkshop.com/images/istio/istio_architecture.svg

# 手順
## クラスタにインストール

```bash
yes | istioctl install --set profile=demo
```

確認

```bash
kubectl -n istio-system get svc
```

TYPE`LoadBalancer`として作成されて、外部公開される。
EKSなので、ELBが自動的に作成される。
Kindなどの、ローカルでインストールするときには、NodePortに変更するなどする必要がある。

```
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)                                                                      AGE
istio-egressgateway    ClusterIP      172.20.5.101     <none>                                                                         80/TCP,443/TCP                                                               58s
istio-ingressgateway   LoadBalancer   172.20.139.154   a6421f0fea96b4a31aeead46f207f8a2-1072490675.ap-northeast-1.elb.amazonaws.com   15021:32561/TCP,80:30329/TCP,443:30167/TCP,31400:31622/TCP,15443:32086/TCP   58s
istiod                 ClusterIP      172.20.125.6     <none>                                                                         15010/TCP,15012/TCP,443/TCP,15014/TCP                                        74s
```

## サンプルアプリのデプロイ

Namespaceを作成

```bash
kubectl create namespace bookinfo
```

Namespaceに対して、`istio-injection=enabled`のLableを付与することで、各Podに自動的にEnvoyがサイドカーコンテナとして起動するようになる

```bash
kubectl label namespace bookinfo istio-injection=enabled
```

ラベルの確認

```bash
kubectl get ns bookinfo --show-labels
```

```
NAME       STATUS   AGE    LABELS
bookinfo   Active   113m   istio-injection=enabled,kubernetes.io/metadata.name=bookinfo
```

アプリデプロイ

```bash
kubectl -n bookinfo apply -f samples/bookinfo/platform/kube/bookinfo.yaml
```

確認

```bash
kubectl -n bookinfo get pod,svc
```

どのPodもREADYが2/2となっているのは、サイドカーコンテナが注入されているため

```
NAME                                  READY   STATUS    RESTARTS   AGE
pod/details-v1-7d88846999-cdm8p       2/2     Running   0          100s
pod/productpage-v1-7795568889-bxzb5   2/2     Running   0          100s
pod/ratings-v1-754f9c4975-vqlgk       2/2     Running   0          100s
pod/reviews-v1-55b668fc65-5qvkd       2/2     Running   0          100s
pod/reviews-v2-858f99c99-9kpf5        2/2     Running   0          100s
pod/reviews-v3-7886dd86b9-x9kp9       2/2     Running   0          100s

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/details       ClusterIP   172.20.208.7     <none>        9080/TCP   100s
service/productpage   ClusterIP   172.20.46.224    <none>        9080/TCP   100s
service/ratings       ClusterIP   172.20.66.215    <none>        9080/TCP   100s
service/reviews       ClusterIP   172.20.255.157   <none>        9080/TCP   100s
```

## Gatewayを作る

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
```

```
export GATEWAY_URL=(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo "http://$GATEWAY_URL/productpage"
```

表示されたURLへアクセスするとサンプルアプリケーションのUIが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/85346b4a-38dc-d058-9b8d-6c48c0cabb7c.png)

ここまでで一旦インストールまでは完了

## ルールを作る

### Default Destination Rule
ベースとなるルール

```
kubectl -n bookinfo apply -f samples/bookinfo/networking/destination-rule-all.yaml
```

```
kubectl -n bookinfo get destinationrules -o yaml
```


### 特定バージョンへのみにトラフィックを流すためのルールを作成

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
```

```bash
kubectl -n bookinfo get virtualservice ratings -o yaml
```


v1だけにトラフィックが流れる

```
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"ratings","namespace":"bookinfo"},"spec":{"hosts":["ratings"],"http":[{"route":[{"destination":{"host":"ratings","subset":"v1"}}]}]}}
  creationTimestamp: "2022-07-02T15:45:04Z"
  generation: 3
  name: ratings
  namespace: bookinfo
  resourceVersion: "138892057"
  uid: c4b2d4a7-ee76-430b-8087-8976533a38cb
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1

```

何度更新しても、reviews-v1のPodのみにトラフィックが流れていることがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/4f02d307-94f9-1c1f-50b8-d1cb114402ad.png)

### 特定ユーザーのトラフィックを制御する

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml 
```

```
kubectl -n bookinfo get virtualservices reviews -o yaml
```

ユーザー`jason`なら、v2からのみリクエストが返るというルール

```
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"reviews","namespace":"bookinfo"},"spec":{"hosts":["reviews"],"http":[{"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"reviews","subset":"v2"}}]},{"route":[{"destination":{"host":"reviews","subset":"v1"}}]}]}}
  creationTimestamp: "2022-07-02T17:28:07Z"
  generation: 2
  name: reviews
  namespace: bookinfo
  resourceVersion: "138926747"
  uid: ac05dc6c-ed86-46c1-b7d5-a5f68a4e3efe
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
```

jasonでログインするとv2が返る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/a3b7f126-62e4-ae4c-5488-0ee220b692f8.png)

yutaでログインするとv1が返る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/989e4f13-baf8-13d0-67e1-8de6c1a2203d.png)

### HTTPリクエストを遅延させる

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
```

```
kubectl -n bookinfo get virtualservice ratings -o yaml
```

`jason`ユーザーでアクセスしたときに、7秒遅延させる

```
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"ratings","namespace":"bookinfo"},"spec":{"hosts":["ratings"],"http":[{"fault":{"delay":{"fixedDelay":"7s","percentage":{"value":100}}},"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"ratings","subset":"v1"}}]},{"route":[{"destination":{"host":"ratings","subset":"v1"}}]}]}}
  creationTimestamp: "2022-07-02T17:28:07Z"
  generation: 2
  name: ratings
  namespace: bookinfo
  resourceVersion: "138936032"
  uid: 9e4a2e4e-f107-4379-9b4a-5a309875c1f0
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        fixedDelay: 7s
        percentage:
          value: 100
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

```

jasonでログインすると、「Ratings service is currently unavailable」と出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/f33fc9c1-e4ba-7e0b-961c-3152d122194d.png)

リクエストが7秒遅延することで、アプリ側でタイムアウト的な扱いとなりエラーになっている模様。


## jasonユーザーの通信にHTTPがabortするようにする

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
```

```bash
kubectl -n bookinfo get virtualservice ratings -o yaml
```

```bash
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"ratings","namespace":"bookinfo"},"spec":{"hosts":["ratings"],"http":[{"fault":{"abort":{"httpStatus":500,"percentage":{"value":100}}},"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"ratings","subset":"v1"}}]},{"route":[{"destination":{"host":"ratings","subset":"v1"}}]}]}}
  creationTimestamp: "2022-07-02T15:45:04Z"
  generation: 2
  name: ratings
  namespace: bookinfo
  resourceVersion: "138889423"
  uid: c4b2d4a7-ee76-430b-8087-8976533a38cb
spec:
  hosts:
  - ratings
  http:
  - fault:
      abort:
        httpStatus: 500
        percentage:
          value: 100
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
```

jasonでログインすると、「*Ratings service is currently unavailable*」と出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/cbc90a72-93c7-12a1-c9c5-ab78af25f404.png)


jason以外のユーザーでログインすると、エラーメッセージは出ない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/c5d7c798-d9ea-2727-1ac0-a8deeffa7d80.png)


### トラフィックシャットダウン

あるバージョンのマイクロサービスから別バージョンのマイクロサービスに段階的に移行する場合に使う。

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
```

```bash
kubectl -n bookinfo apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
```

```bash
kubectl -n bookinfo get virtualservice reviews -o yaml
```

```bash
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"reviews","namespace":"bookinfo"},"spec":{"hosts":["reviews"],"http":[{"route":[{"destination":{"host":"reviews","subset":"v1"},"weight":50},{"destination":{"host":"reviews","subset":"v3"},"weight":50}]}]}}
  creationTimestamp: "2022-07-02T15:57:55Z"
  generation: 2
  name: reviews
  namespace: bookinfo
  resourceVersion: "138892285"
  uid: 18633276-3ff9-4059-9426-a72fbdd37a04
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50
```

## モニタリング

[https://istio.io/latest/docs/ops/integrations/prometheus/](https://istio.io/latest/docs/ops/integrations/prometheus/)

### Prometheus & grafana インストール

```bash

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/grafana.yaml
```

```bash
kubectl -n istio-system get deploy grafana prometheus
```

```bash
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
grafana      1/1     1            1           40s
prometheus   1/1     1            1           79s
```

### Jagerインストール

ネットワークモニタリングや分析のために必要なデータを収集するもの

```bash
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/jaeger.yaml
```

### Kialiインストール

サービスメッシュを可視化するダッシュボード

```bash
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/kiali.yaml
```

```bash
kubectl -n istio-system get deploy jaeger kiali
```

```bash
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
jaeger   1/1     1            1           6m44s
kiali    1/1     1            1           5m30s
```

## トラフィックを生成

```bash
export GATEWAY_URL=(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

```

別ターミナルで実行

```bash
watch --interval 1 curl -s -I -XGET "http://$GATEWAY_URL/productpage"
```

別ターミナルで実行

```bash
kubectl -n istio-system port-forward \
(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 8080:20001
```

localhost:8080のダッシュボードへアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/379fc948-a5f6-753d-cb6e-8479c76692f8.png)


別ターミナルで実行

```bash
kubectl -n istio-system port-forward (kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metad
ata.name}') 8080:3000

```

localhost:8080のダッシュボードへアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/45f29a4e-0ae8-1588-1d30-c2793413fb14.png)






# 参考
https://www.eksworkshop.com/advanced/310_servicemesh_with_istio/install/