How do you access pods through a service?

11/26/2019

I have a deployment with 2 replicas. I can access the pods via curl.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

I created a service.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

I was expecting to be able to access the pods through the service via the EndPoints but the result I get is.

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
  "reason": "Forbidden",
  "details": {

  },
  "code": 403
}

Can someone help me understand what is going on here better?

kubectl get svc

NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP   2d23h
nginx-service   ClusterIP   10.109.19.46   <none>        80/TCP    22h

curl --insecure https://PUBLICIP:6443

-- tink3r
kubernetes

3 Answers

11/26/2019

The easiest way is to expose the service as "NodePort" using kubectl,

Initially, you have to delete the existing service,

kubectl delete svc nginx-service //if you have a namespace -n yourNameSpace

Then expose your deployment as "NodePort" as following,

kubectl expose deployment nginx-deployment --port=80 --type=NodePort --name=nginx-service //if you have a namespace -n yourNameSpace

Now the "NodePort" service has been created and you could curl to the service through,

curl NODE_IP:NODE_PORT
-- JMadushan
Source: StackOverflow

11/26/2019

With your command you're trying to access the / path of the Kubernetes API, but it fails because you're not supplying any credentials to the request:

curl --insecure https://PUBLICIP:6443

But anyway, if you want to access the Pods behind the Service, you don't need to access the Kubernetes API, but you need to access the exposed Service.

A ClusterIP service as in your example (the default) cannot be accessed from outside the cluster. If you want to access the Service from outside the cluster, you need to create, for example, a NodePort Service:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

And then you can access the Service (and thus the Pods behind it) through the IP address and NodePort of one of the worker nodes:

curl NODE_IP:NODE_PORT

You can get the NODE_IP of one of the nodes with kubectl get nodes -o wide and the NODE_PORT of the Service with kubectl get svc nginx-service.

-- weibeld
Source: StackOverflow

11/26/2019

The curl command you are using will hit the Kubernetes API server (defaults to 6443 port) ; NOT the service you created.

The nginx-service you created will create a ClusterIP service, which will not be accessible from outside. You have to use either NodePort or LoadBalancer type service.

To access your service, you can try below (using NodePort)

kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

Then get the NodePort from kubectl get svc

NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP   2d23h
nginx-service   NodePort    10.109.19.46   <none>        80:32474/TCP    22h <<<-- (NodePort is 32474)

You can use any node's IP and the port 32474 combinations to access the service.

Eg:-

curl http://192.168.10.10:32474

-- Ansil
Source: StackOverflow