為了方便理解,以 Istio 官方提供的 Bookinfo 應(yīng)用示例為例,利用 ratings 服務(wù)外部 MySQL 數(shù)據(jù)庫。
Bookinfo應(yīng)用的架構(gòu)圖如下:

其中,包含四個(gè)單獨(dú)的微服務(wù):
-
productpage:調(diào)用details和reviews兩個(gè)服務(wù),用來生成頁面。 -
details:包含了書籍的信息。 -
reviews:包含了書籍相關(guān)的評(píng)論。它還會(huì)調(diào)用 ratings 微服務(wù)。 -
rating:包含了由書籍評(píng)價(jià)組成的評(píng)級(jí)信息。
其中,reviews 服務(wù)有 3 個(gè)版本:
- v1 版本不會(huì)調(diào)用
ratings服務(wù)。 - v2 版本會(huì)調(diào)用
ratings服務(wù),并使用 1 到 5 個(gè)黑色星形圖標(biāo)來顯示評(píng)分信息。 - v3 版本會(huì)調(diào)用
ratings服務(wù),并使用 1 到 5 個(gè)紅色星形圖標(biāo)來顯示評(píng)分信息。
準(zhǔn)備 MySQL 數(shù)據(jù)庫
創(chuàng)建一個(gè)名為 test 數(shù)據(jù)庫,執(zhí)行以下SQL創(chuàng)建表和數(shù)據(jù):
DROP TABLE IF EXISTS `ratings`;
CREATE TABLE `ratings` (
`ReviewID` int(11) NOT NULL,
`Rating` int(11) NULL DEFAULT 0,
PRIMARY KEY (`ReviewID`) USING BTREE
) ENGINE = InnoDB;
INSERT INTO ratings (ReviewID, Rating) VALUES (1, 2);
INSERT INTO ratings (ReviewID, Rating) VALUES (2, 4);
創(chuàng)建ServiceEntry
執(zhí)行以下命令創(chuàng)建ServiceEntry:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
ports:
- number: 3306
name: mysql
protocol: MySQL
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: 192.168.1.116
ports:
mysql: 3306
EOF
其中,192.168.1.116是 MySQL 數(shù)據(jù)庫的IP,3306是 MySQL 數(shù)據(jù)庫的端口。
創(chuàng)建ratings服務(wù)
首先,執(zhí)行以下命令,獲取密碼的Base64編碼:

其中,OneMoreSociety是連接 MySQL 數(shù)據(jù)庫的密碼。
然后,執(zhí)行以下命令,創(chuàng)建 ratings 服務(wù):
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: mysql-credentials
type: Opaque
data:
dbpasswd: T25lTW9yZVNvY2lldHk=
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v2-mysql
labels:
app: ratings
version: v2-mysql
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v2-mysql
template:
metadata:
labels:
app: ratings
version: v2-mysql
spec:
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: DB_TYPE
value: "mysql"
- name: MYSQL_DB_HOST
value: mysqldb.svc.remote
- name: MYSQL_DB_PORT
value: "3306"
- name: MYSQL_DB_USER
value: root
- name: MYSQL_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-credentials
key: dbpasswd
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
EOF
其中,T25lTW9yZVNvY2lldHk=是連接 MySQL 數(shù)據(jù)庫的密碼的Base64編碼。
修改路由規(guī)則
執(zhí)行以下命令,把對(duì) reviews 服務(wù)的調(diào)用全部路由到 v2 版本上:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
EOF
執(zhí)行以下命令,把對(duì) ratings 服務(wù)的調(diào)用全部路由到 v2-mysql 版本上:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v2-mysql
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
spec:
host: ratings
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2-mysql
name: v2-mysql
EOF
效果
訪問 productpage 頁面,可以看到 Reviewer1 顯示2星, Reviewer2 顯示4星,和數(shù)據(jù)庫中的數(shù)據(jù)一致,如下圖:

在Kiali中也可以看到對(duì)應(yīng)的拓?fù)浣Y(jié)構(gòu),如下圖:

流量轉(zhuǎn)移
訪問 MySQL 數(shù)據(jù)庫時(shí),所有流量都路由到v1版本,具體配置如下:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
ports:
- number: 3306
name: tcp
protocol: TCP
location: MESH_EXTERNAL
resolution: STATIC
endpoints:
- address: 192.168.1.116
ports:
tcp: 3306
labels:
version: v1
- address: 192.168.1.118
ports:
tcp: 3306
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
tcp:
- route:
- destination:
host: mysqldb.svc.remote
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mysqldb
spec:
host: mysqldb.svc.remote
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
EOF
訪問 MySQL 數(shù)據(jù)庫時(shí),把50%流量轉(zhuǎn)移到v2版本,具體配置如下:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
tcp:
- route:
- destination:
host: mysqldb.svc.remote
subset: v1
weight: 50
- destination:
host: mysqldb.svc.remote
subset: v2
weight: 50
EOF
訪問 MySQL 數(shù)據(jù)庫時(shí),所有流量都路由到v2版本,具體配置如下:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mysqldb
spec:
hosts:
- mysqldb.svc.remote
tcp:
- route:
- destination:
host: mysqldb.svc.remote
subset: v2
EOF