2

I set up a simple redis ClusterIP service to be accessed by a php LoadBalancer service inside the Cluster. The php log shows the connection timeout error. The redis service is not accessible.

'production'.ERROR: Operation timed out {"exception":"[object] (RedisException(code: 0): 
Operation timed out at /var/www/html/vendor/laravel/framework/src/Illuminate/Redis
/html/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php(109): 
    Redis->connect('redis-svc', '6379', 0, '', 0, 0)

My redis service is quite simple so I don't know what went wrong:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    io.kompose.service: redis
  name: redis
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
        io.kompose.service: redis
    spec:
      containers:
      - image: redis:alpine
        name: redis
        resources: {}
        ports:
        - containerPort: 6379
      restartPolicy: Always
status: {}
---
kind: Service
apiVersion: v1
metadata:
  name: redis-svc
spec:
  selector:
    app: redis
  ports:
  - protocol: TCP
    port: 6379
    targetPort: 6379
  type: ClusterIP

I verify redis-svc is running, so why it can't be access by other service

kubectl get service redis-svc                                                                                                                                  git:k8s*
NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
redis-svc   ClusterIP   10.101.164.225   <none>        6379/TCP   22m

This SO kubernetes cannot ping another service said ping doesn't work with service's cluster IP(indeed) how do I verify whether redis-svc can be accessed or not ?

---- update ----

My first question was a silly mistake but I still don't know how do I verify whether the service can be accessed or not (by its name). For example I changed the service name to be the same as the deployment name and I found php failed to access redis again.

kubectl get endpoints did not help now.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
...
status: {}
---
kind: Service
apiVersion: v1
metadata:
  name: redis
...

my php is another service with env set the redis's service name

spec:
  containers:
  - env:
    - name: REDIS_HOST # the php code access this variable
      value: redis-svc #changed to "redis" when redis service name changed to "redis"

----- update 2------

The reason I can' set my redis service name to "redis" is b/c "kubelet adds a set of environment variables for each active Service" so with the name "redis", there will be a REDIS_PORT=tcp://10.101.210.23:6379 which overwrite my own REDIS_PORT=6379 But my php just expect the value of REDIS_PORT to be 6379

Qiulang
  • 10,295
  • 11
  • 80
  • 129
  • 2
    Your redis pods don't appear to have the `app: redis` label, so the Service isn't routing to them. Try adding that label to the deployment's `spec`. – kevingessner Jul 09 '19 at 11:46
  • You are a lifesaver! I feel so embarrassed :$. I left my question here b/c of second question. How do I verify whether redis-svc can be accessed or not ? – Qiulang Jul 09 '19 at 11:55
  • Btw, you totally can ping service IP addresses, it all depends on what network plugin you've chosen. – zerkms Jul 10 '19 at 02:57

1 Answers1

5

I ran the yaml configuration given by you and it created the deployment and service. However when I run the below commands:

>>> kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    5d14h
redis-svc    ClusterIP   10.105.31.201   <none>        6379/TCP   109s

>>>> kubectl get endpoints
NAME         ENDPOINTS             AGE
kubernetes   192.168.99.116:8443   5d14h
redis-svc    <none>                78s

As you see, the endpoints for redis-svc is none, it means that the service doesn't have an endpoint to connect to. You are using selector labels as app: redis in the redis-svc. But the pods doesn't have the selector label defined in the service. Adding the label app: redis to the pod template will work. The complete working yaml configuration of deployment will look like:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    io.kompose.service: redis
  name: redis
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
        io.kompose.service: redis
        app: redis
    spec:
      containers:
      - image: redis:alpine
        name: redis
        resources: {}
        ports:
        - containerPort: 6379
      restartPolicy: Always
status: {}
Malathi
  • 2,119
  • 15
  • 40
  • So about my second question how do I verify whether redis-svc can be accessed or not ? – Qiulang Jul 09 '19 at 15:06
  • The endpoints are populated with pods ip that match the spec.selector label defined in service. So as mentioned, in my above question `kubectl get endpoints` doesn't have any pods ip initially. However once the pods matching the selector labels are running, the endpoints are added with the ip addresses of pods. – Malathi Jul 09 '19 at 16:14
  • Hi can you check my updated question. I used the same name for deployment and service and redis can not be access again. – Qiulang Jul 10 '19 at 02:59
  • I don't understand what exactly was the change you made. What exactly is the error? Can you please give a detailed explanation? – Malathi Jul 10 '19 at 05:04
  • I just changed the service name from "redis-svc" to "redis", other remains the same. And php reported it can not connect to redis. If I changed the name back, php can again connect to redis. – Qiulang Jul 10 '19 at 05:10
  • How are you calling the redis service from php? Is it `redis.local` or `redis-svc.local`? Also is your php code running as a pod in your cluster? – Malathi Jul 10 '19 at 05:12
  • 1
    Hi, I found the reason, as this one said https://stackoverflow.com/questions/44849024/kubectl-adding-extra-env-variable-to-pod – Qiulang Jul 11 '19 at 06:48