GKE Kubernetes HOW to Proxy SELECT Queries from POD to read replicas - kubernetes

I have multiple SQL Read-only replicas setup on my GCP environment. I have two requirements.
Loadbalance select queries from my app pod to multiple read-only replicas.
Read-Replicas can increase/decrease and i want to keep this logic separate from application.

According to the Cloud SQL documentation:
Does Cloud SQL provide load balancing for requests to read replicas?
Cloud SQL does not automatically provide or configure load balancing. You can use connection pooling to distribute read requests between read replicas by switching between multiple connection endpoints.
Thus there isn't a build-in way to achieve the logic you are searching for in Cloud SQL. This means that it might need to be programmed on the logic of the application that you use to manage your connections to Cloud SQL.

Related

How to connect a web server to a Kubernetes statefulset and headless service

I have been learning Kubernetes for a few weeks and now I am trying to figure out the right way to connect a web server to a statefulset correctly.
Let's say I deployed a master-slave Postgres statefulset and now I will connect my web server to it. By using a cluster IP service, the requests will be load balanced across the master and the slaves for both reading (SELECT) and writing (UPDATE, INSERT, DELETE) records, right? But I can't do that because writing requests should be handled by the master. However, when I point my web server to the master using the headless service that will give us a DNS entry for each pod, I won't get any load balancing to the other slave replications and all of the requests will be handled by one instance and that is the master. So how am I supposed to connect them the right way? By obtaining both load balancing to all replications along with the slave in reading records and forwarding writing records requests to the master?
Should I use two endpoints in the web server and configure them in writing and reading records?
Or maybe I am using headless services and statefulsets the wrong way since I am new to Kubernetes?
Well, your thinking is correct - the master should be read-write and replicas should be read only. How to configure it properly? There are different possible approaches.
First approach is what you thinking about, to setup two headless services - one for accessing primary instances, the second one to access to the replica instances - good example is Kubegres:
In this example, Kubegres created 2 Kubernetes Headless services (of default type ClusterIP) using the name defined in YAML (e.g. "mypostgres"):
a Kubernetes service "mypostgres" allowing to access to the Primary PostgreSql instances
a Kubernetes service "mypostgres-replica" allowing to access to the Replica PostgreSql instances
Then you will have two endpoints:
Consequently, a client app running inside a Kubernetes cluster, would use the hostname "mypostgres" to connect to the Primary PostgreSql for read and write requests, and optionally it can also use the hostname "mypostgres-replica" to connect to any of the available Replica PostgreSql for read requests.
Check this starting guide for more details.
It's worth noting that there are many database solutions which are using this approach - another example is MySQL. Here is a good article in Kubernetes documentation about setting MySQL using Stateful set.
Another approach is to use some middleware component which will act as a gatekeeper to the cluster, for example Pg-Pool:
Pg pool is a middleware component that sits in front of the Postgres servers and acts as a gatekeeper to the cluster.
It mainly serves two purposes: Load balancing & Limiting the requests.
Load Balancing: Pg pool takes connection requests and queries. It analyzes the query to decide where the query should be sent.
Read-only queries can be handled by read-replicas. Write operations can only be handled by the primary server. In this way, it loads balances the cluster.
Limits the requests: Like any other system, Postgres has a limit on no. of concurrent connections it can handle gracefully.
Pg-pool limits the no. of connections it takes up and queues up the remaining. Thus, gracefully handling the overload.
Then you will have one endpoint for all operations - the Pg-Pool service. Check this article for more details, including the whole setup process.

Which endpoint to connect to for read/write operations using AWS Aurora PostgreSQL Database Cluster

I have an application (AWS API Gateway) using an Aurora PostgreSQL cluster.
The cluster has 1 read/write (primary) and one reader endpoint.
At the moment, my application connections to the specific writer instance for all operations:
rds-instance-1.xxx.ap-southeast-2.rds.amazonaws.com
But I have the following endpoints available:
rds.cluster-xxx.ap-southeast-2.rds.amazonaws.com
rds.cluster-ro-xxx.ap-southeast-2.rds.amazonaws.com
rds-instance-1.xxx.ap-southeast-2.rds.amazonaws.com
rds-instance-1-ap-southeast-2c.xxx.ap-southeast-2.rds.amazonaws.com
If I am doing read and write operations, should I be connecting to the instance endpoint I'm using? Or should i use rds.cluster-xxx.ap-southeast-2.rds.amazonaws.com ? What are the benefits of using the different endpoints? I understand that if I connect to a read only endpoint I can only do reads, but for read/writes what's the difference connecting to:
rds.cluster-xxx.ap-southeast-2.rds.amazonaws.com
Or
rds-instance-1.xxx.ap-southeast-2.rds.amazonaws.com
?
What is the right / best endpoint to use for general workloads, and why?
You should use cluster reader/writer endpoint.
rds.cluster-xxx.ap-southeast-2.rds.amazonaws.com
rds.cluster-ro-xxx.ap-southeast-2.rds.amazonaws.com
The main benefit of using cluster endpoint is that if the failover occurs due to some reason you will not worry about the endpoint and you will can expect a minimal interruption of service.
Or what if you have 3 read replica then how you will manage to connect the reader? so Better to use cluster reader/writer endpoint.
Using the Reader Endpoint
You use the reader endpoint for read-only connections for your Aurora
cluster. This endpoint uses a load-balancing mechanism to help your
cluster handle a query-intensive workload. The reader endpoint is the
endpoint that you supply to applications that do reporting or other
read-only operations on the cluster.
Using the Cluster Endpoint
You use the cluster endpoint when you administer your cluster, perform
extract, transform, load (ETL) operations, or develop and test
applications. The cluster endpoint connects to the primary instance of
the cluster. The primary instance is the only DB instance where you
can create tables and indexes, run INSERT statements, and perform
other DDL and DML operations.
Instance endpoint
The instance endpoint provides direct control over connections to the
DB cluster, for scenarios where using the cluster endpoint or reader
endpoint might not be appropriate. For example, your client
application might require more fine-grained load balancing based on
workload type. In this case, you can configure multiple clients to
connect to different Aurora Replicas in a DB cluster to distribute
read workloads. For an example that uses instance endpoints to improve
connection speed after a failover for Aurora PostgreSQL
You can check furhter details AWS RDS Endpoints

How does Kubernetes create replicas of containerized apps with a common database?

This is more of a question to understand the architecture. If I have a containerized e-commerce web application, how would K8s make sure that different replicas of the application have the same information in sync?
For example, what if I use K8s to deploy the application and scale it and use a load balancer so I can optimally route traffic. Now, if I have two (or more) replicas of the application running, and the load balancer is actively dividing the traffic between the applications, how would I ensure data is in sync between the different replicas?
Like if I am routed to one replica and place an order there, and tomorrow I'm routed to another replica, how would I ensure that the second replica also shows I've placed an order and has all the data in sync with the other one?

How can I achieve an active/passive setup across multiple kubernetes clusters?

We have 2 kubernetes clusters hosted on different data centers and we're deploying the applications to both these clusters. We have an external load balancer which is outside the clusters but the the load balancer only accepts static IPs. We don't have control over the clusters and we can't provision a static IP. How can we go about this?
We've also tried kong as an api gateway. We were able to create an upstream with targets as load balanced application endpoints and providing different weights but this doesn't give us active/passive or active/failover. Is there a way we can configure kong/nginx upstream to achieve this?
Consider using HA proxy, where you can configure your passive cluster as backup upstream, and you will get active/passive cluster working. As mentioned in this nice guide about HA proxy
backup meaning it won’t participate in the load balance unless both
the nodes above have failed their health check (more on that later).
This configuration is referred to as active-passive since the backup
node is just sitting there passively doing nothing. This enables you
to economize by having the same backup system for different
application servers.
Hope it helps!

one service fabric cluster or multiple cluster?

I am migrating several of my cloud service web/worker roles into service fabric.
There will be many (around 5+) service fabric services (stateless or stateful). Shall we put all of them into one service fabric cluster, or multiple clusters? Is there best practice on cluster plan?
Also, I will add multi-tenant support on my service. per this post Service Fabric multi-tenant, I can choose application instance per customer pattern.
I am wondering if it is good idea to choose cluster per customer pattern?
It depends on your requirements per-tenant, but generally it is better to have a single cluster with multiple applications and services:
A single cluster is much easier to manage than multiple clusters.
Service Fabric was designed to host and manage a large number of applications and services in a single cluster.
Multiple services in a single cluster allows you to utilize your cluster resources much more efficiently and use Service Fabric's resource balancing to manage resources effectively.
Standing up a new cluster, depending on size, can take 30 minutes or more. Creating application instances in a cluster takes seconds.