Kubernetes - Curl a Cluster-IP Service

Viewed 7515

I'm following this kubernetes tutorial to create a service https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#creating-a-service

I'm using minikube on my local environment. Everything works fine but I cannot curl my cluster IP. I have an operation timeout:

curl: (7) Failed to connect to 10.105.7.117 port 80: Operation timed out

My kubectl get svc

NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP      10.96.0.1       <none>        443/TCP        5d17h
my-nginx       ClusterIP      10.105.7.117    <none>        80/TCP         42h

It seems that I'm having the same issue that this guys here who did not find any answer to his problem: https://github.com/kubernetes/kubernetes/issues/86471

I have tried to do the same on my gcloud console but I have the same result. I can only curl my external IP service.

If I understood well, I'm suppose to be already in my minikube local cluster when I start minikube, so for me I should be able to curl the service like it is mention in the tutorial.

What I'm doing wrong?

2 Answers

Although each Pod has a unique IP address, those IPs are not exposed outside the cluster without a Service. Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a type in the ServiceSpec:

  • ClusterIP (default) - Exposes the Service on an internal IP in the cluster. This type makes the Service only reachable from within the cluster. That is why you cannot access your service via ClusterIP from outside the cluster.
  • NodePort - Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a Service accessible from outside the cluster using <NodeIP>:<NodePort>. Superset of ClusterIP.
kind: Service
apiVersion: v1
metadata:
  name: example
  namespace: example
spec:
  type: NodePort
  selector:
    app: example
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      name: ui

Then execute command:

$ kubectl get svc --namespace=example

NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
jenkins-ui         NodePort    yy.zz.xx.xx     <none>        8080:30960/TCP   1d

Get minikube ip to get the nodeIP

$ minikube ip
aa.bb.cc.dd

then you can curl it:

curl http://aa.bb.cc.dd:8080
  • LoadBalancer - Creates an external load balancer in the current cloud (if supported) and assigns a fixed, external IP to the Service. Superset of NodePort.
kind: Service
apiVersion: v1
metadata:
  name: example
spec:
  selector:
    app: example
  ports:
  - protocol: "TCP"
    port: 8080
    targetPort: 8080
  type: LoadBalancer
  externalIPs:
  - <your minikube ip>

then you can curl it:

$ curl http://yourminikubeip:8080/
  • ExternalName - Exposes the Service using an arbitrary name (specified by externalName in the spec) by returning a CNAME record with the name. No proxy is used. This type requires v1.7 or higher of kube-dns. The service itself is only exposed within the cluster, however, the FQDN external-name is not handled or controlled by the cluster. This is likely a publicly accessible URL so you can curl from anywhere. You'll have to configure your domain in a way that restricts who can access it.

The service type externalName is external to the cluster and really only allows for a CNAME redirect from within your cluster to an external path.

See more: esposing-services-kubernetes.

ClusterIP is only available inside the kubernetes network.

If you want to be able to hit this from outside of the cluster use a LoadBalancer to expose a public IP that you can then access from outside of the cluster

Or..

kubectl port-forward <pod_name> 8080:80

then curl

curl http://localhost:8080

which will route through the port-forward to port 80 of the pod.

Related