全部產品
Search
文件中心

Alibaba Cloud Service Mesh:對網格內服務訪問外部資料庫進行授權控制

更新時間:Jan 13, 2025

為了保障資料庫的安全性,需要對訪問資料庫的服務進行限制,例如只有某些生產環境的命名空間才能被允許訪問生產資料庫,開發環境不能訪問生產資料庫。您可以使用ASM零安全體系,動態配置授權策略,實現對命名空間下服務訪問外部資料庫進行授權控制,從而降低風險。以demo-server命名空間為例,本文介紹如何使用授權策略實現對外部特定的RDS資料庫訪問的控制。

前提條件

已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體

步驟一:注入Sidecar代理

建立demo-server命名空間,並為該命名空間注入Sidecar代理,便於對該命名空間下的服務進行授權管理。具體操作,請參見管理全域命名空間

步驟二:建立資料庫用戶端

在demo-server命名空間下建立發起資料庫連接請求的用戶端。

  1. 在本地命令列工具中,對資料庫連接密碼進行Base64編碼。

    echo  <資料庫連接密碼> | base64 
  2. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  3. 在demo-server命名空間下建立MySQL用戶端。

    1. 使用以下內容,建立k8s-mysql.yaml

      apiVersion: v1
      data:
        password: {yourPasswordBase64}  # 資料庫連接密碼的Base64編碼。
      kind: Secret
      metadata:
        name: mysql-pass
      type: Opaque
      ---
      
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          name: lbl-k8s-mysql
        name: k8s-mysql
      spec:
        progressDeadlineSeconds: 600
        replicas: 1
        revisionHistoryLimit: 10
        selector:
          matchLabels:
            name: lbl-k8s-mysql
        strategy:
          rollingUpdate:
            maxSurge: 25%
            maxUnavailable: 25%
          type: RollingUpdate
        template:
          metadata:
            labels:
              name: lbl-k8s-mysql
          spec:
            containers:
              - env:
                  - name: MYSQL_ROOT_PASSWORD
                    valueFrom:
                      secretKeyRef:
                        key: password
                        name: mysql-pass
                image: 'mysql:latest'
                imagePullPolicy: Always
                name: mysql
                ports:
                  - containerPort: 3306
                    name: mysql
                    protocol: TCP
                resources:
                  limits:
                    cpu: 500m
                terminationMessagePath: /dev/termination-log
                terminationMessagePolicy: File
                volumeMounts:
                  - mountPath: /var/lib/mysql
                    name: k8s-mysql-storage
            dnsPolicy: ClusterFirst
            restartPolicy: Always
            schedulerName: default-scheduler
            securityContext: {}
            terminationGracePeriodSeconds: 30
            volumes:
              - emptyDir: {}
                name: k8s-mysql-storage
    2. 執行以下命令,建立MySQL用戶端。

      kubectl apply -f k8s-mysql.yaml -n demo-server
  4. 驗證MySQL用戶端是否注入Sidecar成功。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

    3. 容器組頁面,單擊MySQL用戶端的容器組名稱。

      容器頁簽,可以看到istio-proxy,說明建立MySQL用戶端注入Sidecar成功。

步驟三:建立出口網關

服務網格內的服務訪問網格外的網站時,需要通過出口網關管控流量。配置出口網關的授權策略後,還可以設定條件來控制是否允許訪問資料庫。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 出口網關

  3. 出口網關頁面,單擊建立

  4. 建立頁面,配置出口網關的名稱egressgateway,選擇部署叢集,在連接埠映射地區,配置協議TCP服務連接埠13306,然後單擊建立

    關於配置項的說明,請參見建立出口網關

步驟四:設定外部服務的存取原則

預設對外部服務的存取原則為允許訪問全部外部服務。為了實現對特定的外部網站進行存取控制,您需要設定外部服務存取原則為REGISTRY_ONLY,未註冊為ServiceEntry的外部服務將無法被服務網格中的服務訪問。

  1. 設定外部服務的存取原則。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇資料面組件管理 > Sidecar代理配置

    3. 全域頁簽,單擊外部服務存取原則,配置對外部服務的存取原則OutboundTrafficPolicyREGISTRY_ONLY,然後單擊更新設定

  2. 將外部服務註冊到ServiceEntry中。

    1. 在網格詳情頁面左側導覽列,選擇叢集與工作負載管理 > 叢集外服務(ServiceEntry),然後在右側頁面,單擊使用YAML建立

    2. 設定命名空間istio-system,將以下內容複寫到文字框中,然後單擊建立

      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: demo-server-rds
        namespace: demo-server
      spec:
        endpoints:
          - address: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com   # 資料庫地址。
            ports:
              tcp: 3306  
        hosts:
          - rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
        location: MESH_EXTERNAL
        ports:
          - name: tcp
            number: 3306  # 資料庫連接埠。
            protocol: TCP  # 資料庫協議。
        resolution: DNS
                                      

步驟五:建立流量策略

建立網關規則、目標規則和虛擬服務,使demo-server命名空間下的流量路由到出口網關的13306連接埠,再由出口網關路由到資料庫的3306連接埠。

  1. 建立網關規則。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 網關規則,然後單擊使用YAML建立

    3. 設定命名空間istio-system,將以下內容複寫到文字框,然後單擊建立

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: istio-egressgateway
        namespace: istio-system
      spec:
        selector:
          istio: egressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: http-0
              number: 13306
              protocol: TLS
            tls:
              mode: ISTIO_MUTUAL

      mode:設定為ISTIO_MUTUAL,表示啟用雙向TLS服務認證,網格內服務訪問外部網站需要TLS服務認證。

  2. 建立目標規則。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 目標規則,然後在右側頁面,單擊使用YAML建立

    2. 建立頁面,設定命名空間demo-server,將以下內容複寫到文字框,然後單擊建立

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: demo-server-egress-gateway
        namespace: demo-server
      spec:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subsets:
          - name: mysql-gateway-mTLS
            trafficPolicy:
              loadBalancer:
                simple: ROUND_ROBIN
              portLevelSettings:
                - port:
                    number: 13306 # 網關映射連接埠。
                  tls:
                    mode: ISTIO_MUTUAL
                    sni: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com  # 資料庫Host地址。

      mode:設定為ISTIO_MUTUAL,表示啟用雙向TLS服務認證,外部網站訪問網格內服務需要TLS服務認證。

  3. 建立虛擬服務。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 虛擬服務,然後在右側頁面,單擊使用YAML建立

    2. 建立頁面,設定命名空間demo-server,將以下內容複寫到文字框,然後單擊建立

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: demo-server-through-egress-gateway
        namespace: demo-server
      spec:
        exportTo:
          - istio-system
          - demo-server
        gateways:
          - mesh
          - istio-system/istio-egressgateway
        hosts:
          - rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
        tcp:
          - match:
              - gateways:
                  - mesh
                port: 3306
            route:
              - destination:
                  host: istio-egressgateway.istio-system.svc.cluster.local
                  port:
                    number: 13306
                  subset: mysql-gateway-mTLS
                weight: 100
          - match:
              - gateways:
                  - istio-system/istio-egressgateway
                port: 13306
            route:
              - destination:
                  host: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
                  port:
                    number: 3306
                weight: 100

      http設定了2條匹配規則。第一條設定gatewaysmesh,表示作用範圍為demo-server命名空間下的Sidecar代理,將demo-server命名空間下的流量路由到出口網關的13306連接埠。第二條設定為gatewaysistio-system/istio-egressgateway,將出口網關的流量路由到註冊的資料庫3306連接埠。

步驟六:驗證使用授權策略實現對外部資料庫訪問的控制

通過修改授權策略的動作,您可以禁止或允許demo-server命名空間下的服務訪問外部資料庫,實現對外部資料庫訪問的控制。

  1. 建立授權策略,禁止來自demo-server命名空間的訪問請求。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

    3. 建立頁面,進行相關配置,然後單擊建立

      配置項

      說明

      名稱

      輸入授權策略的名稱。

      策略類型

      配置為拒絕

      網關生效頁簽

      ASM網關

      選擇egressgateway。選擇後,匹配標籤預設為istio:egressgateway

      請求匹配規則

      開啟命名空間(Namespaces)開關,配置為demo-frontend

      建立授權策略

  2. 訪問外部資料庫。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 容器組

    3. 容器組頁面,單擊k8s-mysql容器右側操作列下的終端,單擊容器:mysql

    4. 在容器組終端中執行以下命令,訪問外部資料庫。

      mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com

      返回結果中提示ERROR 2013錯誤,說明訪問資料庫失敗。

  3. 修改授權策略動作為ALLOW,允許來自demo-server命名空間的訪問請求。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略

    3. 授權策略頁面的操作列,單擊目標策略對應的查看YAML

    4. 編輯對話方塊,修改action參數值為ALLOW,然後單擊確定

  4. 在容器組終端中執行以下命令,訪問外部資料庫。

    mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com

    返回結果中顯示Welcome to the MySQL monitor,說明訪問資料庫成功。

    根據以上操作結果,可以看到使用授權策略控制對外部資料庫的訪問成功。