To ensure database security, restrict which services can access your databases. For example, allow services in production namespaces to access production databases, while blocking those in development namespaces. This topic shows how to use an authorization policy to control access to a specific external RDS database.
Prerequisites
The cluster is added to the ASM instance. For more information, see Add a cluster to an ASM instance.
Step 1: Inject a sidecar proxy
Create a namespace named demo-server and inject a sidecar proxy into it. This lets you manage authorization for services within this namespace. For more information, see Manage global namespaces.
Step 2: Create a database client
Create a client in the demo-server namespace to initiate database connection requests.
-
Base64-encode the database connection password.
echo <your-database-password> | base64 -
Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
-
Create a MySQL client in the
demo-servernamespace.-
Create a file named
k8s-mysql.yamlwith the following content.apiVersion: v1 data: password:# The Base64-encoded database connection password. 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 -
Run the following command to create the MySQL client.
kubectl apply -f k8s-mysql.yaml -n demo-server
-
-
Verify that the sidecar proxy is injected into the MySQL client pod.
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, click the name of your cluster. In the left navigation pane, click .
-
On the Pods page, click the name of the MySQL client pod.
On the Containers tab, you can see the
istio-proxycontainer. This confirms the sidecar proxy was injected.
Step 3: Create an egress gateway
Services in a Service Mesh must use an egress gateway to control outbound traffic to external services. By configuring an authorization policy for the egress gateway, you can set conditions to control database access.
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
-
On the Egress Gateway page, click Create.
-
On the Create page, set Name to egressgateway and select a Cluster. In the Port Mapping section, set Protocol to TCP and Service Port to 13306. Then, click Create.
For more information about the parameters, see Create an egress gateway.
Step 4: Configure the outbound traffic policy
By default, services in the mesh can access all external services. To control access to specific external services, set the outbound traffic policy to REGISTRY_ONLY. With this setting, services in the Service Mesh cannot access external services not defined in a ServiceEntry.
-
Set the outbound traffic policy.
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
-
On the global tab, click Outbound Traffic Policy, set Outbound Traffic Policy to REGISTRY_ONLY, and then click Update Settings.
-
-
Register the external service by creating a ServiceEntry.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
-
Set Namespaces to demo-server, paste the following content into the text box, and then click Create. Replace
rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.comwith the endpoint of your RDS instance.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 # Database address. ports: tcp: 3306 hosts: - rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com location: MESH_EXTERNAL ports: - name: tcp number: 3306 # Database port. protocol: TCP # Database protocol. resolution: DNS
-
Step 5: Create traffic policies
Create a Gateway, a DestinationRule, and a VirtualService to route traffic from the demo-server namespace to port 13306 of the egress gateway. The egress gateway then routes the traffic to port 3306 of the database.
-
Create a Gateway.
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose . On the page that appears, click Create from YAML.
-
Set Namespaces to istio-system, paste the following content into the text box, and then click Create.
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_MUTUALThe
modeis set toISTIO_MUTUALto enable mutual TLS (mTLS) authentication on the gateway. This requires clients inside the mesh to present a certificate to the egress gateway.
-
-
Create a DestinationRule.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
-
On the Create page, set Namespaces to demo-server, paste the following content into the text box, and then click Create.
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 # The gateway port mapping. tls: mode: ISTIO_MUTUAL sni: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com # The host address of the database.The
modeis set toISTIO_MUTUAL. This configures the client sidecar proxies to initiate an mTLS connection to the egress gateway service.
-
-
Create a VirtualService.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
-
On the Create page, set Namespaces to demo-server, paste the following content into the text box, and then click Create.
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: 100The http section has two matching rules. The first rule sets gateways to mesh. This setting applies to the sidecar proxies in the demo-server namespace and routes traffic from the demo-server namespace to port 13306 of the egress gateway. The second rule sets gateways to istio-system/istio-egressgateway and routes traffic from the egress gateway to port 3306 of the registered database.
-
Step 6: Verify access control with an authorization policy
By changing the action of the authorization policy, you can deny or allow services in the demo-server namespace to access the external database.
-
Create an authorization policy to deny access requests from the
demo-servernamespace.-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose . On the page that appears, click Create.
-
On the Create page, configure the following parameters and click Create.
Parameter
Description
Name
Enter a name for the authorization policy.
Policy Type
Select DENY.
Gateway Scope tab
ASM Gateway
Select egressgateway. The Match Label is then automatically set to istio:egressgateway.
Request Matching Rules
Turn on the Namespaces switch and set the value to demo-server.
-
-
Attempt to access the external database.
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, click the name of your cluster. In the left navigation pane, click .
-
On the Pods page, find the
k8s-mysqlpod, click Actions in the Terminal column, and then select the mysql container. -
In the pod terminal, run the following command to access the external database.
mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.comThe
ERROR 2013message appears, indicating that the database access fails as expected.
-
To permit access from the
demo-servernamespace, change the authorization policy action toALLOW.-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
-
On the AuthorizationPolicy page, find the target policy and click View YAML in the Actions column.
-
In the Edit dialog box, change the value of the
actionparameter to ALLOW and click OK.
-
-
In the pod terminal, run the following command again to access the external database.
mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.comThe
Welcome to the MySQL monitormessage appears, indicating that the database access is successful.These results demonstrate that you can control access to an external database by using an authorization policy.