在 Istio 服務網格內連接外部 MySQL 數據庫

爲了方便理解,以 Istio 官方提供的 Bookinfo 應用示例爲例,利用 ratings 服務外部 MySQL 數據庫。

Bookinfo應用的架構圖如下:

其中,包含四個單獨的微服務:

  • productpage:調用 detailsreviews 兩個服務,用來生成頁面。
  • details:包含了書籍的信息。
  • reviews:包含了書籍相關的評論。它還會調用 ratings 微服務。
  • rating:包含了由書籍評價組成的評級信息。

其中,reviews 服務有 3 個版本:

  • v1 版本不會調用 ratings 服務。
  • v2 版本會調用 ratings 服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。
  • v3 版本會調用 ratings 服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息。

準備 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 - <<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 數據庫的IP,3306是 MySQL 數據庫的端口。

創建ratings服務

首先,執行以下命令,獲取密碼的Base64編碼:

echo -n 'OneMoreSociety' | base64

其中,OneMoreSociety是連接 MySQL 數據庫的密碼。

然後,執行以下命令,創建 ratings 服務:

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 數據庫的密碼的Base64編碼。

修改路由規則

執行以下命令,把對 reviews 服務的調用全部路由到 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

執行以下命令,把對 ratings 服務的調用全部路由到 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星,和數據庫中的數據一致,如下圖:

productpage@萬貓學社

在Kiali中也可以看到對應的拓撲結構,如下圖:

kiali@萬貓學社

文章持續更新,微信搜索「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

流量轉移

訪問 MySQL 數據庫時,所有流量都路由到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 數據庫時,把50%流量轉移到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 數據庫時,所有流量都路由到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

最後,感謝你這麼帥,還給我點贊

微信公衆號:萬貓學社

微信掃描二維碼

關注後回覆「電子書」

獲取12本Java必讀技術書籍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章