为了方便理解,以 Istio 官方提供的 Bookinfo 应用示例为例,利用 ratings 服务外部 MySQL 数据库。
Bookinfo 应用的架构图如下:
其中,包含四个单独的微服务:
其中,reviews 服务有 3 个版本:
准备 MySQL 数据库
创建一个名为 test 数据库,执行以下 SQL 创建表和数据:
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);
复制代码
创建 ServiceEntry
执行以下命令创建 ServiceEntry:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata: name: mysqldbspec: hosts: - mysqldb.svc.remote ports: - number: 3306 name: mysql protocol: MySQL location: MESH_EXTERNAL resolution: STATIC endpoints: - address: 192.168.1.116 ports: mysql: 3306EOF
复制代码
其中,192.168.1.116是 MySQL 数据库的 IP,3306是 MySQL 数据库的端口。
创建 ratings 服务
首先,执行以下命令,获取密码的 Base64 编码:
echo -n 'OneMoreSociety' | base64
复制代码
其中,OneMoreSociety是连接 MySQL 数据库的密码。
然后,执行以下命令,创建 ratings 服务:
kubectl apply -f - <<EOFapiVersion: v1kind: Secretmetadata: name: mysql-credentialstype: Opaquedata: dbpasswd: T25lTW9yZVNvY2lldHk=---apiVersion: apps/v1kind: Deploymentmetadata: name: ratings-v2-mysql labels: app: ratings version: v2-mysqlspec: 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: 1000EOF
复制代码
其中,T25lTW9yZVNvY2lldHk=是连接 MySQL 数据库的密码的 Base64 编码。
修改路由规则
执行以下命令,把对 reviews 服务的调用全部路由到 v2 版本上:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: reviewsspec: hosts: - reviews http: - route: - destination: host: reviews subset: v2---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: reviewsspec: host: reviews subsets: - labels: version: v1 name: v1 - labels: version: v2 name: v2 - labels: version: v3 name: v3EOF
复制代码
执行以下命令,把对 ratings 服务的调用全部路由到 v2-mysql 版本上:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: ratingsspec: hosts: - ratings http: - route: - destination: host: ratings subset: v2-mysql---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: ratingsspec: host: ratings subsets: - labels: version: v1 name: v1 - labels: version: v2-mysql name: v2-mysqlEOF
复制代码
效果
访问 productpage 页面,可以看到 Reviewer1 显示 2 星, Reviewer2 显示 4 星,和数据库中的数据一致,如下图:
在 Kiali 中也可以看到对应的拓扑结构,如下图:
流量转移
访问 MySQL 数据库时,所有流量都路由到 v1 版本,具体配置如下:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: ServiceEntrymetadata: name: mysqldbspec: 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/v1alpha3kind: VirtualServicemetadata: name: mysqldbspec: hosts: - mysqldb.svc.remote tcp: - route: - destination: host: mysqldb.svc.remote subset: v1---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata: name: mysqldbspec: host: mysqldb.svc.remote subsets: - labels: version: v1 name: v1 - labels: version: v2 name: v2EOF
复制代码
访问 MySQL 数据库时,把 50%流量转移到 v2 版本,具体配置如下:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: mysqldbspec: hosts: - mysqldb.svc.remote tcp: - route: - destination: host: mysqldb.svc.remote subset: v1 weight: 50 - destination: host: mysqldb.svc.remote subset: v2 weight: 50EOF
复制代码
访问 MySQL 数据库时,所有流量都路由到 v2 版本,具体配置如下:
kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: mysqldbspec: hosts: - mysqldb.svc.remote tcp: - route: - destination: host: mysqldb.svc.remote subset: v2EOF
复制代码
最后,感谢你这么帅,还给我点赞。
评论