In Kubernetes, is there any general reason to avoid NodePort services? In what particular circumstances are NodePorts appropriate?
2 Answers
First, let's review quickly what is NodePort
service.
What is NodePort? How does it work?
- Internal Service accessible on
Service IP address + Port
- NodePort also creates ClusterIP internal Service
- NodePort, Opens Port on each Worker Node
- External traffic has access to a fixed port on each Worker Node!
Range:
30000-32676
NodePort Service Accessibility:
- NodePort accessible from outside the cluster
- On IP address of
Node IP + The NodePort
- NodePort accessible from outside the cluster
Well, it is an excellent choice for testing purposes.
But in production is not a good choice.
Why?
Because you should type each worker node IP with the corresponding NodePort.
InProduction, we want only 1 Ip that automatically LoadBalance between each worker Node.
So, let's quickly review the LoadBalancer
type.
Why LoadBalancer?
At this point, our application is accessible from the outside, but it has a couple of downgrades:
- Not user-friendly (
Node IP:NodePort
) - Insecure & messy!
- is it OK to test
- Better Alternative: LoadBalancer Service Type
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
svc: nginx-test
spec:
type: LoadBalancer # The configuration of Loadbalancer is exactly like NodePort except for this part...
selector:
app: nginx
ports:
- protocol: TCP
port: 8080
targetPort: 80
nodePort: 30000 # Notice we still have a nodePort!
How LoadBalancer works?
- LoadBalancer outside of K8s cluster
- Which accepts traffic as an entry point
- LoadBalances to 1 of Worker Node on the NodePort
- Then gets forward to ClusterIP
- Accessible at own IP address & port
- LoadBalancer is not created inside the cluster
Okay, so we learned that LoadBalancer is a better alternative in production.
But, still, it is not the Best practice and the best solution in Production.
The Best Practice in the Production environment is the Ingress
type.
Why Ingress?
Self-Managed K8s cluster: Create LoadBalancer yourself
Managed K8s cluster: Creates LoadBalancers automatically
Loadbalancer Disadvantages:
- LoadbBlancer that all become entry points
- Configure the Domain Name
- Each LoadBalancer exposes new NodePort
- Each Loadbalancer increases the cloud bill
- Configure everything outside the cluster
Isn't it good:
- Having this as part of the K8s cluster?
- Configure secure connection
- LoadBalancing to different services
Ingress
- A K8s component
- Configure
Routing
- Configure
HTTPS
- Ingress is deployed and available inside the cluster
- We need to expose it either as NodePort or LoadBalancer
- 1 NodePort or LoadBalancer, which is the single entry point
Summary
ClusterIP
:Internal
AccessNodePort
:External
Access / TestingLoadBalancer
:External
Access / ProductionIngress
:External
Access / Production / Best Practice
Be sure to check these resources as well:
-
I can't literally think of any reason why load balancing to a single IP is a good idea in production. Commented Dec 15, 2022 at 5:25
NodePorts are discouraged by sources such as this article.
Some problems:
- Nonstandard port numbers get assigned to services. These are undesirable to use, due to lack of human readability and potential to be blocked by firewalls/gateways.
- Services may clobber each other. (For example, if a service gets randomly assigned a port number that another service was going to request.)
- Security may be more difficult to verify, with direct external traffic to many nodes (and ports).
- DNS may behave poorly (hostnames of different services may be synonymous, and address record sets may become too large to fit in UDP query responses).
Situations where NodePort is still justified:
With a gateway (such as a load balancer) that translates automatically between external hostnames and internal port numbers.
For temporary testing, although
kubectl port-forward
is preferred where possible.