Kubernetes is a complex piece of software. Over the years of learning about it, it seems to have become more complex - the more I learn, the more I realize I don't know. One thing that has become more clear, however, is networking. I was once confused as to how to allow pods to talk to each other, but no more. Here are the things that helped me understand Kubernetes Services.
Services - NodePort, Load Balancers, and ExternalName
Kubernetes allows communication in a number of different ways, and they are normally through a service, where we change the type in the yaml:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
type: NodePort
I like to think of Services as being like Pokemon that evolve. NodePort is like the first baby pokemon before it has evolved. It is the simplest way to expose a Service. It forwards the traffic to a set of pods from a port. Then the poke-service evolves into a LoadBalancer, which provides an external IP address, load balancing, and other features. Normally LoadBalancers are used in a cloud environment, which leads to the Ingress, which isn't a service at all. The Ingress provides a way to provide access to multiple services on different paths.
Here is an example LoadBalancer:
apiVersion: v1
kind: Service
metadata:
name: service1
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: service1
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: service2
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: service2
ports:
- name: http
port: 80
targetPort: 80
and Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
name: http
- host: service2.example.com
http:
paths:
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
name: http
Load Balancer vs Ingress
The difference between LoadBalancer and Ingress is a bit nuanced, but both LoadBalancer and Ingress require external implementation, such as ElasticLoadBalancer or Istio's Ingress Controller. Ingress controller's provide more advanced routing, such as based on URL Path, while the LoadBalancer implements a load balancing algorithm. Additionally, the Ingress can be the plugin point for much other features of Service Mesh, such as mTLS. LoadBalancer can provide access to multiple services, but it doesn't use the path rerouting.
Communication
"But how do you make the service call?" - In order to make the service call, just use the name of the service!
In this case:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
I could make the REST call like so, from the metadata.name:
http://**my-service**/v1/make/some-call
.
Top comments (0)