eksworkshop.comのIstioハンズオンをやってみる
eksworkshop.comのIstioハンズオンをやってみたメモ。
環境
コンポーネント | バージョン | 備考 |
---|---|---|
eksctl | 0.14.0 | |
Kubernetes バージョン | 1.14 | |
プラットフォームのバージョン | eks.9 | |
istioctl | 1.4.5 |
クラスターを作成する。
eksctl create cluster --name=istio --nodes=3 --managed --ssh-access --ssh-public-key=sotosugi
istioctl
はHomebrewで入っていたものを使う。
$ istioctl version --remote=false 1.4.5
サンプルアプリケーションのマニフェストが必要なので、作業ディレクトリにIstioをダウンロードする。
ISTIO_VERSION="1.4.5" curl -L https://istio.io/downloadIstio | sh -
Istioのインストール
Istioのインストール方法は以下3つの方法がある。
istioctl
が現在の推奨。
istioctl
ではプロファイルを指定することができるが、使用できるプロファイルはprofile list
で確認できる。
$ istioctl profile list Istio configuration profiles: default demo minimal remote sds
profile dump
でプロファイルの詳細が確認できる。
$ istioctl profile dump demo autoInjection: components: injector: enabled: true k8s: replicaCount: 1 strategy: rollingUpdate: maxSurge: 100% maxUnavailable: 25% enabled: true cni: enabled: false configManagement: components: galley: enabled: true (省略)
インストールには、manifest apply
で直接適用するか、manifest generate
で一旦マニフェストを生成してから適用する。
細かく設定をカスタマイズしたい場合は、以下のようなYAMLを作ってdefault
プロファイルを上書きできる。
apiVersion: install.istio.io/v1alpha2 kind: IstioControlPlane spec: telemetry: enabled: false
istioctl manifest apply -f telemetry_off.yaml
なお、Operatorの場合にはこのkind: IstioControlPlane
のリソースを作成すればOperatorがIstioをインストールしてくれるようだ。
以下のコマンドでdemo
プロファイルでIstioをインストールする。
istioctl manifest apply --set profile=demo
$ istioctl manifest apply --set profile=demo - Applying manifest for component Base... ✔ Finished applying manifest for component Base. - Applying manifest for component Tracing... - Applying manifest for component Citadel... - Applying manifest for component IngressGateway... - Applying manifest for component Galley... - Applying manifest for component Kiali... - Applying manifest for component EgressGateway... - Applying manifest for component Prometheus... - Applying manifest for component Policy... - Applying manifest for component Pilot... - Applying manifest for component Injector... - Applying manifest for component Telemetry... - Applying manifest for component Grafana... ✔ Finished applying manifest for component Citadel. ✔ Finished applying manifest for component Prometheus. ✔ Finished applying manifest for component Kiali. ✔ Finished applying manifest for component Tracing. ✔ Finished applying manifest for component Galley. ✔ Finished applying manifest for component Injector. ✔ Finished applying manifest for component IngressGateway. ✔ Finished applying manifest for component Pilot. ✔ Finished applying manifest for component Policy. ✔ Finished applying manifest for component EgressGateway. ✔ Finished applying manifest for component Grafana. ✔ Finished applying manifest for component Telemetry. ✔ Installation complete
Serviceを確認する。
$ kubectl -n istio-system get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana ClusterIP 10.100.88.107 <none> 3000/TCP 60s istio-citadel ClusterIP 10.100.132.156 <none> 8060/TCP,15014/TCP 63s istio-egressgateway ClusterIP 10.100.64.33 <none> 80/TCP,443/TCP,15443/TCP 61s istio-galley ClusterIP 10.100.88.94 <none> 443/TCP,15014/TCP,9901/TCP,15019/TCP 62s istio-ingressgateway LoadBalancer 10.100.198.18 a2fd22ea85d6511ea915f0ec6e811fa2-179736594.ap-northeast-1.elb.amazonaws.com 15020:32122/TCP,80:30530/TCP,443:31399/TCP,15029:31432/TCP,15030:30310/TCP,15031:30979/TCP,15032:32370/TCP,15443:30848/TCP 61s istio-pilot ClusterIP 10.100.126.231 <none> 15010/TCP,15011/TCP,8080/TCP,15014/TCP 61s istio-policy ClusterIP 10.100.72.152 <none> 9091/TCP,15004/TCP,15014/TCP 61s istio-sidecar-injector ClusterIP 10.100.124.141 <none> 443/TCP 62s istio-telemetry ClusterIP 10.100.110.67 <none> 9091/TCP,15004/TCP,15014/TCP,42422/TCP 59s jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 63s jaeger-collector ClusterIP 10.100.78.120 <none> 14267/TCP,14268/TCP,14250/TCP 63s jaeger-query ClusterIP 10.100.210.72 <none> 16686/TCP 63s kiali ClusterIP 10.100.151.38 <none> 20001/TCP 63s prometheus ClusterIP 10.100.188.165 <none> 9090/TCP 63s tracing ClusterIP 10.100.65.161 <none> 80/TCP 63s zipkin ClusterIP 10.100.86.195 <none> 9411/TCP
Type: LoadBalancer
のServiceがあり、これによってCLBが作られていることが確認できる。
aws elb describe-load-balancers
Podを確認する。
$ kubectl -n istio-system get pods NAME READY STATUS RESTARTS AGE grafana-5f798469fd-79ls6 1/1 Running 0 5m41s istio-citadel-58bb67f9b8-zvjqb 1/1 Running 0 5m43s istio-egressgateway-6fd57475b5-wm9rp 1/1 Running 0 5m43s istio-galley-7d4b9874c8-x9pk4 1/1 Running 0 5m42s istio-ingressgateway-7d65bf7fdf-bpvjv 1/1 Running 0 5m43s istio-pilot-65f8557545-5z5mm 1/1 Running 0 5m43s istio-policy-6c6449c56f-t8h8r 1/1 Running 2 5m43s istio-sidecar-injector-774969d686-w7z26 1/1 Running 0 5m42s istio-telemetry-585cc965f7-jnd7z 1/1 Running 2 5m42s istio-tracing-cd67ddf8-cfqwt 1/1 Running 0 5m43s kiali-7964898d8c-rxmdv 1/1 Running 0 5m42s prometheus-586d4445c7-2ltkq 1/1 Running 0 5m43s
サンプルアプリケーションのデプロイ
Namespacesを作成し、このNamespacesでAuto Injectionを有効にする。
kubectl create namespace bookinfo kubectl label namespace bookinfo istio-injection=enabled
ラベルを確認する。
$ kubectl get ns bookinfo --show-labels NAME STATUS AGE LABELS bookinfo Active 51s istio-injection=enabled
アプリケーションをデプロイする。
kubectl -n bookinfo apply \ -f istio-${ISTIO_VERSION}/samples/bookinfo/platform/kube/bookinfo.yaml
確認する。
$ kubectl -n bookinfo get pod,svc NAME READY STATUS RESTARTS AGE pod/details-v1-c5b5f496d-zq57c 2/2 Running 0 34s pod/productpage-v1-c7765c886-kbk4q 2/2 Running 0 33s pod/ratings-v1-f745cf57b-zvxmb 2/2 Running 0 33s pod/reviews-v1-75b979578c-4v756 2/2 Running 0 33s pod/reviews-v2-597bf96c8f-hcqp6 2/2 Running 0 33s pod/reviews-v3-54c6c64795-zbr7l 2/2 Running 0 33s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/details ClusterIP 10.100.75.161 <none> 9080/TCP 34s service/productpage ClusterIP 10.100.192.148 <none> 9080/TCP 33s service/ratings ClusterIP 10.100.148.131 <none> 9080/TCP 34s service/reviews ClusterIP 10.100.144.233 <none> 9080/TCP 33s
EnvoyがインジェクションされたPodの設定を見てみる。
$ kubectl get po -n bookinfo details-v1-c5b5f496d-zq57c -o yaml apiVersion: v1 kind: Pod metadata: annotations: kubernetes.io/psp: eks.privileged sidecar.istio.io/status: '{"version":"b5faac9e6b02231b7db3b29487392a395f1c85c746bf62dc8cb660444af6e0d9","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}' creationTimestamp: "2020-03-03T15:59:16Z" generateName: details-v1-c5b5f496d- labels: app: details pod-template-hash: c5b5f496d security.istio.io/tlsMode: istio version: v1 name: details-v1-c5b5f496d-zq57c namespace: bookinfo ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true controller: true kind: ReplicaSet name: details-v1-c5b5f496d uid: ef685e96-5d67-11ea-ac5d-062ae758ff04 resourceVersion: "4604" selfLink: /api/v1/namespaces/bookinfo/pods/details-v1-c5b5f496d-zq57c uid: ef6e6577-5d67-11ea-ac5d-062ae758ff04 spec: containers: - image: docker.io/istio/examples-bookinfo-details-v1:1.15.0 imagePullPolicy: IfNotPresent name: details ports: - containerPort: 9080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: bookinfo-details-token-jx8zv readOnly: true - args: - proxy - sidecar - --domain - $(POD_NAMESPACE).svc.cluster.local - --configPath - /etc/istio/proxy - --binaryPath - /usr/local/bin/envoy - --serviceCluster - details.$(POD_NAMESPACE) - --drainDuration - 45s - --parentShutdownDuration - 1m0s - --discoveryAddress - istio-pilot.istio-system:15010 - --zipkinAddress - zipkin.istio-system:9411 - --proxyLogLevel=warning - --proxyComponentLogLevel=misc:error - --connectTimeout - 10s - --proxyAdminPort - "15000" - --concurrency - "2" - --controlPlaneAuthPolicy - NONE - --dnsRefreshRate - 300s - --statusPort - "15020" - --applicationPorts - "9080" - --trust-domain=cluster.local env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: INSTANCE_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.podIP - name: SERVICE_ACCOUNT valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.serviceAccountName - name: HOST_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.hostIP - name: ISTIO_META_POD_PORTS value: |- [ {"containerPort":9080,"protocol":"TCP"} ] - name: ISTIO_META_CLUSTER_ID value: Kubernetes - name: ISTIO_META_POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: ISTIO_META_CONFIG_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: SDS_ENABLED value: "false" - name: ISTIO_META_INTERCEPTION_MODE value: REDIRECT - name: ISTIO_META_INCLUDE_INBOUND_PORTS value: "9080" - name: ISTIO_METAJSON_ANNOTATIONS value: | {"kubernetes.io/psp":"eks.privileged"} - name: ISTIO_METAJSON_LABELS value: | {"app":"details","pod-template-hash":"c5b5f496d","version":"v1"} - name: ISTIO_META_WORKLOAD_NAME value: details-v1 - name: ISTIO_META_OWNER value: kubernetes://apis/apps/v1/namespaces/bookinfo/deployments/details-v1 - name: ISTIO_META_MESH_ID value: cluster.local image: docker.io/istio/proxyv2:1.4.5 imagePullPolicy: IfNotPresent name: istio-proxy ports: - containerPort: 15090 name: http-envoy-prom protocol: TCP readinessProbe: failureThreshold: 30 httpGet: path: /healthz/ready port: 15020 scheme: HTTP initialDelaySeconds: 1 periodSeconds: 2 successThreshold: 1 timeoutSeconds: 1 resources: limits: cpu: "2" memory: 1Gi requests: cpu: 10m memory: 40Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL privileged: false readOnlyRootFilesystem: true runAsGroup: 1337 runAsNonRoot: true runAsUser: 1337 terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /etc/istio/proxy name: istio-envoy - mountPath: /etc/certs/ name: istio-certs readOnly: true - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: bookinfo-details-token-jx8zv readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true initContainers: - command: - istio-iptables - -p - "15001" - -z - "15006" - -u - "1337" - -m - REDIRECT - -i - '*' - -x - "" - -b - '*' - -d - "15020" image: docker.io/istio/proxyv2:1.4.5 imagePullPolicy: IfNotPresent name: istio-init resources: limits: cpu: 100m memory: 50Mi requests: cpu: 10m memory: 10Mi securityContext: allowPrivilegeEscalation: false capabilities: add: - NET_ADMIN - NET_RAW drop: - ALL privileged: false readOnlyRootFilesystem: false runAsGroup: 0 runAsNonRoot: false runAsUser: 0 terminationMessagePath: /dev/termination-log terminationMessagePolicy: File nodeName: ip-192-168-65-11.ap-northeast-1.compute.internal priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: bookinfo-details serviceAccountName: bookinfo-details terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: bookinfo-details-token-jx8zv secret: defaultMode: 420 secretName: bookinfo-details-token-jx8zv - emptyDir: medium: Memory name: istio-envoy - name: istio-certs secret: defaultMode: 420 optional: true secretName: istio.bookinfo-details status: (省略)
Init ContainerがNET_ADMIN
とNET_RAW
のCapabilityを持っていて、iptablesを操作していそうなことがわかる。
UbuntuのPodに特権を付けて起動してみる。
cat <<EOF >ubuntu-pod.yaml apiVersion: v1 kind: Pod metadata: labels: run: ubuntu name: ubuntu spec: containers: - name: ubuntu image: ubuntu command: - tail - -f - /dev/null securityContext: privileged: true EOF kubectl apply -f ubuntu-pod.yaml -n bookinfo
このPodに入り、iptablesをインストールしてiptablesのルールを確認する。
kubectl exec -it -n bookinfo ubuntu bash apt-get update apt-get install -y iptables iptables -t nat -n -L -v
root@ubuntu:/# iptables -t nat -n -L -v Chain PREROUTING (policy ACCEPT 333 packets, 19980 bytes) pkts bytes target prot opt in out source destination 334 20040 ISTIO_INBOUND tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT 334 packets, 20040 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 40 packets, 3126 bytes) pkts bytes target prot opt in out source destination 15 900 ISTIO_OUTPUT tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain POSTROUTING (policy ACCEPT 43 packets, 3306 bytes) pkts bytes target prot opt in out source destination Chain ISTIO_INBOUND (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 333 19980 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:15020 1 60 ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 Chain ISTIO_IN_REDIRECT (2 references) pkts bytes target prot opt in out source destination 1 60 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15006 Chain ISTIO_OUTPUT (1 references) pkts bytes target prot opt in out source destination 1 60 RETURN all -- * lo 127.0.0.6 0.0.0.0/0 0 0 ISTIO_IN_REDIRECT all -- * lo 0.0.0.0/0 !127.0.0.1 11 660 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 1337 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner GID match 1337 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.1 3 180 ISTIO_REDIRECT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain ISTIO_REDIRECT (1 references) pkts bytes target prot opt in out source destination 3 180 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15001
utuntuのPodを削除する。
kubectl delete pod ubuntu -n bookinfo
続いてVirtualServiceとGatewayをデプロイする。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/bookinfo-gateway.yaml
(上記YAMLの内容)
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080
確認する。
$ kubectl get virtualservice,gateway -n bookinfo NAME GATEWAYS HOSTS AGE virtualservice.networking.istio.io/bookinfo [bookinfo-gateway] [*] 44s NAME AGE gateway.networking.istio.io/bookinfo-gateway 44s
istio-ingressgateway
というServiceのExternal IPを確認する。
GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') echo "http://${GATEWAY_URL}/productpage"
URLにアクセスする。
この状態では、reviews
というServiceはv1、v2、v3のPodにランダムに割り振っている。
セレクターがapp: reviews
となっていて、v1、v2、v3のPodがこのラベルを持っているため。
つまりVirtualServiceやDestinationRuleがない状態では、普通にService経由で通信されている。
$ kubectl get po --show-labels -n bookinfo NAME READY STATUS RESTARTS AGE LABELS details-v1-c5b5f496d-zq57c 2/2 Running 0 57m app=details,pod-template-hash=c5b5f496d,security.istio.io/tlsMode=istio,version=v1 productpage-v1-c7765c886-kbk4q 2/2 Running 0 57m app=productpage,pod-template-hash=c7765c886,security.istio.io/tlsMode=istio,version=v1 ratings-v1-f745cf57b-zvxmb 2/2 Running 0 57m app=ratings,pod-template-hash=f745cf57b,security.istio.io/tlsMode=istio,version=v1 reviews-v1-75b979578c-4v756 2/2 Running 0 57m app=reviews,pod-template-hash=75b979578c,security.istio.io/tlsMode=istio,version=v1 reviews-v2-597bf96c8f-hcqp6 2/2 Running 0 57m app=reviews,pod-template-hash=597bf96c8f,security.istio.io/tlsMode=istio,version=v2 reviews-v3-54c6c64795-zbr7l 2/2 Running 0 57m app=reviews,pod-template-hash=54c6c64795,security.istio.io/tlsMode=istio,version=v3
トラフィックマネジメント
サブセットの定義
DestinationRuleを定義する。DestinationRuleでは、各サービスのサブセットをラベルに基づいて定義している。
kubectl -n bookinfo apply \ -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/destination-rule-all.yaml
(上記YAMLの内容)
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: productpage spec: host: productpage subsets: - name: v1 labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: ratings spec: host: ratings subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v2-mysql labels: version: v2-mysql - name: v2-mysql-vm labels: version: v2-mysql-vm --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: details spec: host: details subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 ---
確認する。
$ kubectl get destinationrule -n bookinfo NAME HOST AGE details details 19s productpage productpage 19s ratings ratings 19s reviews reviews 19s
単一バージョンへのルーティング
続いてVirtualServieを作成する。VirtualServiceが各サブセットへの振り分けのルールを記述している。ここでは全てv1にルーティングするルールを適用する。 DestinationRuleがそのリソース名からすると振り分けのルールっぽいが、DestinationRuleはサブセットの定義で、VirtualServiveが振り分けのルールなので注意が必要。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/virtual-service-all-v1.yaml
(上記YAMLの内容)
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: productpage spec: hosts: - productpage http: - route: - destination: host: productpage subset: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - route: - destination: host: ratings subset: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: details spec: hosts: - details http: - route: - destination: host: details subset: v1 ---
確認する。
$ kubectl get virtualservice -n bookinfo NAME GATEWAYS HOSTS AGE bookinfo [bookinfo-gateway] [*] 27m details [details] 64s productpage [productpage] 64s ratings [ratings] 64s reviews [reviews] 64s
HTTPヘッダーに基づいたルーティング
ヘッダーにend-user: jason
が含まれる場合はreviews:v2
にルーティングするルールを適用する。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
(上記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
jasonでログインするとv2(黒い星)が、それ以外ではv1(星なし)が表示される。
遅延のインジェクション
jasonに対して7秒の遅延をインジェクションするルールを適用する。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
(上記YAMLの内容)
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
productpage
がreviews
を呼び出すときのタイムアウトは6秒なため、jasonでアクセスすると6秒待った後、reviews
の取得がエラーとなる。
失敗のインジェクション
jasonに対して直ちに500エラーを返すルールを適用する。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
(上記YAMLの内容)
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
jasonでアクセスするとreviews
の取得が直ちにエラーとなる。
トラフィックの重み付け
v1とv3で50%づつ振り分けるルールを適用する。
kubectl -n bookinfo \ apply -f istio-${ISTIO_VERSION}/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
(上記YAMLの内容)
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50
v1(星なし)とv3(赤い星)が半々で表示される。
モニタリングと可視化
新しくメトリクスを定義する。
kubectl apply -f istio-${ISTIO_VERSION}/samples/bookinfo/telemetry/metrics.yaml
(上記YAMLの内容)
# Configuration for metric instances apiVersion: config.istio.io/v1alpha2 kind: instance metadata: name: doublerequestcount namespace: istio-system spec: compiledTemplate: metric params: value: "2" # count each request twice dimensions: reporter: conditional((context.reporter.kind | "inbound") == "outbound", "client", "server") source: source.workload.name | "unknown" destination: destination.workload.name | "unknown" message: '"twice the fun!"' monitored_resource_type: '"UNSPECIFIED"' --- # Configuration for a Prometheus handler apiVersion: config.istio.io/v1alpha2 kind: handler metadata: name: doublehandler namespace: istio-system spec: compiledAdapter: prometheus params: metrics: - name: double_request_count # Prometheus metric name instance_name: doublerequestcount.instance.istio-system # Mixer instance name (fully-qualified) kind: COUNTER label_names: - reporter - source - destination - message --- # Rule to send metric instances to a Prometheus handler apiVersion: config.istio.io/v1alpha2 kind: rule metadata: name: doubleprom namespace: istio-system spec: actions: - handler: doublehandler instances: [ doublerequestcount ]
PrometheusとGrafanaが稼働していることを確認する。
kubectl -n istio-system get svc prometheus grafana
Prometheusにポートフォワードする。
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090
以下のURLにアクセスし、新しく定義したdouble_request_count
というメトリクスが取得できていることを確認する。
Grafanaにポートフォワードする。
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000
以下のURLにアクセスし、Istioのメトリクスがいろいろ表示されることを確認する。