Connecting to a Redis instance from a Google Kubernetes Engine cluster

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

Setup

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

  1. Install the gcloud CLI and initialize:

     gcloud init 
    
  2. Follow the Quickstart Guide to create a Redis instance. Take note of the zone, IP address, and port of the Redis instance.

Preparing your GKE cluster

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

    1. Designate the project for this sample application in gcloud .

      gcloud config set project [PROJECT_ID] 
      
    2. Set the Compute Engine zone configuration variable in gcloud .

      gcloud config set compute/zone [ZONE] 
      
    3. Create a GKE cluster called visitcount-cluster .

      gcloud container clusters create visitcount-cluster --num-nodes=3 --enable-ip-alias
  2. If you did not create the cluster via gcloud , use this command to retrieve the cluster credentials:

      gcloud 
      
     container 
      
     clusters 
      
     get 
     - 
     credentials 
      
     [ 
     CLUSTER_NAME 
     ] 
      
     --zone [CLUSTER_ZONE] --project [PROJECT_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 higher andhas 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.git
      cd k8s-custom-iptables/
      TARGETS="RESERVED_IP_RANGE" ./install.sh
      cd .. 
      
    2. If you don't know the reserved IP range of your instance, you can find out via the console (advanced options) or by entering this command:

        gcloud 
        
       redis 
        
       instances 
        
       describe 
        
       INSTANCE_ID 
        
       -- 
       region 
       = 
       REGION 
       
      

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

Sample application

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

Clone the repository for your desired programming language and navigate to the folder that contains the sample code:

Go

  git 
  
 clone 
  
 https 
 : 
 //github.com/GoogleCloudPlatform/golang-samples 
 cd 
  
 golang 
 - 
 samples 
 / 
 memorystore 
 / 
 redis 
 

Java

  git 
  
 clone 
  
 https 
 : 
 //github.com/GoogleCloudPlatform/java-docs-samples 
 cd 
  
 java 
 - 
 docs 
 - 
 samples 
 / 
 memorystore 
 / 
 redis 
 

Node.js

  git 
  
 clone 
  
 https 
 : 
 //github.com/GoogleCloudPlatform/nodejs-docs-samples 
 cd 
  
 nodejs 
 - 
 docs 
 - 
 samples 
 / 
 memorystore 
 / 
 redis 
 

Python

  git 
 clone 
 https 
 : 
 // 
 github 
 . 
 com 
 / 
 GoogleCloudPlatform 
 / 
 python 
 - 
 docs 
 - 
 samples 
 cd 
 python 
 - 
 docs 
 - 
 samples 
 / 
 memorystore 
 / 
 redis 
 

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

Go

This application uses the github.com/gomodule/redigo/redis client. Install it by running the following command:

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

Java

This application is Jetty 3.1 servlet-based.

It uses the Jedis library:

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

The AppServletContextListener class is used to create a long-lived Redis connection pool:

  package 
  
 com.example.redis 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.Properties 
 ; 
 import 
  
 javax.servlet.ServletContextEvent 
 ; 
 import 
  
 javax.servlet.ServletContextListener 
 ; 
 import 
  
 javax.servlet.annotation.WebListener 
 ; 
 import 
  
 redis.clients.jedis.JedisPool 
 ; 
 import 
  
 redis.clients.jedis.JedisPoolConfig 
 ; 
 @WebListener 
 public 
  
 class 
 AppServletContextListener 
  
 implements 
  
 ServletContextListener 
  
 { 
  
 private 
  
 Properties 
  
 config 
  
 = 
  
 new 
  
 Properties 
 (); 
  
 private 
  
 JedisPool 
  
 createJedisPool 
 () 
  
 throws 
  
 IOException 
  
 { 
  
 String 
  
 host 
 ; 
  
 Integer 
  
 port 
 ; 
  
 config 
 . 
 load 
 ( 
  
 Thread 
 . 
 currentThread 
 () 
  
 . 
 getContextClassLoader 
 () 
  
 . 
 getResourceAsStream 
 ( 
 "application.properties" 
 )); 
  
 host 
  
 = 
  
 config 
 . 
 getProperty 
 ( 
 "redis.host" 
 ); 
  
 port 
  
 = 
  
 Integer 
 . 
 valueOf 
 ( 
 config 
 . 
 getProperty 
 ( 
 "redis.port" 
 , 
  
 "6379" 
 )); 
  
 JedisPoolConfig 
  
 poolConfig 
  
 = 
  
 new 
  
 JedisPoolConfig 
 (); 
  
 // Default : 8, consider how many concurrent connections into Redis you will need under load 
  
 poolConfig 
 . 
 setMaxTotal 
 ( 
 128 
 ); 
  
 return 
  
 new 
  
 JedisPool 
 ( 
 poolConfig 
 , 
  
 host 
 , 
  
 port 
 ); 
  
 } 
  
 @Override 
  
 public 
  
 void 
  
 contextDestroyed 
 ( 
 ServletContextEvent 
  
 event 
 ) 
  
 { 
  
 JedisPool 
  
 jedisPool 
  
 = 
  
 ( 
 JedisPool 
 ) 
  
 event 
 . 
 getServletContext 
 (). 
 getAttribute 
 ( 
 "jedisPool" 
 ); 
  
 if 
  
 ( 
 jedisPool 
  
 != 
  
 null 
 ) 
  
 { 
  
 jedisPool 
 . 
 destroy 
 (); 
  
 event 
 . 
 getServletContext 
 (). 
 setAttribute 
 ( 
 "jedisPool" 
 , 
  
 null 
 ); 
  
 } 
  
 } 
  
 // Run this before web application is started 
  
 @Override 
  
 public 
  
 void 
  
 contextInitialized 
 ( 
 ServletContextEvent 
  
 event 
 ) 
  
 { 
  
 JedisPool 
  
 jedisPool 
  
 = 
  
 ( 
 JedisPool 
 ) 
  
 event 
 . 
 getServletContext 
 (). 
 getAttribute 
 ( 
 "jedisPool" 
 ); 
  
 if 
  
 ( 
 jedisPool 
  
 == 
  
 null 
 ) 
  
 { 
  
 try 
  
 { 
  
 jedisPool 
  
 = 
  
 createJedisPool 
 (); 
  
 event 
 . 
 getServletContext 
 (). 
 setAttribute 
 ( 
 "jedisPool" 
 , 
  
 jedisPool 
 ); 
  
 } 
  
 catch 
  
 ( 
 IOException 
  
 e 
 ) 
  
 { 
  
 // handle exception 
  
 } 
  
 } 
  
 } 
 } 
 

The VisitCounterServlet class is a web servlet that increments a Redis counter:

  package 
  
 com.example.redis 
 ; 
 import 
  
 java.io.IOException 
 ; 
 import 
  
 java.net.SocketException 
 ; 
 import 
  
 javax.servlet.annotation.WebServlet 
 ; 
 import 
  
 javax.servlet.http.HttpServlet 
 ; 
 import 
  
 javax.servlet.http.HttpServletRequest 
 ; 
 import 
  
 javax.servlet.http.HttpServletResponse 
 ; 
 import 
  
 redis.clients.jedis.Jedis 
 ; 
 import 
  
 redis.clients.jedis.JedisPool 
 ; 
 @WebServlet 
 ( 
 name 
  
 = 
  
 "Track visits" 
 , 
  
 value 
  
 = 
  
 "" 
 ) 
 public 
  
 class 
 VisitCounterServlet 
  
 extends 
  
 HttpServlet 
  
 { 
  
 @Override 
  
 public 
  
 void 
  
 doGet 
 ( 
 HttpServletRequest 
  
 req 
 , 
  
 HttpServletResponse 
  
 resp 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 try 
  
 { 
  
 JedisPool 
  
 jedisPool 
  
 = 
  
 ( 
 JedisPool 
 ) 
  
 req 
 . 
 getServletContext 
 (). 
 getAttribute 
 ( 
 "jedisPool" 
 ); 
  
 if 
  
 ( 
 jedisPool 
  
 == 
  
 null 
 ) 
  
 { 
  
 throw 
  
 new 
  
 SocketException 
 ( 
 "Error connecting to Jedis pool" 
 ); 
  
 } 
  
 Long 
  
 visits 
 ; 
  
 try 
  
 ( 
 Jedis 
  
 jedis 
  
 = 
  
 jedisPool 
 . 
 getResource 
 ()) 
  
 { 
  
 visits 
  
 = 
  
 jedis 
 . 
 incr 
 ( 
 "visits" 
 ); 
  
 } 
  
 resp 
 . 
 setStatus 
 ( 
 HttpServletResponse 
 . 
 SC_OK 
 ); 
  
 resp 
 . 
 getWriter 
 (). 
 println 
 ( 
 "Visitor counter: " 
  
 + 
  
 String 
 . 
 valueOf 
 ( 
 visits 
 )); 
  
 } 
  
 catch 
  
 ( 
 Exception 
  
 e 
 ) 
  
 { 
  
 resp 
 . 
 sendError 
 ( 
 HttpServletResponse 
 . 
 SC_INTERNAL_SERVER_ERROR 
 , 
  
 e 
 . 
 getMessage 
 ()); 
  
 } 
  
 } 
 } 
 

Node.js

This application uses the redis module.

  { 
  
 "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" 
  
 } 
 } 
 
  'use strict' 
 ; 
 const 
  
 http 
  
 = 
  
 require 
 ( 
 'http' 
 ); 
 const 
  
 redis 
  
 = 
  
 require 
 ( 
 'redis' 
 ); 
 const 
  
 REDISHOST 
  
 = 
  
 process 
 . 
 env 
 . 
 REDISHOST 
  
 || 
  
 'localhost' 
 ; 
 const 
  
 REDISPORT 
  
 = 
  
 process 
 . 
 env 
 . 
 REDISPORT 
  
 || 
  
 6379 
 ; 
 const 
  
 client 
  
 = 
  
 redis 
 . 
 createClient 
 ( 
 REDISPORT 
 , 
  
 REDISHOST 
 ); 
 client 
 . 
 on 
 ( 
 'error' 
 , 
  
 err 
  
 = 
>  
 console 
 . 
 error 
 ( 
 'ERR:REDIS:' 
 , 
  
 err 
 )); 
 // create a server 
 http 
  
 . 
 createServer 
 (( 
 req 
 , 
  
 res 
 ) 
  
 = 
>  
 { 
  
 // increment the visit counter 
  
 client 
 . 
 incr 
 ( 
 'visits' 
 , 
  
 ( 
 err 
 , 
  
 reply 
 ) 
  
 = 
>  
 { 
  
 if 
  
 ( 
 err 
 ) 
  
 { 
  
 console 
 . 
 log 
 ( 
 err 
 ); 
  
 res 
 . 
 status 
 ( 
 500 
 ). 
 send 
 ( 
 err 
 . 
 message 
 ); 
  
 return 
 ; 
  
 } 
  
 res 
 . 
 writeHead 
 ( 
 200 
 , 
  
 { 
 'Content-Type' 
 : 
  
 'text/plain' 
 }); 
  
 res 
 . 
 end 
 ( 
 `Visitor number: 
 ${ 
 reply 
 } 
 \n` 
 ); 
  
 }); 
  
 }) 
  
 . 
 listen 
 ( 
 8080 
 ); 
 

Python

This application uses Flask for web serving and the redis-py package to communicate with the Redis instance.

  Flask 
 == 
 3.0.3 
 gunicorn 
 == 
 23.0.0 
 redis 
 == 
 6.0.0 
 Werkzeug 
 == 
 3.0.3 
 
  import 
  
 logging 
 import 
  
 os 
 from 
  
 flask 
  
 import 
 Flask 
 import 
  
 redis 
 app 
 = 
 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 
 ( 
 "/" 
 ) 
 def 
  
 index 
 (): 
 value 
 = 
 redis_client 
 . 
 incr 
 ( 
 "counter" 
 , 
 1 
 ) 
 return 
 f 
 "Visitor number: 
 { 
 value 
 } 
 " 
 @app 
 . 
 errorhandler 
 ( 
 500 
 ) 
 def 
  
 server_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 to Container Registry:

  cp 
  
 gke_deployment 
 / 
 Dockerfile 
  
 . 
 export 
  
 PROJECT_ID 
 = 
 "$(gcloud config get-value project -q)" 
 docker 
  
 build 
  
 - 
 t 
  
 gcr 
 . 
 io 
 /$ 
 { 
 PROJECT_ID 
 } 
 / 
 visit 
 - 
 counter 
 : 
 v1 
  
 . 
 gcloud 
  
 docker 
  
 -- 
  
 push 
  
 gcr 
 . 
 io 
 /$ 
 { 
 PROJECT_ID 
 } 
 / 
 visit 
 - 
 counter 
 : 
 v1 
 

Deploying your application to Google Kubernetes Engine

Update gke_deployment/visit-counter.yaml replacing <PROJECT_ID> with your Google Cloud Project ID. This file contains the configuration for the deployment and service.

Go

To avoid hard-coding the Redis instance IP, you can create a redishost ConfigMap :

   
 export 
  
 REDISHOST_IP 
 = 
 XXX 
 . 
 XXX 
 . 
 XXX 
 . 
 XXX 
  
 kubectl 
  
 create 
  
 configmap 
  
 redishost 
  
 -- 
 from 
 - 
 literal 
 = 
 REDISHOST 
 = 
 $ 
 { 
 REDISHOST_IP 
 } 
 

Verify the configuration using the following command:

   
 kubectl 
  
 get 
  
 configmaps 
  
 redishost 
  
 - 
 o 
  
 yaml 
 
  # Copyright 2019 Google LLC 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #     https://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 apiVersion 
 : 
  
 extensions/v1beta1 
 kind 
 : 
  
 Deployment 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
 spec 
 : 
  
 replicas 
 : 
  
 1 
  
 template 
 : 
  
 metadata 
 : 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
  
 spec 
 : 
  
 containers 
 : 
  
 - 
  
 name 
 : 
  
 visit-counter 
  
 image 
 : 
  
 "gcr.io/<PROJECT_ID>/visit-counter:v1" 
  
 env 
 : 
  
 - 
  
 name 
 : 
  
 REDISHOST 
  
 valueFrom 
 : 
  
 configMapKeyRef 
 : 
  
 name 
 : 
  
 redishost 
  
 key 
 : 
  
 REDISHOST 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 http 
  
 containerPort 
 : 
  
 8080 
 --- 
 apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
 spec 
 : 
  
 type 
 : 
  
 LoadBalancer 
  
 selector 
 : 
  
 app 
 : 
  
 visit-counter 
  
 ports 
 : 
  
 - 
  
 port 
 : 
  
 80 
  
 targetPort 
 : 
  
 8080 
  
 protocol 
 : 
  
 TCP 
 

Java

  apiVersion 
 : 
  
 extensions/v1beta1 
 kind 
 : 
  
 Deployment 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
 spec 
 : 
  
 replicas 
 : 
  
 1 
  
 template 
 : 
  
 metadata 
 : 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
  
 spec 
 : 
  
 containers 
 : 
  
 - 
  
 name 
 : 
  
 visit-counter 
  
 image 
 : 
  
 "gcr.io/<PROJECT_ID>/visit-counter:v1" 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 http 
  
 containerPort 
 : 
  
 8080 
 --- 
 apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
 spec 
 : 
  
 type 
 : 
  
 LoadBalancer 
  
 selector 
 : 
  
 app 
 : 
  
 visit-counter 
  
 ports 
 : 
  
 - 
  
 port 
 : 
  
 80 
  
 targetPort 
 : 
  
 8080 
  
 protocol 
 : 
  
 TCP 
 

Node.js

To avoid hard-coding the Redis instance IP, you can create a redishost ConfigMap :

   
 export 
  
 REDISHOST_IP 
 = 
 XXX 
 . 
 XXX 
 . 
 XXX 
 . 
 XXX 
  
 kubectl 
  
 create 
  
 configmap 
  
 redishost 
  
 -- 
 from 
 - 
 literal 
 = 
 REDISHOST 
 = 
 $ 
 { 
 REDISHOST_IP 
 } 
 

Verify the configuration using the following command:

   
 kubectl 
  
 get 
  
 configmaps 
  
 redishost 
  
 - 
 o 
  
 yaml 
 
  apiVersion 
 : 
  
 extensions/v1beta1 
 kind 
 : 
  
 Deployment 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
 spec 
 : 
  
 replicas 
 : 
  
 1 
  
 template 
 : 
  
 metadata 
 : 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
  
 spec 
 : 
  
 containers 
 : 
  
 - 
  
 name 
 : 
  
 visit-counter 
  
 image 
 : 
  
 "gcr.io/<PROJECT_ID>/visit-counter:v1" 
  
 env 
 : 
  
 - 
  
 name 
 : 
  
 REDISHOST 
  
 valueFrom 
 : 
  
 configMapKeyRef 
 : 
  
 name 
 : 
  
 redishost 
  
 key 
 : 
  
 REDISHOST 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 http 
  
 containerPort 
 : 
  
 8080 
 --- 
 apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
 spec 
 : 
  
 type 
 : 
  
 LoadBalancer 
  
 selector 
 : 
  
 app 
 : 
  
 visit-counter 
  
 ports 
 : 
  
 - 
  
 port 
 : 
  
 80 
  
 targetPort 
 : 
  
 8080 
  
 protocol 
 : 
  
 TCP 
 

Python

To avoid hard-coding the Redis instance IP, you can create a redishost ConfigMap :

  export 
 REDISHOST_IP 
 = 
 XXX 
 . 
 XXX 
 . 
 XXX 
 . 
 XXX 
 kubectl 
 create 
 configmap 
 redishost 
 -- 
 from 
 - 
 literal 
 = 
 REDISHOST 
 = 
 $ 
 { 
 REDISHOST_IP 
 } 
 

Verify the configuration using the following command:

  kubectl 
 get 
 configmaps 
 redishost 
 - 
 o 
 yaml 
 
  # Copyright 2021 Google LLC 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #      http://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 apiVersion 
 : 
  
 extensions/v1beta1 
 kind 
 : 
  
 Deployment 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
 spec 
 : 
  
 replicas 
 : 
  
 1 
  
 template 
 : 
  
 metadata 
 : 
  
 labels 
 : 
  
 app 
 : 
  
 visit-counter 
  
 spec 
 : 
  
 containers 
 : 
  
 - 
  
 name 
 : 
  
 visit-counter 
  
 image 
 : 
  
 "gcr.io/<PROJECT-ID>/visit-counter:v1" 
  
 env 
 : 
  
 - 
  
 name 
 : 
  
 REDISHOST 
  
 valueFrom 
 : 
  
 configMapKeyRef 
 : 
  
 name 
 : 
  
 redishost 
  
 key 
 : 
  
 REDISHOST 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 http 
  
 containerPort 
 : 
  
 8080 
 --- 
 apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 visit-counter 
 spec 
 : 
  
 type 
 : 
  
 LoadBalancer 
  
 selector 
 : 
  
 app 
 : 
  
 visit-counter 
  
 ports 
 : 
  
 - 
  
 port 
 : 
  
 80 
  
 targetPort 
 : 
  
 8080 
  
 protocol 
 : 
  
 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 this command:

 kubectl get service visit-counter 

See your app hosted at http://[EXTERNAL-IP] via your browser, or send a GET request via cURL or your 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 called Preparing your GKE cluster , you installed the reserved IP range of your Redis instance to your GKE instance's IP tables. If you want to remove this Redis IP range entry from the IP tables of your GKE instance, run the following command from the k8s-custom-iptables/ directory:

 ./uninstall.sh 
Create a Mobile Website
View Site in Mobile | Classic
Share by: