Vitess clients connect to Vitess gateways using gRPC, and establishing that connection securely requires careful setup of both the client and the gateway credentials.
Let’s see this in action. Imagine you have a Vitess cluster running, and you want to connect to it from a Python application.
import grpc
from vitess.vtgate.v2.vtgate_pb2_grpc import VtGateStub
from vitess.vtgate.v2.vtgate_pb2 import ExecuteRequest
# Assuming your Vitess gateway is running on localhost:15991
# and you have the necessary TLS certificates.
# Load client certificate and private key
client_cert = open("client.crt", "rb").read()
client_key = open("client.key", "rb").read()
# Load CA certificate to verify the server's certificate
ca_cert = open("ca.crt", "rb").read()
# Create credentials
creds = grpc.ssl_channel_credentials(
root_certificates=ca_cert,
private_key=client_key,
certificate_chain=client_cert
)
# Create a secure channel
channel = grpc.secure_channel("localhost:15991", creds)
# Create a stub for the VtGate service
vtgate_stub = VtGateStub(channel)
# Example: Execute a simple query
request = ExecuteRequest(
query="SELECT 1",
tablet_type="master"
)
response = vtgate_stub.Execute(request)
print(response)
This code snippet demonstrates a client initiating a secure gRPC connection to a Vitess gateway. The grpc.ssl_channel_credentials function is key here, as it takes your client’s certificate and key, along with the CA certificate used to sign the server’s certificate, to establish a mutually authenticated TLS connection. The VtGateStub then uses this secure channel to send requests.
The problem Vitess solves is providing a scalable, sharded relational database solution. At its core, Vitess breaks down large databases into smaller, more manageable shards. When a client needs to interact with this sharded database, it doesn’t talk directly to individual MySQL instances. Instead, it communicates with a Vitess component called vtgate. vtgate acts as a gateway, intelligently routing queries to the appropriate shards and aggregating results. This abstraction hides the complexity of sharding from the application.
The gRPC connection is the conduit for this communication. vtgate exposes a gRPC API that clients use to send queries and receive data. For security and reliability, especially in production environments, these gRPC connections are typically secured using TLS. This involves a handshake where the client and server verify each other’s identities using digital certificates.
For a Vitess cluster, you’ll typically generate a Certificate Authority (CA) certificate, and then use that CA to sign both the vtgate server certificates and the client certificates.
On the vtgate side, you configure it to use its server certificate and private key, and to trust your CA for client verification. A common configuration might look like this in your vtgate startup flags:
./vtgate \
... \
-grpc_cert /path/to/vt-gate.crt \
-grpc_key /path/to/vt-gate.key \
-grpc_ca_cert /path/to/ca.crt \
-tls_client_ca_cert /path/to/ca.crt \
...
Here, -grpc_cert and -grpc_key are the certificate and private key for the vtgate server itself. -grpc_ca_cert tells vtgate which CA to use to verify incoming client certificates. The -tls_client_ca_cert is crucial; it specifies the CA certificate that vtgate will use to verify the identity of clients connecting to it. Without this, vtgate might accept connections from any client, even if the client provides a certificate signed by a different CA.
On the client side, as shown in the Python example, you need the client’s certificate (client.crt), the client’s private key (client.key), and the CA certificate (ca.crt) that signed the vtgate server’s certificate. This CA certificate is used by the client to verify that the vtgate server it’s connecting to is indeed the legitimate server and not an imposter.
The most surprising truth about this setup is that the grpc_ca_cert on the server and the root_certificates passed to grpc.ssl_channel_credentials on the client are often the same CA certificate. This single CA certificate serves a dual purpose: it’s used by the server to authenticate clients and by the client to authenticate the server. This simplifies certificate management significantly, as you only need to distribute one CA certificate to all clients and configure it on all servers.
The next challenge you’ll likely encounter is handling different tablet types and keyspaces in your ExecuteRequest and understanding how vtgate routes these requests based on your sharding schema.