Xubuntu上のminikubeでIstioのGetting Startedを試してみる

Xubuntu上のminikubeでIstioのGetting Startedを試してみる

minikubeが停止している場合は開始します。

1
minikube start --driver=docker

Istioをダウンロード

Istioをダウンロードしてコマンドにパスを通します。
ドキュメント:https://istio.io/latest/docs/setup/getting-started/

1
2
3
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.11.4
echo export PATH=$PWD/'bin:$PATH' >> ~/.zshrc

Istioをインストール

1
2
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled

サンプルアプリケーションをデプロイ

1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

デプロイされたサービスを確認します。

1
2
3
4
5
6
7
$ kubectl get services                       
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.103.121.59 <none> 9080/TCP 45s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 96m
productpage ClusterIP 10.102.77.95 <none> 9080/TCP 45s
ratings ClusterIP 10.102.127.232 <none> 9080/TCP 45s
reviews ClusterIP 10.97.231.104 <none> 9080/TCP 45s

デプロイされたポッドを確認します。

1
2
3
4
5
6
7
8
9
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-xznsc 2/2 Running 0 87s
productpage-v1-6b746f74dc-kprg5 2/2 Running 0 87s
ratings-v1-b6994bb9-psq5z 2/2 Running 0 87s
reviews-v1-545db77b95-pvd6q 2/2 Running 0 87s
reviews-v2-7bf8c9648f-brqqg 2/2 Running 0 87s
reviews-v3-84779c7bbc-5wfv5 2/2 Running 0 86s

デプロイされたアプリケーションはクラスタの外からアクセスできないためゲートウェイをデプロイします。

1
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

ここまでの設定を確認します。

1
2
$ istioctl analyze
✔ No validation issues found when analyzing namespace: default.

インストールされたサービスを確認します。

1
2
3
4
5
$ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egressgateway ClusterIP 10.109.45.222 <none> 80/TCP,443/TCP 2m22s
istio-ingressgateway LoadBalancer 10.109.115.29 <pending> 15021:30451/TCP,80:32750/TCP,443:31674/TCP,31400:32170/TCP,15443:30677/TCP 2m22s
istiod ClusterIP 10.107.66.49 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 2m39s

ここでは、istio-ingressgatewayの80ポートは32750ポートで公開されていることがわかります。
続いて、minikubeのIPを確認します。

1
2
$ minikube ip
192.168.49.2

このIPとポートを環境変数にセットします。

1
2
3
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export INGRESS_HOST=$(minikube ip)
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

ここで、このアプリケーションへのアクセスをしてみます。

1
curl 192.168.49.2:32750/productpage

HTML が返ってきます。この HTML はどこのアプリケーションのレスポンスでしょうか。
先ほどデプロイした bookinfo-gateway.yaml を見てみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$ cat samples/bookinfo/networking/bookinfo-gateway.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

なんとなく /productpage へのアクセスを productpage ホストの9080ポートにルーティングしていることが読み取れます。
productpage があったかどうかもう1度確認します。

1
2
3
4
5
6
7
$ kubectl get svc                
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.101.220.243 <none> 9080/TCP 9m57s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m
productpage ClusterIP 10.99.253.196 <none> 9080/TCP 9m57s
ratings ClusterIP 10.102.110.105 <none> 9080/TCP 9m57s
reviews ClusterIP 10.108.72.211 <none> 9080/TCP 9m57s

3つ目にありました。
続いて、ブラウザでアプリケーションにアクセスしてみます。
今回の例では http://192.168.49.2:32750/productpage です。
BookInfo Sample のページが表示されればOKです。何回かリロードしてみると、表示内容が変化することがわかります。
これは BookInfo Sample の中に複数のバージョンのアプリケーションがあり、毎回異なるバージョンの API を呼び出すことがあるからです。
どの API が呼び出されているのかを視覚的に確認するためにダッシュボードをインストールします。

1
2
kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system

新しくターミナルを開きます。
インストールしたダッシュボードにアクセスします。

1
istioctl dashboard kiali

左のサイドメニューの Graph をクリックします。続いて Namespace に default を選択します。
ここでターミナルに戻り、プロダクトページに100回アクセスするコマンドを実行します。もちろんブラウザを使ってリロードしてもOKです。

1
for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done

ダッシュボードに戻るとグラフが表示されていて、以下の経路が確認できるはずです。

  • productpage(v1) -> details(v1)
  • productpage(v1) -> reviews(v1)
  • productpage(v1) -> reviews(v2)
  • productpage(v1) -> reviews(v3)
  • reviews(v2) -> ratings(v1)
  • reviews(v3) -> ratings(v1)

Getting Started はここまでですが、productpage(v1) -> reviews(v1,v2,v3) の振り分けの部分を確認してみます。
インストールした以下のファイルを開きます。
samples/bookinfo/platform/kube/bookinfo.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
~
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}

reviews Service から以下の条件を満たす Pod にプロキシしてます。

1
2
selector:
app: reviews

そして、この条件を満たすポッドが v1、v2、v3 の3つ用意されています。
特に Istio に関係する設定はなさそう(アプリケーションが Istio に依存していない)です。