I'm new to K8s and am currently using Minikube to play around with the platform. How do I configure a public (i.e. outside the cluster) port for the service? I followed the nginx example, and K8s service tutorials. In my case, I created the service like so:
kubectl expose deployment/mysrv --type=NodePort --port=1234
The service's port is 1234 for anyone trying to access it from INSIDE the cluster. The minikube tutorials say I need to access the service directly through it's random nodePort, which works for manual testing purposes:
kubectl describe service mysrv | grep NodePort
...
NodePort: <unset> 32387/TCP
# curl "http://`minikube ip`:32387/"
But I don't understand how, in a real cluster, the service could have a fixed world-accessible port. The nginx examples describe something about using the LoadBalancer service kind, but they don't even specify ports there...
Any ideas how to fix the external port for the entire service?
According to questions:
In cloud provided Kubernetes clusters
LoadBalancer
type of service will have a external IP assigned by cloud provider. The desired service will be accessible by provided external IP.LoadBalancer
will also create aNodePort
type of service automatically to route the traffic internally.NodePort
ports will not be accessible for direct connection with Node IP address with external traffic.Created
LoadBalancer
will allow you to specify a port on which it willl respond to traffic.Take a look at below reference with a link:
When you create service object of type
NodePort
with a$ kubectl expose
command you cannot choose yourNodePort
port. To choose aNodePort
port you will need to create aYAML
definition of it.You can manually specify the port in service object of type
Nodeport
with below example:You can apply above
YAML
definition by invoking command:$ kubectl apply -f FILE_NAME.yaml
Above service object will be created only if
nodePort
port is available to use.In clusters managed by cloud providers (for example GKE) you can use a service object of type
LoadBalancer
which will have a fixed external IP and fixed port.Clusters that have nodes with public IP's can use service object of type
NodePort
to direct traffic into the cluster.In
minikube
environment you can use a service object of typeLoadBalancer
but it will have some caveats described in last paragraph.A little bit of explanation:
NodePort
Nodeport
is exposing the service on each node IP at a static port. It allows external traffic to enter with theNodePort
port. This port will be automatically assigned from range of30000
to32767
.You can change the default
NodePort
port range by following this manual.You can check what is exactly happening when creating a service object of type
NodePort
by looking on this answer.Imagine that:
192.168.0.100
192.168.0.101
192.168.0.102
50001
withhello
and they have IP's:10.244.1.10
10.244.1.11
10.244.1.12
NodePort
(port32222
) with:ClusterIP
:10.96.0.100
port
:7654
targetPort
:50001
A word about
targetPort
. It's a definition for port on the pod that is for example a web server.According to above example you will get
hello
response with:NodeIP:NodePort
(all the pods could respond withhello
):192.168.0.100:32222
192.168.0.101:32222
192.168.0.102:32222
ClusterIP:port
(all the pods could respond withhello
):10.0.96.100:7654
PodIP:targetPort
(only the pod that request is sent to can respond withhello
)10.244.1.10:50001
10.244.1.11:50001
10.244.1.12:50001
You can check access with
curl
command as below:$ curl http://NODE_IP:NODEPORT
In the example you mentioned:
What will happen:
30000
to32767
on yourminikube
instance directing traffic entering this port to pods.ClusterIP
with port of1234
In the example above there was no parameter
targetPort
. IftargetPort
is not provided it will be the same asport
in the command.Traffic entering a
NodePort
will be routed directly to pods and will not go to theClusterIP
.From the
minikube
perspective aNodePort
will be a port on yourminikube
instance. It's IP address will be dependent on the hypervisor used. Exposing it outside your local machine will be heavily dependent on operating system.LoadBalancer
There is a difference between a service object of type
LoadBalancer
(1) and an externalLoadBalancer
(2):LoadBalancer
(1) allows to expose a service externally using a cloud provider’sLoadBalancer
(2). It's a service within Kubernetes environment that through service controller can schedule a creation of externalLoadBalancer
(2).LoadBalancer
(2) is a load balancer provided by cloud provider. It will operate at Layer 4.Example definition of service of type
LoadBalancer
(1):Applying above
YAML
will create a service of typeLoadBalancer
(1)Take a specific look at:
This definition will simultaneously:
LoadBalancer
(2)port
as 1234ClusterIP
port
as 1234Imagine that:
LoadBalancer
(2) have:ExternalIP
:34.88.255.5
port
:7654
192.168.0.100
192.168.0.101
192.168.0.102
50001
withhello
and they have IP's:10.244.1.10
10.244.1.11
10.244.1.12
NodePort
(port32222
) with:ClusterIP
:10.96.0.100
port
:7654
targetPort
:50001
According to above example you will get
hello
response with:ExternalIP
:port
(all the pods could respond withhello
):34.88.255.5:7654
NodeIP:NodePort
(all the pods could respond withhello
):192.168.0.100:32222
192.168.0.101:32222
192.168.0.102:32222
ClusterIP:port
(all the pods could respond withhello
):10.0.96.100:7654
PodIP:targetPort
(only the pod that request is sent to can respond withhello
)10.244.1.10:50001
10.244.1.11:50001
10.244.1.12:50001
ExternalIP
can be checked with command:$ kubectl get services
Flow of the traffic: Client ->
LoadBalancer:port
(2) ->NodeIP:NodePort
->Pod:targetPort
Minikube: LoadBalancer
Minikube
can create service object of typeLoadBalancer
(1) but it will not create an externalLoadBalancer
(2).The
ExternalIP
in command$ kubectl get services
will have pending status.To address that there is no external
LoadBalancer
(2) you can invoke$ minikube tunnel
which will create a route from host tominikube
environment to access theCIDR
ofClusterIP
directly.