为了保障数据库的安全性,需要对访问数据库的服务进行限制,例如只有某些生产环境的命名空间才能被允许访问生产数据库,开发环境不能访问生产数据库。您可以使用ASM零安全体系,动态配置授权策略,实现对命名空间下服务访问外部数据库进行授权控制,从而降低风险。本文以demo-server命名空间为例,介绍如何使用授权策略实现对外部特定的RDS数据库访问的控制。

前提条件

添加集群到ASM实例。具体操作,请参见添加集群到ASM实例

步骤一:注入Sidecar代理

为命名空间注入Sidecar代理,便于对该命名空间下的服务进行授权管理。

  1. 新建demo-server命名空间。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择网格实例 > 全局命名空间,然后在右侧页面单击新建
    5. 新建命名空间面板设置名称为demo-server,然后单击确定
  2. 为demo-server命名空间注入Sidecar代理。
    1. 全局命名空间页面单击demo-server命名空间右侧自动注入列下的启用Sidecar自动注入
    2. 确认对话框单击确定

步骤二:创建数据库客户端

在demo-server命名空间下创建发起数据库连接请求的客户端。

  1. 在本地命令行工具中对数据库连接密码进行Base64编码。
    echo  <数据库连接密码> | base64 
  2. 通过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. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择工作负载 > 容器组
    5. 容器组页面单击MySQL客户端的容器组名称。
      容器页签下可以看到istio-proxy,说明创建MySQL客户端注入Sidecar成功。

步骤三:创建出口网关

服务网格内的服务访问网格外的网站时,需要通过出口网关管控流量。配置出口网关的授权策略后,还可以设置条件来控制是否允许访问数据库。

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 在网格详情页面左侧导航栏单击ASM网关,然后在右侧页面单击创建
  5. 输入出口网关的名称,选择部署集群,设置网关类型南北向-出口,单击端口映射右侧的添加端口,设置协议TCP服务端口为13306,然后单击创建。本文设置出口网关的名称为egressgateway。

步骤四:创建对等身份认证

创建对等身份认证,便于授权策略使用TLS对服务进行授权。

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 在网格详情页面左侧导航栏选择网格安全中心 > 对等身份认证
  5. 对等身份认证页面单击创建双向mTLS模式
  6. 设置命名空间为demo-server,输入名称,设置mTLS模式为STRICT模式,然后单击创建

步骤五:设置外部服务的访问策略

默认对外部服务的访问策略为允许访问全部外部服务。为了实现对特定的外部网站进行访问控制,您需要设置外部服务访问策略为REGISTRY_ONLY,未注册为ServiceEntry的外部服务将无法被服务网格中的服务访问。

  1. 设置外部服务的访问策略。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择Sidecar管理(数据面) > Sidecar代理配置
    5. 全局页签下单击外部服务访问策略,配置对外部服务的访问策略OutboundTrafficPolicyREGISTEY_ONLY,然后单击更新设置
  2. 将外部服务注册到ServiceEntry中。
    1. 在网格详情页面左侧导航栏选择集群与工作负载管理 > 服务条目,然后在右侧页面单击使用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. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择流量管理中心 > 网关规则,然后在右侧页面单击使用YAML创建
    5. 设置命名空间为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. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择网格安全中心 > 授权策略,然后在右侧页面单击创建
    5. 设置授权策略参数,然后单击创建
      参数 说明
      命名空间 设置命名空间为demo-server。
      名称 输入授权策略的名称。
      策略 设置策略RULES
      动作 设置动作DENY
      工作负载标签选择 打开工作负载标签选择开关,单击新增匹配标签,设置名称istio为egressgateway。
      请求来源 打开请求来源开关,单击增加请求来源到列表中,单击增加请求来源,设置请求来源域namespaces为demo-server。
  2. 访问外部数据库。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
    4. 在集群管理页左侧导航栏中,选择工作负载 > 容器组
    5. 容器组页面单击k8s-mysql容器右侧操作列下的终端,单击容器:mysql
    6. 在容器组终端中执行以下命令,访问外部数据库。
      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. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择网格安全中心 > 授权策略
    5. 授权策略页面单击目标策略右侧操作列下的YAML
    6. 编辑面板修改action参数值为ALLOW,然后单击确定
  4. 在容器组终端中执行以下命令,访问外部数据库。
    mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com

    返回结果中显示Welcome to the MySQL monitor,说明访问数据库成功。

    根据以上操作结果,可以看到使用授权策略控制对外部数据库的访问成功。