Connect to a Redis instance from a Google Kubernetes Engine cluster

Note: To connect to a Redis instance that uses theprivate services access connect mode you must haveVPC-native/IP aliasing enabled on your GKE cluster. To useGKE to connect to a Redis instance that uses thedirect peering connect mode,use the workaround in step 3 ofpreparing your GKE cluster.

To verify if your cluster uses IP aliasing, usegcloud container clusters describe.

You can only connect to your Redis instance from Google Kubernetes Engine clustersthat use the same authorized network as the Redis instance.

Setup

If you have already installed the Google Cloud CLI and have created a Redisinstance, you can skip these steps.

  1. Install the gcloud CLI and initialize:

    gcloud init
  2. Follow theQuickstart Guideto create a Redis instance. Take note of the zone, IP address, and port ofthe Redis instance.

Preparing your GKE cluster

  1. If you have not created a GKE cluster, create one using thefollowing commands for the Google Cloud CLI:

    1. Designate the project for this sample application ingcloud.

      gcloud config set projectPROJECT_ID

    2. Set the Compute Engine zone configuration variable ingcloud.

      gcloud config set compute/zoneZONE

    3. Create a GKE cluster calledvisitcount-cluster.

      gcloud container clusters create visitcount-cluster --num-nodes=3 --enable-ip-alias

  2. If you didn't create the cluster usinggcloud, then use the following command to retrieve the cluster credentials:

    gcloud container clusters get-credentialsCLUSTER_NAME --zoneCLUSTER_ZONE --projectPROJECT_ID
    1. CLUSTER_NAME is the name of your GKE cluster.
    2. CLUSTER_ZONE is the zone your cluster is in.
    3. PROJECT_ID is the project where your cluster and your Redis instances exist.
  3. If your cluster is version 1.8 or higherand has IP aliases enabled, skip this step. If your cluster is version 1.7 or lower, or your version 1.8 or higher cluster doesn't have IP aliases enabled, follow these workaround steps before trying to connect to your instance.

    1. Run these commands, replacing RESERVED_IP_RANGE with the reserved IP range of your instance:

      git clone https://github.com/bowei/k8s-custom-iptables.gitcd k8s-custom-iptables/TARGETS="RESERVED_IP_RANGE" ./install.shcd ..
    2. If you don't know the reserved IP range of your instance, then find out either by using the console (advanced options) or the following command:

      gcloudredisinstancesdescribeINSTANCE_ID--region=REGION

    For more information about IP aliases, including how to create a cluster with this setting enabled, see theIP aliases documentation.

Sample application

This sample HTTP server application establishes a connection to a Redis instancefrom a Google Kubernetes Engine cluster.

Clone the repository for your chosen programming language and navigateto the folder that contains the sample code:

Go

gitclonehttps://github.com/GoogleCloudPlatform/golang-samplescdgolang-samples/memorystore/redis

Java

gitclonehttps://github.com/GoogleCloudPlatform/java-docs-samplescdjava-docs-samples/memorystore/redis

Node.js

gitclonehttps://github.com/GoogleCloudPlatform/nodejs-docs-samplescdnodejs-docs-samples/memorystore/redis

Python

gitclonehttps://github.com/GoogleCloudPlatform/python-docs-samplescdpython-docs-samples/memorystore/redis

This sample application increments a Redis counter every time the/ endpointis accessed.

Go

This application uses thegithub.com/gomodule/redigo/redisclient. Install it by running the following command:

gogetgithub.com/gomodule/redigo/redis@latest

Example application:

// Command redis is a basic app that connects to a managed Redis instance.packagemainimport("fmt""log""net/http""os""github.com/gomodule/redigo/redis")varredisPool*redis.PoolfuncincrementHandler(whttp.ResponseWriter,r*http.Request){conn:=redisPool.Get()deferconn.Close()counter,err:=redis.Int(conn.Do("INCR","visits"))iferr!=nil{http.Error(w,"Error incrementing visitor counter",http.StatusInternalServerError)return}fmt.Fprintf(w,"Visitor number: %d",counter)}funcmain(){redisHost:=os.Getenv("REDISHOST")redisPort:=os.Getenv("REDISPORT")redisAddr:=fmt.Sprintf("%s:%s",redisHost,redisPort)constmaxConnections=10redisPool=&redis.Pool{MaxIdle:maxConnections,Dial:func()(redis.Conn,error){returnredis.Dial("tcp",redisAddr)},}http.HandleFunc("/",incrementHandler)port:=os.Getenv("PORT")ifport==""{port="8080"}log.Printf("Listening on port %s",port)iferr:=http.ListenAndServe(":"+port,nil);err!=nil{log.Fatal(err)}}

Java

This application is Jetty 3.1 servlet-based.

It uses theJedis library:

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.1.0</version></dependency>

TheAppServletContextListener class is used to create a long-livedRedis connection pool:

packagecom.example.redis;importjava.io.IOException;importjava.util.Properties;importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.annotation.WebListener;importredis.clients.jedis.JedisPool;importredis.clients.jedis.JedisPoolConfig;@WebListenerpublicclassAppServletContextListenerimplementsServletContextListener{privatePropertiesconfig=newProperties();privateJedisPoolcreateJedisPool()throwsIOException{Stringhost;Integerport;config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties"));host=config.getProperty("redis.host");port=Integer.valueOf(config.getProperty("redis.port","6379"));JedisPoolConfigpoolConfig=newJedisPoolConfig();// Default : 8, consider how many concurrent connections into Redis you will need under loadpoolConfig.setMaxTotal(128);returnnewJedisPool(poolConfig,host,port);}@OverridepublicvoidcontextDestroyed(ServletContextEventevent){JedisPooljedisPool=(JedisPool)event.getServletContext().getAttribute("jedisPool");if(jedisPool!=null){jedisPool.destroy();event.getServletContext().setAttribute("jedisPool",null);}}// Run this before web application is started@OverridepublicvoidcontextInitialized(ServletContextEventevent){JedisPooljedisPool=(JedisPool)event.getServletContext().getAttribute("jedisPool");if(jedisPool==null){try{jedisPool=createJedisPool();event.getServletContext().setAttribute("jedisPool",jedisPool);}catch(IOExceptione){// handle exception}}}}

TheVisitCounterServlet class is a web servlet that incrementsa Redis counter:

packagecom.example.redis;importjava.io.IOException;importjava.net.SocketException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importredis.clients.jedis.Jedis;importredis.clients.jedis.JedisPool;@WebServlet(name="Track visits",value="")publicclassVisitCounterServletextendsHttpServlet{@OverridepublicvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsIOException{try{JedisPooljedisPool=(JedisPool)req.getServletContext().getAttribute("jedisPool");if(jedisPool==null){thrownewSocketException("Error connecting to Jedis pool");}Longvisits;try(Jedisjedis=jedisPool.getResource()){visits=jedis.incr("visits");}resp.setStatus(HttpServletResponse.SC_OK);resp.getWriter().println("Visitor counter: "+String.valueOf(visits));}catch(Exceptione){resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());}}}

Node.js

This application uses theredismodule. This is a samplepackage.json file:

{"name":"memorystore-redis","description":"An example of using Memorystore(Redis) with Node.js","version":"0.0.1","private":true,"license":"Apache Version 2.0","author":"Google Inc.","engines":{"node":">=16.0.0"},"dependencies":{"redis":"^4.0.0"}}

Sample application code:

'use strict';consthttp=require('http');constredis=require('redis');constREDISHOST=process.env.REDISHOST||'localhost';constREDISPORT=process.env.REDISPORT||6379;constclient=redis.createClient({url:`redis://${REDISHOST}:${REDISPORT}`,});client.on('error',err=>console.error('ERR:REDIS:',err));client.connect().then(()=>{console.log('Connected to Redis');http.createServer(async(req,res)=>{try{constreply=awaitclient.incr('visits');res.writeHead(200,{'Content-Type':'text/plain'});res.end(`Visitor number:${reply}\n`);}catch(err){console.error(err);res.statusCode=500;res.end(err.message);}}).listen(8080,()=>{console.log('Server listening on port 8080');});}).catch(err=>{console.error('Failed to connect to Redis:',err);throwerr;});

Python

This application usesFlaskfor web serving and theredis-pypackage to communicate with the Redis instance.

Flask==3.0.3gunicorn==23.0.0redis==6.0.0Werkzeug==3.0.3

Sample application code:

importloggingimportosfromflaskimportFlaskimportredisapp=Flask(__name__)redis_host=os.environ.get("REDISHOST","localhost")redis_port=int(os.environ.get("REDISPORT",6379))redis_client=redis.StrictRedis(host=redis_host,port=redis_port)@app.route("/")defindex():value=redis_client.incr("counter",1)returnf"Visitor number:{value}"@app.errorhandler(500)defserver_error(e):logging.exception("An error occurred during a request.")return("""    An internal error occurred: <pre>{}</pre>    See logs for full stacktrace.    """.format(e),500,)if__name__=="__main__":# This is used when running locally. Gunicorn is used to run the# application on Google App Engine and Cloud Run.# See entrypoint in app.yaml or Dockerfile.app.run(host="127.0.0.1",port=8080,debug=True)

Building the container image

Build and push the container image with Cloud Build to Container Registry:

cp gke_deployment/Dockerfile .gcloud artifacts repositories create --locationREPO_REGION --repository-format=dockerREPO_IDgcloud builds submit --tagREPO_REGION-docker.pkg.dev/PROJECT_ID/REPO_ID/visit-counter:v1

Deploying your application to Google Kubernetes Engine

To avoid hard-coding the Redis instance IP, you can create aredishostConfigMap:

export REDISHOST_IP=REDISHOST_IPkubectl create configmap redishost --from-literal=REDISHOST=${REDISHOST_IP}

Verify that the configuration using the following command:

kubectl get configmaps redishost -o yaml

Updategke_deployment/visit-counter.yaml, replacing<REPO_REGION>,<PROJECT_ID>, and<REPO_ID> with the values from your container image created inBuilding the container image. This file contains the configuration for the deployment and service.

apiVersion:apps/v1kind:Deploymentmetadata:name:visit-counterlabels:app:visit-counterspec:replicas:1selector:matchLabels:app:visit-countertemplate:metadata:labels:app:visit-counterspec:containers:-name:visit-counterimage:"<REPO_REGION>-docker.pkg.dev/<PROJECT_ID>/<REPO_ID>/visit-counter:v1"env:-name:REDISHOSTvalueFrom:configMapKeyRef:name:redishostkey:REDISHOSTports:-name:httpcontainerPort:8080---apiVersion:v1kind:Servicemetadata:name:visit-counterspec:type:LoadBalancerselector:app:visit-counterports:-port:80targetPort:8080protocol:TCP

Apply the configuration to your cluster:

kubectl apply -f gke_deployment/visit-counter.yaml

Determine the external IP address for this sample app by running the following command:

kubectl get service visit-counter

Verify that your app hosted at the external IP by using your browser, or send a GET request using curl oryour browser:

curl http://EXTERNAL_IP

Removing the IP tables entry for the Redis instance

If you followed step three of the section of this walkthrough ofPreparing your GKE cluster,then you installed the reserved IP range of your Redis instance to yourGKE instance's IP tables. If you want to remove this RedisIP range entry from the IP tables of your GKE instance, runthe following command from thek8s-custom-iptables/ directory:

./uninstall.sh

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.