为了保障数据库的安全性,需要对访问数据库的服务进行限制,例如只有某些生产环境的命名空间才能被允许访问生产数据库,开发环境不能访问生产数据库。您可以使用ASM零安全体系,动态配置授权策略,实现对命名空间下服务访问外部数据库进行授权控制,从而降低风险。以demo-server命名空间为例,本文介绍如何使用授权策略实现对外部特定的RDS数据库访问的控制。
前提条件
已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
步骤一:注入Sidecar代理
新建demo-server命名空间,并为该命名空间注入Sidecar代理,便于对该命名空间下的服务进行授权管理。具体操作,请参见管理全局命名空间。
步骤二:创建数据库客户端
在demo-server命名空间下创建发起数据库连接请求的客户端。
在本地命令行工具中,对数据库连接密码进行Base64编码。
echo <数据库连接密码> | base64
在demo-server命名空间下创建MySQL客户端。
使用以下内容,创建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
执行以下命令,创建MySQL客户端。
kubectl apply -f k8s-mysql.yaml -n demo-server
验证MySQL客户端是否注入Sidecar成功。
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在容器组页面,单击MySQL客户端的容器组名称。
在容器页签,可以看到istio-proxy,说明创建MySQL客户端注入Sidecar成功。
步骤三:创建出口网关
服务网格内的服务访问网格外的网站时,需要通过出口网关管控流量。配置出口网关的授权策略后,还可以设置条件来控制是否允许访问数据库。
步骤四:设置外部服务的访问策略
默认对外部服务的访问策略为允许访问全部外部服务。为了实现对特定的外部网站进行访问控制,您需要设置外部服务访问策略为REGISTRY_ONLY,未注册为ServiceEntry的外部服务将无法被服务网格中的服务访问。
设置外部服务的访问策略。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在全局页签,单击外部服务访问策略,配置对外部服务的访问策略OutboundTrafficPolicy为REGISTRY_ONLY,然后单击更新设置。
将外部服务注册到ServiceEntry中。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
设置命名空间为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端口。
创建网关规则。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击使用YAML创建。
设置命名空间为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服务认证。
创建目标规则。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
在创建页面,设置命名空间为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服务认证。
创建虚拟服务。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击使用YAML创建。
在创建页面,设置命名空间为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条匹配规则。第一条设置gateways为mesh,表示作用范围为demo-server命名空间下的Sidecar代理,将demo-server命名空间下的流量路由到出口网关的13306端口。第二条设置为gateways为istio-system/istio-egressgateway,将出口网关的流量路由到注册的数据库3306端口。
步骤六:验证使用授权策略实现对外部数据库访问的控制
通过修改授权策略的动作,您可以禁止或允许demo-server命名空间下的服务访问外部数据库,实现对外部数据库访问的控制。
创建授权策略,禁止来自demo-server命名空间的访问请求。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击创建。
在创建页面,进行相关配置,然后单击创建。
配置项
说明
名称
输入授权策略的名称。
策略类型
配置为拒绝。
网关生效页签
ASM网关
选择egressgateway。选择后,匹配标签默认为istio:egressgateway。
请求匹配规则
打开命名空间(Namespaces)开关,配置为demo-frontend。
访问外部数据库。
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在容器组页面,单击k8s-mysql容器右侧操作列下的终端,单击容器:mysql。
在容器组终端中执行以下命令,访问外部数据库。
mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
返回结果中提示
ERROR 2013
错误,说明访问数据库失败。
修改授权策略动作为ALLOW,允许来自demo-server命名空间的访问请求。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在授权策略页面的操作列,单击目标策略对应的查看YAML。
在编辑对话框,修改action参数值为ALLOW,然后单击确定。
在容器组终端中执行以下命令,访问外部数据库。
mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
返回结果中显示
Welcome to the MySQL monitor
,说明访问数据库成功。根据以上操作结果,可以看到使用授权策略控制对外部数据库的访问成功。