Route gRPC traffic to backend services running across multiple clusters using an Application Load Balancer (ALB) multi-cluster gateway. The gateway acts as a single HTTPS entry point, and an Ingress routes requests to the grpc-service backend in each associated cluster.
How it works
When a gRPC request reaches the ALB multi-cluster gateway:
The ALB listener on port 443 (HTTPS) accepts the request.
The Ingress matches the request against the host and path rules.
The ALB forwards the request to the
grpc-servicebackend in the associated clusters.
The alb.ingress.kubernetes.io/backend-protocol: grpc annotation is required. Without it, the ALB defaults to HTTP/1.1, which is incompatible with gRPC — gRPC requires HTTP/2.
Prerequisites
Before you begin, ensure that you have:
The ALB service activated. Go to the ALB console to activate it.
Fleet management enabled in ACK One.
The ACK One Fleet associated with two ACK clusters in the same VPC as the Fleet instance. See Manage associated clusters.
The kubeconfig for the Fleet instance, obtained from the ACK One console, with kubectl configured to connect to the Fleet instance.
The grpcurl tool installed.
A trusted TLS certificate. Obtain one in any of the following ways:
Purchase a certificate from Certificate Management Service. See Purchase an SSL certificate.
Purchase a certificate from another certificate authority (CA).
Generate a self-signed certificate as described in Step 1.
ImportantThe self-signed certificate in this topic is for demonstration only. Do not use it in a production environment. If you already have a purchased certificate, skip to Step 2.
Step 1: Generate a self-signed certificate (optional)
If you do not have a certificate, follow these steps to generate a self-signed certificate using grpc.example.com as the domain name. For information about how to configure a certificate for an ALB instance, see Configure an HTTPS certificate to implement encrypted communication. This topic uses the Secret certificate method from that guide.
Create the
/tmp/openssl.cnffile with the following content.[ req ] #default_bits = 2048 #default_md = sha256 #default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes req_extensions = v3_req [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, fully qualified host name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 [v3_req] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = grpc.example.comGenerate a certificate signing request (CSR).
openssl req -new -nodes -keyout grpc.key -out grpc.csr -config /tmp/openssl.cnf -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=AlibabaCloud/OU=ContainerService/CN=grpc.example.com"Sign the certificate.
openssl x509 -req -days 3650 -in grpc.csr -signkey grpc.key -out grpc.crt -extensions v3_req -extfile /tmp/openssl.cnfAfter the command completes, you have two files:
grpc.crt(the certificate) andgrpc.key(the private key).Add the certificate as a Kubernetes Secret named
grpc-secretin thegateway-demonamespace.# Replace grpc.key with your private key filename and grpc.crt with your certificate filename. kubectl create secret tls grpc-secret --key grpc.key --cert grpc.crt -n gateway-demo
Step 2: Deploy a gRPC service to multiple clusters
Use GitOps to deploy the gRPC service to all associated clusters. You can also use the application distribution feature or create a multi-cluster application directly. For GitOps background, see Get started with GitOps.
Log on to the ACK One console. In the left navigation pane, choose Fleet > Multi-cluster GitOps.
In the upper-left corner of the Multi-cluster GitOps page, click the
button next to the fleet name, and select the target fleet from the drop-down list.Click Create Multi-cluster Application > GitOps to open the Create Multi-cluster Application - GitOps page.
On the Create from YAML tab, paste the following YAML into the code editor, then click OK.
NoteThis ApplicationSet deploys to the
gateway-demonamespace in all associated clusters. You can also use Quick Create to select specific clusters — changes are synced back to the Create from YAML tab. If thegateway-demonamespace does not exist in a cluster, create it manually before proceeding.apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: appset-grpc-demo namespace: argocd spec: template: metadata: name: '{{.metadata.annotations.cluster_name}}-grpc' namespace: argocd spec: destination: name: '{{.name}}' namespace: gateway-demo project: default source: repoURL: https://github.com/ivan-cai/gitops-demo.git path: manifests/directory/grpc targetRevision: main syncPolicy: automated: {} syncOptions: - CreateNamespace=true generators: - clusters: selector: matchExpressions: - values: - cluster key: argocd.argoproj.io/secret-type operator: In - values: - in-cluster key: name operator: NotIn goTemplateOptions: - missingkey=error syncPolicy: preserveResourcesOnDeletion: false goTemplate: true
Step 3: Create an ALB multi-cluster gateway and Ingress
Create an AlbConfig object in the ACK One Fleet to provision an ALB multi-cluster gateway and associate your clusters with it. Because gRPC requires HTTPS, the gateway must include an HTTPS listener on port 443.
Get the IDs of two vSwitches in the ACK One Fleet's VPC.
Create the
gateway.yamlfile with the following content.NoteReplace
${vsw-id1}and${vsw-id2}with the vSwitch IDs from the previous step, and replace${cluster1}and${cluster2}with the IDs of the clusters to add. The security groups for subclusters${cluster1}and${cluster2}must have inbound rules that allow traffic from the vSwitch CIDR on all ports.apiVersion: alibabacloud.com/v1 kind: AlbConfig metadata: name: ackone-gateway-demo annotations: # Add the associated clusters that process traffic to the ALB multi-cluster instance. alb.ingress.kubernetes.io/remote-clusters: ${cluster1},${cluster2} spec: config: name: one-alb-demo addressType: Internet addressAllocatedMode: Fixed zoneMappings: - vSwitchId: ${vsw-id1} - vSwitchId: ${vsw-id2} listeners: - port: 8001 protocol: HTTP - port: 443 protocol: HTTPS --- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: alb spec: controller: ingress.k8s.alibabacloud/alb parameters: apiGroup: alibabacloud.com kind: AlbConfig name: ackone-gateway-demoCreate the Ingress. Two annotations are required for gRPC routing: The TLS section must reference the Secret created in Step 1.
Annotation Value Purpose alb.ingress.kubernetes.io/backend-protocolgrpcInstructs the ALB to use HTTP/2 for backend connections. Without this, the ALB defaults to HTTP/1.1, which breaks gRPC. alb.ingress.kubernetes.io/listen-ports[{"HTTPS": 443}]Binds the Ingress to the HTTPS listener on port 443. apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/listen-ports: | [{"HTTPS": 443}] alb.ingress.kubernetes.io/backend-protocol: grpc name: grpc-ingress namespace: gateway-demo spec: ingressClassName: alb rules: - host: grpc.example.com http: paths: - backend: service: name: grpc-service port: number: 50051 path: / pathType: Prefix tls: - hosts: - grpc.example.com secretName: grpc-secret
Step 4: Verify traffic forwarding
Get the Ingress address.
kubectl get ingress -n gateway-demoExpected output:
NAME CLASS HOSTS ADDRESS PORTS AGE grpc-ingress alb grpc.example.com alb-***** 80, 443 3m51sNote the value in the
ADDRESScolumn — this is the ALB domain name.Use grpcurl to confirm that the Ingress is forwarding traffic to the gRPC backend.
NoteThis command relies on gRPC Reflection being enabled on the backend service. gRPC Reflection lets clients like grpcurl discover available services without a local copy of the service's protocol buffers. It is useful in development and staging environments, but evaluate the security implications before enabling it in production.
# Replace <ADDRESS> with the ALB domain name from the previous step. grpcurl -insecure -authority grpc.example.com <ADDRESS>:443 listThe following output confirms that traffic is reaching the backend gRPC service:
grpc.reflection.v1alpha.ServerReflection helloworld.Greeter