1
votes

i'm new to kubernetes , i'm trying to learn it using minikube and i'm facing a problem with accessing apps outside the cluster. i created a deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx

  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 8080

To access it i need to expose it decoratively or imperatively. In the imperative way it works :

kubectl expose deployment nginx-deployment --port 80 --type NodePort

When i create a service declaratively i always end up with a connection refused error :

apiVersion: v1

kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type : NodePort
  ports:
  - port : 8080
    nodePort : 30018
    protocol : TCP
  selector:
    app: nginx

curl -k http://NodeIP:NodePort returns :

curl: (7) Failed to connect to Node IP port NodePORT: Connection refused

2
Add target port ( kubernetes.io/docs/concepts/services-networking/service/…) and use port 30018 in your curl commandAnsil
i did it and it doesn"t work, and btw " By default and for convenience, the targetPort is set to the same value as the port field."Elias
Is it possible to update "kubectl describe" output of service and endpoints? Did you configure Nginx to listen on port 8080Ansil
There is no fundamental difference between the imperative and declarative approach in kubernetes. The imperative command boils down to the generation of a specific declarative specification. Try to run kubectl expose deployment nginx-deployment --port 80 --type NodePort --dry-run -o yaml and you'll see what I mean. Try to compare this output with your declarative yaml specification written by yourself and you should notice the key differences. I can already see a fundamental difference. Most probably if you use kubectl expose ... --port 8080 ... it won't work either ;)mario
@mario yes indeed but i can"t figure out why ? the port number should match the exact containerPort am i right ? so what's the difference in this case scenario ?Elias

2 Answers

1
votes

As @Ansil suggested, your nginx should be configured to listen on port 8080 if you want to refer to this port in your Service definition. By default it listens on port 80.

You cannot make it listen on different port like 8080 simply by specifying different containerPort in your Deployment definition as in your example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx

  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 8080

You can easily verify it on your own by attaching to such Pod:

kubectl exec -ti <nginx-pod-name> -- /bin/bash

Once you're there, run:

ss -ntlp

And you should see on which port your nginx actually listens on.

Additionally you may:

cat /etc/nginx/conf.d/default.conf

It will also tell you on which port your nginx is configured to listen. That's all. It's really simple. You changed containerPort to 8080 but inside your container nothing actually listens on such port.

You can still expose it as a Service (no matter declaratively or imperatively) but it won't change anything as eventually it points to the wrong port on your container, on which nothing listens and you'll see message similar to this one:

curl: (7) Failed to connect to 10.1.2.3 port 30080: Connection refused
0
votes

Once you create a service in minikube you can expose the service to the outside of the minikube VM (host machine) using the command

minikube service SERVICE_NAME

Refer: https://minikube.sigs.k8s.io/docs/reference/commands/service/